This commit was manufactured by cvs2svn to create tag 'antville_1_0'.

This commit is contained in:
hns 2003-08-18 11:55:35 +00:00
parent ebdf361ce5
commit 55009478a8
205 changed files with 0 additions and 49016 deletions

View file

@ -1,97 +0,0 @@
This is the README file for version 1.2 of Helma Object Publisher.
===========
ABOUT HELMA
===========
Helma is a scriptable platform for creating dynamic, database backed
web sites.
Helma provides an easy way to map relational database tables to objects.
These objects are wrapped with a layer of scripts and skins that allow
them to be presented and manipulated over the web. The clue here is that
both functions and skins work in an object oriented manner and force
a clear separation between content, functionality and presentation.
Actions are special functions that are callable over the web. Macros are
special functions that expose functionality to the presentation layer.
Skins are pieces of layout that do not contain any application logic,
only macro tags as placeholders for parts that are dynamically provided
by the application.
In short, Helma provides a one stop framework to create web applications
with less code and in shorter time than most of the other software out
there.
===================
SYSTEM REQUIREMENTS
===================
You need a Java virtual machine 1.3 or higher to run Helma.
For Windows, Linux and Solaris you can get a Java runtime or development
kit from http://java.sun.com/j2se/downloads.html.
If you are on Mac OS X, you already have a Java runtime that will work
well with Helma.
Unfortunately, there is no Java 2 interpreter for Mac OS Classic, so
you can't use Helma on Mac OS 9.
============================
INSTALLING AND RUNNING HELMA
============================
Simply unzip or untar the contents of the archive file into any place
on your hard disk. Start Helma by invoking hop.bat or hop.sh from the
command line, depending on whether you are on Windows or
Linux/Unix/MacOSX. If the java command is not found, try setting the
JAVA_HOME variable in the start script to the location of your Java
installation.
You may also want to have a look at the start script for other settings.
You can adjust server wide settings in the server.properties file. For
example, you should set the smtp property to the name of the SMTP server
that Helma should use to send Email. Applications can be started or
stopped by editing the apps.properties file through the web interface
using the Management application that is part of Helma.
If you manage to get it running you should be able to connect your
browser to http://localhost:8080/ or http://127.0.0.1:8080/
(port 8080 on the local machine, that is).
Helma comes with a version of Jetty, a lightweight yet industrial strenth
web server developed by Mortbay Consulting. See http://jetty.mortbay.com/
for more information. While Jetty works well for deploying real web sites,
you may want to run Helma behind an existing web server. This is most
easily done by running Helma with the AJPv13 listener which allows you to
plug Helma into any web server using the Apache mod_jk module. See
http://jakarta.apache.org/tomcat/tomcat-4.1-doc/jk2/index.html for more
information on mod_jk and AJPv13.
Finally, Helma can be plugged into Servlet containers using Servlet
classes that communicate with Helma either directly or via Java RMI.
(Be warned that these options may be harder to set up and maintain though,
since most of the recent development efforts have been geared towards the
mod_jk/AJPv13 setup.)
=====================================
DOCUMENTATION AND FURTHER INFORMATION
=====================================
Currently, documentation-in-progress is available online at
http://helma.org/. We know that it sucks and hope to do some substantial
improvments within the coming weeks and months.
Your input is highly welcome. There is a mailing-list to discuss Helma at
http://helma.org/lists/listinfo/hop. Don't hesitate to voice any questions,
proposals, complaints, praise you may have on the list. We know we have
a lot to do and to learn, and we're open to suggestions.
For questions, comments or suggestions also feel free to contact
hannes@helma.at.
--
Last modified on December 5, 2002 by Hannes Wallnoefer <hannes@helma.at>

View file

@ -1,4 +0,0 @@
# List of apps to start.
test

View file

@ -1,93 +0,0 @@
This is the README file for the Helma build files as part of the Helma Object Publisher. It is included in the current distribution (version 1.2pre as of 8 November 2001) downloadable at <http://helma.org/download>.
The build directory consists of the following files:
ant.jar
build.bat
build.sh
build.xml
crimson.jar
jaxp.jar
README
PREREQUISITES
=============
The Helma build script is using a software called Ant. Ant is a build system that was developed for the Jakarta Tomcat project. For more information about Ant, see <http://jakarta.apache.org/ant/>.
To run Ant, you also need JDK 1.3 or higher <http://java.sun.com/j2se/>.
For checking out the source files from Helma's CVS you also need a local installation of a CVS command-line client. More information about CVS at <http://www.cvshome.org/>.
STARTING BUILD
==============
The build system is started by invoking the shell script appropriate to your platform, ie. build.sh for *nix (Linux, NetBSD etc.) and build.bat for Windows systems. You need to modify the script and set the JAVA_HOME to fit your system.
The generic syntax is
./build target
The parameter "target" specifies one of the following build targets.
BUILD A SNAPSHOT
================
To build a helma.jar with the most up-to-date version of helma yourself you need to run
./build checkout
and
./build snapshot
BUILD TARGETS
=============
checkout
Fetches (or updates, resp.) the Helma source code in the src/-directory from the CVS. If you've still got the sourcecode that came with the distribution in there, you need to move that away first.
snapshot
Runs snapshotcompile and stuffs the class files as .jar archive in the lib directory. The file is named helma-yyyymmdd.jar.
snapshotcompile
Compiles the source files contained in the src/hop directory into the classes directory (which will be created if necessary). You can use the source files from your distribution or you can get the most recent version by checking out the "hop"-module from the cvs.
fullcheckout
Fetches (or updates, resp.) everything that's needed to create a full Helma distribution (source files, build files, libs, demo-apps) from the CVS and copies them into the work/checkout/ directory (which will be created if necessary).
compile
Compiles the source files contained in the work/checkout/hop/ directory into the work/classes/ directory (which will be created if necessary).
jar
Stuffs the files in work/classes/ together and saves them as .jar archive in the work directory. The file is named helma-yyyymmdd.jar.
javadocs
Creates the Java API documentation for the Helma classes. The resulting files are saved into the work/docs/api/ directory (which will be created if necessary).
helmadocs
Gets the documentation from helma.org via http in a printable version. (still some way to go..)
package
Builds all previous targets (checkout, compile, jar, javadoc) and saves the created files in the directory work/helma-1.x/ (with 1.x being the version number). All directories will be created if necessary.
package-zip
Same as "package". Additionally, the files in the output directory will be compressed as .zip file.
package-tgz
Same as "package". Additionall, the file in the output directory will be compressed as .tar.gz file.
package-all
Builds all previous targets. The result is a complete and up-to-date (as in the CVS) installation of Helma, the API documentation, source and build files as well as compressed packages for *nix and Windows systems including all the files.
--
This README was last updated on 26 April 2002. Questions? tobi@helma.org

Binary file not shown.

View file

@ -1,48 +0,0 @@
@echo off
set TARGET=%1%
REM set JAVA_HOME=c:\programme\jdk13
REM --------------------------------------------
REM No need to edit anything past here
REM --------------------------------------------
set BUILDFILE=build.xml
if "%TARGET%" == "" goto setdist
goto cont1
:cont1
if not "%2%" == "" goto setapp
goto final
:setdist
set TARGET=usage
goto cont1
:setapp
set APPNAME=-Dapplication=%2%
goto final
:final
if "%JAVA_HOME%" == "" goto javahomeerror
set CP=%CLASSPATH%;ant.jar;jaxp.jar;crimson.jar
if exist %JAVA_HOME%\lib\tools.jar set CP=%CP%;%JAVA_HOME%\lib\tools.jar
echo Classpath: %CP%
echo JAVA_HOME: %JAVA_HOME%
%JAVA_HOME%\bin\java.exe -classpath "%CP%" %APPNAME% org.apache.tools.ant.Main -buildfile %BUILDFILE% %TARGET%
goto end
REM -----------ERROR-------------
:javahomeerror
echo "ERROR: JAVA_HOME not found in your environment."
echo "Please, set the JAVA_HOME variable in your environment to match the"
echo "location of the Java Virtual Machine you want to use."
:end

View file

@ -1,31 +0,0 @@
#!/bin/sh
# export JAVA_HOME=/usr/lib/j2sdk1.4.0
#--------------------------------------------
# No need to edit anything past here
#--------------------------------------------
if test -z "${JAVA_HOME}" ; then
echo "ERROR: JAVA_HOME not found in your environment."
echo "Please, set the JAVA_HOME variable in your environment to match the"
echo "location of the Java Virtual Machine you want to use."
exit
fi
if test -f ${JAVA_HOME}/lib/tools.jar ; then
CLASSPATH=${CLASSPATH}:${JAVA_HOME}/lib/tools.jar
fi
if test -n "${2}" ; then
APPNAME=-Dapplication=${2}
fi
CP=${CLASSPATH}:ant.jar:jaxp.jar:../lib/crimson.jar
echo "Classpath: ${CP}"
echo "JAVA_HOME: ${JAVA_HOME}"
BUILDFILE=build.xml
${JAVA_HOME}/bin/java -classpath ${CP} ${APPNAME} org.apache.tools.ant.Main -buildfile ${BUILDFILE} ${1}

View file

@ -1,402 +0,0 @@
<?xml version="1.0"?>
<project name="Helma" default="usage" basedir=".">
<!-- =================================================================== -->
<!-- Initializes some variables -->
<!-- =================================================================== -->
<target name="init">
<property name="Name" value="helma"/>
<property name="year" value="1998-${year}"/>
<property name="version" value="1.3.0-alpha"/>
<property name="project" value="helma"/>
<property name="build.compiler" value="classic"/>
<property name="cvs.root.apps" value=":pserver:anonymous@adele.helma.at:/opt/cvs/apps"/>
<property name="cvs.root.helma" value=":pserver:anonymous@adele.helma.at:/opt/cvs/helma"/>
<property name="home.dir" value=".."/>
<property name="build.dir" value="${home.dir}/build"/>
<property name="build.src" value="${home.dir}/src"/>
<property name="build.lib" value="${home.dir}/lib"/>
<property name="build.classes" value="${home.dir}/classes"/>
<property name="build.docs" value="${home.dir}/docs"/>
<property name="build.javadocs" value="${home.dir}/docs/api"/>
<property name="build.work" value="${home.dir}/work"/>
<property name="build.dist" value="${home.dir}/dist"/>
<property name="jar.name" value="${project}"/>
<property name="package.name" value="${project}-${version}"/>
<property name="antclick.name" value="antclick-1.0.1-pre1"/>
<property name="debug" value="on"/>
<property name="optimize" value="on"/>
<property name="deprecation" value="off"/>
<path id="build.class.path">
<fileset dir="${home.dir}/lib">
<exclude name="**/helma*.jar" />
<include name="**/*.jar" />
</fileset>
</path>
<tstamp/>
<filter token="year" value="${year}"/>
<filter token="version" value="${version}"/>
<filter token="date" value="${TODAY}"/>
</target>
<!-- =================================================================== -->
<!-- Help on usage -->
<!-- =================================================================== -->
<target name="help" depends="usage" />
<target name="usage">
<echo message=""/>
<echo message=""/>
<echo message="Helma build instructions"/>
<echo message="-------------------------------------------------------------"/>
<echo message=""/>
<echo message=" available targets are:"/>
<echo message=""/>
<echo message=" compile --> compiles the source code to ./classes"/>
<echo message=" jar --> generates the ./lib/helma-YYYYMMDD.jar file"/>
<echo message=" javadocs --> generates the API docs"/>
<echo message=" docs --> tries to retrieve the HTML documentation "/>
<echo message=" (may need proxy settings in startscript)"/>
<echo message=" package --> generates the distribution (zip and tar.gz)"/>
<echo message=" antclick --> generates the distribution (zip and tar.gz)"/>
<echo message=" with antville preconfigured"/>
<echo message=" app [name] --> gets an application from the cvs and zips it"/>
<echo message=""/>
<echo message=" usage --> provides help on using the build tool (default)"/>
<echo message=""/>
<echo message=" See comments inside the build.xml file for more details."/>
<echo message="-------------------------------------------------------------"/>
<echo message=""/>
<echo message=""/>
</target>
<!-- =================================================================== -->
<!-- Compiles the source directory -->
<!-- =================================================================== -->
<target name="compile" depends="init">
<mkdir dir="${build.classes}"/>
<javac srcdir="${build.src}"
destdir="${build.classes}"
debug="${debug}"
deprecation="${deprecation}"
optimize="${optimize}">
<classpath refid="build.class.path" />
</javac>
<rmic classname="helma.framework.core.RemoteApplication" base="${build.classes}"/>
</target>
<!-- =================================================================== -->
<!-- Creates a helma.jar file (snapshot) in the lib-directory -->
<!-- =================================================================== -->
<target name="jar" depends="compile">
<jar jarfile="${build.lib}/${jar.name}-${DSTAMP}.jar"
basedir="${build.classes}"
excludes="**/package.html,**/main/launcher/**"/>
<jar jarfile="${home.dir}/launcher.jar"
basedir="${build.classes}"
includes="**/main/launcher/**"
manifest="${build.src}/helma/main/launcher/manifest.txt"/>
</target>
<!-- =================================================================== -->
<!-- Creates the API documentation -->
<!-- =================================================================== -->
<target name="javadocs" depends="init">
<mkdir dir="${build.javadocs}"/>
<javadoc packagenames="helma.*"
sourcepath="${build.src}"
destdir="${build.javadocs}"
author="false"
private="false"
version="false"
windowtitle="${Name} ${version} API"
doctitle="${Name} ${version} API"
bottom="Copyright &#169; ${year} Helma.org. All Rights Reserved."
classpathref="build.class.path"
/>
</target>
<!-- =================================================================== -->
<!-- Get the documentation (currently can fail due to request time-out -->
<!-- or missing support for proxies) -->
<!-- =================================================================== -->
<target name="docs" depends="init">
<get src="http://www.helma.org/docs/reference/print"
dest="${build.docs}/reference.html"
ignoreerrors="true"
/>
</target>
<!-- =================================================================== -->
<!-- Creates the full helma distribution -->
<!-- =================================================================== -->
<target name="package" depends="init">
<mkdir dir="${build.work}"/>
<!-- create the main part of helma -->
<antcall target="package-raw">
<param name="distribution" value="main" />
</antcall>
<chmod perm="755">
<fileset dir="${build.work}">
<include name="hop.sh"/>
</fileset>
</chmod>
<!-- checkout the demo apps (and zip manage-app) -->
<antcall target="package-apps" />
<!-- zip up the whole thing -->
<antcall target="package-zip">
<param name="filename" value="${package.name}"/>
</antcall>
<antcall target="package-tgz">
<param name="filename" value="${package.name}"/>
</antcall>
<!-- make the src distributions -->
<antcall target="package-src-zip">
<param name="filename" value="${package.name}"/>
</antcall>
<antcall target="package-src-tgz">
<param name="filename" value="${package.name}"/>
</antcall>
<!-- clean up -->
<delete dir="${build.work}"/>
</target>
<!-- =================================================================== -->
<!-- Compile Helma and prepare the skeleton in a temporary directory. -->
<!-- Used by package and antclick. -->
<!-- =================================================================== -->
<target name="package-raw" depends="init, jar">
<!-- copy the framework (apps.props, server.props, hop/db, hop/static) -->
<copy todir="${build.work}">
<fileset dir="${build.dir}/${distribution}" excludes="**/CVS**"/>
</copy>
<!-- copy the launcher jar file -->
<copy file="${home.dir}/launcher.jar" todir="${build.work}/"/>
<!-- copy README.txt -->
<copy file="${home.dir}/README.txt" todir="${build.work}/"/>
<!-- copy the whole docs-directory -->
<!-- copy todir="${build.work}/docs">
<fileset dir="${build.docs}"/>
</copy -->
<!-- copy all libraries except helma-YYYYMMDD.jar -->
<copy todir="${build.work}/lib">
<fileset dir="${home.dir}/lib">
<exclude name="**/helma*.jar" />
<include name="**/*.jar" />
</fileset>
</copy>
<!-- copy the whole licenses-directory -->
<copy todir="${build.work}/licenses">
<fileset dir="${home.dir}/licenses" excludes="**/CVS**"/>
</copy>
<!-- rename the current jar-file -->
<copy file="${build.lib}/${jar.name}-${DSTAMP}.jar" tofile="${build.work}/lib/helma.jar"/>
<!-- zip the sourcecode -->
<!-- mkdir dir="${build.work}/src"/>
<tar tarfile="${build.work}/src/helma-src.tar" basedir="${build.src}/">
<tarfileset dir="${build.src}">
<include name="${build.src}/**"/>
</tarfileset>
</tar>
<gzip zipfile="${build.work}/src/helma-src.tar.gz" src="${build.work}/src/helma-src.tar"/>
<delete file="${build.work}/src/helma-src.tar"/ -->
</target>
<!-- =================================================================== -->
<!-- Checkout demo apps, put them in work directory and zip manage app -->
<!-- =================================================================== -->
<target name="package-apps" depends="init">
<mkdir dir="${build.work}/apps" />
<!-- get demo apps -->
<cvs cvsRoot="${cvs.root.apps}" command="export" tag="HEAD" package="base" dest="${build.work}/apps" />
<cvs cvsRoot="${cvs.root.apps}" command="export" tag="HEAD" package="bloggerapi" dest="${build.work}/apps" />
<cvs cvsRoot="${cvs.root.apps}" command="export" tag="HEAD" package="himp" dest="${build.work}/apps" />
<cvs cvsRoot="${cvs.root.apps}" command="export" tag="HEAD" package="gong" dest="${build.work}/apps" />
<cvs cvsRoot="${cvs.root.apps}" command="export" tag="HEAD" package="lillebror" dest="${build.work}/apps" />
<antcall target="package-manage" />
</target>
<!-- =================================================================== -->
<!-- Checkout and zip manage application -->
<!-- =================================================================== -->
<target name="package-manage" depends="init">
<cvs cvsRoot="${cvs.root.apps}" command="export" tag="HEAD" package="manage" dest="${build.work}" />
<mkdir dir="${build.work}/apps/manage"/>
<zip zipfile="${build.work}/apps/manage/manage.zip" basedir="${build.work}/manage/" includes="**" excludes="**/properties,readme/**" />
<copy todir="${build.work}/apps/manage">
<fileset dir="${build.work}/manage" includes="app.properties,class.properties,readme.txt"/>
</copy>
<delete dir="${build.work}/manage" />
</target>
<!-- =================================================================== -->
<!-- Packages the work directory with TAR-GZIP -->
<!-- needs parameter ${filename} for final dist-file -->
<!-- =================================================================== -->
<target name="package-tgz" depends="init">
<mkdir dir="${build.dist}" />
<fixcrlf srcdir="${build.work}" eol="lf" eof="remove" includes="**/*.txt, **/*.properties, **/*.hac, **/*.js, **/*.skin" />
<tar tarfile="${build.dist}/${filename}.tar" basedir="${build.work}" excludes="**">
<tarfileset prefix="${filename}" dir="${build.work}" mode="755">
<include name="hop.sh"/>
</tarfileset>
<tarfileset prefix="${filename}" dir="${build.work}">
<include name="**"/>
<exclude name="hop.sh"/>
</tarfileset>
</tar>
<gzip zipfile="${build.dist}/${filename}.tar.gz" src="${build.dist}/${filename}.tar"/>
<delete file="${build.dist}/${filename}.tar"/>
</target>
<!-- =================================================================== -->
<!-- Packages the work directory with ZIP -->
<!-- needs parameter ${filename} for final dist-file -->
<!-- =================================================================== -->
<target name="package-zip" depends="init">
<mkdir dir="${build.dist}" />
<fixcrlf srcdir="${build.work}" eol="crlf" includes="**/*.txt, **/*.properties, **/*.hac, **/*.js, **/*.skin, **/*.xml" />
<zip zipfile="${build.dist}/${filename}.zip">
<zipfileset dir="${build.work}" prefix="${filename}" includes="**" />
</zip>
</target>
<!-- =================================================================== -->
<!-- Packages Helma src and build directories with TAR-GZIP -->
<!-- needs parameter ${filename} for final dist-file -->
<!-- =================================================================== -->
<target name="package-src-tgz" depends="init">
<mkdir dir="${build.dist}" />
<tar tarfile="${build.dist}/${filename}-src.tar">
<tarfileset prefix="${filename}" dir="${home.dir}"
includes="src/**,build/**,license.txt,licenses/**"/>
</tar>
<gzip zipfile="${build.dist}/${filename}-src.tar.gz" src="${build.dist}/${filename}-src.tar"/>
<delete file="${build.dist}/${filename}-src.tar"/>
</target>
<!-- =================================================================== -->
<!-- Packages Helma src and build directories with ZIP -->
<!-- needs parameter ${filename} for final dist-file -->
<!-- =================================================================== -->
<target name="package-src-zip" depends="init">
<mkdir dir="${build.dist}" />
<zip zipfile="${build.dist}/${filename}-src.zip">
<zipfileset dir="${home.dir}" prefix="${filename}"
includes="src/**,build/**,license.txt,licenses/**" />
</zip>
</target>
<!-- =================================================================== -->
<!-- Make Antclick package (helma plus Antville and manage apps) -->
<!-- =================================================================== -->
<target name="antclick" depends="init">
<mkdir dir="${build.work}"/>
<!-- create the main part of helma -->
<antcall target="package-raw">
<param name="distribution" value="antclick" />
</antcall>
<!-- get antville -->
<mkdir dir="${build.work}/apps" />
<!-- to retrieve special versions of antville insert additional attributes:
tag="TAGNAME", date="1972-09-24" or date="1972-09-24 20:05" -->
<cvs cvsRoot="${cvs.root.apps}" command="export" tag="HEAD" package="antville" dest="${build.work}/apps" />
<!-- unzip images -->
<mkdir dir="${build.work}/static/images"/>
<unzip src="${build.work}/apps/antville/images.zip" dest="${build.work}/static/images">
<patternset>
<include name="**"/>
</patternset>
</unzip>
<!-- delete antville's mysql-scripts, image-zip etc -->
<delete>
<fileset dir="${build.work}/apps/antville" includes="images.zip,*.sql" />
</delete>
<!-- get and zip manage-app -->
<antcall target="package-manage" />
<!-- zip up the whole thing -->
<antcall target="package-zip">
<param name="filename" value="${antclick.name}"/>
</antcall>
<antcall target="package-tgz">
<param name="filename" value="${antclick.name}"/>
</antcall>
<!-- clean up -->
<delete dir="${build.work}"/>
</target>
<!-- =================================================================== -->
<!-- Gets an application from the cvs and zips/targzs it -->
<!-- =================================================================== -->
<target name="app" depends="init">
<mkdir dir="${build.dist}" />
<mkdir dir="${build.work}" />
<!-- to retrieve special versions of an application insert
additional attributes: tag="TAGNAME" or date="1972-09-24 20:05" -->
<cvs cvsRoot="${cvs.root.apps}" command="export" tag="HEAD" package="${application}" dest="${build.work}" />
<fixcrlf srcdir="${build.work}" eol="crlf" eof="add" includes="**/*.txt, **/*.properties, **/*.hac, **/*.js, **/*.skin, **/*.xml" />
<zip zipfile="${build.dist}/${application}-${DSTAMP}.zip" basedir="${build.work}" includes="**"/>
<fixcrlf srcdir="${build.work}" eol="lf" eof="remove" includes="**/*.txt, **/*.properties, **/*.hac, **/*.js, **/*.skin" />
<tar tarfile="${build.dist}/${application}-${DSTAMP}.tar" basedir="${build.work}">
<tarfileset dir="${build.work}">
<include name="${build.work}/**"/>
</tarfileset>
</tar>
<gzip zipfile="${build.dist}/${application}-${DSTAMP}.tar.gz" src="${build.dist}/${application}-${DSTAMP}.tar" />
<delete file="${build.dist}/${application}-${DSTAMP}.tar" />
<delete dir="${build.work}" />
</target>
</project>

Binary file not shown.

Binary file not shown.

View file

@ -1,13 +0,0 @@
# List of applications to start.
base
base.mountpoint = /
base.static = static
base.staticMountpoint = /static
manage
gong
himp
bloggerapi
lillebror

View file

@ -1,16 +0,0 @@
# This is where you specify relational data sources to
# map Helma types to relational databases.
#
# If you want to define a data source just for one
# application, simply copy the db.properties file to
# the application directory.
#
# The actual mapping of types is done in the
# type.properties file in the prototype directories.
#
# Properties of JDBC data sources
myDataSource.url = jdbc:mysql://db.domain.com/space
myDataSource.driver = org.gjt.mm.mysql.Driver
myDataSource.user = username
myDataSource.password = xyz

View file

@ -1,79 +0,0 @@
@echo off
rem Batch file for Starting Helma with a JDK-like virtual machine.
rem To add jar files to the classpath, simply place them into the
rem lib/ext directory of this Helma installation.
:: Initialize variables
:: (don't touch this section)
set JAVA_HOME=
set HOP_HOME=
set HTTP_PORT=
set XMLRPC_PORT=
set AJP13_PORT=
set RMI_PORT=
set OPTIONS=
:: Set TCP ports for Helma servers
:: (comment/uncomment to de/activate)
set HTTP_PORT=8080
rem set XMLRPC_PORT=8081
rem set AJP13_PORT=8009
rem set RMI_PORT=5050
:: Uncomment to set HOP_HOME
rem set HOP_HOME=c:\program files\helma
:: Uncomment to set JAVA_HOME variable
rem set JAVA_HOME=c:\program files\java
:: Uncomment to pass options to the Java virtual machine
rem set JAVA_OPTIONS=-server -Xmx128m
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::: No user configuration needed below this line :::::::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Setting the script path
set INSTALL_DIR=%~d0%~p0
:: Using JAVA_HOME variable if defined. Otherwise,
:: Java executable must be contained in PATH variable
if "%JAVA_HOME%"=="" goto default
set JAVACMD=%JAVA_HOME%\bin\java
goto end
:default
set JAVACMD=java
:end
:: Setting HOP_HOME to script path if undefined
if "%HOP_HOME%"=="" (
set HOP_HOME=%INSTALL_DIR%
)
cd %HOP_HOME%
:: Setting Helma server options
if not "%HTTP_PORT%"=="" (
echo Starting HTTP server on port %HTTP_PORT%
set OPTIONS=%OPTIONS% -w %HTTP_PORT%
)
if not "%XMLRPC_PORT%"=="" (
echo Starting XML-RPC server on port %XMLRPC_PORT%
set OPTIONS=%OPTIONS% -x %XMLRPC_PORT%
)
if not "%AJP13_PORT%"=="" (
echo Starting AJP13 listener on port %AJP13_PORT%
set OPTIONS=%OPTIONS% -jk %AJP13_PORT%
)
if not "%RMI_PORT%"=="" (
echo Starting RMI server on port %RMI_PORT%
set OPTIONS=%OPTIONS% -p %RMI_PORT%
)
if not "%HOP_HOME%"=="" (
echo Serving applications from %HOP_HOME%
set OPTIONS=%OPTIONS% -h "%HOP_HOME%
)
:: Invoking the Java virtual machine
%JAVACMD% %JAVA_OPTIONS% -jar "%INSTALL_DIR%\launcher.jar" %OPTIONS%

View file

@ -1,80 +0,0 @@
#!/bin/sh
# Shell script for starting Helma with a JDK-like virtual machine.
# To add JAR files to the classpath, simply place them into the
# lib/ext directory.
# uncomment to set JAVA_HOME variable
# JAVA_HOME=/usr/lib/java
# uncomment to set HOP_HOME, otherwise we get it from the script path
# HOP_HOME=/usr/local/helma
# options to pass to the Java virtual machine
# JAVA_OPTIONS="-server -Xmx128m"
# Set TCP ports for Helma servers
# (comment/uncomment to de/activate)
HTTP_PORT=8080
# XMLRPC_PORT=8081
# AJP13_PORT=8009
# RMI_PORT=5050
###########################################################
###### No user configuration needed below this line #######
###########################################################
# if JAVA_HOME variable is set, use it. Otherwise, Java executable
# must be contained in PATH variable.
if [ "$JAVA_HOME" ]; then
JAVACMD="$JAVA_HOME/bin/java"
else
JAVACMD=java
fi
# Check if java command is executable
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly."
echo " We cannot execute $JAVACMD"
exit
fi
# Get the Helma installation directory
INSTALL_DIR="${0%/*}"
cd $INSTALL_DIR
INSTALL_DIR=$PWD
# get HOP_HOME variable if it isn't set
if [ -z "$HOP_HOME" ]; then
# try to get HOP_HOME from script file and pwd
# strip everyting behind last slash
HOP_HOME="${0%/*}"
cd $HOP_HOME
HOP_HOME=$PWD
else
cd $HOP_HOME
fi
echo "Starting Helma in directory $HOP_HOME"
if [ "$HTTP_PORT" ]; then
SWITCHES="$SWITCHES -w $HTTP_PORT"
echo Starting HTTP server on port $HTTP_PORT
fi
if [ "$XMLRPC_PORT" ]; then
SWITCHES="$SWITCHES -x $XMLRPC_PORT"
echo Starting XML-RPC server on port $XMLRPC_PORT
fi
if [ "$AJP13_PORT" ]; then
SWITCHES="$SWITCHES -jk $AJP13_PORT"
echo Starting AJP13 listener on port $AJP13_PORT
fi
if [ "$RMI_PORT" ]; then
SWITCHES="$SWITCHES -p $RMI_PORT"
echo Starting RMI server on port $RMI_PORT
fi
if [ "$HOP_HOME" ]; then
SWITCHES="$SWITCHES -h $HOP_HOME"
fi
# Invoke the Java VM
$JAVACMD $JAVA_OPTIONS -jar "$INSTALL_DIR/launcher.jar" $SWITCHES

View file

@ -1,49 +0,0 @@
Copyright (c) 1999-2002 Helma Project. All rights reserved.
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. Products derived from this software may not be called "Helma"
or "Hop", nor may "Helma" or "Hop" appear in their name, without
prior written permission of the Helma Project Group. For written
permission, please contact helma@helma.org.
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 THE HELMA PROJECT OR ITS
CONTRIBUTORS 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.
This product contains the FESI EcmaScript interpreter written by
Jean-Marc Lugrin (http://home.worldcom.ch/jmlugrin/fesi/). FESI is
released under the GNU Lesser General Public License (see licenses/lesser.txt).
This product contains software from the Acme package written by Jef
Poskanzer. Please see the licensing terms in the Acme source code and check out
Jef's site at http://www.acme.com/.
This product includes software developed by the Apache Software Foundation
released under the Apache Software License (licenses/apache.txt).
This product includes software developed by the JDOM Project
(http://www.jdom.org/). Please see the licensing terms in licenses/jdom.txt
This product includes software developed by the Word Wide Web Consortium
(http://www.w3c.org/). Please see the licensing terms in licenses/w3c.html.

View file

@ -1,27 +0,0 @@
# The SMTP server to use for sending mails. Set and
# uncomment this line before trying to send mails from
# Helma applications.
#
# smtp=mail.yourdomain.com
# Some examples for server-wide locale settings
# (please refer to http://userpage.chemie.fu-berlin.de/diverse/doc/ISO_3166.html
# for country codes, resp. http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt
# for language codes).
#
# country = AT
# language = de
#
# country = UK
# language = en
#
# country = FR
# language = fr
#
# country = CZ
# language = cs
# list ip addresses for admin-application here:
allowAdmin=127.0.0.1, 192.168.0.1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

View file

@ -1,4 +0,0 @@
This file should appear at http://<host>:<port>/static/test.txt
if you use the embedded Web server (-w option on commandline).

View file

@ -1,6 +0,0 @@
cd build
./build.sh jar
cd ..
mv lib/helma-* lib/helma.jar
./hop.sh

View file

@ -1,16 +0,0 @@
# This is where you specify relational data sources to
# map Helma types to relational databases.
#
# If you want to define a data source just for one
# application, simply copy the db.properties file to
# the application directory.
#
# The actual mapping of types is done in the
# type.properties file in the prototype directories.
#
# Properties of JDBC data sources
myDataSource.url = jdbc:mysql://db.domain.com/space
myDataSource.driver = org.gjt.mm.mysql.Driver
myDataSource.user = username
myDataSource.password = xyz

File diff suppressed because it is too large Load diff

79
hop.bat
View file

@ -1,79 +0,0 @@
@echo off
rem Batch file for Starting Helma with a JDK-like virtual machine.
rem To add jar files to the classpath, simply place them into the
rem lib/ext directory of this Helma installation.
:: Initialize variables
:: (don't touch this section)
set JAVA_HOME=
set HOP_HOME=
set HTTP_PORT=
set XMLRPC_PORT=
set AJP13_PORT=
set RMI_PORT=
set OPTIONS=
:: Set TCP ports for Helma servers
:: (comment/uncomment to de/activate)
set HTTP_PORT=8080
rem set XMLRPC_PORT=8081
rem set AJP13_PORT=8009
rem set RMI_PORT=5050
:: Uncomment to set HOP_HOME
rem set HOP_HOME=c:\program files\helma
:: Uncomment to set JAVA_HOME variable
rem set JAVA_HOME=c:\program files\java
:: Uncomment to pass options to the Java virtual machine
rem set JAVA_OPTIONS=-server -Xmx128m
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::: No user configuration needed below this line :::::::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Setting the script path
set INSTALL_DIR=%~d0%~p0
:: Using JAVA_HOME variable if defined. Otherwise,
:: Java executable must be contained in PATH variable
if "%JAVA_HOME%"=="" goto default
set JAVACMD=%JAVA_HOME%\bin\java
goto end
:default
set JAVACMD=java
:end
:: Setting HOP_HOME to script path if undefined
if "%HOP_HOME%"=="" (
set HOP_HOME=%INSTALL_DIR%
)
cd %HOP_HOME%
:: Setting Helma server options
if not "%HTTP_PORT%"=="" (
echo Starting HTTP server on port %HTTP_PORT%
set OPTIONS=%OPTIONS% -w %HTTP_PORT%
)
if not "%XMLRPC_PORT%"=="" (
echo Starting XML-RPC server on port %XMLRPC_PORT%
set OPTIONS=%OPTIONS% -x %XMLRPC_PORT%
)
if not "%AJP13_PORT%"=="" (
echo Starting AJP13 listener on port %AJP13_PORT%
set OPTIONS=%OPTIONS% -jk %AJP13_PORT%
)
if not "%RMI_PORT%"=="" (
echo Starting RMI server on port %RMI_PORT%
set OPTIONS=%OPTIONS% -p %RMI_PORT%
)
if not "%HOP_HOME%"=="" (
echo Serving applications from %HOP_HOME%
set OPTIONS=%OPTIONS% -h "%HOP_HOME%
)
:: Invoking the Java virtual machine
%JAVACMD% %JAVA_OPTIONS% -jar "%INSTALL_DIR%\launcher.jar" %OPTIONS%

80
hop.sh
View file

@ -1,80 +0,0 @@
#!/bin/sh
# Shell script for starting Helma with a JDK-like virtual machine.
# To add JAR files to the classpath, simply place them into the
# lib/ext directory.
# uncomment to set JAVA_HOME variable
# JAVA_HOME=/usr/lib/java
# uncomment to set HOP_HOME, otherwise we get it from the script path
# HOP_HOME=/usr/local/helma
# options to pass to the Java virtual machine
# JAVA_OPTIONS="-server -Xmx128m"
# Set TCP ports for Helma servers
# (comment/uncomment to de/activate)
HTTP_PORT=8080
# XMLRPC_PORT=8081
# AJP13_PORT=8009
# RMI_PORT=5050
###########################################################
###### No user configuration needed below this line #######
###########################################################
# if JAVA_HOME variable is set, use it. Otherwise, Java executable
# must be contained in PATH variable.
if [ "$JAVA_HOME" ]; then
JAVACMD="$JAVA_HOME/bin/java"
else
JAVACMD=java
fi
# Check if java command is executable
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly."
echo " We cannot execute $JAVACMD"
exit
fi
# Get the Helma installation directory
INSTALL_DIR="${0%/*}"
cd $INSTALL_DIR
INSTALL_DIR=$PWD
# get HOP_HOME variable if it isn't set
if [ -z "$HOP_HOME" ]; then
# try to get HOP_HOME from script file and pwd
# strip everyting behind last slash
HOP_HOME="${0%/*}"
cd $HOP_HOME
HOP_HOME=$PWD
else
cd $HOP_HOME
fi
echo "Starting Helma in directory $HOP_HOME"
if [ "$HTTP_PORT" ]; then
SWITCHES="$SWITCHES -w $HTTP_PORT"
echo Starting HTTP server on port $HTTP_PORT
fi
if [ "$XMLRPC_PORT" ]; then
SWITCHES="$SWITCHES -x $XMLRPC_PORT"
echo Starting XML-RPC server on port $XMLRPC_PORT
fi
if [ "$AJP13_PORT" ]; then
SWITCHES="$SWITCHES -jk $AJP13_PORT"
echo Starting AJP13 listener on port $AJP13_PORT
fi
if [ "$RMI_PORT" ]; then
SWITCHES="$SWITCHES -p $RMI_PORT"
echo Starting RMI server on port $RMI_PORT
fi
if [ "$HOP_HOME" ]; then
SWITCHES="$SWITCHES -h $HOP_HOME"
fi
# Invoke the Java VM
$JAVACMD $JAVA_OPTIONS -jar "$INSTALL_DIR/launcher.jar" $SWITCHES

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,49 +0,0 @@
Copyright (c) 1999-2002 Helma Project. All rights reserved.
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. Products derived from this software may not be called "Helma"
or "Hop", nor may "Helma" or "Hop" appear in their name, without
prior written permission of the Helma Project Group. For written
permission, please contact helma@helma.org.
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 THE HELMA PROJECT OR ITS
CONTRIBUTORS 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.
This product contains the FESI EcmaScript interpreter written by
Jean-Marc Lugrin (http://home.worldcom.ch/jmlugrin/fesi/). FESI is
released under the GNU Lesser General Public License (see licenses/lesser.txt).
This product contains software from the Acme package written by Jef
Poskanzer. Please see the licensing terms in the Acme source code and check out
Jef's site at http://www.acme.com/.
This product includes software developed by the Apache Software Foundation
released under the Apache Software License (licenses/apache.txt).
This product includes software developed by the JDOM Project
(http://www.jdom.org/). Please see the licensing terms in licenses/jdom.txt
This product includes software developed by the Word Wide Web Consortium
(http://www.w3c.org/). Please see the licensing terms in licenses/w3c.html.

View file

@ -1,56 +0,0 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* 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 end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* 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 THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS 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.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/

View file

@ -1,56 +0,0 @@
/*--
$Id$
Copyright (C) 2000-2002 Brett McLaughlin & Jason Hunter.
All rights reserved.
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 disclaimer that follows
these conditions in the documentation and/or other materials
provided with the distribution.
3. The name "JDOM" must not be used to endorse or promote products
derived from this software without prior written permission. For
written permission, please contact license@jdom.org.
4. Products derived from this software may not be called "JDOM", nor
may "JDOM" appear in their name, without prior written permission
from the JDOM Project Management (pm@jdom.org).
In addition, we request (but do not require) that you include in the
end-user documentation provided with the redistribution and/or in the
software itself an acknowledgement equivalent to the following:
"This product includes software developed by the
JDOM Project (http://www.jdom.org/)."
Alternatively, the acknowledgment may be graphical using the logos
available at http://www.jdom.org/images/logos.
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 THE JDOM AUTHORS OR THE PROJECT
CONTRIBUTORS 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.
This software consists of voluntary contributions made by many
individuals on behalf of the JDOM Project and was originally
created by Brett McLaughlin <brett@jdom.org> and
Jason Hunter <jhunter@jdom.org>. For more information on the
JDOM Project, please see <http://www.jdom.org/>.
*/

View file

@ -1,504 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View file

@ -1,170 +0,0 @@
Sun Microsystems, Inc.
Binary Code License Agreement
READ THE TERMS OF THIS AGREEMENT AND ANY PROVIDED SUPPLEMENTAL LICENSE TERMS
(COLLECTIVELY "AGREEMENT") CAREFULLY BEFORE OPENING THE SOFTWARE MEDIA
PACKAGE. BY OPENING THE SOFTWARE MEDIA PACKAGE, YOU AGREE TO THE TERMS OF
THIS AGREEMENT. IF YOU ARE ACCESSING THE SOFTWARE ELECTRONICALLY, INDICATE
YOUR ACCEPTANCE OF THESE TERMS BY SELECTING THE "ACCEPT" BUTTON AT THE END
OF THIS AGREEMENT. IF YOU DO NOT AGREE TO ALL THESE TERMS, PROMPTLY RETURN
THE UNUSED SOFTWARE TO YOUR PLACE OF PURCHASE FOR A REFUND OR, IF THE
SOFTWARE IS ACCESSED ELECTRONICALLY, SELECT THE "DECLINE" BUTTON AT THE END
OF THIS AGREEMENT.
1. LICENSE TO USE. Sun grants you a non-exclusive and non-transferable
license for the internal use only of the accompanying software and
documentation and any error corrections provided by Sun (collectively
"Software"), by the number of users and the class of computer hardware for
which the corresponding fee has been paid.
2. RESTRICTIONS. Software is confidential and copyrighted. Title to
Software and all associated intellectual property rights is retained by Sun
and/or its licensors. Except as specifically authorized in any Supplemental
License Terms, you may not make copies of Software, other than a single copy
of Software for archival purposes. Unless enforcement is prohibited by
applicable law, you may not modify, decompile, or reverse engineer
Software. You acknowledge that Software is not designed, licensed or
intended for use in the design, construction, operation or maintenance of
any nuclear facility. Sun disclaims any express or implied warranty of
fitness for such uses. No right, title or interest in or to any trademark,
service mark, logo or trade name of Sun or its licensors is granted under
this Agreement.
3. LIMITED WARRANTY. Sun warrants to you that for a period of ninety (90)
days from the date of purchase, as evidenced by a copy of the receipt, the
media on which Software is furnished (if any) will be free of defects in
materials and workmanship under normal use. Except for the foregoing,
Software is provided "AS IS". Your exclusive remedy and Sun's entire
liability under this limited warranty will be at Sun's option to replace
Software media or refund the fee paid for Software.
4. DISCLAIMER OF WARRANTY. UNLESS SPECIFIED IN THIS AGREEMENT, ALL EXPRESS
OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED
WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
NON-INFRINGEMENT ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT THESE DISCLAIMERS
ARE HELD TO BE LEGALLY INVALID.
5. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO
EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR
DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
DAMAGES, HOWEVER CAUSED REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT
OF OR RELATED TO THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. In no event will Sun's
liability to you, whether in contract, tort (including negligence), or
otherwise, exceed the amount paid by you for Software under this Agreement.
The foregoing limitations will apply even if the above stated warranty fails
of its essential purpose.
6. Termination. This Agreement is effective until terminated. You may
terminate this Agreement at any time by destroying all copies of Software.
This Agreement will terminate immediately without notice from Sun if you
fail to comply with any provision of this Agreement. Upon Termination, you
must destroy all copies of Software.
7. Export Regulations. All Software and technical data delivered under this
Agreement are subject to US export control laws and may be subject to export
or import regulations in other countries. You agree to comply strictly with
all such laws and regulations and acknowledge that you have the
responsibility to obtain such licenses to export, re-export, or import as
may be required after delivery to you.
8. U.S. Government Restricted Rights. If Software is being acquired by or
on behalf of the U.S. Government or by a U.S. Government prime contractor or
subcontractor (at any tier), then the Government's rights in Software and
accompanying documentation will be only as set forth in this Agreement; this
is in accordance with 48 CFR 227.7201 through 227.7202-4 (for Department of
Defense (DOD) acquisitions) and with 48 CFR 2.101 and 12.212 (for non-DOD
acquisitions).
9. Governing Law. Any action related to this Agreement will be governed by
California law and controlling U.S. federal law. No choice of law rules of
any jurisdiction will apply.
10. Severability. If any provision of this Agreement is held to be
unenforceable, this Agreement will remain in effect with the provision
omitted, unless omission would frustrate the intent of the parties, in which
case this Agreement will immediately terminate.
11. Integration. This Agreement is the entire agreement between you and
Sun relating to its subject matter. It supersedes all prior or
contemporaneous oral or written communications, proposals, representations
and warranties and prevails over any conflicting or additional terms of any
quote, order, acknowledgment, or other communication between the parties
relating to its subject matter during the term of this Agreement. No
modification of this Agreement will be binding, unless in writing and signed
by an authorized representative of each party.
JAVAMAIL, VERSION 1.2
SUPPLEMENTAL LICENSE TERMS
These supplemental license terms ("Supplemental Terms") add to or modify the
terms of the Binary Code License Agreement (collectively, the "Agreement").
Capitalized terms not defined in these Supplemental Terms shall have the
same meanings ascribed to them in the Agreement. These Supplemental Terms
shall supersede any inconsistent or conflicting terms in the Agreement, or
in any license contained within the Software.
1. Software Internal Use and Development License Grant. Subject to the
terms and conditions of this Agreement, including, but not limited to
Section 3 (Java(TM) Technology Restrictions) of these Supplemental Terms,
Sun grants you a non-exclusive, non-transferable, limited license to
reproduce internally and use internally the binary form of the Software,
complete and unmodified, for the sole purpose of designing, developing and
testing your Java applets and applications ("Programs").
2. License to Distribute Software. Subject to the terms and conditions of
this Agreement, including, but not limited to Section 3 (Java (TM)
Technology Restrictions) of these Supplemental Terms, Sun grants you a
non-exclusive, non-transferable, limited license to reproduce and distribute
the Software in binary code form only, provided that (i) you distribute the
Software complete and unmodified and only bundled as part of, and for the
sole purpose of running, your Java applets or applications ("Programs"),
(ii) the Programs add significant and primary functionality to the Software,
(iii) you do not distribute additional software intended to replace any
component(s) of the Software, (iv) you do not remove or alter any
proprietary legends or notices contained in the Software, (v) you only
distribute the Software subject to a license agreement that protects Sun's
interests consistent with the terms contained in this Agreement, and (vi)
you agree to defend and indemnify Sun and its licensors from and against any
damages, costs, liabilities, settlement amounts and/or expenses (including
attorneys' fees) incurred in connection with any claim, lawsuit or action by
any third party that arises or results from the use or distribution of any
and all Programs and/or Software.
3. Java Technology Restrictions. You may not modify the Java Platform
Interface ("JPI", identified as classes contained within the "java" package
or any subpackages of the "java" package), by creating additional classes
within the JPI or otherwise causing the addition to or modification of the
classes in the JPI. In the event that you create an additional class and
associated API(s) which (i) extends the functionality of the Java platform,
and (ii) is exposed to third party software developers for the purpose of
developing additional software which invokes such additional API, you must
promptly publish broadly an accurate specification for such API for free use
by all developers. You may not create, or authorize your licensees to
create additional classes, interfaces, or subpackages that are in any way
identified as "java", "javax", "sun" or similar convention as specified by
Sun in any naming convention designation.
4. Trademarks and Logos. You acknowledge and agree as between you and Sun
that Sun owns the SUN, SOLARIS, JAVA, JINI, FORTE, STAROFFICE, STARPORTAL
and iPLANET trademarks and all SUN, SOLARIS, JAVA, JINI, FORTE, STAROFFICE,
STARPORTAL and iPLANET-related trademarks, service marks, logos and other
brand designations ("Sun Marks"), and you agree to comply with the Sun
Trademark and Logo Usage Requirements currently located at
http://www.sun.com/policies/trademarks. Any use you make of the Sun Marks
inures to Sun's benefit.
5. Source Code. Software may contain source code that is provided solely for
reference purposes pursuant to the terms of this Agreement. Source code may
not be redistributed unless expressly provided for in this Agreement.
6. Termination for Infringement. Either party may terminate this Agreement
immediately should any Software become, or in either party's opinion be
likely to become, the subject of a claim of infringement of any intellectual
property right.
For inquiries please contact: Sun Microsystems, Inc. 901 San Antonio Road,
Palo Alto, California 94303

View file

@ -1,100 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>W3C IPR SOFTWARE NOTICE</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<h1>
W3C IPR SOFTWARE NOTICE
</h1>
<h3>
Copyright &copy; 2000 <loc href="http://www.w3.org/">World Wide Web
Consortium</loc>, (<loc href="http://www.lcs.mit.edu/">Massachusetts
Institute of Technology</loc>, <loc href="http://www.inria.fr/">Institut
National de Recherche en Informatique et en Automatique</loc>, <loc
href="http://www.keio.ac.jp/">Keio University</loc>). All Rights
Reserved.
</h3>
<p>
The DOM bindings are published under the W3C Software Copyright Notice
and License. The software license requires "Notice of any changes or
modifications to the W3C files, including the date changes were made."
Consequently, modified versions of the DOM bindings must document that
they do not conform to the W3C standard; in the case of the IDL binding,
the pragma prefix can no longer be 'w3c.org'; in the case of the Java
binding, the package names can no longer be in the 'org.w3c' package.
</p>
<p>
<b>Note:</b> The original version of the W3C Software Copyright Notice
and License could be found at <a
href='http://www.w3.org/Consortium/Legal/copyright-software-19980720'>http://www.w3.org/Consortium/Legal/copyright-software-19980720</a>
</p>
<h3>
Copyright &copy; 1994-2000 <a href="http://www.w3.org/">World Wide Web
Consortium</a>, (<a href="http://www.lcs.mit.edu/">Massachusetts
Institute of Technology</a>, <a href="http://www.inria.fr/">Institut
National de Recherche en Informatique et en Automatique</a>, <a
href="http://www.keio.ac.jp/">Keio University</a>). All Rights
Reserved. http://www.w3.org/Consortium/Legal/
</h3>
<p>
This W3C work (including software, documents, or other related items) is
being provided by the copyright holders under the following license. By
obtaining, using and/or copying this work, you (the licensee) agree that
you have read, understood, and will comply with the following terms and
conditions:
</p>
<p>
Permission to use, copy, and modify this software and its documentation,
with or without modification,&nbsp; for any purpose and without fee or
royalty is hereby granted, provided that you include the following on ALL
copies of the software and documentation or portions thereof, including
modifications, that you make:
</p>
<ol>
<li>
The full text of this NOTICE in a location viewable to users of the
redistributed or derivative work.
</li>
<li>
Any pre-existing intellectual property disclaimers, notices, or terms
and conditions. If none exist, a short notice of the following form
(hypertext is preferred, text is permitted) should be used within the
body of any redistributed or derivative code: "Copyright &copy;
[$date-of-software] <a href="http://www.w3.org/">World Wide Web
Consortium</a>, (<a href="http://www.lcs.mit.edu/">Massachusetts
Institute of Technology</a>, <a href="http://www.inria.fr/">Institut
National de Recherche en Informatique et en Automatique</a>, <a
href="http://www.keio.ac.jp/">Keio University</a>). All Rights
Reserved. http://www.w3.org/Consortium/Legal/"
</li>
<li>
Notice of any changes or modifications to the W3C files, including the
date changes were made. (We recommend you provide URIs to the location
from which the code is derived.)
</li>
</ol>
<p>
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT
HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR
DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS,
TRADEMARKS OR OTHER RIGHTS.
</p>
<p>
COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR
DOCUMENTATION.
</p>
<p>
The name and trademarks of copyright holders may NOT be used in
advertising or publicity pertaining to the software without specific,
written prior permission. Title to copyright in this software and any
associated documentation will at all times remain with copyright
holders.
</p>
</body>
</html>

View file

@ -1,27 +0,0 @@
# The SMTP server to use for sending mails. Set and
# uncomment this line before trying to send mails from
# Helma applications.
#
# smtp=mail.yourdomain.com
# Some examples for server-wide locale settings
# (please refer to http://userpage.chemie.fu-berlin.de/diverse/doc/ISO_3166.html
# for country codes, resp. http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt
# for language codes).
#
# country = AT
# language = de
#
# country = UK
# language = en
#
# country = FR
# language = fr
#
# country = CZ
# language = cs
# list ip addresses for admin-application here:
allowAdmin=127.0.0.1, 192.168.0.1

View file

@ -1,396 +0,0 @@
// IntHashtable - a Hashtable that uses ints as the keys
//
// This is 90% based on JavaSoft's java.util.Hashtable.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme;
import java.util.*;
/// A Hashtable that uses ints as the keys.
// <P>
// Use just like java.util.Hashtable, except that the keys must be ints.
// This is much faster than creating a new Integer for each access.
// <P>
// <A HREF="/resources/classes/Acme/IntHashtable.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see java.util.Hashtable
public class IntHashtable extends Dictionary implements Cloneable
{
/// The hash table data.
private IntHashtableEntry table[];
/// The total number of entries in the hash table.
private int count;
/// Rehashes the table when count exceeds this threshold.
private int threshold;
/// The load factor for the hashtable.
private float loadFactor;
/// Constructs a new, empty hashtable with the specified initial
// capacity and the specified load factor.
// @param initialCapacity the initial number of buckets
// @param loadFactor a number between 0.0 and 1.0, it defines
// the threshold for rehashing the hashtable into
// a bigger one.
// @exception IllegalArgumentException If the initial capacity
// is less than or equal to zero.
// @exception IllegalArgumentException If the load factor is
// less than or equal to zero.
public IntHashtable( int initialCapacity, float loadFactor )
{
if ( initialCapacity <= 0 || loadFactor <= 0.0 )
throw new IllegalArgumentException();
this.loadFactor = loadFactor;
table = new IntHashtableEntry[initialCapacity];
threshold = (int) ( initialCapacity * loadFactor );
}
/// Constructs a new, empty hashtable with the specified initial
// capacity.
// @param initialCapacity the initial number of buckets
public IntHashtable( int initialCapacity )
{
this( initialCapacity, 0.75f );
}
/// Constructs a new, empty hashtable. A default capacity and load factor
// is used. Note that the hashtable will automatically grow when it gets
// full.
public IntHashtable()
{
this( 101, 0.75f );
}
/// Returns the number of elements contained in the hashtable.
public int size()
{
return count;
}
/// Returns true if the hashtable contains no elements.
public boolean isEmpty()
{
return count == 0;
}
/// Returns an enumeration of the hashtable's keys.
// @see IntHashtable#elements
public synchronized Enumeration keys()
{
return new IntHashtableEnumerator( table, true );
}
/// Returns an enumeration of the elements. Use the Enumeration methods
// on the returned object to fetch the elements sequentially.
// @see IntHashtable#keys
public synchronized Enumeration elements()
{
return new IntHashtableEnumerator( table, false );
}
/// Returns true if the specified object is an element of the hashtable.
// This operation is more expensive than the containsKey() method.
// @param value the value that we are looking for
// @exception NullPointerException If the value being searched
// for is equal to null.
// @see IntHashtable#containsKey
public synchronized boolean contains( Object value )
{
if ( value == null )
throw new NullPointerException();
IntHashtableEntry tab[] = table;
for ( int i = tab.length ; i-- > 0 ; )
{
for ( IntHashtableEntry e = tab[i] ; e != null ; e = e.next )
{
if ( e.value.equals( value ) )
return true;
}
}
return false;
}
/// Returns true if the collection contains an element for the key.
// @param key the key that we are looking for
// @see IntHashtable#contains
public synchronized boolean containsKey( int key )
{
IntHashtableEntry tab[] = table;
int hash = key;
int index = ( hash & 0x7FFFFFFF ) % tab.length;
for ( IntHashtableEntry e = tab[index] ; e != null ; e = e.next )
{
if ( e.hash == hash && e.key == key )
return true;
}
return false;
}
/// Gets the object associated with the specified key in the
// hashtable.
// @param key the specified key
// @returns the element for the key or null if the key
// is not defined in the hash table.
// @see IntHashtable#put
public synchronized Object get( int key )
{
IntHashtableEntry tab[] = table;
int hash = key;
int index = ( hash & 0x7FFFFFFF ) % tab.length;
for ( IntHashtableEntry e = tab[index] ; e != null ; e = e.next )
{
if ( e.hash == hash && e.key == key )
return e.value;
}
return null;
}
/// A get method that takes an Object, for compatibility with
// java.util.Dictionary. The Object must be an Integer.
public Object get( Object okey )
{
if ( ! ( okey instanceof Integer ) )
throw new InternalError( "key is not an Integer" );
Integer ikey = (Integer) okey;
int key = ikey.intValue();
return get( key );
}
/// Rehashes the content of the table into a bigger table.
// This method is called automatically when the hashtable's
// size exceeds the threshold.
protected void rehash()
{
int oldCapacity = table.length;
IntHashtableEntry oldTable[] = table;
int newCapacity = oldCapacity * 2 + 1;
IntHashtableEntry newTable[] = new IntHashtableEntry[newCapacity];
threshold = (int) ( newCapacity * loadFactor );
table = newTable;
for ( int i = oldCapacity ; i-- > 0 ; )
{
for ( IntHashtableEntry old = oldTable[i] ; old != null ; )
{
IntHashtableEntry e = old;
old = old.next;
int index = ( e.hash & 0x7FFFFFFF ) % newCapacity;
e.next = newTable[index];
newTable[index] = e;
}
}
}
/// Puts the specified element into the hashtable, using the specified
// key. The element may be retrieved by doing a get() with the same key.
// The key and the element cannot be null.
// @param key the specified key in the hashtable
// @param value the specified element
// @exception NullPointerException If the value of the element
// is equal to null.
// @see IntHashtable#get
// @return the old value of the key, or null if it did not have one.
public synchronized Object put( int key, Object value )
{
// Make sure the value is not null.
if ( value == null )
throw new NullPointerException();
// Makes sure the key is not already in the hashtable.
IntHashtableEntry tab[] = table;
int hash = key;
int index = ( hash & 0x7FFFFFFF ) % tab.length;
for ( IntHashtableEntry e = tab[index] ; e != null ; e = e.next )
{
if ( e.hash == hash && e.key == key )
{
Object old = e.value;
e.value = value;
return old;
}
}
if ( count >= threshold )
{
// Rehash the table if the threshold is exceeded.
rehash();
return put( key, value );
}
// Creates the new entry.
IntHashtableEntry e = new IntHashtableEntry();
e.hash = hash;
e.key = key;
e.value = value;
e.next = tab[index];
tab[index] = e;
++count;
return null;
}
/// A put method that takes an Object, for compatibility with
// java.util.Dictionary. The Object must be an Integer.
public Object put( Object okey, Object value )
{
if ( ! ( okey instanceof Integer ) )
throw new InternalError( "key is not an Integer" );
Integer ikey = (Integer) okey;
int key = ikey.intValue();
return put( key, value );
}
/// Removes the element corresponding to the key. Does nothing if the
// key is not present.
// @param key the key that needs to be removed
// @return the value of key, or null if the key was not found.
public synchronized Object remove( int key )
{
IntHashtableEntry tab[] = table;
int hash = key;
int index = ( hash & 0x7FFFFFFF ) % tab.length;
for ( IntHashtableEntry e = tab[index], prev = null ; e != null ; prev = e, e = e.next )
{
if ( e.hash == hash && e.key == key )
{
if ( prev != null )
prev.next = e.next;
else
tab[index] = e.next;
--count;
return e.value;
}
}
return null;
}
/// A remove method that takes an Object, for compatibility with
// java.util.Dictionary. The Object must be an Integer.
public Object remove( Object okey )
{
if ( ! ( okey instanceof Integer ) )
throw new InternalError( "key is not an Integer" );
Integer ikey = (Integer) okey;
int key = ikey.intValue();
return remove( key );
}
/// Clears the hash table so that it has no more elements in it.
public synchronized void clear()
{
IntHashtableEntry tab[] = table;
for ( int index = tab.length; --index >= 0; )
tab[index] = null;
count = 0;
}
/// Creates a clone of the hashtable. A shallow copy is made,
// the keys and elements themselves are NOT cloned. This is a
// relatively expensive operation.
public synchronized Object clone()
{
try
{
IntHashtable t = (IntHashtable) super.clone();
t.table = new IntHashtableEntry[table.length];
for ( int i = table.length ; i-- > 0 ; )
t.table[i] = ( table[i] != null ) ?
(IntHashtableEntry) table[i].clone() : null;
return t;
}
catch ( CloneNotSupportedException e)
{
// This shouldn't happen, since we are Cloneable.
throw new InternalError();
}
}
/// Converts to a rather lengthy String.
public synchronized String toString()
{
int max = size() - 1;
StringBuffer buf = new StringBuffer();
Enumeration k = keys();
Enumeration e = elements();
buf.append( "{" );
for ( int i = 0; i <= max; ++i )
{
String s1 = k.nextElement().toString();
String s2 = e.nextElement().toString();
buf.append( s1 + "=" + s2 );
if ( i < max )
buf.append( ", " );
}
buf.append( "}" );
return buf.toString();
}
}
class IntHashtableEntry
{
int hash;
int key;
Object value;
IntHashtableEntry next;
protected Object clone()
{
IntHashtableEntry entry = new IntHashtableEntry();
entry.hash = hash;
entry.key = key;
entry.value = value;
entry.next = ( next != null ) ? (IntHashtableEntry) next.clone() : null;
return entry;
}
}
class IntHashtableEnumerator implements Enumeration
{
boolean keys;
int index;
IntHashtableEntry table[];
IntHashtableEntry entry;
IntHashtableEnumerator( IntHashtableEntry table[], boolean keys )
{
this.table = table;
this.keys = keys;
this.index = table.length;
}
public boolean hasMoreElements()
{
if ( entry != null )
return true;
while ( index-- > 0 )
if ( ( entry = table[index] ) != null )
return true;
return false;
}
public Object nextElement()
{
if ( entry == null )
while ( ( index-- > 0 ) && ( ( entry = table[index] ) == null ) )
;
if ( entry != null )
{
IntHashtableEntry e = entry;
entry = e.next;
return keys ? new Integer( e.key ) : e.value;
}
throw new NoSuchElementException( "IntHashtableEnumerator" );
}
}

View file

@ -1,690 +0,0 @@
// GifEncoder - write out an image as a GIF
//
// Transparency handling and variable bit size courtesy of Jack Palevich.
//
// Copyright (C)1996,1998 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// 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.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Encoders;
import java.util.*;
import java.io.*;
import java.awt.Image;
import java.awt.image.*;
/// Write out an image as a GIF.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Encoders/GifEncoder.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see ToGif
public class GifEncoder extends ImageEncoder
{
private boolean interlace = false;
/// Constructor from Image.
// @param img The image to encode.
// @param out The stream to write the GIF to.
public GifEncoder( Image img, OutputStream out ) throws IOException
{
super( img, out );
}
/// Constructor from Image with interlace setting.
// @param img The image to encode.
// @param out The stream to write the GIF to.
// @param interlace Whether to interlace.
public GifEncoder( Image img, OutputStream out, boolean interlace ) throws IOException
{
super( img, out );
this.interlace = interlace;
}
/// Constructor from ImageProducer.
// @param prod The ImageProducer to encode.
// @param out The stream to write the GIF to.
public GifEncoder( ImageProducer prod, OutputStream out ) throws IOException
{
super( prod, out );
}
/// Constructor from ImageProducer with interlace setting.
// @param prod The ImageProducer to encode.
// @param out The stream to write the GIF to.
public GifEncoder( ImageProducer prod, OutputStream out, boolean interlace ) throws IOException
{
super( prod, out );
this.interlace = interlace;
}
int width, height;
int[][] rgbPixels;
void encodeStart( int width, int height ) throws IOException
{
this.width = width;
this.height = height;
rgbPixels = new int[height][width];
}
void encodePixels(
int x, int y, int w, int h, int[] rgbPixels, int off, int scansize )
throws IOException
{
// Save the pixels.
for ( int row = 0; row < h; ++row )
System.arraycopy(
rgbPixels, row * scansize + off,
this.rgbPixels[y + row], x, w );
}
Acme.IntHashtable colorHash;
void encodeDone() throws IOException
{
int transparentIndex = -1;
int transparentRgb = -1;
// Put all the pixels into a hash table.
colorHash = new Acme.IntHashtable();
int index = 0;
for ( int row = 0; row < height; ++row )
{
for ( int col = 0; col < width; ++col )
{
int rgb = rgbPixels[row][col];
boolean isTransparent = ( ( rgb >>> 24 ) < 0x80 );
if ( isTransparent )
{
if ( transparentIndex < 0 )
{
// First transparent color; remember it.
transparentIndex = index;
transparentRgb = rgb;
}
else if ( rgb != transparentRgb )
{
// A second transparent color; replace it with
// the first one.
rgbPixels[row][col] = rgb = transparentRgb;
}
}
GifEncoderHashitem item =
(GifEncoderHashitem) colorHash.get( rgb );
if ( item == null )
{
if ( index >= 256 )
throw new IOException( "too many colors for a GIF" );
item = new GifEncoderHashitem(
rgb, 1, index, isTransparent );
++index;
colorHash.put( rgb, item );
}
else
++item.count;
}
}
// Figure out how many bits to use.
int logColors;
if ( index <= 2 )
logColors = 1;
else if ( index <= 4 )
logColors = 2;
else if ( index <= 16 )
logColors = 4;
else
logColors = 8;
// Turn colors into colormap entries.
int mapSize = 1 << logColors;
byte[] reds = new byte[mapSize];
byte[] grns = new byte[mapSize];
byte[] blus = new byte[mapSize];
for ( Enumeration e = colorHash.elements(); e.hasMoreElements(); )
{
GifEncoderHashitem item = (GifEncoderHashitem) e.nextElement();
reds[item.index] = (byte) ( ( item.rgb >> 16 ) & 0xff );
grns[item.index] = (byte) ( ( item.rgb >> 8 ) & 0xff );
blus[item.index] = (byte) ( item.rgb & 0xff );
}
GIFEncode(
out, width, height, interlace, (byte) 0, transparentIndex,
logColors, reds, grns, blus );
}
byte GetPixel( int x, int y ) throws IOException
{
GifEncoderHashitem item =
(GifEncoderHashitem) colorHash.get( rgbPixels[y][x] );
if ( item == null )
throw new IOException( "color not found" );
return (byte) item.index;
}
static void writeString( OutputStream out, String str ) throws IOException
{
byte[] buf = str.getBytes();
out.write( buf );
}
// Adapted from ppmtogif, which is based on GIFENCOD by David
// Rowley <mgardi@watdscu.waterloo.edu>. Lempel-Zim compression
// based on "compress".
int Width, Height;
boolean Interlace;
int curx, cury;
int CountDown;
int Pass = 0;
void GIFEncode(
OutputStream outs, int Width, int Height, boolean Interlace, byte Background, int Transparent, int BitsPerPixel, byte[] Red, byte[] Green, byte[] Blue )
throws IOException
{
byte B;
int LeftOfs, TopOfs;
int ColorMapSize;
int InitCodeSize;
int i;
this.Width = Width;
this.Height = Height;
this.Interlace = Interlace;
ColorMapSize = 1 << BitsPerPixel;
LeftOfs = TopOfs = 0;
// Calculate number of bits we are expecting
CountDown = Width * Height;
// Indicate which pass we are on (if interlace)
Pass = 0;
// The initial code size
if ( BitsPerPixel <= 1 )
InitCodeSize = 2;
else
InitCodeSize = BitsPerPixel;
// Set up the current x and y position
curx = 0;
cury = 0;
// Write the Magic header
writeString( outs, "GIF89a" );
// Write out the screen width and height
Putword( Width, outs );
Putword( Height, outs );
// Indicate that there is a global colour map
B = (byte) 0x80; // Yes, there is a color map
// OR in the resolution
B |= (byte) ( ( 8 - 1 ) << 4 );
// Not sorted
// OR in the Bits per Pixel
B |= (byte) ( ( BitsPerPixel - 1 ) );
// Write it out
Putbyte( B, outs );
// Write out the Background colour
Putbyte( Background, outs );
// Pixel aspect ratio - 1:1.
//Putbyte( (byte) 49, outs );
// Java's GIF reader currently has a bug, if the aspect ratio byte is
// not zero it throws an ImageFormatException. It doesn't know that
// 49 means a 1:1 aspect ratio. Well, whatever, zero works with all
// the other decoders I've tried so it probably doesn't hurt.
Putbyte( (byte) 0, outs );
// Write out the Global Colour Map
for ( i = 0; i < ColorMapSize; ++i )
{
Putbyte( Red[i], outs );
Putbyte( Green[i], outs );
Putbyte( Blue[i], outs );
}
// Write out extension for transparent colour index, if necessary.
if ( Transparent != -1 )
{
Putbyte( (byte) '!', outs );
Putbyte( (byte) 0xf9, outs );
Putbyte( (byte) 4, outs );
Putbyte( (byte) 1, outs );
Putbyte( (byte) 0, outs );
Putbyte( (byte) 0, outs );
Putbyte( (byte) Transparent, outs );
Putbyte( (byte) 0, outs );
}
// Write an Image separator
Putbyte( (byte) ',', outs );
// Write the Image header
Putword( LeftOfs, outs );
Putword( TopOfs, outs );
Putword( Width, outs );
Putword( Height, outs );
// Write out whether or not the image is interlaced
if ( Interlace )
Putbyte( (byte) 0x40, outs );
else
Putbyte( (byte) 0x00, outs );
// Write out the initial code size
Putbyte( (byte) InitCodeSize, outs );
// Go and actually compress the data
compress( InitCodeSize+1, outs );
// Write out a Zero-length packet (to end the series)
Putbyte( (byte) 0, outs );
// Write the GIF file terminator
Putbyte( (byte) ';', outs );
}
// Bump the 'curx' and 'cury' to point to the next pixel
void BumpPixel()
{
// Bump the current X position
++curx;
// If we are at the end of a scan line, set curx back to the beginning
// If we are interlaced, bump the cury to the appropriate spot,
// otherwise, just increment it.
if ( curx == Width )
{
curx = 0;
if ( ! Interlace )
++cury;
else
{
switch( Pass )
{
case 0:
cury += 8;
if ( cury >= Height )
{
++Pass;
cury = 4;
}
break;
case 1:
cury += 8;
if ( cury >= Height )
{
++Pass;
cury = 2;
}
break;
case 2:
cury += 4;
if ( cury >= Height )
{
++Pass;
cury = 1;
}
break;
case 3:
cury += 2;
break;
}
}
}
}
static final int EOF = -1;
// Return the next pixel from the image
int GIFNextPixel() throws IOException
{
byte r;
if ( CountDown == 0 )
return EOF;
--CountDown;
r = GetPixel( curx, cury );
BumpPixel();
return r & 0xff;
}
// Write out a word to the GIF file
void Putword( int w, OutputStream outs ) throws IOException
{
Putbyte( (byte) ( w & 0xff ), outs );
Putbyte( (byte) ( ( w >> 8 ) & 0xff ), outs );
}
// Write out a byte to the GIF file
void Putbyte( byte b, OutputStream outs ) throws IOException
{
outs.write( b );
}
// GIFCOMPR.C - GIF Image compression routines
//
// Lempel-Ziv compression based on 'compress'. GIF modifications by
// David Rowley (mgardi@watdcsu.waterloo.edu)
// General DEFINEs
static final int BITS = 12;
static final int HSIZE = 5003; // 80% occupancy
// GIF Image compression - modified 'compress'
//
// Based on: compress.c - File compression ala IEEE Computer, June 1984.
//
// By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
// Jim McKie (decvax!mcvax!jim)
// Steve Davies (decvax!vax135!petsd!peora!srd)
// Ken Turkowski (decvax!decwrl!turtlevax!ken)
// James A. Woods (decvax!ihnp4!ames!jaw)
// Joe Orost (decvax!vax135!petsd!joe)
int n_bits; // number of bits/code
int maxbits = BITS; // user settable max # bits/code
int maxcode; // maximum code, given n_bits
int maxmaxcode = 1 << BITS; // should NEVER generate this code
final int MAXCODE( int n_bits )
{
return ( 1 << n_bits ) - 1;
}
int[] htab = new int[HSIZE];
int[] codetab = new int[HSIZE];
int hsize = HSIZE; // for dynamic table sizing
int free_ent = 0; // first unused entry
// block compression parameters -- after all codes are used up,
// and compression rate changes, start over.
boolean clear_flg = false;
// Algorithm: use open addressing double hashing (no chaining) on the
// prefix code / next character combination. We do a variant of Knuth's
// algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
// secondary probe. Here, the modular division first probe is gives way
// to a faster exclusive-or manipulation. Also do block compression with
// an adaptive reset, whereby the code table is cleared when the compression
// ratio decreases, but after the table fills. The variable-length output
// codes are re-sized at this point, and a special CLEAR code is generated
// for the decompressor. Late addition: construct the table according to
// file size for noticeable speed improvement on small files. Please direct
// questions about this implementation to ames!jaw.
int g_init_bits;
int ClearCode;
int EOFCode;
void compress( int init_bits, OutputStream outs ) throws IOException
{
int fcode;
int i /* = 0 */;
int c;
int ent;
int disp;
int hsize_reg;
int hshift;
// Set up the globals: g_init_bits - initial number of bits
g_init_bits = init_bits;
// Set up the necessary values
clear_flg = false;
n_bits = g_init_bits;
maxcode = MAXCODE( n_bits );
ClearCode = 1 << ( init_bits - 1 );
EOFCode = ClearCode + 1;
free_ent = ClearCode + 2;
char_init();
ent = GIFNextPixel();
hshift = 0;
for ( fcode = hsize; fcode < 65536; fcode *= 2 )
++hshift;
hshift = 8 - hshift; // set hash code range bound
hsize_reg = hsize;
cl_hash( hsize_reg ); // clear hash table
output( ClearCode, outs );
outer_loop:
while ( (c = GIFNextPixel()) != EOF )
{
fcode = ( c << maxbits ) + ent;
i = ( c << hshift ) ^ ent; // xor hashing
if ( htab[i] == fcode )
{
ent = codetab[i];
continue;
}
else if ( htab[i] >= 0 ) // non-empty slot
{
disp = hsize_reg - i; // secondary hash (after G. Knott)
if ( i == 0 )
disp = 1;
do
{
if ( (i -= disp) < 0 )
i += hsize_reg;
if ( htab[i] == fcode )
{
ent = codetab[i];
continue outer_loop;
}
}
while ( htab[i] >= 0 );
}
output( ent, outs );
ent = c;
if ( free_ent < maxmaxcode )
{
codetab[i] = free_ent++; // code -> hashtable
htab[i] = fcode;
}
else
cl_block( outs );
}
// Put out the final code.
output( ent, outs );
output( EOFCode, outs );
}
// output
//
// Output the given code.
// Inputs:
// code: A n_bits-bit integer. If == -1, then EOF. This assumes
// that n_bits =< wordsize - 1.
// Outputs:
// Outputs code to the file.
// Assumptions:
// Chars are 8 bits long.
// Algorithm:
// Maintain a BITS character long buffer (so that 8 codes will
// fit in it exactly). Use the VAX insv instruction to insert each
// code in turn. When the buffer fills up empty it and start over.
int cur_accum = 0;
int cur_bits = 0;
int masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
0x001F, 0x003F, 0x007F, 0x00FF,
0x01FF, 0x03FF, 0x07FF, 0x0FFF,
0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
void output( int code, OutputStream outs ) throws IOException
{
cur_accum &= masks[cur_bits];
if ( cur_bits > 0 )
cur_accum |= ( code << cur_bits );
else
cur_accum = code;
cur_bits += n_bits;
while ( cur_bits >= 8 )
{
char_out( (byte) ( cur_accum & 0xff ), outs );
cur_accum >>= 8;
cur_bits -= 8;
}
// If the next entry is going to be too big for the code size,
// then increase it, if possible.
if ( free_ent > maxcode || clear_flg )
{
if ( clear_flg )
{
maxcode = MAXCODE(n_bits = g_init_bits);
clear_flg = false;
}
else
{
++n_bits;
if ( n_bits == maxbits )
maxcode = maxmaxcode;
else
maxcode = MAXCODE(n_bits);
}
}
if ( code == EOFCode )
{
// At EOF, write the rest of the buffer.
while ( cur_bits > 0 )
{
char_out( (byte) ( cur_accum & 0xff ), outs );
cur_accum >>= 8;
cur_bits -= 8;
}
flush_char( outs );
}
}
// Clear out the hash table
// table clear for block compress
void cl_block( OutputStream outs ) throws IOException
{
cl_hash( hsize );
free_ent = ClearCode + 2;
clear_flg = true;
output( ClearCode, outs );
}
// reset code table
void cl_hash( int hsize )
{
for ( int i = 0; i < hsize; ++i )
htab[i] = -1;
}
// GIF Specific routines
// Number of characters so far in this 'packet'
int a_count;
// Set up the 'byte output' routine
void char_init()
{
a_count = 0;
}
// Define the storage for the packet accumulator
byte[] accum = new byte[256];
// Add a character to the end of the current packet, and if it is 254
// characters, flush the packet to disk.
void char_out( byte c, OutputStream outs ) throws IOException
{
accum[a_count++] = c;
if ( a_count >= 254 )
flush_char( outs );
}
// Flush the packet to disk, and reset the accumulator
void flush_char( OutputStream outs ) throws IOException
{
if ( a_count > 0 )
{
outs.write( a_count );
outs.write( accum, 0, a_count );
a_count = 0;
}
}
}
class GifEncoderHashitem
{
public int rgb;
public int count;
public int index;
public boolean isTransparent;
public GifEncoderHashitem( int rgb, int count, int index, boolean isTransparent )
{
this.rgb = rgb;
this.count = count;
this.index = index;
this.isTransparent = isTransparent;
}
}

View file

@ -1,271 +0,0 @@
// ImageEncoder - abstract class for writing out an image
//
// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
//
// 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.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
//
// Visit the ACME Labs Java page for up-to-date versions of this and other
// fine Java utilities: http://www.acme.com/java/
package Acme.JPM.Encoders;
import java.util.*;
import java.io.*;
import java.awt.Image;
import java.awt.image.*;
/// Abstract class for writing out an image.
// <P>
// A framework for classes that encode and write out an image in
// a particular file format.
// <P>
// This provides a simplified rendition of the ImageConsumer interface.
// It always delivers the pixels as ints in the RGBdefault color model.
// It always provides them in top-down left-right order.
// If you want more flexibility you can always implement ImageConsumer
// directly.
// <P>
// <A HREF="/resources/classes/Acme/JPM/Encoders/ImageEncoder.java">Fetch the software.</A><BR>
// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
// <P>
// @see GifEncoder
// @see PpmEncoder
// @see Acme.JPM.Decoders.ImageDecoder
public abstract class ImageEncoder implements ImageConsumer
{
protected OutputStream out;
private ImageProducer producer;
private int width = -1;
private int height = -1;
private int hintflags = 0;
private boolean started = false;
private boolean encoding;
private IOException iox;
private static final ColorModel rgbModel = ColorModel.getRGBdefault();
private Hashtable props = null;
/// Constructor.
// @param img The image to encode.
// @param out The stream to write the bytes to.
public ImageEncoder( Image img, OutputStream out ) throws IOException
{
this( img.getSource(), out );
}
/// Constructor.
// @param producer The ImageProducer to encode.
// @param out The stream to write the bytes to.
public ImageEncoder( ImageProducer producer, OutputStream out ) throws IOException
{
this.producer = producer;
this.out = out;
}
// Methods that subclasses implement.
/// Subclasses implement this to initialize an encoding.
abstract void encodeStart( int w, int h ) throws IOException;
/// Subclasses implement this to actually write out some bits. They
// are guaranteed to be delivered in top-down-left-right order.
// One int per pixel, index is row * scansize + off + col,
// RGBdefault (AARRGGBB) color model.
abstract void encodePixels(
int x, int y, int w, int h, int[] rgbPixels, int off, int scansize )
throws IOException;
/// Subclasses implement this to finish an encoding.
abstract void encodeDone() throws IOException;
// Our own methods.
/// Call this after initialization to get things going.
public synchronized void encode() throws IOException
{
encoding = true;
iox = null;
producer.startProduction( this );
while ( encoding )
try
{
wait();
}
catch ( InterruptedException e ) {}
if ( iox != null )
throw iox;
}
private boolean accumulate = false;
private int[] accumulator;
private void encodePixelsWrapper(
int x, int y, int w, int h, int[] rgbPixels, int off, int scansize )
throws IOException
{
if ( ! started )
{
started = true;
encodeStart( width, height );
if ( ( hintflags & TOPDOWNLEFTRIGHT ) == 0 )
{
accumulate = true;
accumulator = new int[width * height];
}
}
if ( accumulate )
for ( int row = 0; row < h; ++row )
System.arraycopy(
rgbPixels, row * scansize + off,
accumulator, ( y + row ) * width + x,
w );
else
encodePixels( x, y, w, h, rgbPixels, off, scansize );
}
private void encodeFinish() throws IOException
{
if ( accumulate )
{
encodePixels( 0, 0, width, height, accumulator, 0, width );
accumulator = null;
accumulate = false;
}
}
private synchronized void stop()
{
encoding = false;
notifyAll();
}
// Methods from ImageConsumer.
public void setDimensions( int width, int height )
{
this.width = width;
this.height = height;
}
public void setProperties( Hashtable props )
{
this.props = props;
}
public void setColorModel( ColorModel model )
{
// Ignore.
}
public void setHints( int hintflags )
{
this.hintflags = hintflags;
}
public void setPixels(
int x, int y, int w, int h, ColorModel model, byte[] pixels,
int off, int scansize )
{
int[] rgbPixels = new int[w];
for ( int row = 0; row < h; ++row )
{
int rowOff = off + row * scansize;
for ( int col = 0; col < w; ++col )
rgbPixels[col] = model.getRGB( pixels[rowOff + col] & 0xff );
try
{
encodePixelsWrapper( x, y + row, w, 1, rgbPixels, 0, w );
}
catch ( IOException e )
{
iox = e;
stop();
return;
}
}
}
public void setPixels(
int x, int y, int w, int h, ColorModel model, int[] pixels,
int off, int scansize )
{
if ( model == rgbModel )
{
try
{
encodePixelsWrapper( x, y, w, h, pixels, off, scansize );
}
catch ( IOException e )
{
iox = e;
stop();
return;
}
}
else
{
int[] rgbPixels = new int[w];
for ( int row = 0; row < h; ++row )
{
int rowOff = off + row * scansize;
for ( int col = 0; col < w; ++col )
rgbPixels[col] = model.getRGB( pixels[rowOff + col] );
try
{
encodePixelsWrapper( x, y + row, w, 1, rgbPixels, 0, w );
}
catch ( IOException e )
{
iox = e;
stop();
return;
}
}
}
}
public void imageComplete( int status )
{
producer.removeConsumer( this );
if ( status == ImageConsumer.IMAGEABORTED )
iox = new IOException( "image aborted" );
else
{
try
{
encodeFinish();
encodeDone();
}
catch ( IOException e )
{
iox = e;
}
}
stop();
}
}

View file

@ -1,216 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.doc;
import helma.framework.IPathElement;
import helma.main.Server;
import helma.util.SystemProperties;
import java.io.*;
import java.util.*;
import java.awt.*;
/**
*
*/
public class DocApplication extends DocDirElement {
HashSet excluded;
/**
* Creates a new DocApplication object.
*
* @param name ...
* @param location ...
*
* @throws DocException ...
*/
public DocApplication(String name, File location) throws DocException {
super(name, location, APPLICATION);
readProps();
}
/**
* Creates a new DocApplication object.
*
* @param name ...
* @param appDir ...
*
* @throws DocException ...
*/
public DocApplication(String name, String appDir) throws DocException {
super(name, new File(appDir), APPLICATION);
readProps();
}
/**
*
*
* @param args ...
*/
public static void main(String[] args) {
System.out.println("this is helma.doc");
DocApplication app;
app = new DocApplication (args[0], args[1]);
app.readApplication ();
// DocPrototype el = DocPrototype.newInstance (new File(args[0]));
// el.readFiles ();
// DocFunction func = DocFunction.newTemplate (new File(args[0]));
// DocFunction func = DocFunction.newAction (new File(args[0]));
// DocFunction[] func = DocFunction.newFunctions(new File(args[0]));
// for (int i=0; i<func.length; i++) {
// System.out.println("=============================================");
// System.out.println("function " + func[i].name);
// System.out.println("comment = " + func[i].comment + "<<<");
// String[] arr = func[i].listParameters();
// for (int j=0; j<arr.length; j++) {
// System.out.println (arr[j]);
// }
// System.out.println ("\ncontent:\n" + func[i].content + "<<<");
// System.out.println ("\n");
// }
// DocSkin skin = DocSkin.newInstance (new File (args[0]));
// System.out.println (func.getContent ());
// System.out.println ("\n\n\ncomment = " + func.getComment ());
}
/**
* reads the app.properties file and parses for helma.excludeDocs
*/
private void readProps() {
File propsFile = new File(location, "app.properties");
SystemProperties serverProps = null;
if (Server.getServer()!=null) {
serverProps = Server.getServer().getProperties();
}
SystemProperties appProps = new SystemProperties(propsFile.getAbsolutePath(),
serverProps);
excluded = new HashSet();
addExclude("cvs");
addExclude(".docs");
String excludeProps = appProps.getProperty("helma.excludeDocs");
if (excludeProps != null) {
StringTokenizer tok = new StringTokenizer(excludeProps, ",");
while (tok.hasMoreTokens()) {
String str = tok.nextToken().trim();
addExclude(str);
}
}
}
/**
*
*
* @param str ...
*/
public void addExclude(String str) {
excluded.add(str.toLowerCase());
}
/**
*
*
* @param str ...
*
* @return ...
*/
public boolean isExcluded(String str) {
return (excluded.contains(str.toLowerCase()));
}
/**
* reads all prototypes and files of the application
*/
public void readApplication() {
readProps();
String[] arr = location.list();
children.clear();
for (int i = 0; i < arr.length; i++) {
if (isExcluded(arr[i])) {
continue;
}
File f = new File(location.getAbsolutePath(), arr[i]);
if (!f.isDirectory()) {
continue;
}
try {
DocPrototype pt = DocPrototype.newInstance(f, this);
addChild(pt);
pt.readFiles();
} catch (DocException e) {
debug("Couldn't read prototype " + arr[i] + ": " + e.getMessage());
}
System.out.println(f);
}
for (Iterator i = children.values().iterator(); i.hasNext();) {
((DocPrototype) i.next()).checkInheritance();
}
}
/**
*
*
* @return ...
*/
public DocElement[] listFunctions() {
Vector allFunctions = new Vector();
for (Iterator i = children.values().iterator(); i.hasNext();) {
DocElement proto = (DocElement) i.next();
allFunctions.addAll(proto.children.values());
}
Collections.sort(allFunctions, new DocComparator(DocComparator.BY_NAME, this));
return (DocElement[]) allFunctions.toArray(new DocElement[allFunctions.size()]);
}
/**
* from helma.framework.IPathElement, overridden with "api"
* to work in manage-application
*/
public String getElementName() {
return "api";
}
/**
* from helma.framework.IPathElement, overridden with
* Server.getServer() to work in manage-application
*/
public IPathElement getParentElement() {
Server s = helma.main.Server.getServer();
return s.getChildElement(this.name);
}
}

View file

@ -1,88 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.doc;
import java.util.Comparator;
/**
*
*/
public class DocComparator implements Comparator {
public static final int BY_TYPE = 0;
public static final int BY_NAME = 1;
int mode;
DocElement docEl;
/**
* Creates a new DocComparator object.
*
* @param mode ...
* @param docEl ...
*/
public DocComparator(int mode, DocElement docEl) {
this.mode = mode;
this.docEl = docEl;
}
/**
* Creates a new DocComparator object.
*
* @param docEl ...
*/
public DocComparator(DocElement docEl) {
this.mode = 0;
this.docEl = docEl;
}
/**
*
*
* @param obj1 ...
* @param obj2 ...
*
* @return ...
*/
public int compare(Object obj1, Object obj2) {
DocElement e1 = (DocElement) obj1;
DocElement e2 = (DocElement) obj2;
if ((mode == BY_TYPE) && (e1.getType() > e2.getType())) {
return 1;
} else if ((mode == BY_TYPE) && (e1.getType() < e2.getType())) {
return -1;
} else {
return e1.name.compareTo(e2.name);
}
}
/**
*
*
* @param obj ...
*
* @return ...
*/
public boolean equals(Object obj) {
DocElement el = (DocElement) obj;
if (el.name.equals(docEl.name) && (el.getType() == docEl.getType())) {
return true;
} else {
return false;
}
}
}

View file

@ -1,52 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.doc;
import java.io.*;
import java.util.*;
/**
*
*/
public abstract class DocDirElement extends DocElement {
// a default file that is read as comment for applications
// and prototypes if found in their directories
public static final String[] DOCFILES = {
"doc.html", "doc.htm", "app.html",
"app.htm", "prototype.html",
"prototype.htm", "index.html", "index.htm"
};
protected DocDirElement(String name, File location, int type) {
super(name, location, type);
checkCommentFiles();
}
private void checkCommentFiles() throws DocException {
for (int i = 0; i < DOCFILES.length; i++) {
File f = new File(location, DOCFILES[i]);
if (f.exists()) {
String rawComment = Util.readFile(f);
parseComment(rawComment);
return;
}
}
}
}

View file

@ -1,384 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.doc;
import helma.framework.IPathElement;
import java.io.*;
import java.util.*;
/**
*
*/
public abstract class DocElement implements IPathElement {
public static final int APPLICATION = 0;
public static final int PROTOTYPE = 1;
public static final int ACTION = 2;
public static final int TEMPLATE = 3;
public static final int FUNCTION = 4;
public static final int MACRO = 5;
public static final int SKIN = 6;
public static final int PROPERTIES = 7;
// above constants are used as array indices
public static final String[] typeNames = {
"Application", "Prototype", "Action",
"Template", "Function", "Macro", "Skin",
"Properties"
};
// identifiers of this element
String name;
int type;
File location;
DocElement parent = null;
Map children = new HashMap();
// content
String content = "";
String comment = "";
List tags = new Vector();
List parameters = new Vector();
protected DocElement(String name, String location, int type)
throws DocException {
this(name, new File(location), type);
}
protected DocElement(String name, File location, int type)
throws DocException {
if (location.exists() == false) {
throw new DocException(name + " not found in " + location.toString());
}
this.name = name;
this.location = location;
this.type = type;
}
/**
* the simple name of the element
*/
public String getName() {
return name;
}
/**
* @return absolute path to location of element
* (directory for apps and prototypes, file for
* methods and properties files)
*/
public File getLocation() {
return location;
}
/**
*
*
* @return ...
*/
public int getType() {
return type;
}
/**
*
*
* @return ...
*/
public String getTypeName() {
return typeNames[type];
}
/**
* returns the comment string, empty string if no comment is set.
*/
public String getComment() {
return comment;
}
/**
* the actual content of the doc element (the function body, the properties
* list, the file list etc.
*/
public String getContent() {
return content;
}
/**
*
*
* @param rawContent ...
*/
public void addTag(String rawContent) {
if (tags == null) {
tags = new Vector();
}
try {
DocTag tag = DocTag.parse(rawContent);
tags.add(tag);
} catch (DocException doc) {
debug(doc.toString());
}
}
/**
* list all tags
*/
public DocTag[] listTags() {
return (DocTag[]) tags.toArray(new DocTag[0]);
}
/**
* filter the tags according to their type
*/
public DocTag[] listTags(String type) {
Vector retval = new Vector();
for (int i = 0; i < tags.size(); i++) {
if (((DocTag) tags.get(i)).getType().equals(type)) {
retval.add(tags.get(i));
}
}
return (DocTag[]) retval.toArray();
}
/**
*
*
* @param param ...
*
* @return ...
*/
public boolean hasParameter(String param) {
return parameters.contains(param);
}
/**
* the list of parameters
*/
public String[] listParameters() {
return (String[]) parameters.toArray(new String[0]);
}
/**
* add a string to the parameters-list
*/
protected void addParameter(String param) {
parameters.add(param);
}
/**
* parse rawComment, render DocTags
*/
void parseComment(String rawComment) {
try {
rawComment = rawComment.trim();
StringTokenizer tok = new StringTokenizer(rawComment, "\n", true);
int BLANK = 0;
int TEXT = 1;
int TAGS = 2;
boolean lastEmpty = false;
int mode = BLANK;
StringBuffer buf = new StringBuffer();
while (tok.hasMoreTokens()) {
String line = Util.chopDelimiters(tok.nextToken().trim());
if ("".equals(line)) {
// if we've already had text, store that this line was empty
lastEmpty = (mode != BLANK) ? true : false;
continue;
}
// if we come here the first time, start with TEXT mode
mode = (mode == BLANK) ? TEXT : mode;
// check if we have a new tag
if (DocTag.isTagStart(line)) {
// if we appended to comment text until now, store that ...
if (mode == TEXT) {
comment = buf.toString();
}
// if we appended to a tag, store that ...
if (mode == TAGS) {
addTag(buf.toString());
}
// reset buffer
buf = new StringBuffer();
mode = TAGS;
}
// append to current buffer
if (lastEmpty == true) {
buf.append("\n");
}
buf.append(line);
buf.append(" ");
lastEmpty = false;
}
// store the last element, if there was at least one element ...
if (mode == TEXT) {
comment = buf.toString().trim();
} else if (mode == TAGS) {
addTag(buf.toString());
}
} catch (RuntimeException rt) {
debug("parse error in " + location + ": " + rt.getMessage());
}
}
/**
*
*
* @param parent ...
*/
public void setParent(DocElement parent) {
this.parent = parent;
}
/**
*
*
* @param child ...
*/
public void addChild(DocElement child) {
if (child == null) {
return;
}
children.put(child.getElementName(), child);
}
/**
*
*
* @return ...
*/
public int countChildren() {
return children.size();
}
/**
*
*
* @return ...
*/
public Map getChildren() {
return children;
}
/**
* returns an array of doc elements, sorted by their name
*/
public DocElement[] listChildren() {
String[] keys = (String[]) children.keySet().toArray(new String[0]);
Arrays.sort(keys);
DocElement[] arr = new DocElement[keys.length];
for (int i = 0; i < keys.length; i++) {
arr[i] = (DocElement) children.get(keys[i]);
}
return arr;
}
/**
* walks up the tree and tries to find a DocApplication object
*/
public DocApplication getDocApplication() {
DocElement el = this;
while (el != null) {
if (el instanceof DocApplication) {
return (DocApplication) el;
}
el = (DocElement) el.getParentElement();
}
return null;
}
/**
* from helma.framework.IPathElement. Elements are named
* like this: typename_name
*/
public String getElementName() {
return typeNames[type].toLowerCase() + "_" + name;
}
/**
* from helma.framework.IPathElement. Retrieves a child from the
* children map.
*/
public IPathElement getChildElement(String name) {
try {
return (IPathElement) children.get(name);
} catch (ClassCastException cce) {
debug(cce.toString());
cce.printStackTrace();
return null;
}
}
/**
* from helma.framework.IPathElement. Returns the parent object
* of this instance if assigned.
*/
public IPathElement getParentElement() {
return parent;
}
/**
* from helma.framework.IPathElement. Prototypes are assigned like
* this: "doc" + typename (e.g. docapplication, docprototype etc)
*/
public java.lang.String getPrototype() {
return "doc" + typeNames[type].toLowerCase();
}
/**
*
*
* @return ...
*/
public String toString() {
return "[" + typeNames[type] + " " + name + "]";
}
/**
*
*
* @param msg ...
*/
public static void debug(String msg) {
System.out.println(msg);
}
}

View file

@ -1,43 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.doc;
/**
*
*/
public class DocException extends RuntimeException {
String str;
/**
* Creates a new DocException object.
*
* @param str ...
*/
public DocException(String str) {
super(str);
this.str = str;
}
/**
*
*
* @return ...
*/
public String getMessage() {
return str;
}
}

View file

@ -1,34 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.doc;
import java.io.File;
/**
* abstract class for extracting doc information from files.
* not used at the moment but left in for further extensions-
*/
public abstract class DocFileElement extends DocElement {
protected DocFileElement(String name, File location, int type) {
super(name, location, type);
}
}

View file

@ -1,180 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.doc;
import helma.framework.IPathElement;
import java.awt.Point;
import java.lang.reflect.Constructor;
import java.io.*;
import java.util.Vector;
import org.mozilla.javascript.TokenStream;
/**
*
*/
public class DocFunction extends DocFileElement {
protected DocFunction(String name, File location, DocElement parent, int type) {
super(name, location, type);
this.parent = parent;
}
/**
* creates a new independent DocFunction object of type ACTION
*/
public static DocFunction newAction(File location) {
return newAction(location, null);
}
/**
* creates a new DocFunction object of type ACTION connected to another DocElement
*/
public static DocFunction newAction(File location, DocElement parent) {
String name = Util.nameFromFile(location, ".hac");
DocFunction func = new DocFunction(name, location, parent, ACTION);
String rawComment = "";
try {
TokenStream ts = getTokenStream (location);
Point p = getPoint (ts);
ts.getToken();
rawComment = Util.getStringFromFile(location, p, getPoint(ts));
rawComment = Util.chopComment (rawComment);
} catch (IOException io) {
io.printStackTrace();
throw new DocException (io.toString());
}
func.parseComment(rawComment);
func.content = Util.readFile(location);
return func;
}
/**
* reads a function file and creates independent DocFunction objects of type FUNCTION
*/
public static DocFunction[] newFunctions(File location) {
return newFunctions(location, null);
}
/**
* reads a function file and creates DocFunction objects of type FUNCTION
* connected to another DocElement.
*/
public static DocFunction[] newFunctions(File location, DocElement parent) {
Vector vec = new Vector();
try {
// the function file:
TokenStream ts = getTokenStream (location);
DocFunction curFunction = null;
Point curFunctionStart = null;
while (!ts.eof()) {
// store the position of the last token
Point endOfLastToken = getPoint (ts);
// new token
int tok = ts.getToken();
// if we're currently parsing a functionbody and come to the start
// of the next function or eof -> read function body
if (curFunction != null && (tok== TokenStream.FUNCTION || ts.eof())) {
curFunction.content = "function " + Util.getStringFromFile(location, curFunctionStart, endOfLastToken);
}
if (tok == TokenStream.FUNCTION) {
// store the function start for parsing the function body later
curFunctionStart = getPoint (ts);
// get and chop the comment
String rawComment = Util.getStringFromFile(location, endOfLastToken, getPoint (ts)).trim ();
rawComment = Util.chopComment (rawComment);
// position stream at function name token
tok = ts.getToken();
// get the name and create the function object
String name = ts.getString();
curFunction = newFunction (name, location, parent);
curFunction.parseComment (rawComment);
vec.add (curFunction);
// subloop on the tokenstream: find the parameters of a function
// only if it's a function (and not a macro or an action)
if (curFunction.type == FUNCTION) {
while (!ts.eof() && tok != TokenStream.RP) {
// store the position of the last token
endOfLastToken = getPoint (ts);
// new token
tok = ts.getToken();
if (tok==TokenStream.NAME) {
curFunction.addParameter (ts.getString());
}
}
}
} // end if
}
} catch (IOException io) {
io.printStackTrace();
throw new DocException (io.toString());
}
return (DocFunction[]) vec.toArray(new DocFunction[0]);
}
private static DocFunction newFunction (String funcName, File location, DocElement parent) {
if (funcName.endsWith("_action")) {
return new DocFunction(funcName, location, parent, ACTION);
} else if (funcName.endsWith("_macro")) {
return new DocFunction(funcName, location, parent, MACRO);
} else {
return new DocFunction(funcName, location, parent, FUNCTION);
}
}
/**
* creates a rhino token stream for a given file
*/
protected static TokenStream getTokenStream (File f) {
FileReader reader = null;
try {
reader = new FileReader(f);
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
throw new DocException (fnfe.toString());
}
String name = f.getName();
int line = 0;
return new TokenStream (reader, null, null, name, line);
}
/**
* returns a pointer to the current position in the TokenStream
*/
protected static Point getPoint (TokenStream ts) {
return new Point (ts.getOffset(), ts.getLineno());
}
/**
* from helma.framework.IPathElement. All macros, templates, actions etc
* have the same prototype.
*/
public java.lang.String getPrototype() {
return "docfunction";
}
}

View file

@ -1,96 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.doc;
import helma.framework.IPathElement;
import helma.util.SystemProperties;
import java.io.*;
import java.util.*;
/**
*
*/
public class DocProperties extends DocFileElement {
Properties props = null;
protected DocProperties(File location, DocElement parent)
throws DocException {
super(location.getName(), location, PROPERTIES);
this.parent = parent;
content = Util.readFile(location);
props = new SystemProperties();
try {
props.load(new FileInputStream(location));
} catch (IOException e) {
debug("couldn't read file: " + e.toString());
} catch (Exception e) {
throw new DocException(e.toString());
}
}
/**
* creates a new independent DocProperties object
*/
public static DocProperties newInstance(File location) {
return newInstance(location, null);
}
/**
* creates a new DocProperties object connected to another DocElement
*/
public static DocProperties newInstance(File location, DocElement parent) {
try {
return new DocProperties(location, parent);
} catch (DocException doc) {
return null;
}
}
/**
*
*
* @return ...
*/
public Properties getProperties() {
return props;
}
/**
*
*
* @return ...
*/
public Properties getMappings() {
Properties childProps = new Properties();
for (Enumeration e = props.keys(); e.hasMoreElements();) {
String key = (String) e.nextElement();
String value = props.getProperty(key);
if (value.startsWith("collection") || value.startsWith("object") ||
value.startsWith("mountpoint")) {
String prototype = value.substring(value.indexOf("(") + 1,
value.indexOf(")")).trim();
childProps.setProperty(key, prototype);
}
}
return childProps;
}
}

View file

@ -1,147 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.doc;
import helma.framework.IPathElement;
import java.io.*;
import java.util.*;
/**
*
*/
public class DocPrototype extends DocDirElement {
private DocProperties typeProperties = null;
private DocPrototype parentPrototype = null;
private DocPrototype(String name, File location, DocElement parent) {
super(name, location, PROTOTYPE);
this.parent = parent;
typeProperties = DocProperties.newInstance(new File(location, "type.properties"));
}
/**
* creates a prototype that is independent of an
* application object
* @param homedirectory
*/
public static DocPrototype newInstance(File location) {
return newInstance(location, null);
}
/**
* creates a prototype that is connected to an
* application object and resides in app's home dir.
* @param application
* @param name
*/
public static DocPrototype newInstance(File location, DocElement parent) {
DocPrototype pt = new DocPrototype(location.getName(), location, parent);
return pt;
}
/**
* checks the type.properites for _extend values and connected a possible
* parent prototype with this prototype. this can't be successfull at construction
* time but only -after- all prototypes are parsed and attached to a parent
* DocApplication object.
*/
public void checkInheritance() {
// hopobject is the top prototype:
if (name.equals("hopobject")) {
return;
}
if (typeProperties != null) {
// check for "_extends" in the the type.properties
String ext = typeProperties.getProperties().getProperty("_extends");
if ((ext != null) && (parent != null)) {
// try to get the prototype if available
parentPrototype = (DocPrototype) parent.getChildElement("prototype_" +
ext);
}
}
if ((parentPrototype == null) && (parent != null) && !name.equals("global")) {
// if no _extend was set, get the hopobject prototype
parentPrototype = (DocPrototype) parent.getChildElement("prototype_hopobject");
}
}
/**
*
*
* @return ...
*/
public DocPrototype getParentPrototype() {
return parentPrototype;
}
/**
*
*
* @return ...
*/
public DocProperties getTypeProperties() {
return typeProperties;
}
/**
* runs through the prototype directory and parses all helma files
*/
public void readFiles() {
children.clear();
String[] arr = location.list();
for (int i = 0; i < arr.length; i++) {
if (getDocApplication().isExcluded(arr[i])) {
continue;
}
File f = new File(location.getAbsolutePath(), arr[i]);
if (f.isDirectory()) {
continue;
}
try {
if (arr[i].endsWith(".skin")) {
addChild(DocSkin.newInstance(f, this));
} else if (arr[i].endsWith(".properties")) {
continue;
} else if (arr[i].endsWith(".hac")) {
addChild(DocFunction.newAction(f, this));
} else if (arr[i].endsWith(".js")) {
DocElement[] elements = DocFunction.newFunctions(f, this);
for (int j = 0; j < elements.length; j++) {
addChild(elements[j]);
}
}
} catch (Exception ex) {
System.out.println("couldn't parse file " + f.getAbsolutePath() + ": " +
ex.toString());
ex.printStackTrace();
} catch (Throwable err) {
System.out.println("couldn't parse file " + f.getAbsolutePath() + ": " +
err.toString());
}
}
}
}

View file

@ -1,115 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.doc;
import helma.framework.IPathElement;
import java.io.*;
import java.util.*;
/**
*
*/
public class DocSkin extends DocFileElement {
protected DocSkin(String name, File location, DocElement parent) {
super(name, location, SKIN);
this.parent = parent;
content = Util.readFile(location);
parseHandlers();
}
/**
* creates a new independent DocSkin object
*/
public static DocSkin newInstance(File location) {
return newInstance(location, null);
}
/**
* creates a new DocSkin object connected to another DocElement
*/
public static DocSkin newInstance(File location, DocElement parent) {
String skinname = Util.nameFromFile(location, ".skin");
DocSkin skin = new DocSkin(skinname, location, parent);
return skin;
}
/**
* parses the source code of the skin and
* extracts all included macros. code taken
* from helma.framework.core.Skin
* @see helma.framework.core.Skin
*/
private void parseHandlers() {
ArrayList partBuffer = new ArrayList();
char[] source = content.toCharArray();
int sourceLength = source.length;
for (int i = 0; i < (sourceLength - 1); i++) {
if ((source[i] == '<') && (source[i + 1] == '%')) {
// found macro start tag
int j = i + 2;
// search macro end tag
while ((j < (sourceLength - 1)) &&
((source[j] != '%') || (source[j + 1] != '>'))) {
j++;
}
if (j > (i + 2)) {
String str = (new String(source, i + 2, j - i)).trim();
if (str.endsWith("%>")) {
str = str.substring(0, str.length() - 2);
}
if (str.startsWith("//")) {
parseComment(str);
} else {
if (str.indexOf(" ") > -1) {
str = str.substring(0, str.indexOf(" "));
}
if ((str.indexOf(".") > -1) &&
(str.startsWith("param.") || str.startsWith("response.") ||
str.startsWith("request.") || str.startsWith("session.")) &&
!partBuffer.contains(str)) {
partBuffer.add(str);
}
}
}
i = j + 1;
}
}
String[] strArr = (String[]) partBuffer.toArray(new String[0]);
Arrays.sort(strArr);
for (int i = 0; i < strArr.length; i++) {
addParameter(strArr[i]);
}
}
/**
* from helma.framework.IPathElement. Use the same prototype as functions etc.
*/
public java.lang.String getPrototype() {
return "docfunction";
}
}

View file

@ -1,151 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.doc;
import java.util.*;
/**
*
*/
public final class DocTag {
// the tag name
private String type;
// the name of the parameter
private String name;
// the actual comment
private String text;
private DocTag(String type, String name, String text) {
this.type = type;
this.name = (name != null) ? name.trim() : "";
this.text = (text != null) ? text.trim() : "";
}
/**
*
*
* @param rawTag ...
*
* @return ...
*
* @throws DocException ...
*/
public static DocTag parse(String rawTag) throws DocException {
StringTokenizer tok = new StringTokenizer(rawTag.trim());
String name = "";
String type = "";
StringBuffer comment = new StringBuffer ();
try {
type = matchTagName(tok.nextToken().substring (1));
} catch (NoSuchElementException nsee) {
throw new DocException ("invalid tag: " + rawTag);
}
try {
if (isTagWithName(type)) {
name = tok.nextToken();
}
while (tok.hasMoreTokens()) {
comment.append (" " + tok.nextToken());
}
} catch (NoSuchElementException nsee) { // ignore
}
return new DocTag (type, name, comment.toString());
}
/**
* @param checks if a line is a tag
* @return true/false
*/
public static boolean isTagStart(String rawTag) {
if (rawTag.trim().startsWith("@"))
return true;
else
return false;
}
/**
* match tags where we want different names to be valid
* as one and the same tag
* @param tagname original name
* @return modified name if tag was matched
*/
public static String matchTagName(String tagName) {
if ("returns".equals(tagName)) {
return "return";
} else if ("arg".equals(tagName)) {
return "param";
} else {
return tagName;
}
}
public static boolean isTagWithName(String tagName) {
if ("param".equals (tagName))
return true;
else
return false;
}
/**
*
*
* @return ...
*/
public String getType() {
return type;
}
/**
*
*
* @return ...
*/
public String getName() {
return name;
}
/**
*
*
* @return ...
*/
public String getText() {
return text;
}
/**
*
*
* @return ...
*/
public String toString() {
StringBuffer buf = new StringBuffer ("[@" + type);
if (name!=null && !"".equals(name))
buf.append (" " + name);
if (text!=null && !"".equals(text))
buf.append (" " + text);
return buf.toString() + "]";
}
}

View file

@ -1,195 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.doc;
import java.awt.Point;
import java.io.*;
/**
*
*/
public final class Util {
/**
* chops a string from comment-delimiters
*
* @param line a line of raw text
*
* @return chopped string
*/
public static String chopDelimiters(String line) {
line = line.trim();
if (line == null) {
return null;
}
if (line.endsWith("*/")) {
line = line.substring(0, line.length() - 2);
}
if (line.startsWith("/**")) {
line = line.substring(3).trim();
} else if (line.startsWith("/*")) {
line = line.substring(2).trim();
} else if (line.startsWith("*")) {
line = line.substring(1).trim();
} else if (line.startsWith("//")) {
line = line.substring(2).trim();
}
return line;
}
/**
* chops anything that comes after a closing comment tag
*
* @param raw comment
*
* @return chopped comment
*/
public static String chopComment (String comment) {
int idx = comment.indexOf ("*/");
if (idx>0) {
return comment.substring (0, idx+2);
} else {
return comment;
}
}
/**
* reads a complete file
*
* @param file
*
* @return string with content of file
*/
public static String readFile(File file) {
try {
StringBuffer buf = new StringBuffer();
BufferedReader in = new BufferedReader(new FileReader(file));
String line = in.readLine();
while (line != null) {
buf.append(line + "\n");
line = in.readLine();
}
in.close();
return buf.toString();
} catch (IOException e) {
return ("");
}
}
/**
* reads a part of a file defined by two points
* @param start of string to extract defined by column x and row y
* @param end of string to extract
* @return string
*/
public static String getStringFromFile (File sourceFile, Point start, Point end) {
StringBuffer buf = new StringBuffer();
int ct = 0;
try {
BufferedReader in = new BufferedReader(new FileReader(sourceFile));
String line = "";
while (line != null) {
line = in.readLine();
if (line == null) {
break;
}
if ((ct > start.y) && (ct < end.y)) {
buf.append(line + "\n");
} else if (ct == start.y) {
if (start.y==end.y) {
buf.append (line.substring (start.x, end.x));
break;
} else {
buf.append(line.substring(start.x, line.length()) + "\n");
}
} else if (ct == end.y) {
buf.append(line.substring(0, end.x));
break;
}
ct++;
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
return buf.toString().trim();
}
/**
* method to debug file/stream-handling with Point objects. extracts the line p
* points to and prints it with a pointer to the given column
*
* @param sourceFile
* @param p x-value is used for column, y for row
* @param debugStr string prefixed to output
*/
public static void debugLineFromFile (File sourceFile, Point p, String debugStr) {
try {
BufferedReader in = new BufferedReader(new FileReader(sourceFile));
String line = "";
int ct = 0;
while (line != null) {
line = in.readLine ();
if (line==null) {
System.out.println ("eof reached");
break;
}
if (ct==p.y) {
System.out.println (debugStr + ": " + line);
for (int i=0; i<(debugStr.length()+1+p.x); i++) {
System.out.print (" ");
}
System.out.println ("^");
break;
}
ct++;
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
/**
* extracts the function name from a file. basically chops the given suffix
* and throws an error if the file name doesn't fit.
*/
public static String nameFromFile(File f, String suffix)
throws DocException {
String filename = f.getName();
if (!filename.endsWith(suffix)) {
throw new DocException("file doesn't have suffix " + suffix + ": " +
f.toString());
}
return filename.substring(0, filename.lastIndexOf(suffix));
}
}

View file

@ -1,31 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.extensions;
/**
*
*/
public class ConfigurationException extends RuntimeException {
/**
* Creates a new ConfigurationException object.
*
* @param msg ...
*/
public ConfigurationException(String msg) {
super(msg);
}
}

View file

@ -1,71 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.extensions;
import helma.framework.core.Application;
import helma.main.Server;
import helma.scripting.ScriptingEngine;
import java.util.HashMap;
/**
* Helma extensions have to subclass this. The extensions to be loaded are
* defined in <code>server.properties</code> by setting <code>extensions =
* packagename.classname, packagename.classname</code>.
*/
public abstract class HelmaExtension {
/**
* called by the Server at startup time. should check wheter the needed classes
* are present and throw a ConfigurationException if not.
*/
public abstract void init(Server server) throws ConfigurationException;
/**
* called when an Application is started. This should be <b>synchronized</b> when
* any self-initialization is performed.
*/
public abstract void applicationStarted(Application app)
throws ConfigurationException;
/**
* called when an Application is stopped.
* This should be <b>synchronized</b> when any self-destruction is performed.
*/
public abstract void applicationStopped(Application app);
/**
* called when an Application's properties are have been updated.
* note that this will be called at startup once *before* applicationStarted().
*/
public abstract void applicationUpdated(Application app);
/**
* called by the ScriptingEngine when it is initizalized. Throws a ConfigurationException
* when this type of ScriptingEngine is not supported. New methods and prototypes can be
* added to the scripting environment. New global vars should be returned in a HashMap
* with pairs of varname and ESObjects. This method should be <b>synchronized</b>, if it
* performs any other self-initialization outside the scripting environment.
*/
public abstract HashMap initScripting(Application app, ScriptingEngine engine)
throws ConfigurationException;
/**
*
*
* @return ...
*/
public abstract String getName();
}

View file

@ -1,116 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.extensions.demo;
import helma.extensions.ConfigurationException;
import helma.extensions.HelmaExtension;
import helma.framework.core.Application;
import helma.main.Server;
import helma.scripting.ScriptingEngine;
import helma.scripting.rhino.RhinoEngine;
import java.util.HashMap;
/**
* a demo extension implementation, to activate this add <code>extensions =
* helma.extensions.demo.DemoExtensions</code> to your <code>server.properties</code>.
* a new global object <code>demo</code> that wraps helma.main.Server
* will be added to the scripting environment.
*/
public class DemoExtension extends HelmaExtension {
/**
*
*
* @param server ...
*
* @throws ConfigurationException ...
*/
public void init(Server server) throws ConfigurationException {
try {
// just a demo with the server class itself (which is always there, obviously)
Class check = Class.forName("helma.main.Server");
} catch (ClassNotFoundException e) {
throw new ConfigurationException("helma-library not present in classpath. make sure helma.jar is included. get it from http://www.helma.org/");
}
}
/**
*
*
* @param app ...
*
* @throws ConfigurationException ...
*/
public void applicationStarted(Application app) throws ConfigurationException {
app.logEvent("DemoExtension init with app " + app.getName());
}
/**
*
*
* @param app ...
*/
public void applicationStopped(Application app) {
app.logEvent("DemoExtension stopped on app " + app.getName());
}
/**
*
*
* @param app ...
*/
public void applicationUpdated(Application app) {
app.logEvent("DemoExtension updated on app " + app.getName());
}
/**
*
*
* @param app ...
* @param engine ...
*
* @return ...
*
* @throws ConfigurationException ...
*/
public HashMap initScripting(Application app, ScriptingEngine engine)
throws ConfigurationException {
if (!(engine instanceof RhinoEngine)) {
throw new ConfigurationException("scripting engine " + engine.toString() +
" not supported in DemoExtension");
}
app.logEvent("initScripting DemoExtension with " + app.getName() + " and " +
engine.toString());
// initialize prototypes and global vars here
HashMap globals = new HashMap();
globals.put("demo", Server.getServer());
return globals;
}
/**
*
*
* @return ...
*/
public String getName() {
return "DemoExtension";
}
}

View file

@ -1,31 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework;
/**
* This is thrown when a request is made to a stopped
* application
*/
public class ApplicationStoppedException extends RuntimeException {
/**
* Creates a new ApplicationStoppedException object.
*/
public ApplicationStoppedException() {
super("The application has been stopped");
}
}

View file

@ -1,130 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework;
import java.io.Serializable;
import java.util.HashMap;
import javax.servlet.http.Cookie;
/**
* Cookie Transmitter. A simple, serializable representation
* of an HTTP cookie.
*/
public final class CookieTrans implements Serializable {
String name;
String value;
String path;
String domain;
int days;
CookieTrans(String name, String value) {
this.name = name;
this.value = value;
}
void setValue(String value) {
this.value = value;
}
void setDays(int days) {
this.days = days;
}
void setPath(String path) {
this.path = path;
}
void setDomain(String domain) {
this.domain = domain;
}
/**
*
*
* @return ...
*/
public String getName() {
return name;
}
/**
*
*
* @return ...
*/
public String getValue() {
return value;
}
/**
*
*
* @return ...
*/
public int getDays() {
return days;
}
/**
*
*
* @return ...
*/
public String getPath() {
return path;
}
/**
*
*
* @return ...
*/
public String getDomain() {
return domain;
}
/**
*
*
* @param defaultPath ...
* @param defaultDomain ...
*
* @return ...
*/
public Cookie getCookie(String defaultPath, String defaultDomain) {
Cookie c = new Cookie(name, value);
if (days > 0) {
// Cookie time to live, days -> seconds
c.setMaxAge(days * 60 * 60 * 24);
}
if (path != null) {
c.setPath(path);
} else if (defaultPath != null) {
c.setPath(defaultPath);
}
if (domain != null) {
c.setDomain(domain);
} else if (defaultDomain != null) {
c.setDomain(defaultDomain);
}
return c;
}
}

View file

@ -1,33 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework;
/**
* The basic exception class used to tell when certain things go
* wrong in evaluation of requests.
*/
public class FrameworkException extends RuntimeException {
/**
* Creates a new FrameworkException object.
*
* @param msg ...
*/
public FrameworkException(String msg) {
super(msg);
}
}

View file

@ -1,52 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework;
/**
* Interface that objects need to implement to build a Helma URL tree. Apart from methods
* to retrieve the identifier and its child and parent elements, this interface defines a method
* that determines which prototype to use to add scripts and skins to an object. <p>
*
* Please note that this interface is still work in progress. You should expect it to get some
* additional methods that allow for looping through child elements, for example, or retrieving the
* parent element. <p>
*
*/
public interface IPathElement {
/**
* Return the name to be used to get this element from its parent
*/
public String getElementName();
/**
* Retrieve a child element of this object by name.
*/
public IPathElement getChildElement(String name);
/**
* Return the parent element of this object.
*/
public IPathElement getParentElement();
/**
* Get the name of the prototype to be used for this object. This will
* determine which scripts, actions and skins can be called on it
* within the Helma scripting and rendering framework.
*/
public String getPrototype();
}

View file

@ -1,43 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework;
import java.rmi.*;
import java.util.Vector;
/**
* RMI interface for an application. Currently only execute is used and supported.
*/
public interface IRemoteApp extends Remote {
/**
*
*
* @param param ...
*
* @return ...
*
* @throws RemoteException ...
*/
public ResponseTrans execute(RequestTrans param) throws RemoteException;
/**
*
*
* @throws RemoteException ...
*/
public void ping() throws RemoteException;
}

View file

@ -1,65 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework;
/**
* RedirectException is thrown internally when a response is redirected to a
* new URL. Although this is not an Error, it subclasses java.lang.Error
* because it's not meant to be caught by application code (similar to
* java.lang.ThreadDeath).
*/
public class RedirectException extends Error {
String url;
/**
* Creates a new RedirectException object.
*
* @param url ...
*/
public RedirectException(String url) {
super("Redirection Request to " + url);
this.url = url;
}
/**
*
*
* @return ...
*/
public String getMessage() {
return url;
}
/**
*
*
* @param s ...
*/
public void printStackTrace(java.io.PrintStream s) {
// do nothing
}
/**
*
*
* @param w ...
*/
public void printStackTrace(java.io.PrintWriter w) {
// do nothing
}
}

View file

@ -1,127 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework;
import helma.framework.core.Application;
import java.io.Serializable;
import java.util.Date;
import java.util.Map;
/**
*
*/
public class RequestBean implements Serializable {
RequestTrans req;
/**
* Creates a new RequestBean object.
*
* @param req ...
*/
public RequestBean(RequestTrans req) {
this.req = req;
}
/**
*
*
* @param name ...
*
* @return ...
*/
public Object get(String name) {
return req.get(name);
}
/**
*
*
* @return ...
*/
public boolean isGet() {
return req.isGet();
}
/**
*
*
* @return ...
*/
public boolean isPost() {
return req.isPost();
}
/**
*
*
* @return ...
*/
public String toString() {
return "[Request]";
}
// property related methods:
public String getAction() {
return req.action;
}
/**
*
*
* @return ...
*/
public Map getData() {
return req.getRequestData();
}
/**
*
*
* @return ...
*/
public long getRuntime() {
return (System.currentTimeMillis() - req.startTime);
}
/**
*
*
* @return ...
*/
public String getPassword() {
return req.getPassword();
}
/**
*
*
* @return ...
*/
public String getPath() {
return req.path;
}
/**
*
*
* @return ...
*/
public String getUsername() {
return req.getUsername();
}
}

View file

@ -1,288 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework;
import helma.objectmodel.*;
import helma.util.Base64;
import helma.util.SystemMap;
import java.io.*;
import java.util.*;
/**
* A Transmitter for a request from the servlet client. Objects of this
* class are directly exposed to JavaScript as global property req.
*/
public class RequestTrans implements Externalizable {
static final long serialVersionUID = 5398880083482000580L;
// the uri path of the request
public String path;
// the request's session id
public String session;
// the map of form and cookie data
private Map values;
// the request method - 0 for GET, 1 for POST
private byte httpMethod = 0;
// timestamp of client-cached version, if present in request
private long ifModifiedSince = -1;
// set of ETags the client sent with If-None-Match header
private Set etags;
// when was execution started on this request?
public transient long startTime;
// the name of the action being invoked
public transient String action;
private transient String httpUsername;
private transient String httpPassword;
/**
* Create a new Request transmitter with an empty data map.
*/
public RequestTrans() {
httpMethod = 0;
values = new SystemMap();
}
/**
* Create a new request transmitter with the given data map.
*/
public RequestTrans(byte method) {
httpMethod = method;
values = new SystemMap();
}
/**
* Set a parameter value in this request transmitter.
*/
public void set(String name, Object value) {
values.put(name, value);
}
/**
* Get a value from the requests map by key.
*/
public Object get(String name) {
try {
return values.get(name);
} catch (Exception x) {
return null;
}
}
/**
* Get the data map for this request transmitter.
*/
public Map getRequestData() {
return values;
}
/**
* The hash code is computed from the session id if available. This is used to
* detect multiple identic requests.
*/
public int hashCode() {
return (session == null) ? super.hashCode() : session.hashCode();
}
/**
* A request is considered equal to another one if it has the same user, path,
* and request data. This is used to evaluate multiple simultanous requests only once
*/
public boolean equals(Object what) {
try {
RequestTrans other = (RequestTrans) what;
return (session.equals(other.session) && path.equalsIgnoreCase(other.path) &&
values.equals(other.getRequestData()));
} catch (Exception x) {
return false;
}
}
/**
* Return true if this object represents a HTTP GET Request.
*/
public boolean isGet() {
return httpMethod == 0;
}
/**
* Return true if this object represents a HTTP GET Request.
*/
public boolean isPost() {
return httpMethod == 1;
}
/**
* Custom externalization code for quicker serialization.
*/
public void readExternal(ObjectInput s) throws ClassNotFoundException, IOException {
path = s.readUTF();
session = s.readUTF();
values = (Map) s.readObject();
httpMethod = s.readByte();
ifModifiedSince = s.readLong();
etags = (Set) s.readObject();
}
/**
* Custom externalization code for quicker serialization.
*/
public void writeExternal(ObjectOutput s) throws IOException {
s.writeUTF(path);
s.writeUTF(session);
s.writeObject(values);
s.writeByte(httpMethod);
s.writeLong(ifModifiedSince);
s.writeObject(etags);
}
/**
*
*
* @param since ...
*/
public void setIfModifiedSince(long since) {
ifModifiedSince = since;
}
/**
*
*
* @return ...
*/
public long getIfModifiedSince() {
return ifModifiedSince;
}
/**
*
*
* @param etagHeader ...
*/
public void setETags(String etagHeader) {
etags = new HashSet();
if (etagHeader.indexOf(",") > -1) {
StringTokenizer st = new StringTokenizer(etagHeader, ", \r\n");
while (st.hasMoreTokens())
etags.add(st.nextToken());
} else {
etags.add(etagHeader);
}
}
/**
*
*
* @return ...
*/
public Set getETags() {
return etags;
}
/**
*
*
* @param etag ...
*
* @return ...
*/
public boolean hasETag(String etag) {
if ((etags == null) || (etag == null)) {
return false;
}
return etags.contains(etag);
}
/**
*
*
* @return ...
*/
public String getUsername() {
if (httpUsername != null) {
return httpUsername;
}
String auth = (String) get("authorization");
if ((auth == null) || "".equals(auth)) {
return null;
}
decodeHttpAuth(auth);
return httpUsername;
}
/**
*
*
* @return ...
*/
public String getPassword() {
if (httpPassword != null) {
return httpPassword;
}
String auth = (String) get("authorization");
if ((auth == null) || "".equals(auth)) {
return null;
}
decodeHttpAuth(auth);
return httpPassword;
}
private void decodeHttpAuth(String auth) {
if (auth == null) {
return;
}
StringTokenizer tok;
if (auth.startsWith("Basic ")) {
tok = new StringTokenizer(new String(Base64.decode((auth.substring(6)).toCharArray())),
":");
} else {
tok = new StringTokenizer(new String(Base64.decode(auth.toCharArray())), ":");
}
try {
httpUsername = tok.nextToken();
} catch (NoSuchElementException e) {
httpUsername = null;
}
try {
httpPassword = tok.nextToken();
} catch (NoSuchElementException e) {
httpPassword = null;
}
}
}

View file

@ -1,403 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework;
import helma.framework.core.Application;
import java.io.Serializable;
import java.util.Date;
import java.util.Map;
/**
*
*/
public class ResponseBean implements Serializable {
ResponseTrans res;
/**
* Creates a new ResponseBean object.
*
* @param res ...
*/
public ResponseBean(ResponseTrans res) {
this.res = res;
}
/**
*
*
* @param what ...
*/
public void encode(Object what) {
res.encode(what);
}
/**
*
*
* @param what ...
*/
public void encodeXml(Object what) {
res.encodeXml(what);
}
/**
*
*
* @param what ...
*/
public void format(Object what) {
res.format(what);
}
/**
*
*
* @param url ...
*
* @throws RedirectException ...
*/
public void redirect(String url) throws RedirectException {
res.redirect(url);
}
/**
*
*/
public void reset() {
res.reset();
}
/**
*
*
* @param key ...
* @param value ...
*/
public void setCookie(String key, String value) {
res.setCookie(key, value, -1, null, null);
}
/**
*
*
* @param key ...
* @param value ...
* @param days ...
*/
public void setCookie(String key, String value, int days) {
res.setCookie(key, value, days, null, null);
}
/**
*
*
* @param key ...
* @param value ...
* @param days ...
* @param path ...
*/
public void setCookie(String key, String value, int days, String path) {
res.setCookie(key, value, days, path, null);
}
/**
*
*
* @param key ...
* @param value ...
* @param days ...
* @param path ...
* @param domain ...
*/
public void setCookie(String key, String value, int days, String path, String domain) {
res.setCookie(key, value, days, path, domain);
}
/**
*
*
* @param what ...
*/
public void write(String what) {
res.write(what);
}
/**
*
*
* @param what ...
*/
public void writeln(String what) {
res.writeln(what);
}
/**
*
*
* @param what ...
*/
public void writeBinary(byte[] what) {
res.writeBinary(what);
}
/**
*
*
* @param message ...
*/
public void debug(String message) {
res.debug(message);
}
/**
*
*
* @return ...
*/
public String toString() {
return "[Response]";
}
// property-related methods:
public boolean getCache() {
return res.cache;
}
/**
*
*
* @param cache ...
*/
public void setcache(boolean cache) {
res.cache = cache;
}
/**
*
*
* @return ...
*/
public String getCharset() {
return res.charset;
}
/**
*
*
* @param charset ...
*/
public void setCharset(String charset) {
res.charset = charset;
}
/**
*
*
* @return ...
*/
public String getContentType() {
return res.contentType;
}
/**
*
*
* @param contentType ...
*/
public void setContentType(String contentType) {
res.contentType = contentType;
}
/**
*
*
* @return ...
*/
public Map getData() {
return res.getResponseData();
}
/**
*
*
* @return ...
*/
public Map getHandlers() {
return res.getMacroHandlers();
}
/**
*
*
* @return ...
*/
public String getError() {
return res.error;
}
/**
*
*
* @return ...
*/
public String getMessage() {
return res.message;
}
/**
*
*
* @param message ...
*/
public void setMessage(String message) {
res.message = message;
}
/**
*
*
* @return ...
*/
public String getRealm() {
return res.realm;
}
/**
*
*
* @param realm ...
*/
public void setRealm(String realm) {
res.realm = realm;
}
/**
*
*
* @param arr ...
*/
public void setSkinpath(Object[] arr) {
res.setSkinpath(arr);
}
/**
*
*
* @return ...
*/
public Object[] getSkinpath() {
return res.getSkinpath();
}
/**
*
*
* @return ...
*/
public int getStatus() {
return res.status;
}
/**
*
*
* @param status ...
*/
public void setStatus(int status) {
res.status = status;
}
/**
*
*
* @return ...
*/
public Date getLastModified() {
long modified = res.getLastModified();
if (modified > -1) {
return new Date(modified);
} else {
return null;
}
}
/**
*
*
* @param date ...
*/
public void setLastModified(Date date) {
if (date == null) {
res.setLastModified(-1);
} else {
res.setLastModified(date.getTime());
}
}
/**
*
*
* @return ...
*/
public String getETag() {
return res.getETag();
}
/**
*
*
* @param etag ...
*/
public void setETag(String etag) {
res.setETag(etag);
}
/**
*
*
* @param what ...
*/
public void dependsOn(String what) {
res.dependsOn(what);
}
/**
*
*/
public void digest() {
res.digestDependencies();
}
/////////////////////////////////////
// The following are legacy methods used by
// Helma templates (*.hsp files) and shouldn't
// be used otherwise.
////////////////////////////////////
public void pushStringBuffer() {
res.pushStringBuffer();
}
/**
*
*
* @return ...
*/
public String popStringBuffer() {
return res.popStringBuffer();
}
}

View file

@ -1,794 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework;
import helma.framework.core.Skin;
import helma.objectmodel.*;
import helma.util.*;
import java.io.*;
import java.security.*;
import java.util.*;
/**
* A Transmitter for a response to the servlet client. Objects of this
* class are directly exposed to JavaScript as global property res.
*/
public final class ResponseTrans implements Externalizable {
static final long serialVersionUID = -8627370766119740844L;
static final int INITIAL_BUFFER_SIZE = 2048;
static final String newLine = System.getProperty("line.separator");
/**
* Set the MIME content type of the response.
*/
public String contentType = "text/html";
/**
* Set the charset (encoding) to use for the response.
*/
public String charset;
/**
* used to allow or disable client side caching
*/
public boolean cache = true;
/**
* Used for HTTP response code, if 0 code 200 OK will be used.
*/
public int status = 0;
/**
* Used for HTTP authentication
*/
public String realm;
// name of the skin to be rendered after completion, if any
public transient String skin = null;
// the actual response
private byte[] response = null;
// contains the redirect URL
private String redir = null;
// the last-modified date, if it should be set in the response
private long lastModified = -1;
// flag to signal that resource has not been modified
private boolean notModified = false;
// Entity Tag for this response, used for conditional GETs
private String etag = null;
// cookies
Map cookies;
// the buffer used to build the response
private transient StringBuffer buffer = null;
// these are used to implement the _as_string variants for Hop templates.
private transient Stack buffers;
// the path used to tell where to look for skins
private transient Object[] skinpath = null;
// hashmap for skin caching
private transient HashMap skincache;
// buffer for debug messages - will be automatically appended to response
private transient StringBuffer debugBuffer;
/**
* string fields that hold a user message
*/
public transient String message;
/**
* string fields that hold an error message
*/
public transient String error;
// the map of form and cookie data
private transient Map values;
// the map of macro handlers
private transient Map handlers;
// the request trans for this response
private transient RequestTrans reqtrans;
// the message digest used to generate composed digests for ETag headers
private transient MessageDigest digest;
// the appliciation checksum to make ETag headers sensitive to app changes
long applicationChecksum;
/**
* Creates a new ResponseTrans object.
*/
public ResponseTrans() {
super();
message = error = null;
values = new SystemMap();
handlers = new SystemMap();
}
/**
* Creates a new ResponseTrans object.
*
* @param req ...
*/
public ResponseTrans(RequestTrans req) {
this();
reqtrans = req;
}
/**
* Get a value from the responses map by key.
*/
public Object get(String name) {
try {
return values.get(name);
} catch (Exception x) {
return null;
}
}
/**
* Get the data map for this response transmitter.
*/
public Map getResponseData() {
return values;
}
/**
* Get the macro handlers map for this response transmitter.
*/
public Map getMacroHandlers() {
return handlers;
}
/**
* Reset the response object to its initial empty state.
*/
public void reset() {
if (buffer != null) {
buffer.setLength(0);
}
buffers = null;
response = null;
redir = null;
skin = null;
message = error = null;
values.clear();
lastModified = -1;
notModified = false;
etag = null;
if (digest != null) {
digest.reset();
}
}
/**
* This is called before a skin is rendered as string (renderSkinAsString) to redirect the output
* to a new string buffer.
*/
public void pushStringBuffer() {
if (buffers == null) {
buffers = new Stack();
}
if (buffer != null) {
buffers.push(buffer);
}
buffer = new StringBuffer(64);
}
/**
* Returns the content of the current string buffer and switches back to the previos one.
*/
public String popStringBuffer() {
StringBuffer b = buffer;
buffer = buffers.empty() ? null : (StringBuffer) buffers.pop();
return b.toString();
}
/**
* Get the response buffer, creating it if it doesn't exist
*/
public StringBuffer getBuffer() {
if (buffer == null) {
buffer = new StringBuffer(INITIAL_BUFFER_SIZE);
}
return buffer;
}
/**
* Append a string to the response unchanged. This is often called
* at the end of a request to write out the whole page, so if buffer
* is uninitialized we just set it to the string argument.
*/
public void write(Object what) {
if (what != null) {
String str = what.toString();
if (buffer == null) {
buffer = new StringBuffer(Math.max(str.length() + 100, INITIAL_BUFFER_SIZE));
}
buffer.append(str);
}
}
/**
* Utility function that appends a <br> to whatever is written.
*/
public void writeln(Object what) {
write(what);
// if what is null, buffer may still be uninitialized
if (buffer == null) {
buffer = new StringBuffer(INITIAL_BUFFER_SIZE);
}
buffer.append("<br />");
buffer.append(newLine);
}
/**
* Append a part from a char array to the response buffer.
*/
public void writeCharArray(char[] c, int start, int length) {
if (buffer == null) {
buffer = new StringBuffer(Math.max(length, INITIAL_BUFFER_SIZE));
}
buffer.append(c, start, length);
}
/**
* Insert string somewhere in the response buffer. Caller has to make sure
* that buffer exists and its length is larger than offset. str may be null, in which
* case nothing happens.
*/
public void debug(Object message) {
if (debugBuffer == null) {
debugBuffer = new StringBuffer();
}
String str = (message == null) ? "null" : message.toString();
debugBuffer.append("<p><span style=\"background: yellow; color: black\">");
debugBuffer.append(str);
debugBuffer.append("</span></p>");
}
/**
* Replace special characters with entities, including <, > and ", thus allowing
* no HTML tags.
*/
public void encode(Object what) {
if (what != null) {
String str = what.toString();
if (buffer == null) {
buffer = new StringBuffer(Math.max(str.length() + 100, INITIAL_BUFFER_SIZE));
}
HtmlEncoder.encodeAll(str, buffer);
}
}
/**
* Replace special characters with entities but pass through HTML tags
*/
public void format(Object what) {
if (what != null) {
String str = what.toString();
if (buffer == null) {
buffer = new StringBuffer(Math.max(str.length() + 100, INITIAL_BUFFER_SIZE));
}
HtmlEncoder.encode(str, buffer);
}
}
/**
* Replace special characters with entities, including <, > and ", thus allowing
* no HTML tags.
*/
public void encodeXml(Object what) {
if (what != null) {
String str = what.toString();
if (buffer == null) {
buffer = new StringBuffer(Math.max(str.length() + 100, INITIAL_BUFFER_SIZE));
}
HtmlEncoder.encodeXml(str, buffer);
}
}
/**
* Encode HTML entities, but leave newlines alone. This is for the content of textarea forms.
*/
public void encodeForm(Object what) {
if (what != null) {
String str = what.toString();
if (buffer == null) {
buffer = new StringBuffer(Math.max(str.length() + 100, INITIAL_BUFFER_SIZE));
}
HtmlEncoder.encodeAll(str, buffer, false);
}
}
/**
*
*
* @param str ...
*/
public void append(String str) {
if (str != null) {
if (buffer == null) {
buffer = new StringBuffer(Math.max(str.length(), INITIAL_BUFFER_SIZE));
}
buffer.append(str);
}
}
/**
*
*
* @param url ...
*
* @throws RedirectException ...
*/
public void redirect(String url) throws RedirectException {
redir = url;
throw new RedirectException(url);
}
/**
*
*
* @return ...
*/
public String getRedirect() {
return redir;
}
/**
* Allow to directly set the byte array for the response. Calling this more than once will
* overwrite the previous output. We take a generic object as parameter to be able to
* generate a better error message, but it must be byte[].
*/
public void writeBinary(byte[] what) {
response = what;
}
/**
* This has to be called after writing to this response has finished and before it is shipped back to the
* web server. Transforms the string buffer into a char array to minimize size.
*/
public synchronized void close(String cset) throws UnsupportedEncodingException {
// only use default charset if not explicitly set for this response.
if (charset == null) {
charset = cset;
}
// if charset is not set, use western encoding
if (charset == null) {
charset = "ISO-8859-1";
}
boolean encodingError = false;
// only close if the response hasn't been closed yet
if (response == null) {
// if debug buffer exists, append it to main buffer
if (debugBuffer != null) {
if (buffer == null) {
buffer = debugBuffer;
} else {
buffer.append(debugBuffer);
}
}
// get the buffer's bytes in the specified encoding
if (buffer != null) {
try {
response = buffer.toString().getBytes(charset);
} catch (UnsupportedEncodingException uee) {
encodingError = true;
response = buffer.toString().getBytes();
}
// make sure this is done only once, even with more requsts attached
buffer = null;
} else {
response = new byte[0];
}
}
// if etag is not set, calc MD5 digest and check it
if ((etag == null) && (lastModified == -1) && (redir == null)) {
try {
digest = MessageDigest.getInstance("MD5");
// if (contentType != null)
// digest.update (contentType.getBytes());
byte[] b = digest.digest(response);
etag = "\"" + new String(Base64.encode(b)) + "\"";
if ((reqtrans != null) && reqtrans.hasETag(etag)) {
response = new byte[0];
notModified = true;
}
} catch (Exception ignore) {
// Etag creation failed for some reason. Ignore.
}
}
notifyAll();
// if there was a problem with the encoding, let the app know
if (encodingError) {
throw new UnsupportedEncodingException(charset);
}
}
/**
* If we just attached to evaluation we call this instead of close because only the primary thread
* is responsible for closing the result
*/
public synchronized void waitForClose() {
try {
if (response == null) {
wait(10000L);
}
} catch (InterruptedException ix) {
}
}
/**
*
*
* @return ...
*/
public byte[] getContent() {
return (response == null) ? new byte[0] : response;
}
/**
*
*
* @return ...
*/
public int getContentLength() {
if (response != null) {
return response.length;
}
return 0;
}
/**
*
*
* @return ...
*/
public String getContentType() {
if (charset != null) {
return contentType + "; charset=" + charset;
}
return contentType;
}
/**
*
*
* @param modified ...
*/
public void setLastModified(long modified) {
if ((modified > -1) && (reqtrans != null) &&
(reqtrans.getIfModifiedSince() >= modified)) {
notModified = true;
throw new RedirectException(null);
}
lastModified = modified;
}
/**
*
*
* @return ...
*/
public long getLastModified() {
return lastModified;
}
/**
*
*
* @param value ...
*/
public void setETag(String value) {
etag = (value == null) ? null : ("\"" + value + "\"");
if ((etag != null) && (reqtrans != null) && reqtrans.hasETag(etag)) {
notModified = true;
throw new RedirectException(null);
}
}
/**
*
*
* @return ...
*/
public String getETag() {
return etag;
}
/**
*
*
* @return ...
*/
public boolean getNotModified() {
return notModified;
}
/**
*
*
* @param what ...
*/
public void dependsOn(Object what) {
if (digest == null) {
try {
digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException nsa) {
// MD5 should always be available
}
}
if (what == null) {
digest.update(new byte[0]);
} else if (what instanceof Date) {
digest.update(MD5Encoder.toBytes(((Date) what).getTime()));
} else if (what instanceof byte[]) {
digest.update((byte[]) what);
} else {
String str = what.toString();
if (str != null) {
digest.update(str.getBytes());
} else {
digest.update(new byte[0]);
}
}
}
/**
*
*/
public void digestDependencies() {
if (digest == null) {
return;
}
byte[] b = digest.digest(MD5Encoder.toBytes(applicationChecksum));
/* StringBuffer buf = new StringBuffer(b.length*2);
for ( int i=0; i<b.length; i++ ) {
int j = (b[i]<0) ? 256+b[i] : b[i];
if ( j<16 ) buf.append("0");
buf.append(Integer.toHexString(j));
}
setETag (buf.toString ()); */
setETag(new String(Base64.encode(b)));
}
/**
*
*
* @param n ...
*/
public void setApplicationChecksum(long n) {
applicationChecksum = n;
}
/**
*
*
* @param arr ...
*/
public void setSkinpath(Object[] arr) {
this.skinpath = arr;
skincache = null;
}
/**
*
*
* @return ...
*/
public Object[] getSkinpath() {
if (skinpath == null) {
skinpath = new Object[0];
}
return skinpath;
}
/**
*
*
* @param id ...
*
* @return ...
*/
public Skin getCachedSkin(Object id) {
if (skincache == null) {
return null;
}
return (Skin) skincache.get(id);
}
/**
*
*
* @param id ...
* @param skin ...
*/
public void cacheSkin(Object id, Skin skin) {
if (skincache == null) {
skincache = new HashMap();
}
skincache.put(id, skin);
}
/**
*
*
* @param key ...
* @param value ...
* @param days ...
* @param path ...
* @param domain ...
*/
public void setCookie(String key, String value, int days, String path, String domain) {
CookieTrans c = null;
if (cookies == null) {
cookies = new HashMap();
} else {
c = (CookieTrans) cookies.get(key);
}
if (c == null) {
c = new CookieTrans(key, value);
cookies.put(key, c);
} else {
c.setValue(value);
}
c.setDays(days);
c.setPath(path);
c.setDomain(domain);
}
/**
*
*/
public void resetCookies() {
if (cookies != null) {
cookies.clear();
}
}
/**
*
*
* @return ...
*/
public int countCookies() {
if (cookies != null) {
return cookies.size();
}
return 0;
}
/**
*
*
* @return ...
*/
public CookieTrans[] getCookies() {
if (cookies == null) {
return new CookieTrans[0];
}
CookieTrans[] c = new CookieTrans[cookies.size()];
cookies.values().toArray(c);
return c;
}
/**
*
*
* @param s ...
*
* @throws ClassNotFoundException ...
* @throws IOException ...
*/
public void readExternal(ObjectInput s) throws ClassNotFoundException, IOException {
contentType = (String) s.readObject();
response = (byte[]) s.readObject();
redir = (String) s.readObject();
cookies = (Map) s.readObject();
cache = s.readBoolean();
status = s.readInt();
realm = (String) s.readObject();
lastModified = s.readLong();
notModified = s.readBoolean();
charset = (String) s.readObject();
etag = (String) s.readObject();
}
/**
*
*
* @param s ...
*
* @throws IOException ...
*/
public void writeExternal(ObjectOutput s) throws IOException {
s.writeObject(contentType);
s.writeObject(response);
s.writeObject(redir);
s.writeObject(cookies);
s.writeBoolean(cache);
s.writeInt(status);
s.writeObject(realm);
s.writeLong(lastModified);
s.writeBoolean(notModified);
s.writeObject(charset);
s.writeObject(etag);
}
}

View file

@ -1,31 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework;
/**
* TimeoutException is thrown by the request evaluator when a request could
* not be serviced within the timeout period specified for an application.
*/
public class TimeoutException extends RuntimeException {
/**
* Creates a new TimeoutException object.
*/
public TimeoutException() {
super("Request timed out");
}
}

View file

@ -1,53 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework.core;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.util.Enumeration;
/**
* ClassLoader subclass with package accessible addURL method.
*/
public class AppClassLoader extends URLClassLoader {
private final String appname;
/**
* Create a HelmaClassLoader with the given application name and the given URLs
*/
public AppClassLoader(String appname, URL[] urls) {
super(urls, AppClassLoader.class.getClassLoader());
this.appname = appname;
}
protected void addURL(URL url) {
super.addURL(url);
}
/**
*
*
* @return ...
*/
public String getAppName() {
return appname;
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,505 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework.core;
import helma.objectmodel.INode;
import helma.util.CronJob;
import helma.util.SystemMap;
import helma.util.WrappedMap;
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
*
*/
public class ApplicationBean implements Serializable {
Application app;
WrappedMap properties = null;
/**
* Creates a new ApplicationBean object.
*
* @param app ...
*/
public ApplicationBean(Application app) {
this.app = app;
}
/**
*
*/
public void clearCache() {
app.clearCache();
}
/**
*
*
* @param msg ...
*/
public void log(Object msg) {
String str = (msg == null) ? "null" : msg.toString();
app.logEvent(str);
}
/**
*
*
* @param logname ...
* @param msg ...
*/
public void log(String logname, Object msg) {
String str = (msg == null) ? "null" : msg.toString();
app.getLogger(logname).log(str);
}
/**
*
*
* @param msg ...
*/
public void debug(Object msg) {
if (app.debug()) {
String str = (msg == null) ? "null" : msg.toString();
app.logEvent(str);
}
}
/**
*
*
* @param logname ...
* @param msg ...
*/
public void debug(String logname, Object msg) {
if (app.debug()) {
String str = (msg == null) ? "null" : msg.toString();
app.getLogger(logname).log(str);
}
}
/**
*
*
* @return ...
*/
public int countSessions() {
return app.sessions.size();
}
/**
*
*
* @param sessionID ...
*
* @return ...
*/
public SessionBean getSession(String sessionID) {
if (sessionID == null) {
return null;
}
Session session = app.getSession(sessionID.trim());
if (session == null) {
return null;
}
return new SessionBean(session);
}
/**
*
*
* @param sessionID ...
*
* @return ...
*/
public SessionBean createSession(String sessionID) {
if (sessionID == null) {
return null;
}
Session session = session = app.checkSession(sessionID.trim());
if (session == null) {
return null;
}
return new SessionBean(session);
}
/**
*
*
* @return ...
*/
public SessionBean[] getSessions() {
SessionBean[] theArray = new SessionBean[app.sessions.size()];
int i = 0;
for (Enumeration e = app.sessions.elements(); e.hasMoreElements();) {
SessionBean sb = new SessionBean((Session) e.nextElement());
theArray[i++] = sb;
}
return theArray;
}
/**
*
*
* @param username ...
* @param password ...
*
* @return ...
*/
public INode registerUser(String username, String password) {
if ((username == null) || (password == null) || "".equals(username.trim()) ||
"".equals(password.trim())) {
return null;
} else {
return app.registerUser(username, password);
}
}
/**
*
*
* @param username ...
*
* @return ...
*/
public INode getUser(String username) {
if ((username == null) || "".equals(username.trim())) {
return null;
}
return app.getUserNode(username);
}
/**
*
*
* @return ...
*/
public INode[] getActiveUsers() {
List activeUsers = app.getActiveUsers();
return (INode[]) activeUsers.toArray(new INode[0]);
}
/**
*
*
* @return ...
*/
public INode[] getRegisteredUsers() {
List registeredUsers = app.getRegisteredUsers();
return (INode[]) registeredUsers.toArray(new INode[0]);
}
/**
*
*
* @param usernode ...
*
* @return ...
*/
public SessionBean[] getSessionsForUser(INode usernode) {
if (usernode == null) {
return new SessionBean[0];
} else {
return getSessionsForUser(usernode.getName());
}
}
/**
*
*
* @param username ...
*
* @return ...
*/
public SessionBean[] getSessionsForUser(String username) {
if ((username == null) || "".equals(username.trim())) {
return new SessionBean[0];
}
List userSessions = app.getSessionsForUsername(username);
return (SessionBean[]) userSessions.toArray(new SessionBean[0]);
}
/**
*
*
* @param functionName ...
*/
public void addCronJob(String functionName) {
CronJob job = new CronJob(functionName);
job.setFunction(functionName);
app.customCronJobs.put(functionName, job);
}
/**
*
*
* @param functionName ...
* @param year ...
* @param month ...
* @param day ...
* @param weekday ...
* @param hour ...
* @param minute ...
*/
public void addCronJob(String functionName, String year, String month, String day,
String weekday, String hour, String minute) {
CronJob job = CronJob.newJob(functionName, year, month, day, weekday, hour, minute);
app.customCronJobs.put(functionName, job);
}
/**
*
*
* @param functionName ...
*/
public void removeCronJob(String functionName) {
app.customCronJobs.remove(functionName);
}
// getter methods for readonly properties of this application
public int getCacheusage() {
return app.getCacheUsage();
}
/**
*
*
* @return ...
*/
public INode getData() {
return app.getCacheNode();
}
/**
*
*
* @return ...
*/
public Map getModules() {
return app.modules;
}
/**
*
*
* @return ...
*/
public String getDir() {
return app.getAppDir().getAbsolutePath();
}
/**
*
*
* @return ...
*/
public String getName() {
return app.getName();
}
/**
*
*
* @return ...
*/
public Date getUpSince() {
return new Date(app.starttime);
}
/**
*
*
* @return ...
*/
public long getRequestCount() {
return app.getRequestCount();
}
/**
*
*
* @return ...
*/
public long getXmlrpcCount() {
return app.getXmlrpcCount();
}
/**
*
*
* @return ...
*/
public long getErrorCount() {
return app.getErrorCount();
}
/**
*
*
* @return ...
*/
public Application get__app__() {
return app;
}
/**
*
*
* @return ...
*/
public Map getProperties() {
if (properties == null) {
properties = new WrappedMap(app.getProperties());
properties.setReadonly(true);
}
return properties;
}
/**
*
*
* @return ...
*/
public int getFreeThreads() {
return app.countFreeEvaluators();
}
/**
*
*
* @return ...
*/
public int getActiveThreads() {
return app.countActiveEvaluators();
}
/**
*
*
* @return ...
*/
public int getMaxThreads() {
return app.countEvaluators();
}
/**
*
*
* @param n ...
*/
public void setMaxThreads(int n) {
// add one to the number to compensate for the internal scheduler.
app.setNumberOfEvaluators(n + 1);
}
/**
*
*
* @return ...
*/
public Map getSkinfiles() {
Map skinz = new SystemMap();
for (Iterator it = app.getPrototypes().iterator(); it.hasNext();) {
Prototype p = (Prototype) it.next();
skinz.put(p.getName(), p.getSkinMap());
}
return skinz;
}
/**
*
*
* @param skinpath ...
*
* @return ...
*/
public Map getSkinfilesInPath(Object[] skinpath) {
Map skinz = new SystemMap();
for (Iterator it = app.getPrototypes().iterator(); it.hasNext();) {
Prototype p = (Prototype) it.next();
skinz.put(p.getName(), p.getSkinMap(skinpath));
}
return skinz;
}
/**
*
*
* @return ...
*/
public String getAppDir() {
return app.getAppDir().getAbsolutePath();
}
/**
*
*
* @return ...
*/
public String getServerDir() {
File f = app.getServerDir();
if (f == null) {
f = app.getAppDir();
}
return f.getAbsolutePath();
}
/**
*
*
* @return ...
*/
public String toString() {
return "[Application " + app.getName() + "]";
}
}

View file

@ -1,591 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework.core;
import helma.framework.*;
import helma.objectmodel.*;
import helma.objectmodel.db.DbMapping;
import helma.scripting.*;
import helma.util.Updatable;
import helma.util.SystemMap;
import java.io.*;
import java.util.*;
/**
* The Prototype class represents Script prototypes/type defined in a Helma
* application. This class manages a prototypes templates, functions and actions
* as well as optional information about the mapping of this type to a
* relational database table.
*/
public final class Prototype {
String name;
Application app;
File directory;
File[] files;
long lastDirectoryListing;
long checksum;
HashMap code;
HashMap zippedCode;
HashMap skins;
HashMap zippedSkins;
HashMap updatables;
// a map of this prototype's skins as raw strings
// used for exposing skins to application (script) code (via app.skinfiles).
SkinMap skinMap;
DbMapping dbmap;
// lastCheck is the time the prototype's files were last checked
private long lastChecksum;
// lastUpdate is the time at which any of the prototype's files were
// found updated the last time
private long lastUpdate;
private Prototype parent;
// Tells us whether this prototype is used to script a generic Java object,
// as opposed to a Helma objectmodel node object.
boolean isJavaPrototype;
/**
* Creates a new Prototype object.
*
* @param name ...
* @param dir ...
* @param app ...
*/
public Prototype(String name, File dir, Application app) {
// app.logEvent ("Constructing Prototype "+app.getName()+"/"+name);
this.app = app;
this.name = name;
this.directory = dir;
code = new HashMap();
zippedCode = new HashMap();
skins = new HashMap();
zippedSkins = new HashMap();
updatables = new HashMap();
skinMap = new SkinMap();
isJavaPrototype = app.isJavaPrototype(name);
lastUpdate = lastChecksum = 0;
}
/**
* Return the application this prototype is a part of
*/
public Application getApplication() {
return app;
}
/**
* Return this prototype's directory.
*/
public File getDirectory() {
return directory;
}
/**
* Get the list of files in this prototype's directory
*/
public File[] getFiles() {
if ((files == null) || (directory.lastModified() != lastDirectoryListing)) {
lastDirectoryListing = directory.lastModified();
files = directory.listFiles();
if (files == null) {
files = new File[0];
}
}
return files;
}
/**
* Get a checksum over the files in this prototype's directory
*/
public long getChecksum() {
// long start = System.currentTimeMillis();
File[] f = getFiles();
long c = directory.lastModified();
for (int i = 0; i < f.length; i++)
c += f[i].lastModified();
checksum = c;
// System.err.println ("CHECKSUM "+name+": "+(System.currentTimeMillis()-start));
return checksum;
}
/**
*
*
* @return ...
*/
public boolean isUpToDate() {
return checksum == lastChecksum;
}
/**
* Set the parent prototype of this prototype, i.e. the prototype this
* prototype inherits from.
*/
public void setParentPrototype(Prototype parent) {
// this is not allowed for the hopobject and global prototypes
if ("hopobject".equalsIgnoreCase(name) || "global".equalsIgnoreCase(name)) {
return;
}
this.parent = parent;
}
/**
* Get the parent prototype from which we inherit, or null
* if we are top of the line.
*/
public Prototype getParentPrototype() {
return parent;
}
/**
* Check if the given prototype is within this prototype's parent chain.
*/
public final boolean isInstanceOf(String pname) {
if (name.equals(pname)) {
return true;
}
if ((parent != null) && !"hopobject".equalsIgnoreCase(parent.getName())) {
return parent.isInstanceOf(pname);
}
return false;
}
/**
* Register an object as handler for all our parent prototypes.
*/
public final void registerParents(Map handlers, Object obj) {
Prototype p = parent;
while ((p != null) && !"hopobject".equalsIgnoreCase(p.getName())) {
handlers.put(p.name, obj);
p = p.parent;
}
}
/**
*
*
* @param dbmap ...
*/
public void setDbMapping(DbMapping dbmap) {
this.dbmap = dbmap;
}
/**
*
*
* @return ...
*/
public DbMapping getDbMapping() {
return dbmap;
}
/**
* Get a Skinfile for this prototype. This only works for skins
* residing in the prototype directory, not for skin files in
* other locations or database stored skins.
*/
public SkinFile getSkinFile(String sfname) {
SkinFile sf = (SkinFile) skins.get(sfname);
if (sf == null) {
sf = (SkinFile) zippedSkins.get(sfname);
}
return sf;
}
/**
* Get a skin for this prototype. This only works for skins
* residing in the prototype directory, not for skins files in
* other locations or database stored skins.
*/
public Skin getSkin(String sfname) {
SkinFile sf = getSkinFile(sfname);
if (sf != null) {
return sf.getSkin();
} else {
return null;
}
}
/**
*
*
* @return ...
*/
public String getName() {
return name;
}
/**
* Get the last time any script has been re-read for this prototype.
*/
public long getLastUpdate() {
return lastUpdate;
}
/**
* Signal that some script in this prototype has been
* re-read from disk and needs to be re-compiled by
* the evaluators.
*/
public void markUpdated() {
lastUpdate = System.currentTimeMillis();
}
/**
* Signal that the prototype's scripts have been checked for
* changes.
*/
public void markChecked() {
// lastCheck = System.currentTimeMillis ();
lastChecksum = checksum;
}
/**
* Return a clone of this prototype's actions container. Synchronized
* to not return a map in a transient state where it is just being
* updated by the type manager.
*/
public synchronized Map getCode() {
return (Map) code.clone();
}
/**
* Return a clone of this prototype's functions container. Synchronized
* to not return a map in a transient state where it is just being
* updated by the type manager.
*/
public synchronized Map getZippedCode() {
return (Map) zippedCode.clone();
}
/**
*
*
* @param action ...
*/
public synchronized void addActionFile(ActionFile action) {
File f = action.getFile();
if (f != null) {
code.put(action.getSourceName(), action);
updatables.put(f.getName(), action);
} else {
zippedCode.put(action.getSourceName(), action);
}
}
/**
*
*
* @param template ...
*/
public synchronized void addTemplate(Template template) {
File f = template.getFile();
if (f != null) {
code.put(template.getSourceName(), template);
updatables.put(f.getName(), template);
} else {
zippedCode.put(template.getSourceName(), template);
}
}
/**
*
*
* @param funcfile ...
*/
public synchronized void addFunctionFile(FunctionFile funcfile) {
File f = funcfile.getFile();
if (f != null) {
code.put(funcfile.getSourceName(), funcfile);
updatables.put(f.getName(), funcfile);
} else {
zippedCode.put(funcfile.getSourceName(), funcfile);
}
}
/**
*
*
* @param skinfile ...
*/
public synchronized void addSkinFile(SkinFile skinfile) {
File f = skinfile.getFile();
if (f != null) {
skins.put(skinfile.getName(), skinfile);
updatables.put(f.getName(), skinfile);
} else {
zippedSkins.put(skinfile.getName(), skinfile);
}
}
/**
*
*
* @param action ...
*/
public synchronized void removeActionFile(ActionFile action) {
File f = action.getFile();
if (f != null) {
code.remove(action.getSourceName());
updatables.remove(f.getName());
} else {
zippedCode.remove(action.getSourceName());
}
}
/**
*
*
* @param funcfile ...
*/
public synchronized void removeFunctionFile(FunctionFile funcfile) {
File f = funcfile.getFile();
if (f != null) {
code.remove(funcfile.getSourceName());
updatables.remove(f.getName());
} else {
zippedCode.remove(funcfile.getSourceName());
}
}
/**
*
*
* @param template ...
*/
public synchronized void removeTemplate(Template template) {
File f = template.getFile();
if (f != null) {
code.remove(template.getSourceName());
updatables.remove(f.getName());
} else {
zippedCode.remove(template.getSourceName());
}
}
/**
*
*
* @param skinfile ...
*/
public synchronized void removeSkinFile(SkinFile skinfile) {
File f = skinfile.getFile();
if (f != null) {
skins.remove(skinfile.getName());
updatables.remove(f.getName());
} else {
zippedSkins.remove(skinfile.getName());
}
}
/**
* Return a string representing this prototype.
*/
public String toString() {
return "[Prototype " + app.getName() + "/" + name + "]";
}
/**
*
*
* @return ...
*/
public SkinMap getSkinMap() {
return skinMap;
}
// not yet implemented
public SkinMap getSkinMap(Object[] skinpath) {
return new SkinMap(skinpath);
}
// a map that dynamically expands to all skins in this prototype
final class SkinMap extends SystemMap {
long lastSkinmapLoad = 0;
Object[] skinpath;
SkinMap() {
super();
skinpath = null;
}
SkinMap(Object[] path) {
super();
skinpath = path;
}
public boolean containsKey(Object key) {
checkForUpdates();
return super.containsKey(key);
}
public boolean containsValue(Object value) {
checkForUpdates();
return super.containsValue(value);
}
public Set entrySet() {
checkForUpdates();
return super.entrySet();
}
public boolean equals(Object obj) {
checkForUpdates();
return super.equals(obj);
}
public Object get(Object key) {
if (key == null) {
return null;
}
checkForUpdates();
SkinFile sf = (SkinFile) super.get(key);
if (sf == null) {
return null;
}
return sf.getSkin().getSource();
}
public int hashCode() {
checkForUpdates();
return super.hashCode();
}
public boolean isEmpty() {
checkForUpdates();
return super.isEmpty();
}
public Set keySet() {
checkForUpdates();
return super.keySet();
}
public Object put(Object key, Object value) {
// checkForUpdates ();
return super.put(key, value);
}
public void putAll(Map t) {
// checkForUpdates ();
super.putAll(t);
}
public Object remove(Object key) {
checkForUpdates();
return super.remove(key);
}
public int size() {
checkForUpdates();
return super.size();
}
public Collection values() {
checkForUpdates();
return super.values();
}
private void checkForUpdates() {
if ( /* lastCheck < System.currentTimeMillis()- 2000l*/
!isUpToDate()) {
app.typemgr.updatePrototype(Prototype.this);
}
if (lastUpdate > lastSkinmapLoad) {
load();
}
}
private synchronized void load() {
if (lastUpdate == lastSkinmapLoad) {
return;
}
super.clear();
// System.err.println ("LOADING SKIN VALUES: "+Prototype.this);
for (Iterator i = skins.entrySet().iterator(); i.hasNext();) {
Map.Entry e = (Map.Entry) i.next();
super.put(e.getKey(), e.getValue());
}
// if skinpath is not null, overload/add skins from there
if (skinpath != null) {
for (int i = skinpath.length - 1; i >= 0; i--) {
if ((skinpath[i] != null) && skinpath[i] instanceof String) {
Map m = app.skinmgr.getSkinFiles((String) skinpath[i],
Prototype.this);
if (m != null) {
super.putAll(m);
}
}
}
}
lastSkinmapLoad = lastUpdate;
}
public String toString() {
return "[SkinMap " + name + "]";
}
}
}

View file

@ -1,69 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework.core;
import helma.framework.*;
import helma.objectmodel.db.*;
import java.rmi.*;
import java.rmi.server.*;
import java.util.Vector;
/**
* Proxy class for Aplication that listens to requests via RMI.
*/
public class RemoteApplication extends UnicastRemoteObject implements IRemoteApp,
IReplicationListener {
Application app;
/**
* Creates a new RemoteApplication object.
*
* @param app ...
*
* @throws RemoteException ...
*/
public RemoteApplication(Application app) throws RemoteException {
this.app = app;
}
/**
* ping method to let clients know if the server is reachable
*/
public void ping() {
// do nothing
}
/**
* Execute a request coming in from a web client.
*/
public ResponseTrans execute(RequestTrans req) {
return app.execute(req);
}
/**
* Update HopObjects in this application's cache. This is used to replicate
* application caches in a distributed app environment
*/
public void replicateCache(Vector add, Vector delete) {
if (!"true".equalsIgnoreCase(app.getProperty("allowReplication"))) {
app.logEvent("Rejecting cache replication event: allowReplication property is not set to true");
throw new RuntimeException("Replication event rejected: setup does not allow replication.");
}
app.nmgr.replicateCache(add, delete);
}
}

View file

@ -1,933 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework.core;
import helma.framework.*;
import helma.objectmodel.*;
import helma.objectmodel.db.*;
import helma.scripting.*;
import helma.util.*;
import java.lang.reflect.*;
import java.util.*;
/**
* This class does the work for incoming requests. It holds a transactor thread
* and an EcmaScript evaluator to get the work done. Incoming threads are
* blocked until the request has been serviced by the evaluator, or the timeout
* specified by the application has passed. In the latter case, the evaluator thread
* is killed and an error message is returned.
*/
public final class RequestEvaluator implements Runnable {
static final int NONE = 0; // no request
static final int HTTP = 1; // via HTTP gateway
static final int XMLRPC = 2; // via XML-RPC
static final int INTERNAL = 3; // generic function call, e.g. by scheduler
public final Application app;
protected ScriptingEngine scriptingEngine;
public RequestTrans req;
public ResponseTrans res;
volatile Transactor rtx;
// the object on which to invoke a function, if specified
Object thisObject;
// the method to be executed
String method;
// the session object associated with the current request
Session session;
// arguments passed to the function
Object[] args;
// the object path of the request we're evaluating
RequestPath requestPath;
// the result of the operation
Object result;
// the exception thrown by the evaluator, if any.
Exception exception;
// the type of request to be serviced
int reqtype;
protected int skinDepth;
/**
* Create a new RequestEvaluator for this application.
*/
public RequestEvaluator(Application app) {
this.app = app;
}
protected void initScriptingEngine() {
if (scriptingEngine == null) {
String engineClassName = app.getProperty("scriptingEngine",
"helma.scripting.rhino.RhinoEngine");
try {
Class clazz = app.getClassLoader().loadClass(engineClassName);
scriptingEngine = (ScriptingEngine) clazz.newInstance();
scriptingEngine.init(app, this);
} catch (Exception x) {
Throwable t = x;
if (x instanceof InvocationTargetException) {
t = ((InvocationTargetException) x).getTargetException();
}
app.logEvent("******************************************");
app.logEvent("*** Error creating scripting engine: ");
app.logEvent("*** " + t.toString());
app.logEvent("******************************************");
}
}
}
/**
*
*/
public void run() {
// first, set a local variable to the current transactor thread so we know
// when it's time to quit because another thread took over.
Transactor localrtx = (Transactor) Thread.currentThread();
try {
do {
// long startCheck = System.currentTimeMillis ();
app.typemgr.checkPrototypes();
initScriptingEngine();
scriptingEngine.updatePrototypes();
// System.err.println ("Type check overhead: "+(System.currentTimeMillis ()-startCheck)+" millis");
// object refs to ressolve request path
Object root;
// System.err.println ("Type check overhead: "+(System.currentTimeMillis ()-startCheck)+" millis");
// object refs to ressolve request path
Object currentElement;
requestPath = new RequestPath(app);
switch (reqtype) {
case HTTP:
int tries = 0;
boolean done = false;
String error = null;
while (!done) {
currentElement = null;
try {
// used for logging
StringBuffer txname = new StringBuffer(app.getName());
txname.append("/");
txname.append((error == null) ? req.path : "error");
// begin transaction
localrtx.begin(txname.toString());
String action = null;
root = app.getDataRoot();
HashMap globals = new HashMap();
globals.put("root", root);
globals.put("session", new SessionBean(session));
globals.put("req", new RequestBean(req));
globals.put("res", new ResponseBean(res));
globals.put("app", new ApplicationBean(app));
globals.put("path", requestPath);
req.startTime = System.currentTimeMillis();
// enter execution context
scriptingEngine.enterContext(globals);
if (error != null) {
res.error = error;
}
if (session.message != null) {
// bring over the message from a redirect
res.message = session.message;
session.message = null;
}
try {
if (error != null) {
// there was an error in the previous loop, call error handler
currentElement = root;
// do not reset the requestPath so error handler can use the original one
// get error handler action
String errorAction = app.props.getProperty("error",
"error");
action = getAction(currentElement, errorAction);
if (action == null) {
throw new RuntimeException(error);
}
} else if ((req.path == null) ||
"".equals(req.path.trim())) {
currentElement = root;
requestPath.add(null, currentElement);
action = getAction(currentElement, null);
if (action == null) {
throw new FrameworkException("Action not found");
}
} else {
// march down request path...
StringTokenizer st = new StringTokenizer(req.path,
"/");
int ntokens = st.countTokens();
// limit path to < 50 tokens
if (ntokens > 50) {
throw new RuntimeException("Path too long");
}
String[] pathItems = new String[ntokens];
for (int i = 0; i < ntokens; i++)
pathItems[i] = st.nextToken();
currentElement = root;
requestPath.add(null, currentElement);
for (int i = 0; i < ntokens; i++) {
if (currentElement == null) {
throw new FrameworkException("Object not found.");
}
if (pathItems[i].length() == 0) {
continue;
}
// if we're at the last element of the path,
// try to interpret it as action name.
if (i == (ntokens - 1)) {
action = getAction(currentElement,
pathItems[i]);
}
if (action == null) {
currentElement = getChildElement(currentElement,
pathItems[i]);
// add object to request path if suitable
if (currentElement != null) {
// add to requestPath array
requestPath.add(pathItems[i], currentElement);
}
}
}
if (currentElement == null) {
throw new FrameworkException("Object not found.");
}
if (action == null) {
action = getAction(currentElement, null);
}
if (action == null) {
throw new FrameworkException("Action not found");
}
}
} catch (FrameworkException notfound) {
if (error != null) {
// we already have an error and the error template wasn't found,
// display it instead of notfound message
throw new RuntimeException();
}
// The path could not be resolved. Check if there is a "not found" action
// specified in the property file.
res.status = 404;
String notFoundAction = app.props.getProperty("notFound",
"notfound");
currentElement = root;
action = getAction(currentElement, notFoundAction);
if (action == null) {
throw new FrameworkException(notfound.getMessage());
}
}
// register path objects with their prototype names in
// res.handlers
Map macroHandlers = res.getMacroHandlers();
int l = requestPath.size();
Prototype[] protos = new Prototype[l];
for (int i=0; i<l; i++) {
Object obj = requestPath.get(i);
protos[i] = app.getPrototype(obj);
// immediately register objects with their direct prototype name
if (protos[i] != null) {
macroHandlers.put(protos[i].getName(), obj);
}
}
// in a second pass, we register path objects with their indirect
// (i.e. parent prototype) names, starting at the end and only
// if the name isn't occupied yet.
for (int i=l-1; i>=0; i--) {
if (protos[i] != null) {
protos[i].registerParents(macroHandlers, requestPath.get(i));
}
}
/////////////////////////////////////////////////////////////////////////////
// end of path resolution section
/////////////////////////////////////////////////////////////////////////////
// beginning of execution section
try {
// set the req.action property, cutting off the _action suffix
req.action = action.substring(0, action.length() - 7);
// set the application checksum in response to make ETag
// generation sensitive to changes in the app
res.setApplicationChecksum(app.getChecksum());
// reset skin recursion detection counter
skinDepth = 0;
// try calling onRequest() function on object before
// calling the actual action
try {
if (scriptingEngine.hasFunction(currentElement,
"onRequest")) {
scriptingEngine.invoke(currentElement,
"onRequest",
new Object[0], false);
}
} catch (RedirectException redir) {
throw redir;
}
// reset skin recursion detection counter
skinDepth = 0;
// do the actual action invocation
scriptingEngine.invoke(currentElement, action,
new Object[0], false);
} catch (RedirectException redirect) {
// res.redirect = redirect.getMessage ();
// if there is a message set, save it on the user object for the next request
if (res.message != null) {
session.message = res.message;
}
done = true;
}
// check if we're still the one and only or if the waiting thread has given up on us already
commitTransaction();
done = true;
} catch (ConcurrencyException x) {
res.reset();
if (++tries < 8) {
// try again after waiting some period
abortTransaction(true);
try {
// wait a bit longer with each try
int base = 800 * tries;
Thread.sleep((long) (base + (Math.random() * base * 2)));
} catch (Exception ignore) {
}
continue;
} else {
abortTransaction(false);
if (error == null) {
app.errorCount += 1;
// set done to false so that the error will be processed
done = false;
error = "Couldn't complete transaction due to heavy object traffic (tried " +
tries + " times)";
} else {
// error in error action. use traditional minimal error message
res.write("<b>Error in application '" +
app.getName() + "':</b> <br><br><pre>" +
error + "</pre>");
done = true;
}
}
} catch (Exception x) {
abortTransaction(false);
// If the transactor thread has been killed by the invoker thread we don't have to
// bother for the error message, just quit.
if (localrtx != rtx) {
break;
}
res.reset();
// check if we tried to process the error already
if (error == null) {
app.errorCount += 1;
app.logEvent("Exception in " +
Thread.currentThread() + ": " + x);
// Dump the profiling data to System.err
if (app.debug && !(x instanceof ScriptingException)) {
x.printStackTrace ();
}
// set done to false so that the error will be processed
done = false;
error = x.getMessage();
if ((error == null) || (error.length() == 0)) {
error = x.toString();
}
if (error == null) {
error = "Unspecified error";
}
} else {
// error in error action. use traditional minimal error message
res.write("<b>Error in application '" +
app.getName() + "':</b> <br><br><pre>" +
error + "</pre>");
done = true;
}
}
}
break;
case XMLRPC:
try {
localrtx.begin(app.getName() + ":xmlrpc:" + method);
root = app.getDataRoot();
HashMap globals = new HashMap();
globals.put("root", root);
globals.put("res", new ResponseBean(res));
globals.put("app", new ApplicationBean(app));
scriptingEngine.enterContext(globals);
currentElement = root;
if (method.indexOf(".") > -1) {
StringTokenizer st = new StringTokenizer(method, ".");
int cnt = st.countTokens();
for (int i = 1; i < cnt; i++) {
String next = st.nextToken();
currentElement = getChildElement(currentElement,
next);
}
if (currentElement == null) {
throw new FrameworkException("Method name \"" +
method +
"\" could not be resolved.");
}
method = st.nextToken();
}
// check XML-RPC access permissions
String proto = app.getPrototypeName(currentElement);
app.checkXmlRpcAccess(proto, method);
// reset skin recursion detection counter
skinDepth = 0;
result = scriptingEngine.invoke(currentElement, method, args,
true);
commitTransaction();
} catch (Exception x) {
abortTransaction(false);
app.logEvent("Exception in " + Thread.currentThread() + ": " +
x);
// If the transactor thread has been killed by the invoker thread we don't have to
// bother for the error message, just quit.
if (localrtx != rtx) {
return;
}
this.exception = x;
}
break;
case INTERNAL:
// Just a human readable descriptor of this invocation
String funcdesc = app.getName() + ":internal:" + method;
// if thisObject is an instance of NodeHandle, get the node object itself.
if ((thisObject != null) && thisObject instanceof NodeHandle) {
thisObject = ((NodeHandle) thisObject).getNode(app.nmgr.safe);
// see if a valid node was returned
if (thisObject == null) {
reqtype = NONE;
break;
}
}
// avoid going into transaction if called function doesn't exist
boolean functionexists = true;
functionexists = scriptingEngine.hasFunction(thisObject, method);
if (!functionexists) {
// function doesn't exist, nothing to do here.
reqtype = NONE;
} else {
try {
localrtx.begin(funcdesc);
root = app.getDataRoot();
HashMap globals = new HashMap();
globals.put("root", root);
globals.put("res", new ResponseBean(res));
globals.put("app", new ApplicationBean(app));
scriptingEngine.enterContext(globals);
// reset skin recursion detection counter
skinDepth = 0;
result = scriptingEngine.invoke(thisObject, method, args,
false);
commitTransaction();
} catch (Exception x) {
abortTransaction(false);
app.logEvent("Exception in " + Thread.currentThread() +
": " + x);
// If the transactor thread has been killed by the invoker thread we don't have to
// bother for the error message, just quit.
if (localrtx != rtx) {
return;
}
this.exception = x;
}
}
break;
}
// exit execution context
scriptingEngine.exitContext();
// make sure there is only one thread running per instance of this class
// if localrtx != rtx, the current thread has been aborted and there's no need to notify
if (localrtx != rtx) {
localrtx.closeConnections();
return;
}
notifyAndWait();
} while (localrtx == rtx);
} finally {
localrtx.closeConnections();
}
}
/**
* Called by the transactor thread when it has successfully fulfilled a request.
*/
synchronized void commitTransaction() throws Exception {
Transactor localrtx = (Transactor) Thread.currentThread();
if (localrtx == rtx) {
reqtype = NONE;
localrtx.commit();
} else {
throw new TimeoutException();
}
}
synchronized void abortTransaction(boolean retry) {
Transactor localrtx = (Transactor) Thread.currentThread();
if (!retry && (localrtx == rtx)) {
reqtype = NONE;
}
try {
localrtx.abort();
} catch (Exception ignore) {
}
}
/**
* Tell waiting thread that we're done, then wait for next request
*/
synchronized void notifyAndWait() {
Transactor localrtx = (Transactor) Thread.currentThread();
if (reqtype != NONE) {
return; // is there a new request already?
}
notifyAll();
try {
// wait for request, max 10 min
wait(1000 * 60 * 10);
// if no request arrived, release ressources and thread
if ((reqtype == NONE) && (rtx == localrtx)) {
// comment this in to release not just the thread, but also the scripting engine.
// currently we don't do this because of the risk of memory leaks (objects from
// framework referencing into the scripting engine)
// scriptingEngine = null;
rtx = null;
}
} catch (InterruptedException ir) {
}
}
/**
*
*
* @param req ...
* @param session ...
*
* @return ...
*
* @throws Exception ...
*/
public synchronized ResponseTrans invoke(RequestTrans req, Session session)
throws Exception {
this.reqtype = HTTP;
this.req = req;
this.session = session;
this.res = new ResponseTrans(req);
app.activeRequests.put(req, this);
checkThread();
wait(app.requestTimeout);
if (reqtype != NONE) {
app.logEvent("Stopping Thread for Request " + app.getName() + "/" + req.path);
stopThread();
res.reset();
res.write("<b>Error in application '" + app.getName() +
"':</b> <br><br><pre>Request timed out.</pre>");
}
return res;
}
/**
* This checks if the Evaluator is already executing an equal request. If so, attach to it and
* wait for it to complete. Otherwise return null, so the application knows it has to run the request.
*/
public synchronized ResponseTrans attachRequest(RequestTrans req)
throws InterruptedException {
if ((this.req == null) || (res == null) || !this.req.equals(req)) {
return null;
}
// we already know our response object
ResponseTrans r = res;
if (reqtype != NONE) {
wait(app.requestTimeout);
}
return r;
}
/**
*
*
* @param method ...
* @param args ...
*
* @return ...
*
* @throws Exception ...
*/
public synchronized Object invokeXmlRpc(String method, Object[] args)
throws Exception {
this.reqtype = XMLRPC;
this.session = null;
this.method = method;
this.args = args;
this.res = new ResponseTrans();
result = null;
exception = null;
checkThread();
wait(app.requestTimeout);
if (reqtype != NONE) {
stopThread();
}
// reset res for garbage collection (res.data may hold reference to evaluator)
res = null;
if (exception != null) {
throw (exception);
}
return result;
}
/**
*
*
* @param obj ...
* @param functionName ...
* @param args ...
*
* @return ...
*
* @throws Exception ...
*/
public Object invokeDirectFunction(Object obj, String functionName, Object[] args)
throws Exception {
return scriptingEngine.invoke(obj, functionName, args, false);
}
/**
*
*
* @param object ...
* @param functionName ...
* @param args ...
*
* @return ...
*
* @throws Exception ...
*/
public synchronized Object invokeFunction(Object object, String functionName,
Object[] args)
throws Exception {
// give internal call more time (15 minutes) to complete
return invokeFunction(object, functionName, args, 60000L * 15);
}
/**
*
*
* @param object ...
* @param functionName ...
* @param args ...
* @param timeout ...
*
* @return ...
*
* @throws Exception ...
*/
public synchronized Object invokeFunction(Object object, String functionName,
Object[] args, long timeout)
throws Exception {
reqtype = INTERNAL;
session = null;
thisObject = object;
method = functionName;
this.args = args;
this.res = new ResponseTrans();
result = null;
exception = null;
checkThread();
wait(timeout);
if (reqtype != NONE) {
stopThread();
}
// reset res for garbage collection (res.data may hold reference to evaluator)
res = null;
if (exception != null) {
throw (exception);
}
return result;
}
/**
*
*
* @param session ...
* @param functionName ...
* @param args ...
*
* @return ...
*
* @throws Exception ...
*/
public synchronized Object invokeFunction(Session session, String functionName,
Object[] args)
throws Exception {
reqtype = INTERNAL;
this.session = session;
thisObject = null;
method = functionName;
this.args = args;
res = new ResponseTrans();
result = null;
exception = null;
checkThread();
wait(app.requestTimeout);
if (reqtype != NONE) {
stopThread();
}
// reset res for garbage collection (res.data may hold reference to evaluator)
res = null;
if (exception != null) {
throw (exception);
}
return result;
}
private Object getChildElement(Object obj, String name) throws ScriptingException {
if (scriptingEngine.hasFunction(obj, "getChildElement")) {
return scriptingEngine.invoke(obj, "getChildElement", new Object[] {name}, false);
}
if (obj instanceof IPathElement) {
return ((IPathElement) obj).getChildElement(name);
}
return null;
}
/**
* Stop this request evaluator's current thread. If currently active kill the request, otherwise just
* notify.
*/
public synchronized void stopThread() {
app.logEvent("Stopping Thread " + rtx);
Transactor t = rtx;
// let the scripting engine know that the
// current transaction is being aborted.
if (scriptingEngine != null) {
scriptingEngine.abort();
}
rtx = null;
if (t != null) {
if (reqtype != NONE) {
reqtype = NONE;
t.kill();
try {
t.abort();
} catch (Exception ignore) {
}
} else {
notifyAll();
}
t.closeConnections();
}
}
private synchronized void checkThread() throws InterruptedException {
if (app.stopped) {
throw new ApplicationStoppedException();
}
if ((rtx == null) || !rtx.isAlive()) {
// app.logEvent ("Starting Thread");
rtx = new Transactor(this, app.threadgroup, app.nmgr);
rtx.setContextClassLoader(app.getClassLoader());
rtx.start();
} else {
notifyAll();
}
}
/**
* Null out some fields, mostly for the sake of garbage collection.
*/
public void recycle() {
res = null;
req = null;
session = null;
args = null;
requestPath = null;
result = null;
exception = null;
}
/**
* Check if an action with a given name is defined for a scripted object. If it is,
* return the action's function name. Otherwise, return null.
*/
public String getAction(Object obj, String action) {
if (obj == null) {
return null;
}
String act = (action == null) ? "main_action" : (action + "_action");
if (scriptingEngine.hasFunction(obj, act)) {
return act;
}
return null;
}
}

View file

@ -1,134 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework.core;
import java.util.*;
import helma.util.UrlEncoded;
/**
* Represents a URI request path that has been resolved to an object path.
* Offers methods to access objects in the path by index and prototype names,
* and to render the path as URI again.
*/
public class RequestPath {
Application app;
List objects;
List ids;
Map primaryProtos;
Map secondaryProtos;
/**
* Creates a new RequestPath object.
*
* @param app the application we're running in
*/
public RequestPath(Application app) {
this.app = app;
objects = new ArrayList();
ids = new ArrayList();
primaryProtos = new HashMap();
secondaryProtos = new HashMap();
}
/**
* Adds an item to the end of the path.
*
* @param id the item id representing the path in the URL
* @param obj the object to which the id resolves
*/
public void add(String id, Object obj) {
ids.add(id);
objects.add(obj);
Prototype proto = app.getPrototype(obj);
if (proto != null) {
primaryProtos.put(proto.getName(), obj);
proto.registerParents(secondaryProtos, obj);
}
}
/**
* Returns the number of objects in the request path.
*/
public int size() {
return objects.size();
}
/**
* Gets an object in the path by index.
*
* @param idx the index of the object in the request path
*/
public Object get(int idx) {
if (idx < 0 || idx >= objects.size()) {
return null;
}
return objects.get(idx);
}
/**
* Gets an object in the path by prototype name.
*
* @param typeName the prototype name of the object in the request path
*/
public Object getByPrototypeName(String typeName) {
// search primary prototypes first
Object obj = primaryProtos.get(typeName);
if (obj != null) {
return obj;
}
// if that fails, consult secondary prototype map
return secondaryProtos.get(typeName);
}
/**
* Returns the string representation of this path usable for links.
*/
public String href(String action) {
StringBuffer buffer = new StringBuffer(app.getBaseURI());
int start = 1;
String rootPrototype = app.getRootPrototype();
if (rootPrototype != null) {
Object rootObject = getByPrototypeName(rootPrototype);
if (rootObject != null) {
start = objects.indexOf(rootObject) + 1;
}
}
for (int i=start; i<ids.size(); i++) {
buffer.append(UrlEncoded.encode(ids.get(i).toString()));
buffer.append("/");
}
if (action != null) {
buffer.append(UrlEncoded.encode(action));
}
return buffer.toString();
}
}

View file

@ -1,215 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework.core;
import helma.objectmodel.*;
import helma.objectmodel.db.*;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
/**
* This represents a session currently using the Hop application.
* This comprends anybody who happens to surf the site.
* Depending on whether the user is logged in or not, the user object holds a
* persistent user node.
*/
public class Session implements Serializable {
transient Application app;
String sessionID;
// the unique id (login name) for the user, if logged in
String uid;
// the handle to this user's persistent db node, if logged in
NodeHandle userHandle;
// the transient cache node that is exposed to javascript
// this stays the same across logins and logouts.
public TransientNode cacheNode;
long onSince;
long lastTouched;
long lastModified;
// used to remember messages to the user between requests -
// used for redirects.
String message;
/**
* Creates a new Session object.
*
* @param sessionID ...
* @param app ...
*/
public Session(String sessionID, Application app) {
this.sessionID = sessionID;
this.app = app;
this.uid = null;
this.userHandle = null;
cacheNode = new TransientNode("session");
onSince = System.currentTimeMillis();
lastTouched = lastModified = onSince;
}
/**
* attach the given user node to this session.
*/
public void login(INode usernode) {
if (usernode == null) {
userHandle = null;
uid = null;
} else {
userHandle = ((Node) usernode).getHandle();
uid = usernode.getElementName();
}
lastModified = System.currentTimeMillis();
}
/**
* remove this sessions's user node.
*/
public void logout() {
userHandle = null;
uid = null;
lastModified = System.currentTimeMillis();
}
/**
*
*
* @return ...
*/
public boolean isLoggedIn() {
if ((userHandle != null) && (uid != null)) {
return true;
} else {
return false;
}
}
/**
* Gets the user Node from this Application's NodeManager.
*/
public INode getUserNode() {
if (userHandle != null) {
return userHandle.getNode(app.getWrappedNodeManager());
} else {
return null;
}
}
/**
* Gets the transient cache node.
*/
public INode getCacheNode() {
return cacheNode;
}
/**
*
*
* @return ...
*/
public Application getApp() {
return app;
}
/**
*
*
* @param app ...
*/
public void setApp(Application app) {
this.app = app;
}
/**
*
*
* @return ...
*/
public String getSessionID() {
return sessionID;
}
/**
*
*/
public void touch() {
lastTouched = System.currentTimeMillis();
}
/**
*
*
* @return ...
*/
public long lastTouched() {
return lastTouched;
}
/**
*
*
* @return ...
*/
public long lastModified() {
return lastModified;
}
/**
*
*
* @param date ...
*/
public void setLastModified(Date date) {
if (date != null) {
lastModified = date.getTime();
}
}
/**
*
*
* @return ...
*/
public long onSince() {
return onSince;
}
/**
*
*
* @return ...
*/
public String toString() {
if (uid != null) {
return "[Session for user " + uid + "]";
} else {
return "[Anonymous Session]";
}
}
/**
* Get the persistent user id of a registered user. This is usually the user name, or
* null if the user is not logged in.
*/
public String getUID() {
return uid;
}
}

View file

@ -1,187 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework.core;
import helma.objectmodel.INode;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
/**
* The SessionBean wraps a <code>Session</code> object and
* exposes it to the scripting framework.
*/
public class SessionBean implements Serializable {
// the wrapped session object
Session session;
/**
* Creates a new SessionBean around a Session object.
*
* @param session ...
*/
public SessionBean(Session session) {
this.session = session;
}
/**
*
*
* @return ...
*/
public String toString() {
return session.toString();
}
/**
* Attempts to log in a user with the given username/password credentials.
* If username and password match, the user node is associated with the session
* and bound to the session.user property.
*
* @param username the username
* @param password the password
*
* @return true if the user exists and the password matches the user's password property.
*/
public boolean login(String username, String password) {
boolean success = session.getApp().loginSession(username, password, session);
return success;
}
/**
* Directly associates the session with a user object without requiring
* a username/password pair. This is for applications that use their own
* authentication mechanism.
*
* @param userNode the HopObject node representing the user.
*/
public void login(INode userNode) {
session.login(userNode);
}
/**
* Disassociate this session from any user object it may have been associated with.
*/
public void logout() {
session.getApp().logoutSession(session);
}
/**
* Touching the session marks it as active, avoiding session timeout.
* Usually, sessions are touched when the user associated with it sends
* a request. This method may be used to artificially keep a session alive.
*/
public void touch() {
session.touch();
}
/**
* Returns the time this session was last touched.
*
* @return ...
*/
public Date lastActive() {
return new Date(session.lastTouched());
}
/**
* Returns the time this session was created.
*
* @return ...
*/
public Date onSince() {
return new Date(session.onSince());
}
// property-related methods:
/**
* Get the cache/data node for this session. This object may be used
* to store transient per-session data. It is reflected to the scripting
* environment as session.data.
*/
public INode getdata() {
return session.getCacheNode();
}
/**
* Gets the user object for this session. This method returns null unless
* one of the session.login methods was previously invoked.
*
* @return ...
*/
public INode getuser() {
return session.getUserNode();
}
/**
* Returns the unique identifier for a session object (session cookie).
*
* @return ...
*/
public String get_id() {
return session.getSessionID();
}
/**
* Returns the unique identifier for a session object (session cookie).
*
* @return ...
*/
public String getcookie() {
return session.getSessionID();
}
/**
* Returns the time this session was last touched.
*
* @return ...
*/
public Date getlastActive() {
return new Date(session.lastTouched());
}
/**
* Returns a date object representing the time a user's session was started.
*
* @return ...
*/
public Date getonSince() {
return new Date(session.onSince());
}
/**
* Gets the date at which the session was created or a login or
* logout was performed the last time.
*
* @return ...
*/
public Date getLastModified() {
return new Date(session.lastModified());
}
/**
* Sets the date at which the session was created or a login or
* logout was performed the last time.
*
* @param date ...
*/
public void setLastModified(Date date) {
session.setLastModified(date);
}
}

View file

@ -1,683 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework.core;
import helma.framework.*;
import helma.objectmodel.ConcurrencyException;
import helma.objectmodel.INode;
import helma.scripting.*;
import helma.util.HtmlEncoder;
import helma.util.SystemMap;
import helma.util.WrappedMap;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
/**
* This represents a Helma skin, i.e. a template created from containing Macro tags
* that will be dynamically evaluated.. It uses the request path array
* from the RequestEvaluator object to resolve Macro handlers by type name.
*/
public final class Skin {
static final int HANDLER = 0;
static final int MACRO = 1;
static final int PARAMNAME = 2;
static final int PARAMVALUE = 3;
static final int ENCODE_NONE = 0;
static final int ENCODE_HTML = 1;
static final int ENCODE_XML = 2;
static final int ENCODE_FORM = 3;
static final int ENCODE_URL = 4;
static final int ENCODE_ALL = 5;
private Macro[] macros;
private Application app;
private char[] source;
private int sourceLength;
private HashSet sandbox;
/**
* Create a skin without any restrictions on which macros are allowed to be called from it
*/
public Skin(String content, Application app) {
this.app = app;
sandbox = null;
source = content.toCharArray();
sourceLength = source.length;
parse();
}
/**
* Create a skin with a sandbox which contains the names of macros allowed to be called
*/
public Skin(String content, Application app, HashSet sandbox) {
this.app = app;
this.sandbox = sandbox;
source = content.toCharArray();
sourceLength = source.length;
parse();
}
/**
* Create a skin without any restrictions on the macros from a char array.
*/
public Skin(char[] content, int length, Application app) {
this.app = app;
this.sandbox = null;
source = content;
sourceLength = length;
parse();
}
/**
* Parse a skin object from source text
*/
private void parse() {
ArrayList partBuffer = new ArrayList();
for (int i = 0; i < (sourceLength - 1); i++) {
if ((source[i] == '<') && (source[i + 1] == '%')) {
// found macro start tag
int j = i + 2;
// search macr end tag
while ((j < (sourceLength - 1)) &&
((source[j] != '%') || (source[j + 1] != '>'))) {
j++;
}
if (j > (i + 2)) {
partBuffer.add(new Macro(i, j + 2));
}
i = j + 1;
}
}
macros = new Macro[partBuffer.size()];
partBuffer.toArray(macros);
}
/**
* Get the raw source text this skin was parsed from
*/
public String getSource() {
return new String(source, 0, sourceLength);
}
/**
* Render this skin
*/
public void render(RequestEvaluator reval, Object thisObject, Map paramObject)
throws RedirectException {
// check for endless skin recursion
if (++reval.skinDepth > 50) {
throw new RuntimeException("Recursive skin invocation suspected");
}
if (macros == null) {
reval.res.writeCharArray(source, 0, sourceLength);
reval.skinDepth--;
return;
}
try {
int written = 0;
Map handlerCache = null;
if (macros.length > 3) {
handlerCache = new HashMap();
}
for (int i = 0; i < macros.length; i++) {
if (macros[i].start > written) {
reval.res.writeCharArray(source, written, macros[i].start - written);
}
macros[i].render(reval, thisObject, paramObject, handlerCache);
written = macros[i].end;
}
if (written < sourceLength) {
reval.res.writeCharArray(source, written, sourceLength - written);
}
} finally {
reval.skinDepth--;
}
}
/**
* Check if a certain macro is present in this skin. The macro name is in handler.name notation
*/
public boolean containsMacro(String macroname) {
for (int i = 0; i < macros.length; i++) {
if (macros[i] instanceof Macro) {
Macro m = (Macro) macros[i];
if (macroname.equals(m.fullName)) {
return true;
}
}
}
return false;
}
/**
* Adds a macro to the list of allowed macros. The macro is in handler.name notation.
*/
public void allowMacro(String macroname) {
if (sandbox == null) {
sandbox = new HashSet();
}
sandbox.add(macroname);
}
class Macro {
final int start;
final int end;
String handler;
String name;
String fullName;
String prefix;
String suffix;
String defaultValue;
int encoding = ENCODE_NONE;
Map parameters = null;
public Macro(int start, int end) {
this.start = start;
this.end = end;
int state = HANDLER;
boolean escape = false;
char quotechar = '\u0000';
String lastParamName = null;
StringBuffer b = new StringBuffer();
for (int i = start + 2; i < (end - 2); i++) {
switch (source[i]) {
case '.':
if (state == HANDLER) {
handler = b.toString().trim();
b.setLength(0);
state = MACRO;
} else {
b.append(source[i]);
}
break;
case '\\':
if (escape) {
b.append(source[i]);
}
escape = !escape;
break;
case '"':
case '\'':
if (!escape && (state == PARAMVALUE)) {
if (quotechar == source[i]) {
String paramValue = b.toString();
if (!setSpecialParameter(lastParamName, paramValue)) {
addGenericParameter(lastParamName, paramValue);
}
lastParamName = null;
b.setLength(0);
state = PARAMNAME;
quotechar = '\u0000';
} else if (quotechar == '\u0000') {
quotechar = source[i];
b.setLength(0);
} else {
b.append(source[i]);
}
} else {
b.append(source[i]);
}
escape = false;
break;
case ' ':
case '\t':
case '\n':
case '\r':
case '\f':
if ((state == MACRO) || ((state == HANDLER) && (b.length() > 0))) {
name = b.toString().trim();
b.setLength(0);
state = PARAMNAME;
} else if ((state == PARAMVALUE) && (quotechar == '\u0000')) {
String paramValue = b.toString();
if (!setSpecialParameter(lastParamName, paramValue)) {
addGenericParameter(lastParamName, paramValue);
}
lastParamName = null;
b.setLength(0);
state = PARAMNAME;
} else if (state == PARAMVALUE) {
b.append(source[i]);
} else {
b.setLength(0);
}
break;
case '=':
if (state == PARAMNAME) {
lastParamName = b.toString().trim();
b.setLength(0);
state = PARAMVALUE;
} else {
b.append(source[i]);
}
break;
default:
b.append(source[i]);
escape = false;
}
}
if (b.length() > 0) {
if ((lastParamName != null) && (b.length() > 0)) {
String paramValue = b.toString();
if (!setSpecialParameter(lastParamName, paramValue)) {
addGenericParameter(lastParamName, paramValue);
}
} else if (state <= MACRO) {
name = b.toString().trim();
}
}
if (handler == null) {
fullName = name;
} else {
fullName = handler + "." + name;
}
}
private boolean setSpecialParameter(String name, String value) {
if ("prefix".equals(name)) {
prefix = value;
return true;
} else if ("suffix".equals(name)) {
suffix = value;
return true;
} else if ("encoding".equals(name)) {
if ("html".equalsIgnoreCase(value)) {
encoding = ENCODE_HTML;
} else if ("xml".equalsIgnoreCase(value)) {
encoding = ENCODE_XML;
} else if ("form".equalsIgnoreCase(value)) {
encoding = ENCODE_FORM;
} else if ("url".equalsIgnoreCase(value)) {
encoding = ENCODE_URL;
} else if ("all".equalsIgnoreCase(value)) {
encoding = ENCODE_ALL;
}
return true;
} else if ("default".equals(name)) {
defaultValue = value;
return true;
}
return false;
}
private void addGenericParameter(String name, String value) {
if (parameters == null) {
parameters = new HashMap();
}
parameters.put(name, value);
}
/**
* Render the macro given a handler object
*/
public void render(RequestEvaluator reval, Object thisObject, Map paramObject,
Map handlerCache) throws RedirectException {
if ((sandbox != null) && !sandbox.contains(fullName)) {
//String h = (handler == null) ? "global" : handler;
reval.res.write("[Macro " + fullName + " not allowed in sandbox]");
return;
} else if ("response".equalsIgnoreCase(handler)) {
renderFromResponse(reval);
return;
} else if ("request".equalsIgnoreCase(handler)) {
renderFromRequest(reval);
return;
} else if ("param".equalsIgnoreCase(handler)) {
renderFromParam(reval, paramObject);
return;
} else if ("session".equalsIgnoreCase(handler)) {
renderFromSession(reval);
return;
}
try {
Object handlerObject = null;
// flag to tell whether we found our invocation target object
boolean objectFound = true;
if (handler != null) {
// try to get handler from handlerCache first
if (handlerCache != null) {
handlerObject = handlerCache.get(handler);
}
if (handlerObject == null) {
// if handler object wasn't found in cache retrieve it
if ((handlerObject == null) && (thisObject != null)) {
// not a global macro - need to find handler object
// was called with this object - check it or its parents for matching prototype
if (!handler.equals("this") &&
!handler.equals(app.getPrototypeName(thisObject))) {
// the handler object is not what we want
Object n = thisObject;
// walk down parent chain to find handler object
while (n != null) {
Prototype proto = app.getPrototype(n);
if ((proto != null) && proto.isInstanceOf(handler)) {
handlerObject = n;
break;
}
n = app.getParentElement(n);
}
} else {
// we already have the right handler object
handlerObject = thisObject;
}
}
if (handlerObject == null) {
// eiter because thisObject == null or the right object wasn't found
// in the object's parent path. Check if a matching macro handler
// is registered with the response object (res.handlers).
handlerObject = reval.res.getMacroHandlers().get(handler);
}
// the macro handler object couldn't be found
if (handlerObject == null) {
objectFound = false;
}
// else put the found handler object into the cache so we don't have to look again
else if (handlerCache != null) {
handlerCache.put(handler, handlerObject);
}
}
} else {
// this is a global macro with no handler specified
handlerObject = null;
}
if (objectFound) {
// check if a function called name_macro is defined.
// if so, the macro evaluates to the function. Otherwise,
// a property/field with the name is used, if defined.
String funcName = name + "_macro";
if (reval.scriptingEngine.hasFunction(handlerObject, funcName)) {
StringBuffer buffer = reval.res.getBuffer();
// remember length of response buffer before calling macro
int bufLength = buffer.length();
// remember length of buffer with prefix written out
int preLength = 0;
if (prefix != null) {
buffer.append(prefix);
preLength = prefix.length();
}
// System.err.println ("Getting macro from function");
// pass a clone/copy of the parameter map so if the script changes it,
Object[] arguments = new Object[1];
if (parameters == null) {
arguments[0] = new SystemMap(4);
} else {
arguments[0] = new WrappedMap(parameters, WrappedMap.COPY_ON_WRITE);
// arguments[0] = new SystemMap(parameters);
}
Object value = reval.scriptingEngine.invoke(handlerObject,
funcName, arguments,
false);
// check if macro wrote out to response buffer
if (buffer.length() == (bufLength + preLength)) {
// function didn't write out anything itself.
// erase previously written prefix
if (preLength > 0) {
buffer.setLength(bufLength);
}
// write out macro's return value
writeResponse(value, buffer, true);
} else {
if (encoding != ENCODE_NONE) {
// if an encoding is specified, re-encode the macro's output
String output = buffer.substring(bufLength + preLength);
buffer.setLength(bufLength);
writeResponse(output, buffer, false);
} else {
// no re-encoding needed, just append suffix
if (suffix != null) {
buffer.append(suffix);
}
}
writeResponse(value, buffer, false);
}
} else {
// System.err.println ("Getting macro from property");
Object value = reval.scriptingEngine.get(handlerObject, name);
writeResponse(value, reval.res.getBuffer(), true);
}
} else {
String msg = "[HopMacro unhandled: " + fullName + "]";
reval.res.write(" " + msg + " ");
app.logEvent(msg);
}
} catch (RedirectException redir) {
throw redir;
} catch (ConcurrencyException concur) {
throw concur;
} catch (TimeoutException timeout) {
throw timeout;
} catch (Exception x) {
// x.printStackTrace();
String msg = x.getMessage();
if ((msg == null) || (msg.length() < 10)) {
msg = x.toString();
}
msg = "[HopMacro error in " + fullName + ": " + msg + "]";
reval.res.write(" " + msg + " ");
app.logEvent(msg);
}
}
private void renderFromResponse(RequestEvaluator reval) {
Object value = null;
if ("message".equals(name)) {
value = reval.res.message;
} else if ("error".equals(name)) {
value = reval.res.error;
}
if (value == null) {
value = reval.res.get(name);
}
writeResponse(value, reval.res.getBuffer(), true);
}
private void renderFromRequest(RequestEvaluator reval) {
if (reval.req == null) {
return;
}
Object value = reval.req.get(name);
writeResponse(value, reval.res.getBuffer(), true);
}
private void renderFromSession(RequestEvaluator reval) {
if (reval.session == null) {
return;
}
Object value = reval.session.getCacheNode().getString(name);
writeResponse(value, reval.res.getBuffer(), true);
}
private void renderFromParam(RequestEvaluator reval, Map paramObject) {
if (paramObject == null) {
reval.res.write("[HopMacro error: Skin requires a parameter object]");
} else {
Object value = paramObject.get(name);
writeResponse(value, reval.res.getBuffer(), true);
}
}
/**
* Utility method for writing text out to the response object.
*/
void writeResponse(Object value, StringBuffer buffer, boolean useDefault) {
String text;
if (value == null) {
if (useDefault) {
text = defaultValue;
} else {
return;
}
} else {
// do not render doubles as doubles unless
// they actually have a decimal place. This is necessary because
// all numbers are handled as Double in JavaScript.
if (value instanceof Double) {
Double d = (Double) value;
if (d.longValue() == d.doubleValue()) {
text = Long.toString(d.longValue());
} else {
text = d.toString();
}
} else {
text = value.toString();
}
}
if ((text != null) && (text.length() > 0)) {
// only write prefix/suffix if value is not null, if we write the default
// value provided by the macro tag, we assume it's already complete
if (prefix != null && value != null) {
buffer.append(prefix);
}
switch (encoding) {
case ENCODE_NONE:
buffer.append(text);
break;
case ENCODE_HTML:
HtmlEncoder.encode(text, buffer);
break;
case ENCODE_XML:
HtmlEncoder.encodeXml(text, buffer);
break;
case ENCODE_FORM:
HtmlEncoder.encodeFormValue(text, buffer);
break;
case ENCODE_URL:
buffer.append(URLEncoder.encode(text));
break;
case ENCODE_ALL:
HtmlEncoder.encodeAll(text, buffer);
break;
}
if (suffix != null && value != null) {
buffer.append(suffix);
}
}
}
public String toString() {
return "[HopMacro: " + fullName + "]";
}
/**
* Return the full name of the macro in handler.name notation
*/
public String getFullName() {
return fullName;
}
}
}

View file

@ -1,163 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework.core;
import helma.util.Updatable;
import java.io.*;
import java.util.*;
/**
* This represents a File containing a Hop skin
*/
public final class SkinFile implements Updatable {
String name;
Prototype prototype;
Application app;
File file;
Skin skin;
long lastmod = 0;
/**
* Creates a new SkinFile object.
*
* @param file ...
* @param name ...
* @param proto ...
*/
public SkinFile(File file, String name, Prototype proto) {
this.prototype = proto;
this.file = file;
this.name = name;
this.app = proto.app;
skin = null;
}
/**
* Create a skinfile without a file, passing the skin body directly. This is used for
* Skins contained in zipped applications. The whole update mechanism is bypassed
* by immediately setting the skin member.
*/
public SkinFile(String body, String name, Prototype proto) {
this.prototype = proto;
this.app = proto.app;
this.name = name;
this.file = null;
skin = new Skin(body, app);
}
/**
* Create a skinfile that doesn't belong to a prototype, or at
* least it doesn't know about its prototype and isn't managed by the prototype.
*/
public SkinFile(File file, String name, Application app) {
this.app = app;
this.file = file;
this.name = name;
this.prototype = null;
skin = null;
}
/**
* Tell the type manager whether we need an update. this is the case when
* the file has been modified or deleted.
*/
public boolean needsUpdate() {
// if skin object is null we only need to call update if the file doesn't
// exist anymore, while if the skin is initialized, we'll catch both
// cases (file deleted and file changed) by just calling lastModified().
return (skin != null) ? (lastmod != file.lastModified()) : (!file.exists());
}
/**
*
*/
public void update() {
if (!file.exists()) {
// remove skin from prototype
remove();
} else {
// we only need to update if the skin has already been initialized
if (skin != null) {
read();
}
}
}
private void read() {
try {
FileReader reader = new FileReader(file);
char[] c = new char[(int) file.length()];
int length = reader.read(c);
reader.close();
skin = new Skin(c, length, app);
} catch (IOException x) {
app.logEvent("Error reading Skin " + file + ": " + x);
}
lastmod = file.lastModified();
}
/**
*
*/
public void remove() {
if (prototype != null) {
prototype.removeSkinFile(this);
}
}
/**
*
*
* @return ...
*/
public File getFile() {
return file;
}
/**
*
*
* @return ...
*/
public Skin getSkin() {
if (skin == null) {
read();
}
return skin;
}
/**
*
*
* @return ...
*/
public String getName() {
return name;
}
/**
*
*
* @return ...
*/
public String toString() {
return prototype.getName() + "/" + file.getName();
}
}

View file

@ -1,140 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework.core;
import helma.objectmodel.INode;
import java.io.*;
import java.util.*;
/**
* Manages skins for a Helma application
*/
public final class SkinManager implements FilenameFilter {
Application app;
/**
* Creates a new SkinManager object.
*
* @param app ...
*/
public SkinManager(Application app) {
this.app = app;
}
protected Skin getSkin(Prototype proto, String skinname, Object[] skinpath) {
if (proto == null) {
return null;
}
Skin skin = null;
// First check if the skin has been already used within the execution of this request
// check for skinsets set via res.skinpath property
do {
if (skinpath != null) {
for (int i = 0; i < skinpath.length; i++) {
skin = getSkinInternal(skinpath[i], proto.getName(), skinname);
if (skin != null) {
return skin;
}
}
}
// skin for this prototype wasn't found in the skinsets.
// the next step is to look if it is defined as skin file in the application directory
skin = proto.getSkin(skinname);
if (skin != null) {
return skin;
}
// still not found. See if there is a parent prototype which might define the skin.
proto = proto.getParentPrototype();
} while (proto != null);
// looked every where, nothing to be found
return null;
}
protected Skin getSkinInternal(Object skinset, String prototype, String skinname) {
if ((prototype == null) || (skinset == null)) {
return null;
}
// check if the skinset object is a HopObject (db based skin)
// or a String (file based skin)
if (skinset instanceof INode) {
INode n = ((INode) skinset).getNode(prototype);
if (n != null) {
n = n.getNode(skinname);
if (n != null) {
String skin = n.getString("skin");
if (skin != null) {
return new Skin(skin, app);
}
}
}
} else {
// Skinset is interpreted as directory name from which to
// retrieve the skin
File f = new File(skinset.toString(), prototype);
f = new File(f, skinname + ".skin");
if (f.exists() && f.canRead()) {
SkinFile sf = new SkinFile(f, skinname, app);
return sf.getSkin();
}
}
// Inheritance is taken care of in the above getSkin method.
// the sequence is prototype.skin-from-db, prototype.skin-from-file, parent.from-db, parent.from-file etc.
return null;
}
protected Map getSkinFiles(String skinDir, Prototype proto) {
File dir = new File(skinDir.toString(), proto.getName());
String[] skinNames = dir.list(this);
if ((skinNames == null) || (skinNames.length == 0)) {
return null;
}
HashMap map = new HashMap();
for (int i = 0; i < skinNames.length; i++) {
String name = skinNames[i].substring(0, skinNames[i].length() - 5);
File file = new File(dir, skinNames[i]);
map.put(name, new SkinFile(file, name, proto));
}
return map;
}
/**
* Implements java.io.FilenameFilter.accept()
*/
public boolean accept(File d, String n) {
return n.endsWith(".skin");
}
}

View file

@ -1,476 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework.core;
import helma.objectmodel.*;
import helma.objectmodel.db.DbMapping;
import helma.scripting.*;
import helma.util.*;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.*;
/**
* The type manager periodically checks the prototype definitions for its
* applications and updates the evaluators if anything has changed.
*/
public final class TypeManager {
final static String[] standardTypes = { "user", "global", "root", "hopobject" };
final static String templateExtension = ".hsp";
final static String scriptExtension = ".js";
final static String actionExtension = ".hac";
final static String skinExtension = ".skin";
Application app;
File appDir;
HashMap prototypes; // map of prototypes
HashMap zipfiles; // map of zipped script files
HashSet jarfiles; // set of Java archives
long lastCheck = 0;
long appDirMod = 0;
// a checksum that changes whenever something in the application files changes.
long checksum;
// the hopobject prototype
Prototype hopobjectProto;
// the global prototype
Prototype globalProto;
// app specific class loader, includes jar files in the app directory
AppClassLoader loader;
/**
* Creates a new TypeManager object.
*
* @param app ...
*
* @throws MalformedURLException ...
* @throws RuntimeException ...
*/
public TypeManager(Application app) throws MalformedURLException {
this.app = app;
appDir = app.appDir;
// make sure the directories for the standard prototypes exist, and lament otherwise
if (appDir.list().length == 0) {
for (int i = 0; i < standardTypes.length; i++) {
File f = new File(appDir, standardTypes[i]);
if (!f.exists() && !f.mkdir()) {
app.logEvent("Warning: directory " + f.getAbsolutePath() +
" could not be created.");
} else if (!f.isDirectory()) {
app.logEvent("Warning: " + f.getAbsolutePath() +
" is not a directory.");
}
}
}
prototypes = new HashMap();
zipfiles = new HashMap();
jarfiles = new HashSet();
URL helmajar = TypeManager.class.getResource("/");
if (helmajar == null) {
// Helma classes are in jar file, get helma.jar URL
URL[] urls = ((URLClassLoader) TypeManager.class.getClassLoader()).getURLs();
for (int i = 0; i < urls.length; i++) {
String url = urls[i].toString().toLowerCase();
if (url.endsWith("helma.jar")) {
helmajar = urls[i];
break;
}
}
}
if (helmajar == null) {
throw new RuntimeException("helma.jar not found in embedding classpath");
}
loader = new AppClassLoader(app.getName(), new URL[] { helmajar });
}
/**
* Run through application's prototype directories and create prototypes, but don't
* compile or evaluate any scripts.
*/
public void createPrototypes() {
// create standard prototypes.
createPrototype("root");
createPrototype("user");
// get references to hopobject and global protos,
// since we need it regularly when setting parent prototypes.
hopobjectProto = createPrototype("hopobject");
globalProto = createPrototype("global");
// loop through directories and create prototypes
checkFiles();
}
/**
* Run through application's prototype directories and check if anything has been updated.
* If so, update prototypes and scripts.
*/
public synchronized void checkPrototypes() {
if ((System.currentTimeMillis() - lastCheck) < 1000L) {
return;
}
try {
checkFiles();
} catch (Exception ignore) {
}
lastCheck = System.currentTimeMillis();
}
/**
* Run through application's prototype directories and check if
* there are any prototypes to be created.
*/
public void checkFiles() {
// check if any files have been created/removed since last time we
// checked...
if (appDir.lastModified() > appDirMod) {
appDirMod = appDir.lastModified();
String[] list = appDir.list();
if (list == null) {
throw new RuntimeException("Can't read app directory " + appDir +
" - check permissions");
}
for (int i = 0; i < list.length; i++) {
if (list[i].endsWith(".zip")) {
ZippedAppFile zipped = (ZippedAppFile) zipfiles.get(list[i]);
if (zipped == null) {
File f = new File(appDir, list[i]);
if (!f.isDirectory() && f.exists()) {
zipped = new ZippedAppFile(f, app);
zipfiles.put(list[i], zipped);
}
}
continue;
}
if (list[i].endsWith(".jar")) {
if (!jarfiles.contains(list[i])) {
jarfiles.add(list[i]);
File f = new File(appDir, list[i]);
try {
loader.addURL(new URL("file:" + f.getAbsolutePath()));
} catch (MalformedURLException ignore) {
}
}
continue;
}
if (list[i].indexOf('.') > -1) {
continue;
}
Prototype proto = getPrototype(list[i]);
// if prototype doesn't exist, create it
if ((proto == null) && isValidTypeName(list[i])) {
File f = new File(appDir, list[i]);
if (f.isDirectory()) {
// create new prototype
createPrototype(list[i], f);
}
}
}
}
// calculate this app's checksum by adding all checksums from all prototypes
long newChecksum = 0;
// loop through zip files to check for updates
for (Iterator it = zipfiles.values().iterator(); it.hasNext();) {
ZippedAppFile zipped = (ZippedAppFile) it.next();
if (zipped.needsUpdate()) {
zipped.update();
}
newChecksum += zipped.lastmod;
}
// loop through prototypes and check if type.properties needs updates
// it's important that we do this _after_ potentially new prototypes
// have been created in the previous loop.
for (Iterator i = prototypes.values().iterator(); i.hasNext();) {
Prototype proto = (Prototype) i.next();
// calculate this app's type checksum
newChecksum += proto.getChecksum();
// update prototype's type mapping
DbMapping dbmap = proto.getDbMapping();
if ((dbmap != null) && dbmap.needsUpdate()) {
dbmap.update();
// this is now done in dbmap.update()!!!
/*if ((proto != hopobjectProto) && (proto != globalProto)) {
// set parent prototype, in case it has changed.
String parentName = dbmap.getExtends();
if (parentName != null) {
proto.setParentPrototype(getPrototype(parentName));
} else if (!app.isJavaPrototype(proto.getName())) {
proto.setParentPrototype(hopobjectProto);
}
} */
}
}
checksum = newChecksum;
}
protected void removeZipFile(String zipname) {
zipfiles.remove(zipname);
for (Iterator i = prototypes.values().iterator(); i.hasNext();) {
Prototype proto = (Prototype) i.next();
// update prototype's type mapping
DbMapping dbmap = proto.getDbMapping();
SystemProperties props = dbmap.getProperties();
props.removeProps(zipname);
}
}
private boolean isValidTypeName(String str) {
if (str == null) {
return false;
}
char[] c = str.toCharArray();
for (int i = 0; i < c.length; i++)
if (!Character.isJavaIdentifierPart(c[i])) {
return false;
}
return true;
}
/**
* Return a checksum over all files in all prototypes in this application.
* The checksum can be used to find out quickly if any file has changed.
*/
public long getChecksum() {
return checksum;
}
/**
* Get a prototype defined for this application
*/
public Prototype getPrototype(String typename) {
return (Prototype) prototypes.get(typename);
}
/**
* Get a prototype, creating it if it doesn't already exist. Note
* that it doesn't create a DbMapping - this is left to the
* caller (e.g. ZippedAppFile).
*/
public Prototype createPrototype(String typename) {
return createPrototype(typename, new File(appDir, typename));
}
/**
* Create a prototype from a directory containing scripts and other stuff
*/
public Prototype createPrototype(String typename, File dir) {
Prototype proto = new Prototype(typename, dir, app);
// Create and register type properties file
File propfile = new File(dir, "type.properties");
SystemProperties props = new SystemProperties(propfile.getAbsolutePath());
DbMapping dbmap = new DbMapping(app, typename, props);
// we don't need to put the DbMapping into proto.updatables, because
// dbmappings are checked separately in checkFiles for each request
// proto.updatables.put ("type.properties", dbmap);
proto.setDbMapping(dbmap);
// put the prototype into our map
prototypes.put(typename, proto);
return proto;
}
/**
* Update a prototype to the files in the prototype directory.
*/
public void updatePrototype(String name) {
// System.err.println ("UPDATE PROTO: "+app.getName()+"/"+name);
Prototype proto = getPrototype(name);
updatePrototype(proto);
}
/**
* Update a prototype to the files in the prototype directory.
*/
public void updatePrototype(Prototype proto) {
if ((proto == null) || proto.isUpToDate()) {
return;
}
synchronized (proto) {
// check again because another thread may have checked the
// prototype while we were waiting for access to the synchronized section
/* if (System.currentTimeMillis() - proto.getLastCheck() < 1000)
return; */
File dir = proto.getDirectory();
HashSet updateSet = null;
HashSet createSet = null;
// our plan is to do as little as possible, so first check if
// anything the prototype knows about has changed on disk
for (Iterator i = proto.updatables.values().iterator(); i.hasNext();) {
Updatable upd = (Updatable) i.next();
if (upd.needsUpdate()) {
if (updateSet == null) {
updateSet = new HashSet();
}
updateSet.add(upd);
}
}
// next we check if files have been created or removed since last update
// if (proto.getLastCheck() < dir.lastModified ()) {
File[] list = proto.getFiles();
for (int i = 0; i < list.length; i++) {
String fn = list[i].getName();
// ignore files starting with ".".
if (fn.startsWith(".")) {
continue;
}
if (!proto.updatables.containsKey(fn)) {
if (fn.endsWith(templateExtension) || fn.endsWith(scriptExtension) ||
fn.endsWith(actionExtension) || fn.endsWith(skinExtension) ||
"type.properties".equalsIgnoreCase(fn)) {
if (createSet == null) {
createSet = new HashSet();
}
createSet.add(list[i]);
}
}
}
// }
// if nothing needs to be updated, mark prototype as checked and return
if ((updateSet == null) && (createSet == null)) {
proto.markChecked();
return;
}
// first go through new files and create new items
if (createSet != null) {
Object[] newFiles = createSet.toArray();
for (int i = 0; i < newFiles.length; i++) {
File file = (File) newFiles[i];
String filename = file.getName();
int dot = filename.lastIndexOf(".");
String tmpname = filename.substring(0, dot);
if (filename.endsWith(templateExtension)) {
try {
Template t = new Template(file, tmpname, proto);
proto.addTemplate(t);
} catch (Throwable x) {
app.logEvent("Error updating prototype: " + x);
}
} else if (filename.endsWith(scriptExtension)) {
try {
FunctionFile ff = new FunctionFile(file, proto);
proto.addFunctionFile(ff);
} catch (Throwable x) {
app.logEvent("Error updating prototype: " + x);
}
} else if (filename.endsWith(actionExtension)) {
try {
ActionFile af = new ActionFile(file, tmpname, proto);
proto.addActionFile(af);
} catch (Throwable x) {
app.logEvent("Error updating prototype: " + x);
}
} else if (filename.endsWith(skinExtension)) {
SkinFile sf = new SkinFile(file, tmpname, proto);
proto.addSkinFile(sf);
}
}
}
// next go through existing updatables
if (updateSet != null) {
for (Iterator i = updateSet.iterator(); i.hasNext();) {
Updatable upd = (Updatable) i.next();
try {
upd.update();
} catch (Exception x) {
if (upd instanceof DbMapping) {
app.logEvent("Error updating db mapping for type " +
proto.getName() + ": " + x);
} else {
app.logEvent("Error updating " + upd + " of prototye type " +
proto.getName() + ": " + x);
}
}
}
}
// mark prototype as checked and updated.
proto.markChecked();
proto.markUpdated();
}
// end of synchronized (proto)
}
}

View file

@ -1,218 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework.core;
import helma.framework.*;
import helma.objectmodel.db.DbMapping;
import helma.scripting.*;
import helma.util.SystemProperties;
import helma.util.Updatable;
import java.io.*;
import java.util.*;
import java.util.zip.*;
/**
* This represents a Zip-File which may contain other Updatables for one or more prototypes.
*/
public class ZippedAppFile implements Updatable {
Application app;
File file;
long lastmod;
Set updatables;
/**
* Creates a new ZippedAppFile object.
*
* @param file ...
* @param app ...
*/
public ZippedAppFile(File file, Application app) {
this.app = app;
this.file = file;
// System.err.println ("CREATING ZIP FILE "+this);
}
/**
* Tell the type manager whether we need an update. this is the case when
* the file has been modified or deleted.
*/
public boolean needsUpdate() {
return !file.exists() || (lastmod != file.lastModified());
}
/**
*
*/
public void update() {
if (!file.exists()) {
remove();
} else {
ZipFile zip = null;
// collect created protos - we need this to check DbMappings for each created
// prototype afterwards
HashSet newPrototypes = new HashSet();
try {
lastmod = file.lastModified();
// System.err.println ("UPDATING ZIP FILE "+this);
zip = new ZipFile(file);
updatables = new HashSet();
for (Enumeration en = zip.entries(); en.hasMoreElements();) {
ZipEntry entry = (ZipEntry) en.nextElement();
String ename = entry.getName();
StringTokenizer st = new StringTokenizer(ename, "/");
int tokens = st.countTokens();
if (tokens == 1) {
String fname = st.nextToken();
if ("app.properties".equalsIgnoreCase(fname)) {
app.props.addProps(file.getName(), zip.getInputStream(entry));
} else if ("db.properties".equalsIgnoreCase(fname)) {
app.dbProps.addProps(file.getName(), zip.getInputStream(entry));
}
} else if (tokens == 2) {
String dir = st.nextToken();
String fname = st.nextToken();
// System.err.println ("ZIPENTRY: "+ dir +" ~ "+fname);
Prototype proto = app.typemgr.getPrototype(dir);
if (proto == null) {
proto = app.typemgr.createPrototype(dir);
newPrototypes.add(proto);
}
if (fname.endsWith(".hac")) {
String name = fname.substring(0, fname.lastIndexOf("."));
String sourceName = file.getName() + "/" + ename;
String content = getZipEntryContent(zip, entry);
// System.err.println ("["+content+"]");
ActionFile act = new ActionFile(content, name, sourceName,
proto);
proto.addActionFile(act);
updatables.add(act);
// mark prototype as updated
proto.markUpdated();
} else if (fname.endsWith(".hsp")) {
String name = fname.substring(0, fname.lastIndexOf("."));
String sourceName = file.getName() + "/" + ename;
String content = getZipEntryContent(zip, entry);
// System.err.println ("["+content+"]");
Template tmp = new Template(content, name, sourceName, proto);
proto.addTemplate(tmp);
updatables.add(tmp);
// mark prototype as updated
proto.markUpdated();
} else if (fname.endsWith(".skin")) {
String name = fname.substring(0, fname.lastIndexOf("."));
String content = getZipEntryContent(zip, entry);
// System.err.println ("["+content+"]");
SkinFile skin = new SkinFile(content, name, proto);
proto.addSkinFile(skin);
updatables.add(skin);
} else if (fname.endsWith(".js")) {
String sourceName = file.getName() + "/" + ename;
String content = getZipEntryContent(zip, entry);
// System.err.println ("["+content+"]");
FunctionFile ff = new FunctionFile(content, sourceName, proto);
proto.addFunctionFile(ff);
updatables.add(ff);
// mark prototype as updated
proto.markUpdated();
} else if ("type.properties".equalsIgnoreCase(fname)) {
DbMapping dbmap = proto.getDbMapping();
SystemProperties props = dbmap.getProperties();
props.addProps(file.getName(), zip.getInputStream(entry));
// mark prototype as updated
proto.markUpdated();
}
}
}
} catch (Throwable x) {
System.err.println("Error updating ZipFile: " + x);
} finally {
try {
zip.close();
} catch (Exception ignore) {
}
}
}
}
/**
*
*/
public void remove() {
if (updatables != null) {
for (Iterator it = updatables.iterator(); it.hasNext();)
((Updatable) it.next()).remove();
}
app.typemgr.removeZipFile(file.getName());
// System.err.println ("REMOVING ZIP FILE "+this);
}
/**
*
*
* @param zip ...
* @param entry ...
*
* @return ...
*
* @throws IOException ...
*/
public String getZipEntryContent(ZipFile zip, ZipEntry entry)
throws IOException {
int size = (int) entry.getSize();
char[] c = new char[size];
InputStreamReader reader = new InputStreamReader(zip.getInputStream(entry));
reader.read(c);
return new String(c);
}
/**
*
*
* @return ...
*/
public String toString() {
return file.getName();
}
}

View file

@ -1,83 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.framework.demo;
import helma.framework.IPathElement;
/**
* This is an example implementation for the helma.framework.IPathElement interface.
* It creates any child element which is requested on the fly without ever asking.
*/
public class SimplePathElement implements IPathElement {
String name;
String prototype;
IPathElement parent;
/**
* Constructor for the root element.
*/
public SimplePathElement() {
name = "root";
prototype = "root";
parent = null;
}
/**
* Constructor for non-root elements.
*/
public SimplePathElement(String n, IPathElement p) {
name = n;
prototype = "hopobject";
parent = p;
}
/**
* Returns a child element for this object, creating it on the fly.
*/
public IPathElement getChildElement(String n) {
return new SimplePathElement(n, this);
}
/**
* Returns this object's parent element
*/
public IPathElement getParentElement() {
return parent;
}
/**
* Returns the element name to be used for this object.
*/
public String getElementName() {
return name;
}
/**
* Returns the name of the scripting prototype to be used for this object.
* This will be "root" for the root element and "hopobject for everything else.
*/
public String getPrototype() {
return prototype;
}
/**
* Returns a string representation of this element.
*/
public String toString() {
return "SimplePathElement " + name;
}
}

View file

@ -1,295 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.image;
import java.awt.*;
import java.awt.image.*;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Factory class for generating Image objects from various sources.
*
*/
public class ImageGenerator {
/**
* Creates a new ImageGenerator object.
*/
public ImageGenerator() {
// nothing to do
}
/**
*
*
* @param w ...
* @param h ...
*
* @return ...
*/
public ImageWrapper createPaintableImage(int w, int h) {
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics g = img.getGraphics();
ImageWrapper rimg = new SunImageWrapper(img, g, w, h, this);
return rimg;
}
/**
*
*
* @param src ...
*
* @return ...
*/
public ImageWrapper createPaintableImage(byte[] src) {
ImageWrapper rimg = null;
Image img1 = Toolkit.getDefaultToolkit().createImage(src);
ImageLoader loader = new ImageLoader(img1);
try {
loader.getDimensions();
int w = loader.getWidth();
int h = loader.getHeight();
Image img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics g = img.getGraphics();
g.drawImage(img1, 0, 0, null);
rimg = new SunImageWrapper(img, g, w, h, this);
} finally {
loader.done();
}
return rimg;
}
/**
*
*
* @param src ...
*
* @return ...
*/
public ImageWrapper createImage(byte[] src) {
ImageWrapper rimg = null;
Image img = Toolkit.getDefaultToolkit().createImage(src);
ImageLoader loader = new ImageLoader(img);
try {
loader.getDimensions();
int w = loader.getWidth();
int h = loader.getHeight();
rimg = new SunImageWrapper(img, null, w, h, this);
} finally {
loader.done();
}
return rimg;
}
/**
*
*
* @param urlstring ...
*
* @return ...
*
* @throws MalformedURLException ...
*/
public ImageWrapper createPaintableImage(String urlstring)
throws MalformedURLException {
ImageWrapper rimg = null;
URL url = new URL(urlstring);
Image img1 = Toolkit.getDefaultToolkit().createImage(url);
ImageLoader loader = new ImageLoader(img1);
try {
loader.getDimensions();
int w = loader.getWidth();
int h = loader.getHeight();
Image img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics g = img.getGraphics();
g.drawImage(img1, 0, 0, null);
rimg = new SunImageWrapper(img, g, w, h, this);
} finally {
loader.done();
}
return rimg;
}
/**
*
*
* @param iw ...
* @param filter ...
*
* @return ...
*/
public ImageWrapper createPaintableImage(ImageWrapper iw, ImageFilter filter) {
ImageWrapper rimg = null;
FilteredImageSource fis = new FilteredImageSource(iw.getSource(), filter);
Image img1 = Toolkit.getDefaultToolkit().createImage(fis);
ImageLoader loader = new ImageLoader(img1);
try {
loader.getDimensions();
int w = loader.getWidth();
int h = loader.getHeight();
Image img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics g = img.getGraphics();
g.drawImage(img1, 0, 0, null);
rimg = new SunImageWrapper(img, g, w, h, this);
} finally {
loader.done();
}
return rimg;
}
/**
*
*
* @param filename ...
*
* @return ...
*/
public Image createImage(String filename) {
Image img = null;
img = Toolkit.getDefaultToolkit().createImage(filename);
ImageLoader loader = new ImageLoader(img);
loader.getDimensions();
loader.done();
return img;
}
/**
*
*
* @param producer ...
*
* @return ...
*/
public Image createImage(ImageProducer producer) {
Image img = null;
img = Toolkit.getDefaultToolkit().createImage(producer);
ImageLoader loader = new ImageLoader(img);
loader.getDimensions();
loader.done();
return img;
}
class ImageLoader implements ImageObserver {
Image img;
int w;
int h;
boolean waiting;
boolean firstFrameLoaded;
ImageLoader(Image img) {
this.img = img;
waiting = true;
firstFrameLoaded = false;
}
synchronized void getDimensions() {
w = img.getWidth(this);
h = img.getHeight(this);
if ((w == -1) || (h == -1)) {
try {
wait(45000);
} catch (InterruptedException x) {
waiting = false;
return;
} finally {
waiting = false;
}
}
// if width and height haven't been set, throw tantrum
if ((w == -1) || (h == -1)) {
throw new RuntimeException("Error loading image");
}
}
synchronized void done() {
waiting = false;
notifyAll();
}
int getWidth() {
return w;
}
int getHeight() {
return h;
}
public synchronized boolean imageUpdate(Image img, int infoflags, int x, int y,
int width, int height) {
// check if there was an error
if (!waiting || ((infoflags & ERROR) > 0) || ((infoflags & ABORT) > 0)) {
// we either timed out or there was an error.
notifyAll();
return false;
}
if (((infoflags & WIDTH) > 0) || ((infoflags & HEIGHT) > 0)) {
if ((infoflags & WIDTH) > 0) {
w = width;
}
if ((infoflags & HEIGHT) > 0) {
h = height;
}
if ((w > -1) && (h > -1) && firstFrameLoaded) {
notifyAll();
return false;
}
}
if (((infoflags & ALLBITS) > 0) || ((infoflags & FRAMEBITS) > 0)) {
firstFrameLoaded = true;
notifyAll();
return false;
}
return true;
}
}
}

View file

@ -1,414 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.image;
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
/**
* Abstract base class for Image Wrappers.
*/
public abstract class ImageWrapper {
Image img;
Graphics g;
int width;
int height;
int fontstyle;
int fontsize;
String fontname;
ImageGenerator imggen;
/**
* Creates a new ImageWrapper object.
*
* @param img ...
* @param g ...
* @param width ...
* @param height ...
* @param imggen ...
*/
public ImageWrapper(Image img, Graphics g, int width, int height,
ImageGenerator imggen) {
this.img = img;
this.g = g;
this.width = width;
this.height = height;
this.imggen = imggen;
if (g != null) {
Font f = g.getFont();
fontname = f.getName();
fontstyle = f.getStyle();
fontsize = f.getSize();
}
}
/**
* Return the Graphics object to directly paint to this Image.
*
* @return the Graphics object used by this image
*/
public Graphics getGraphics() {
return g;
}
/**
* Returns the Image object represented by this ImageWrapper.
*
* @return the image object
*/
public Image getImage() {
return img;
}
/**
* Set the font used to write on this image.
*/
public void setFont(String name, int style, int size) {
this.fontname = name;
this.fontstyle = style;
this.fontsize = size;
g.setFont(new Font(name, style, size));
}
/**
* Set the color used to write/paint to this image.
*
* @param red ...
* @param green ...
* @param blue ...
*/
public void setColor(int red, int green, int blue) {
g.setColor(new Color(red, green, blue));
}
/**
* Set the color used to write/paint to this image.
*
* @param color ...
*/
public void setColor(int color) {
g.setColor(new Color(color));
}
/**
* Draw a string to this image at the given coordinates.
*
* @param str ...
* @param x ...
* @param y ...
*/
public void drawString(String str, int x, int y) {
g.drawString(str, x, y);
}
/**
* Draw a line to this image from x1/y1 to x2/y2.
*
* @param x1 ...
* @param y1 ...
* @param x2 ...
* @param y2 ...
*/
public void drawLine(int x1, int y1, int x2, int y2) {
g.drawLine(x1, y1, x2, y2);
}
/**
* Draw a rectangle to this image.
*
* @param x ...
* @param y ...
* @param w ...
* @param h ...
*/
public void drawRect(int x, int y, int w, int h) {
g.drawRect(x, y, w, h);
}
/**
* Draw another image to this image.
*
* @param filename ...
* @param x ...
* @param y ...
*/
public void drawImage(String filename, int x, int y) {
try {
Image i = imggen.createImage(filename);
g.drawImage(i, x, y, null);
} catch (Exception ignore) {
}
}
/**
* Draw a filled rectangle to this image.
*
* @param x ...
* @param y ...
* @param w ...
* @param h ...
*/
public void fillRect(int x, int y, int w, int h) {
g.fillRect(x, y, w, h);
}
/**
* get the width of this image.
*
* @return ...
*/
public int getWidth() {
return width;
}
/**
* get the height of this image.
*
* @return ...
*/
public int getHeight() {
return height;
}
/**
* crop this image.
*
* @param x ...
* @param y ...
* @param w ...
* @param h ...
*/
public void crop(int x, int y, int w, int h) {
ImageFilter filter = new CropImageFilter(x, y, w, h);
img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(img.getSource(),
filter));
}
/**
* resize this image
*
* @param w ...
* @param h ...
*/
public void resize(int w, int h) {
img = img.getScaledInstance(w, h, Image.SCALE_SMOOTH);
width = w;
height = h;
}
/**
* resize this image, using a fast and cheap algorithm
*
* @param w ...
* @param h ...
*/
public void resizeFast(int w, int h) {
img = img.getScaledInstance(w, h, Image.SCALE_FAST);
width = w;
height = h;
}
/**
* reduce the colors used in this image. Necessary before saving as GIF.
*
* @param colors ...
*/
public abstract void reduceColors(int colors);
/**
* Save this image. Image format is deduced from filename.
*
* @param filename ...
*/
public abstract void saveAs(String filename);
/**
* Get ImageProducer of the wrapped image
*/
public ImageProducer getSource() {
return img.getSource();
}
/**
* Draw a string to this image, breaking lines when necessary.
*
* @param str ...
*/
public void fillString(String str) {
Filler filler = new Filler(0, 0, width, height);
filler.layout(str);
}
/**
* Draw a line to a rectangular section of this image, breaking lines when necessary.
*
* @param str ...
* @param x ...
* @param y ...
* @param w ...
* @param h ...
*/
public void fillString(String str, int x, int y, int w, int h) {
Filler filler = new Filler(x, y, w, h);
filler.layout(str);
}
class Filler {
int x;
int y;
int w;
int h;
int addedSpace = 0;
int xLeft;
int yLeft;
int realHeight;
transient Vector lines;
public Filler(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
public void layout(String str) {
int size = fontsize;
lines = new Vector();
while (!splitMessage(str, size) && (size > 10)) {
lines.setSize(0);
size = Math.max(2, size - 1);
}
Font oldfont = g.getFont();
g.setFont(new Font(fontname, fontstyle, size));
int l = lines.size();
for (int i = 0; i < l; i++) {
((Line) lines.elementAt(i)).paint(g, xLeft / 2, (yLeft / 2) + y);
}
g.setFont(oldfont);
}
private boolean splitMessage(String string, int size) {
Font font = new Font(fontname, fontstyle, size);
FontMetrics metrics = Toolkit.getDefaultToolkit().getFontMetrics(font);
int longestLine = 0;
int heightSoFar = 0;
int heightIncrement = (int) (0.84f * metrics.getHeight());
StringTokenizer tk = new StringTokenizer(string);
StringBuffer buffer = new StringBuffer();
int spaceWidth = metrics.stringWidth(" ");
int currentWidth = 0;
int maxWidth = w - 2;
int maxHeight = (h + addedSpace) - 2;
while (tk.hasMoreTokens()) {
String nextToken = tk.nextToken();
int nextWidth = metrics.stringWidth(nextToken);
if ((((currentWidth + nextWidth) >= maxWidth) && (currentWidth != 0))) {
Line line = new Line(buffer.toString(), x, heightSoFar, metrics);
lines.addElement(line);
if (line.textwidth > longestLine) {
longestLine = line.textwidth;
}
buffer = new StringBuffer();
currentWidth = 0;
heightSoFar += heightIncrement;
}
buffer.append(nextToken);
buffer.append(" ");
currentWidth += (nextWidth + spaceWidth);
if (((1.18 * heightSoFar) > maxHeight) && (fontsize > 10)) {
return false;
}
}
if (!"".equals(buffer.toString().trim())) {
Line line = new Line(buffer.toString(), x, heightSoFar, metrics);
lines.addElement(line);
if (line.textwidth > longestLine) {
longestLine = line.textwidth;
}
if ((longestLine > maxWidth) && (fontsize > 10)) {
return false;
}
heightSoFar += heightIncrement;
}
xLeft = w - longestLine;
yLeft = (addedSpace + h) - heightSoFar;
realHeight = heightSoFar;
return ((1.18 * heightSoFar) <= maxHeight);
}
}
class Line implements Serializable {
String text;
int xoff;
int yoff;
FontMetrics fm;
public int textwidth;
public int len;
int ascent;
public Line(String text, int xoff, int yoff, FontMetrics fm) {
this.text = text.trim();
len = text.length();
this.xoff = xoff;
this.yoff = yoff;
this.fm = fm;
textwidth = (len == 0) ? 0 : fm.stringWidth(this.text);
ascent = (int) (0.9f * fm.getAscent());
}
public void paint(Graphics g, int xadd, int yadd) {
g.drawString(text, xoff + xadd, yoff + ascent + yadd);
}
public boolean contains(int y) {
return (y < (yoff + fm.getHeight())) ? true : false;
}
}
}

View file

@ -1,701 +0,0 @@
/*
* @(#)Quantize.java 0.90 9/19/00 Adam Doppelt
*/
package helma.image;
/**
* An efficient color quantization algorithm, adapted from the C++
* implementation quantize.c in <a
* href="http://www.imagemagick.org/">ImageMagick</a>. The pixels for
* an image are placed into an oct tree. The oct tree is reduced in
* size, and the pixels from the original image are reassigned to the
* nodes in the reduced tree.<p>
*
* Here is the copyright notice from ImageMagick:
*
* <pre>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Permission is hereby granted, free of charge, to any person obtaining a %
% copy of this software and associated documentation files ("ImageMagick"), %
% to deal in ImageMagick without restriction, including without limitation %
% the rights to use, copy, modify, merge, publish, distribute, sublicense, %
% and/or sell copies of ImageMagick, and to permit persons to whom the %
% ImageMagick is furnished to do so, subject to the following conditions: %
% %
% The above copyright notice and this permission notice shall be included in %
% all copies or substantial portions of ImageMagick. %
% %
% The software is provided "as is", without warranty of any kind, express or %
% implied, including but not limited to the warranties of merchantability, %
% fitness for a particular purpose and noninfringement. In no event shall %
% E. I. du Pont de Nemours and Company be liable for any claim, damages or %
% other liability, whether in an action of contract, tort or otherwise, %
% arising from, out of or in connection with ImageMagick or the use or other %
% dealings in ImageMagick. %
% %
% Except as contained in this notice, the name of the E. I. du Pont de %
% Nemours and Company shall not be used in advertising or otherwise to %
% promote the sale, use or other dealings in ImageMagick without prior %
% written authorization from the E. I. du Pont de Nemours and Company. %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
</pre>
*
*
* @version 0.90 19 Sep 2000
* @author <a href="http://www.gurge.com/amd/">Adam Doppelt</a>
*/
public class Quantize {
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% QQQ U U AAA N N TTTTT IIIII ZZZZZ EEEEE %
% Q Q U U A A NN N T I ZZ E %
% Q Q U U AAAAA N N N T I ZZZ EEEEE %
% Q QQ U U A A N NN T I ZZ E %
% QQQQ UUU A A N N T IIIII ZZZZZ EEEEE %
% %
% %
% Reduce the Number of Unique Colors in an Image %
% %
% %
% Software Design %
% John Cristy %
% July 1992 %
% %
% %
% Copyright 1998 E. I. du Pont de Nemours and Company %
% %
% Permission is hereby granted, free of charge, to any person obtaining a %
% copy of this software and associated documentation files ("ImageMagick"), %
% to deal in ImageMagick without restriction, including without limitation %
% the rights to use, copy, modify, merge, publish, distribute, sublicense, %
% and/or sell copies of ImageMagick, and to permit persons to whom the %
% ImageMagick is furnished to do so, subject to the following conditions: %
% %
% The above copyright notice and this permission notice shall be included in %
% all copies or substantial portions of ImageMagick. %
% %
% The software is provided "as is", without warranty of any kind, express or %
% implied, including but not limited to the warranties of merchantability, %
% fitness for a particular purpose and noninfringement. In no event shall %
% E. I. du Pont de Nemours and Company be liable for any claim, damages or %
% other liability, whether in an action of contract, tort or otherwise, %
% arising from, out of or in connection with ImageMagick or the use or other %
% dealings in ImageMagick. %
% %
% Except as contained in this notice, the name of the E. I. du Pont de %
% Nemours and Company shall not be used in advertising or otherwise to %
% promote the sale, use or other dealings in ImageMagick without prior %
% written authorization from the E. I. du Pont de Nemours and Company. %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Realism in computer graphics typically requires using 24 bits/pixel to
% generate an image. Yet many graphic display devices do not contain
% the amount of memory necessary to match the spatial and color
% resolution of the human eye. The QUANTIZE program takes a 24 bit
% image and reduces the number of colors so it can be displayed on
% raster device with less bits per pixel. In most instances, the
% quantized image closely resembles the original reference image.
%
% A reduction of colors in an image is also desirable for image
% transmission and real-time animation.
%
% Function Quantize takes a standard RGB or monochrome images and quantizes
% them down to some fixed number of colors.
%
% For purposes of color allocation, an image is a set of n pixels, where
% each pixel is a point in RGB space. RGB space is a 3-dimensional
% vector space, and each pixel, pi, is defined by an ordered triple of
% red, green, and blue coordinates, (ri, gi, bi).
%
% Each primary color component (red, green, or blue) represents an
% intensity which varies linearly from 0 to a maximum value, cmax, which
% corresponds to full saturation of that color. Color allocation is
% defined over a domain consisting of the cube in RGB space with
% opposite vertices at (0,0,0) and (cmax,cmax,cmax). QUANTIZE requires
% cmax = 255.
%
% The algorithm maps this domain onto a tree in which each node
% represents a cube within that domain. In the following discussion
% these cubes are defined by the coordinate of two opposite vertices:
% The vertex nearest the origin in RGB space and the vertex farthest
% from the origin.
%
% The tree's root node represents the the entire domain, (0,0,0) through
% (cmax,cmax,cmax). Each lower level in the tree is generated by
% subdividing one node's cube into eight smaller cubes of equal size.
% This corresponds to bisecting the parent cube with planes passing
% through the midpoints of each edge.
%
% The basic algorithm operates in three phases: Classification,
% Reduction, and Assignment. Classification builds a color
% description tree for the image. Reduction collapses the tree until
% the number it represents, at most, the number of colors desired in the
% output image. Assignment defines the output image's color map and
% sets each pixel's color by reclassification in the reduced tree.
% Our goal is to minimize the numerical discrepancies between the original
% colors and quantized colors (quantization error).
%
% Classification begins by initializing a color description tree of
% sufficient depth to represent each possible input color in a leaf.
% However, it is impractical to generate a fully-formed color
% description tree in the classification phase for realistic values of
% cmax. If colors components in the input image are quantized to k-bit
% precision, so that cmax= 2k-1, the tree would need k levels below the
% root node to allow representing each possible input color in a leaf.
% This becomes prohibitive because the tree's total number of nodes is
% 1 + sum(i=1,k,8k).
%
% A complete tree would require 19,173,961 nodes for k = 8, cmax = 255.
% Therefore, to avoid building a fully populated tree, QUANTIZE: (1)
% Initializes data structures for nodes only as they are needed; (2)
% Chooses a maximum depth for the tree as a function of the desired
% number of colors in the output image (currently log2(colormap size)).
%
% For each pixel in the input image, classification scans downward from
% the root of the color description tree. At each level of the tree it
% identifies the single node which represents a cube in RGB space
% containing the pixel's color. It updates the following data for each
% such node:
%
% n1: Number of pixels whose color is contained in the RGB cube
% which this node represents;
%
% n2: Number of pixels whose color is not represented in a node at
% lower depth in the tree; initially, n2 = 0 for all nodes except
% leaves of the tree.
%
% Sr, Sg, Sb: Sums of the red, green, and blue component values for
% all pixels not classified at a lower depth. The combination of
% these sums and n2 will ultimately characterize the mean color of a
% set of pixels represented by this node.
%
% E: The distance squared in RGB space between each pixel contained
% within a node and the nodes' center. This represents the quantization
% error for a node.
%
% Reduction repeatedly prunes the tree until the number of nodes with
% n2 > 0 is less than or equal to the maximum number of colors allowed
% in the output image. On any given iteration over the tree, it selects
% those nodes whose E count is minimal for pruning and merges their
% color statistics upward. It uses a pruning threshold, Ep, to govern
% node selection as follows:
%
% Ep = 0
% while number of nodes with (n2 > 0) > required maximum number of colors
% prune all nodes such that E <= Ep
% Set Ep to minimum E in remaining nodes
%
% This has the effect of minimizing any quantization error when merging
% two nodes together.
%
% When a node to be pruned has offspring, the pruning procedure invokes
% itself recursively in order to prune the tree from the leaves upward.
% n2, Sr, Sg, and Sb in a node being pruned are always added to the
% corresponding data in that node's parent. This retains the pruned
% node's color characteristics for later averaging.
%
% For each node, n2 pixels exist for which that node represents the
% smallest volume in RGB space containing those pixel's colors. When n2
% > 0 the node will uniquely define a color in the output image. At the
% beginning of reduction, n2 = 0 for all nodes except a the leaves of
% the tree which represent colors present in the input image.
%
% The other pixel count, n1, indicates the total number of colors
% within the cubic volume which the node represents. This includes n1 -
% n2 pixels whose colors should be defined by nodes at a lower level in
% the tree.
%
% Assignment generates the output image from the pruned tree. The
% output image consists of two parts: (1) A color map, which is an
% array of color descriptions (RGB triples) for each color present in
% the output image; (2) A pixel array, which represents each pixel as
% an index into the color map array.
%
% First, the assignment phase makes one pass over the pruned color
% description tree to establish the image's color map. For each node
% with n2 > 0, it divides Sr, Sg, and Sb by n2 . This produces the
% mean color of all pixels that classify no lower than this node. Each
% of these colors becomes an entry in the color map.
%
% Finally, the assignment phase reclassifies each pixel in the pruned
% tree to identify the deepest node containing the pixel's color. The
% pixel's value in the pixel array becomes the index of this node's mean
% color in the color map.
%
% With the permission of USC Information Sciences Institute, 4676 Admiralty
% Way, Marina del Rey, California 90292, this code was adapted from module
% ALCOLS written by Paul Raveling.
%
% The names of ISI and USC are not used in advertising or publicity
% pertaining to distribution of the software without prior specific
% written permission from ISI.
%
*/
final static boolean QUICK = true;
final static int MAX_RGB = 255;
final static int MAX_NODES = 266817;
final static int MAX_TREE_DEPTH = 8;
// these are precomputed in advance
static int SQUARES[];
static int SHIFT[];
static {
SQUARES = new int[MAX_RGB + MAX_RGB + 1];
for (int i= -MAX_RGB; i <= MAX_RGB; i++) {
SQUARES[i + MAX_RGB] = i * i;
}
SHIFT = new int[MAX_TREE_DEPTH + 1];
for (int i = 0; i < MAX_TREE_DEPTH + 1; ++i) {
SHIFT[i] = 1 << (15 - i);
}
}
/**
* Reduce the image to the given number of colors. The pixels are
* reduced in place.
* @return The new color palette.
*/
public static int[] quantizeImage(int pixels[][], int max_colors) {
Cube cube = new Cube(pixels, max_colors);
cube.classification();
cube.reduction();
cube.assignment();
return cube.colormap;
}
static class Cube {
int pixels[][];
int max_colors;
int colormap[];
Node root;
int depth;
// counter for the number of colors in the cube. this gets
// recalculated often.
int colors;
// counter for the number of nodes in the tree
int nodes;
Cube(int pixels[][], int max_colors) {
this.pixels = pixels;
this.max_colors = max_colors;
int i = max_colors;
// tree_depth = log max_colors
// 4
for (depth = 1; i != 0; depth++) {
i /= 4;
}
if (depth > 1) {
--depth;
}
if (depth > MAX_TREE_DEPTH) {
depth = MAX_TREE_DEPTH;
} else if (depth < 2) {
depth = 2;
}
root = new Node(this);
}
/*
* Procedure Classification begins by initializing a color
* description tree of sufficient depth to represent each
* possible input color in a leaf. However, it is impractical
* to generate a fully-formed color description tree in the
* classification phase for realistic values of cmax. If
* colors components in the input image are quantized to k-bit
* precision, so that cmax= 2k-1, the tree would need k levels
* below the root node to allow representing each possible
* input color in a leaf. This becomes prohibitive because the
* tree's total number of nodes is 1 + sum(i=1,k,8k).
*
* A complete tree would require 19,173,961 nodes for k = 8,
* cmax = 255. Therefore, to avoid building a fully populated
* tree, QUANTIZE: (1) Initializes data structures for nodes
* only as they are needed; (2) Chooses a maximum depth for
* the tree as a function of the desired number of colors in
* the output image (currently log2(colormap size)).
*
* For each pixel in the input image, classification scans
* downward from the root of the color description tree. At
* each level of the tree it identifies the single node which
* represents a cube in RGB space containing It updates the
* following data for each such node:
*
* number_pixels : Number of pixels whose color is contained
* in the RGB cube which this node represents;
*
* unique : Number of pixels whose color is not represented
* in a node at lower depth in the tree; initially, n2 = 0
* for all nodes except leaves of the tree.
*
* total_red/green/blue : Sums of the red, green, and blue
* component values for all pixels not classified at a lower
* depth. The combination of these sums and n2 will
* ultimately characterize the mean color of a set of pixels
* represented by this node.
*/
void classification() {
int pixels[][] = this.pixels;
int width = pixels.length;
int height = pixels[0].length;
// convert to indexed color
for (int x = width; x-- > 0; ) {
for (int y = height; y-- > 0; ) {
int pixel = pixels[x][y];
int red = (pixel >> 16) & 0xFF;
int green = (pixel >> 8) & 0xFF;
int blue = (pixel >> 0) & 0xFF;
// a hard limit on the number of nodes in the tree
if (nodes > MAX_NODES) {
System.out.println("pruning");
root.pruneLevel();
--depth;
}
// walk the tree to depth, increasing the
// number_pixels count for each node
Node node = root;
for (int level = 1; level <= depth; ++level) {
int id = (((red > node.mid_red ? 1 : 0) << 0) |
((green > node.mid_green ? 1 : 0) << 1) |
((blue > node.mid_blue ? 1 : 0) << 2));
if (node.child[id] == null) {
new Node(node, id, level);
}
node = node.child[id];
node.number_pixels += SHIFT[level];
}
++node.unique;
node.total_red += red;
node.total_green += green;
node.total_blue += blue;
}
}
}
/*
* reduction repeatedly prunes the tree until the number of
* nodes with unique > 0 is less than or equal to the maximum
* number of colors allowed in the output image.
*
* When a node to be pruned has offspring, the pruning
* procedure invokes itself recursively in order to prune the
* tree from the leaves upward. The statistics of the node
* being pruned are always added to the corresponding data in
* that node's parent. This retains the pruned node's color
* characteristics for later averaging.
*/
void reduction() {
int threshold = 1;
while (colors > max_colors) {
colors = 0;
threshold = root.reduce(threshold, Integer.MAX_VALUE);
}
}
/**
* The result of a closest color search.
*/
static class Search {
int distance;
int color_number;
}
/*
* Procedure assignment generates the output image from the
* pruned tree. The output image consists of two parts: (1) A
* color map, which is an array of color descriptions (RGB
* triples) for each color present in the output image; (2) A
* pixel array, which represents each pixel as an index into
* the color map array.
*
* First, the assignment phase makes one pass over the pruned
* color description tree to establish the image's color map.
* For each node with n2 > 0, it divides Sr, Sg, and Sb by n2.
* This produces the mean color of all pixels that classify no
* lower than this node. Each of these colors becomes an entry
* in the color map.
*
* Finally, the assignment phase reclassifies each pixel in
* the pruned tree to identify the deepest node containing the
* pixel's color. The pixel's value in the pixel array becomes
* the index of this node's mean color in the color map.
*/
void assignment() {
colormap = new int[colors];
colors = 0;
root.colormap();
int pixels[][] = this.pixels;
int width = pixels.length;
int height = pixels[0].length;
Search search = new Search();
// convert to indexed color
for (int x = width; x-- > 0; ) {
for (int y = height; y-- > 0; ) {
int pixel = pixels[x][y];
int red = (pixel >> 16) & 0xFF;
int green = (pixel >> 8) & 0xFF;
int blue = (pixel >> 0) & 0xFF;
// walk the tree to find the cube containing that color
Node node = root;
for ( ; ; ) {
int id = (((red > node.mid_red ? 1 : 0) << 0) |
((green > node.mid_green ? 1 : 0) << 1) |
((blue > node.mid_blue ? 1 : 0) << 2) );
if (node.child[id] == null) {
break;
}
node = node.child[id];
}
if (QUICK) {
// if QUICK is set, just use that
// node. Strictly speaking, this isn't
// necessarily best match.
pixels[x][y] = node.color_number;
} else {
// Find the closest color.
search.distance = Integer.MAX_VALUE;
node.parent.closestColor(red, green, blue, search);
pixels[x][y] = search.color_number;
}
}
}
}
/**
* A single Node in the tree.
*/
static class Node {
Cube cube;
// parent node
Node parent;
// child nodes
Node child[];
int nchild;
// our index within our parent
int id;
// our level within the tree
int level;
// our color midpoint
int mid_red;
int mid_green;
int mid_blue;
// the pixel count for this node and all children
int number_pixels;
// the pixel count for this node
int unique;
// the sum of all pixels contained in this node
int total_red;
int total_green;
int total_blue;
// used to build the colormap
int color_number;
Node(Cube cube) {
this.cube = cube;
this.parent = this;
this.child = new Node[8];
this.id = 0;
this.level = 0;
this.number_pixels = Integer.MAX_VALUE;
this.mid_red = (MAX_RGB + 1) >> 1;
this.mid_green = (MAX_RGB + 1) >> 1;
this.mid_blue = (MAX_RGB + 1) >> 1;
}
Node(Node parent, int id, int level) {
this.cube = parent.cube;
this.parent = parent;
this.child = new Node[8];
this.id = id;
this.level = level;
// add to the cube
++cube.nodes;
if (level == cube.depth) {
++cube.colors;
}
// add to the parent
++parent.nchild;
parent.child[id] = this;
// figure out our midpoint
int bi = (1 << (MAX_TREE_DEPTH - level)) >> 1;
mid_red = parent.mid_red + ((id & 1) > 0 ? bi : -bi);
mid_green = parent.mid_green + ((id & 2) > 0 ? bi : -bi);
mid_blue = parent.mid_blue + ((id & 4) > 0 ? bi : -bi);
}
/**
* Remove this child node, and make sure our parent
* absorbs our pixel statistics.
*/
void pruneChild() {
--parent.nchild;
parent.unique += unique;
parent.total_red += total_red;
parent.total_green += total_green;
parent.total_blue += total_blue;
parent.child[id] = null;
--cube.nodes;
cube = null;
parent = null;
}
/**
* Prune the lowest layer of the tree.
*/
void pruneLevel() {
if (nchild != 0) {
for (int id = 0; id < 8; id++) {
if (child[id] != null) {
child[id].pruneLevel();
}
}
}
if (level == cube.depth) {
pruneChild();
}
}
/**
* Remove any nodes that have fewer than threshold
* pixels. Also, as long as we're walking the tree:
*
* - figure out the color with the fewest pixels
* - recalculate the total number of colors in the tree
*/
int reduce(int threshold, int next_threshold) {
if (nchild != 0) {
for (int id = 0; id < 8; id++) {
if (child[id] != null) {
next_threshold = child[id].reduce(threshold, next_threshold);
}
}
}
if (number_pixels <= threshold) {
pruneChild();
} else {
if (unique != 0) {
cube.colors++;
}
if (number_pixels < next_threshold) {
next_threshold = number_pixels;
}
}
return next_threshold;
}
/*
* colormap traverses the color cube tree and notes each
* colormap entry. A colormap entry is any node in the
* color cube tree where the number of unique colors is
* not zero.
*/
void colormap() {
if (nchild != 0) {
for (int id = 0; id < 8; id++) {
if (child[id] != null) {
child[id].colormap();
}
}
}
if (unique != 0) {
int r = ((total_red + (unique >> 1)) / unique);
int g = ((total_green + (unique >> 1)) / unique);
int b = ((total_blue + (unique >> 1)) / unique);
cube.colormap[cube.colors] = ((( 0xFF) << 24) |
((r & 0xFF) << 16) |
((g & 0xFF) << 8) |
((b & 0xFF) << 0));
color_number = cube.colors++;
}
}
/* ClosestColor traverses the color cube tree at a
* particular node and determines which colormap entry
* best represents the input color.
*/
void closestColor(int red, int green, int blue, Search search) {
if (nchild != 0) {
for (int id = 0; id < 8; id++) {
if (child[id] != null) {
child[id].closestColor(red, green, blue, search);
}
}
}
if (unique != 0) {
int color = cube.colormap[color_number];
int distance = distance(color, red, green, blue);
if (distance < search.distance) {
search.distance = distance;
search.color_number = color_number;
}
}
}
/**
* Figure out the distance between this node and som color.
*/
final static int distance(int color, int r, int g, int b) {
return (SQUARES[((color >> 16) & 0xFF) - r + MAX_RGB] +
SQUARES[((color >> 8) & 0xFF) - g + MAX_RGB] +
SQUARES[((color >> 0) & 0xFF) - b + MAX_RGB]);
}
public String toString() {
StringBuffer buf = new StringBuffer();
if (parent == this) {
buf.append("root");
} else {
buf.append("node");
}
buf.append(' ');
buf.append(level);
buf.append(" [");
buf.append(mid_red);
buf.append(',');
buf.append(mid_green);
buf.append(',');
buf.append(mid_blue);
buf.append(']');
return new String(buf);
}
}
}
}

View file

@ -1,131 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.image;
import Acme.JPM.Encoders.GifEncoder;
import com.sun.jimi.core.*;
import com.sun.jimi.core.util.*;
import java.awt.*;
import java.awt.image.*;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* A wrapper for an image that uses the Sun version of JIMI available at
* http://java.sun.com/products/jimi.
*/
public class SunImageWrapper extends ImageWrapper {
/**
* Creates a new SunImageWrapper object.
*
* @param img ...
* @param g ...
* @param width ...
* @param height ...
* @param imggen ...
*/
public SunImageWrapper(Image img, Graphics g, int width, int height,
ImageGenerator imggen) {
super(img, g, width, height, imggen);
}
/**
* Reduce the colors used in this image. Useful and necessary before saving
* the image as GIF file.
*
* @param colors the number of colors to use, usually <= 256.
*/
public void reduceColors(int colors) {
try {
// first, try to use JIMI's ColorReducer class. It is able to
// preserve transparency on GIF files, but does throw exceptions on some GIFs.
img = new ColorReducer(colors, false).getColorReducedImage(img);
} catch (Exception excpt) {
// JIMI sometimes fails to reduce colors, throwing an exception.
// Use our alternative Quantizer in this case.
System.err.println("Using alternative color reducer ("+excpt+")");
try {
int[][] pixels = getPixels();
int[] palette = Quantize.quantizeImage(pixels, colors);
int w = pixels.length;
int h = pixels[0].length;
int[] pix = new int[w * h];
// convert to RGB
for (int x = w; x-- > 0;) {
for (int y = h; y-- > 0;) {
pix[(y * w) + x] = palette[pixels[x][y]];
}
}
img = imggen.createImage(new MemoryImageSource(w, h, pix, 0, w));
} catch (IOException ioxcpt) {
System.err.println("Error in reduceColors(): "+ioxcpt);
}
}
}
/**
* Snag the pixels from an image.
*/
int[][] getPixels() throws IOException {
int[] pix = new int[width * height];
PixelGrabber grabber = new PixelGrabber(img, 0, 0, width, height, pix, 0, width);
try {
if (grabber.grabPixels() != true) {
throw new IOException("Grabber returned false: " + grabber.status());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
int[][] pixels = new int[width][height];
for (int x = width; x-- > 0;) {
for (int y = height; y-- > 0;) {
pixels[x][y] = pix[(y * width) + x];
}
}
return pixels;
}
/**
*
*
* @param filename ...
*/
public void saveAs(String filename) {
try {
if (filename.toLowerCase().endsWith(".gif")) {
// sun's jimi package doesn't encode gifs, use Acme encoder
FileOutputStream fout = new FileOutputStream(filename);
// Acme gif encoder
GifEncoder enc = new GifEncoder(img, fout);
enc.encode();
fout.close();
} else {
Jimi.putImage(img, filename);
}
} catch (Exception x) {
throw new RuntimeException(x.getMessage());
}
}
}

View file

@ -1,469 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.main;
import helma.framework.*;
import helma.framework.core.*;
import helma.objectmodel.*;
import helma.servlet.*;
import helma.util.SystemProperties;
import helma.util.StringUtils;
import org.apache.xmlrpc.XmlRpcHandler;
import org.mortbay.http.*;
import org.mortbay.http.handler.*;
import org.mortbay.jetty.servlet.*;
import org.mortbay.util.*;
import java.io.*;
import java.lang.reflect.*;
import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
import javax.servlet.Servlet;
/**
* This class is responsible for starting and stopping Helma applications.
*/
public class ApplicationManager implements XmlRpcHandler {
private Hashtable descriptors;
private Hashtable applications;
private Hashtable xmlrpcHandlers;
private int port;
private File hopHome;
private SystemProperties props;
private Server server;
private long lastModified;
/**
* Creates a new ApplicationManager object.
*
* @param hopHome The Helma home directory
* @param props the properties defining the running apps
* @param server the server instance
* @param port The RMI port we're binding to
*/
public ApplicationManager(File hopHome, SystemProperties props,
Server server, int port) {
this.hopHome = hopHome;
this.props = props;
this.server = server;
this.port = port;
descriptors = new Hashtable();
applications = new Hashtable();
xmlrpcHandlers = new Hashtable();
lastModified = 0;
}
/**
* Called regularely check applications property file
* to create and start new applications.
*/
protected void checkForChanges() {
if (props.lastModified() > lastModified) {
try {
for (Enumeration e = props.keys(); e.hasMoreElements();) {
String appName = (String) e.nextElement();
if ((appName.indexOf(".") == -1) &&
(applications.get(appName) == null)) {
AppDescriptor appDesc = new AppDescriptor(appName);
appDesc.start();
appDesc.bind();
}
}
// then stop deleted ones
for (Enumeration e = descriptors.elements(); e.hasMoreElements();) {
AppDescriptor appDesc = (AppDescriptor) e.nextElement();
// check if application has been removed and should be stopped
if (!props.containsKey(appDesc.appName)) {
appDesc.stop();
} else if (server.http != null) {
// If application continues to run, remount
// as the mounting options may have changed.
appDesc.unbind();
AppDescriptor ndesc = new AppDescriptor(appDesc.appName);
ndesc.app = appDesc.app;
ndesc.bind();
descriptors.put(ndesc.appName, ndesc);
}
}
} catch (Exception mx) {
Server.getLogger().log("Error checking applications: " + mx);
}
lastModified = System.currentTimeMillis();
}
}
/**
* Start an application by name
*/
public void start(String appName) {
AppDescriptor desc = new AppDescriptor(appName);
desc.start();
}
/**
* Bind an application by name
*/
public void register(String appName) {
AppDescriptor desc = (AppDescriptor) descriptors.get(appName);
if (desc != null) {
desc.bind();
}
}
/**
* Stop an application by name
*/
public void stop(String appName) {
AppDescriptor desc = (AppDescriptor) descriptors.get(appName);
if (desc != null) {
desc.stop();
}
}
/**
* Start all applications listed in the properties
*/
public void startAll() {
try {
for (Enumeration e = props.keys(); e.hasMoreElements();) {
String appName = (String) e.nextElement();
if (appName.indexOf(".") == -1) {
String appValue = props.getProperty(appName);
if (appValue != null && appValue.length() > 0) {
appName = appValue;
}
AppDescriptor desc = new AppDescriptor(appName);
desc.start();
}
}
for (Enumeration e = descriptors.elements(); e.hasMoreElements();) {
AppDescriptor appDesc = (AppDescriptor) e.nextElement();
appDesc.bind();
}
lastModified = System.currentTimeMillis();
} catch (Exception mx) {
Server.getLogger().log("Error starting applications: " + mx);
mx.printStackTrace();
}
}
/**
* Stop all running applications.
*/
public void stopAll() {
for (Enumeration en = descriptors.elements(); en.hasMoreElements();) {
AppDescriptor appDesc = (AppDescriptor) en.nextElement();
appDesc.stop();
}
}
/**
* Get an array containing all currently running applications.
*/
public Object[] getApplications() {
return applications.values().toArray();
}
/**
* Get an application by name.
*/
public Application getApplication(String name) {
return (Application) applications.get(name);
}
/**
* Implements org.apache.xmlrpc.XmlRpcHandler.execute()
*/
public Object execute(String method, Vector params)
throws Exception {
int dot = method.indexOf(".");
if (dot == -1) {
throw new Exception("Method name \"" + method +
"\" does not specify a handler application");
}
if ((dot == 0) || (dot == (method.length() - 1))) {
throw new Exception("\"" + method + "\" is not a valid XML-RPC method name");
}
String handler = method.substring(0, dot);
String method2 = method.substring(dot + 1);
Application app = (Application) xmlrpcHandlers.get(handler);
if (app == null) {
app = (Application) xmlrpcHandlers.get("*");
// use the original method name, the handler is resolved within the app.
method2 = method;
}
if (app == null) {
throw new Exception("Handler \"" + handler + "\" not found for " + method);
}
return app.executeXmlRpc(method2, params);
}
private String getMountpoint(String mountpoint) {
mountpoint = mountpoint.trim();
if ("".equals(mountpoint)) {
return "/";
} else if (!mountpoint.startsWith("/")) {
return "/" + mountpoint;
}
return mountpoint;
}
private String joinMountpoint(String prefix, String suffix) {
if (prefix.endsWith("/") || suffix.startsWith("/")) {
return prefix+suffix;
} else {
return prefix+"/"+suffix;
}
}
private String getPathPattern(String mountpoint) {
if (!mountpoint.startsWith("/")) {
mountpoint = "/"+mountpoint;
}
if ("/".equals(mountpoint)) {
return "/";
}
if (mountpoint.endsWith("/")) {
return mountpoint + "*";
}
return mountpoint + "/*";
}
/**
* Inner class that describes an application and its start settings.
*/
class AppDescriptor {
Application app;
String appName;
File appDir;
File dbDir;
String mountpoint;
String pathPattern;
String staticDir;
String staticMountpoint;
String xmlrpcHandlerName;
String cookieDomain;
String uploadLimit;
String debug;
String charset;
boolean encode;
/**
* Creates an AppDescriptor from the properties.
*/
AppDescriptor(String name) {
appName = name;
mountpoint = getMountpoint(props.getProperty(name+".mountpoint",
appName));
pathPattern = getPathPattern(mountpoint);
staticDir = props.getProperty(name+".static");
staticMountpoint = getPathPattern(props.getProperty(name+".staticMountpoint",
joinMountpoint(mountpoint, "static")));
cookieDomain = props.getProperty(name+".cookieDomain");
uploadLimit = props.getProperty(name+".uploadLimit");
debug = props.getProperty(name+".debug");
encode = "true".equalsIgnoreCase(props.getProperty(name +
".responseEncoding"));
String appDirName = props.getProperty(name + ".appdir");
appDir = (appDirName == null) ? null : new File(appDirName);
String dbDirName = props.getProperty(name + ".dbdir");
dbDir = (dbDirName == null) ? null : new File(dbDirName);
}
void start() {
Server.getLogger().log("Building application " + appName);
try {
// create the application instance
app = new Application(appName, server, appDir, dbDir);
// register ourselves
descriptors.put(appName, this);
applications.put(appName, app);
// the application is started later in the register method, when it's bound
app.init();
app.start();
} catch (Exception x) {
Server.getLogger().log("Error creating application " + appName + ": " + x);
x.printStackTrace();
}
}
void stop() {
Server.getLogger().log("Stopping application " + appName);
// unbind application
unbind();
// stop application
try {
app.stop();
Server.getLogger().log("Stopped application " + appName);
} catch (Exception x) {
Server.getLogger().log("Couldn't stop app: " + x);
}
descriptors.remove(appName);
applications.remove(appName);
}
void bind() {
try {
Server.getLogger().log("Binding application " + appName);
// bind to RMI server
if (port > 0) {
Naming.rebind("//:" + port + "/" + appName, new RemoteApplication(app));
}
// bind to Jetty HTTP server
if (server.http != null) {
// if using embedded webserver (not AJP) set application URL prefix
if (!app.hasExplicitBaseURI()) {
app.setBaseURI(mountpoint);
}
ServletHttpContext context = new ServletHttpContext();
context.setContextPath(pathPattern);
server.http.addContext(context);
if (encode) {
context.addHandler(new ContentEncodingHandler());
}
ServletHolder holder = context.addServlet(appName, "/*",
"helma.servlet.EmbeddedServletClient");
holder.setInitParameter("application", appName);
// holder.setInitParameter("mountpoint", mountpoint);
if (cookieDomain != null) {
holder.setInitParameter("cookieDomain", cookieDomain);
}
if (uploadLimit != null) {
holder.setInitParameter("uploadLimit", uploadLimit);
}
if (debug != null) {
holder.setInitParameter("debug", debug);
}
holder.setInitParameter("charset", app.getCharset());
context.start();
if (staticDir != null) {
File staticContent = new File(staticDir);
if (!staticContent.isAbsolute()) {
staticContent = new File(server.getHopHome(), staticDir);
}
Server.getLogger().log("Serving static from " +
staticContent.getAbsolutePath());
Server.getLogger().log("Mounting static at " +
staticMountpoint);
HttpContext cx = server.http.addContext(staticMountpoint);
cx.setResourceBase(staticContent.getAbsolutePath());
ResourceHandler handler = new ResourceHandler();
cx.addHandler(handler);
cx.start();
}
}
// register as XML-RPC handler
xmlrpcHandlerName = app.getXmlRpcHandlerName();
xmlrpcHandlers.put(xmlrpcHandlerName, app);
// app.start();
} catch (Exception x) {
Server.getLogger().log("Couldn't bind app: " + x);
x.printStackTrace();
}
}
void unbind() {
Server.getLogger().log("Unbinding application " + appName);
try {
// unbind from RMI server
if (port > 0) {
Naming.unbind("//:" + port + "/" + appName);
}
// unbind from Jetty HTTP server
if (server.http != null) {
HttpContext context = server.http.getContext(null, pathPattern);
if (context != null) {
context.stop();
context.destroy();
}
if (staticDir != null) {
context = server.http.getContext(null, staticMountpoint);
if (context != null) {
context.stop();
context.destroy();
}
}
}
// unregister as XML-RPC handler
xmlrpcHandlers.remove(xmlrpcHandlerName);
} catch (Exception x) {
Server.getLogger().log("Couldn't unbind app: " + x);
}
}
}
}

View file

@ -1,327 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.main;
import helma.framework.core.AppClassLoader;
import java.io.FileDescriptor;
import java.net.InetAddress;
import java.security.Permission;
import java.util.HashSet;
/**
* Liberal security manager for Helma system that makes sure application code
* is not allowed to exit the VM and set a security manager.
*
* This class can be subclassed to implement actual security policies. It contains
* a utility method <code>getApplication</code> that can be used to determine
* the name of the application trying to execute the action in question, if any.
*/
public class HelmaSecurityManager extends SecurityManager {
// The set of actions forbidden to application code.
// We are pretty permissive, forbidding only System.exit()
// and setting the security manager.
private final static HashSet forbidden = new HashSet();
static {
forbidden.add("exitVM");
forbidden.add("setSecurityManager");
}
/**
*
*
* @param p ...
*/
public void checkPermission(Permission p) {
if (p instanceof RuntimePermission) {
if (forbidden.contains(p.getName())) {
Class[] classes = getClassContext();
for (int i = 0; i < classes.length; i++) {
if (classes[i].getClassLoader() instanceof AppClassLoader) {
throw new SecurityException(p.getName() +
" not allowed for application code");
}
}
}
}
}
/**
*
*
* @param p ...
* @param context ...
*/
public void checkPermission(Permission p, Object context) {
}
/**
*
*/
public void checkCreateClassLoader() {
}
/**
*
*
* @param thread ...
*/
public void checkAccess(Thread thread) {
}
/**
*
*
* @param group ...
*/
public void checkAccess(ThreadGroup group) {
}
/**
*
*
* @param status ...
*/
public void checkExit(int status) {
Class[] classes = getClassContext();
for (int i = 0; i < classes.length; i++) {
if (classes[i].getClassLoader() instanceof AppClassLoader) {
throw new SecurityException("operation not allowed for application code");
}
}
}
/**
*
*
* @param cmd ...
*/
public void checkExec(String cmd) {
}
/**
*
*
* @param lib ...
*/
public void checkLink(String lib) {
}
/**
*
*
* @param fdesc ...
*/
public void checkRead(FileDescriptor fdesc) {
}
/**
*
*
* @param file ...
*/
public void checkRead(String file) {
}
/**
*
*
* @param file ...
* @param context ...
*/
public void checkRead(String file, Object context) {
}
/**
*
*
* @param fdesc ...
*/
public void checkWrite(FileDescriptor fdesc) {
}
/**
*
*
* @param file ...
*/
public void checkWrite(String file) {
}
/**
*
*
* @param file ...
*/
public void checkDelete(String file) {
}
/**
*
*
* @param host ...
* @param port ...
*/
public void checkConnect(String host, int port) {
}
/**
*
*
* @param host ...
* @param port ...
* @param context ...
*/
public void checkConnect(String host, int port, Object context) {
}
/**
*
*
* @param port ...
*/
public void checkListen(int port) {
}
/**
*
*
* @param host ...
* @param port ...
*/
public void checkAccept(String host, int port) {
}
/**
*
*
* @param addr ...
*/
public void checkMulticast(InetAddress addr) {
}
/**
*
*
* @param addr ...
* @param ttl ...
*/
public void checkMulticast(InetAddress addr, byte ttl) {
}
/**
*
*/
public void checkPropertiesAccess() {
}
/**
*
*
* @param key ...
*/
public void checkPropertyAccess(String key) {
}
/**
*
*
* @param window ...
*
* @return ...
*/
public boolean checkTopLevelWindow(Object window) {
return true;
}
/**
*
*/
public void checkPrintJobAccess() {
}
/**
*
*/
public void checkSystemClipboardAccess() {
}
/**
*
*/
public void checkAwtEventQueueAccess() {
}
/**
*
*
* @param pkg ...
*/
public void checkPackageAccess(String pkg) {
}
/**
*
*
* @param pkg ...
*/
public void checkPackageDefinition(String pkg) {
}
/**
*
*/
public void checkSetFactory() {
}
/**
*
*
* @param clazz ...
* @param which ...
*/
public void checkMemberAccess(Class clazz, int which) {
}
/**
*
*
* @param target ...
*/
public void checkSecurityAccess(String target) {
}
/**
* Utility method that returns the name of the application trying
* to execute the code in question. Returns null if the current code
* does not belong to any application.
*/
protected String getApplication() {
Class[] classes = getClassContext();
for (int i = 0; i < classes.length; i++) {
if (classes[i].getClassLoader() instanceof AppClassLoader) {
return ((AppClassLoader) classes[i].getClassLoader()).getAppName();
}
}
// no application class loader found in stack - return null
return null;
}
}

View file

@ -1,59 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.main;
import helma.util.Logger;
import java.util.List;
/**
* ShutdownHook that shuts down all running Helma applications on exit.
*/
public class HelmaShutdownHook extends Thread {
ApplicationManager appmgr;
/**
* Creates a new HelmaShutdownHook object.
*
* @param appmgr ...
*/
public HelmaShutdownHook(ApplicationManager appmgr) {
this.appmgr = appmgr;
}
/**
*
*/
public void run() {
System.err.println("Shutting down Helma - please stand by");
Logger logger = Server.getLogger();
if (logger != null) {
logger.log("Shutting down Helma");
}
appmgr.stopAll();
List loggers = Logger.getLoggers();
int l = loggers.size();
for (int i = 0; i < l; i++)
((Logger) loggers.get(i)).close();
Logger.wakeup();
}
}

View file

@ -1,79 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.main;
import helma.util.*;
import java.io.IOException;
import java.net.*;
import java.rmi.server.*;
/**
* An RMI socket factory that has a "paranoid" option to filter clients.
* We only do direct connections, no HTTP proxy stuff, since this is
* server-to-server.
*/
public class HelmaSocketFactory extends RMISocketFactory {
private InetAddressFilter filter;
/**
* Creates a new HelmaSocketFactory object.
*/
public HelmaSocketFactory() {
filter = new InetAddressFilter();
}
/**
*
*
* @param address ...
*/
public void addAddress(String address) {
try {
filter.addAddress(address);
} catch (IOException x) {
Server.getLogger().log("Could not add " + address +
" to Socket Filter: invalid address.");
}
}
/**
*
*
* @param host ...
* @param port ...
*
* @return ...
*
* @throws IOException ...
*/
public Socket createSocket(String host, int port) throws IOException {
return new Socket(host, port);
}
/**
*
*
* @param port ...
*
* @return ...
*
* @throws IOException ...
*/
public ServerSocket createServerSocket(int port) throws IOException {
return new ParanoidServerSocket(port, filter);
}
}

View file

@ -1,755 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.main;
import helma.extensions.HelmaExtension;
import helma.framework.*;
import helma.framework.core.*;
import helma.objectmodel.db.DbSource;
import helma.util.*;
import org.apache.xmlrpc.*;
import org.mortbay.http.*;
import org.mortbay.http.ajp.*;
import org.mortbay.util.*;
import java.io.*;
import java.net.*;
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
import java.util.*;
/**
* Helma server main class.
*/
public class Server implements IPathElement, Runnable {
public static final String version = "1.3.0 alpha (2003/06/26)";
// server-wide properties
static SystemProperties appsProps;
static SystemProperties dbProps;
static SystemProperties sysProps;
// static server instance
private static Server server;
protected static File hopHome = null;
// our logger
private static Logger logger;
public final long starttime;
// if true we only accept RMI and XML-RPC connections from
// explicitly listed hosts.
public boolean paranoid;
private ApplicationManager appManager;
private Vector extensions;
private Thread mainThread;
// server ports
InetAddrPort rmiPort = null;
InetAddrPort xmlrpcPort = null;
InetAddrPort websrvPort = null;
InetAddrPort ajp13Port = null;
// map of server-wide database sources
Hashtable dbSources;
// the embedded web server
// protected Serve websrv;
protected HttpServer http;
// the AJP13 Listener, used for connecting from external webserver to servlet via JK
protected AJP13Listener ajp13;
// the XML-RPC server
protected WebServer xmlrpc;
/**
* Constructs a new Server instance with an array of command line options.
*/
public Server(String[] args) {
starttime = System.currentTimeMillis();
String homeDir = null;
boolean usageError = false;
// file names of various property files
String propfile = null;
String dbPropfile = "db.properties";
String appsPropfile = null;
// parse arguments
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-h") && ((i + 1) < args.length)) {
homeDir = args[++i];
} else if (args[i].equals("-f") && ((i + 1) < args.length)) {
propfile = args[++i];
} else if (args[i].equals("-p") && ((i + 1) < args.length)) {
try {
rmiPort = new InetAddrPort(args[++i]);
} catch (Exception portx) {
usageError = true;
}
} else if (args[i].equals("-x") && ((i + 1) < args.length)) {
try {
xmlrpcPort = new InetAddrPort(args[++i]);
} catch (Exception portx) {
usageError = true;
}
} else if (args[i].equals("-w") && ((i + 1) < args.length)) {
try {
websrvPort = new InetAddrPort(args[++i]);
} catch (Exception portx) {
usageError = true;
}
} else if (args[i].equals("-jk") && ((i + 1) < args.length)) {
try {
ajp13Port = new InetAddrPort(args[++i]);
} catch (Exception portx) {
usageError = true;
}
} else if (args[i].equals("-i") && ((i + 1) < args.length)) {
// eat away the -i parameter which is meant for helma.main.launcher.Main
i++;
} else {
System.err.println("Unknown command line token: " + args[i]);
usageError = true;
}
}
// get main property file from home dir or vice versa, depending on what we have.
// get property file from hopHome
if (propfile == null) {
if (homeDir != null) {
propfile = new File(homeDir, "server.properties").getAbsolutePath();
} else {
propfile = new File("server.properties").getAbsolutePath();
}
}
// create system properties
sysProps = new SystemProperties(propfile);
// check if there's a property setting for those ports not specified via command line
if ((websrvPort == null) && (sysProps.getProperty("webPort") != null)) {
try {
websrvPort = new InetAddrPort(sysProps.getProperty("webPort"));
} catch (Exception fmt) {
System.err.println("Error parsing web server port property: " + fmt);
}
}
if ((ajp13Port == null) && (sysProps.getProperty("ajp13Port") != null)) {
try {
ajp13Port = new InetAddrPort(sysProps.getProperty("ajp13Port"));
} catch (Exception fmt) {
System.err.println("Error parsing AJP1.3 server port property: " + fmt);
}
}
if ((rmiPort == null) && (sysProps.getProperty("rmiPort") != null)) {
try {
rmiPort = new InetAddrPort(sysProps.getProperty("rmiPort"));
} catch (Exception fmt) {
System.err.println("Error parsing RMI server port property: " + fmt);
}
}
if ((xmlrpcPort == null) && (sysProps.getProperty("xmlrpcPort") != null)) {
try {
xmlrpcPort = new InetAddrPort(sysProps.getProperty("xmlrpcPort"));
} catch (Exception fmt) {
System.err.println("Error parsing XML-RPC server port property: " + fmt);
}
}
// check server ports. If no port is set, issue a warning and exit.
if (!usageError && websrvPort == null && ajp13Port == null &&
rmiPort == null && xmlrpcPort == null) {
System.out.println(" Error: No server port specified.");
usageError = true;
}
// if there's a usage error, output message and exit
if (usageError) {
System.out.println("");
System.out.println("Usage: java helma.main.Server [options]");
System.out.println("Possible options:");
System.out.println(" -h dir Specify hop home directory");
System.out.println(" -f file Specify server.properties file");
System.out.println(" -w [ip:]port Specify embedded web server address/port");
System.out.println(" -x [ip:]port Specify XML-RPC address/port");
System.out.println(" -jk [ip:]port Specify AJP13 address/port");
System.out.println(" -p [ip:]port Specify RMI address/port");
System.out.println("");
System.out.println("Supported formats for server ports:");
System.out.println(" <port-number>");
System.out.println(" <ip-address>:<port-number>");
System.out.println(" <hostname>:<port-number>");
System.out.println("");
System.err.println("Usage Error - exiting");
System.out.println("");
System.exit(0);
}
// check if any of the specified server ports is in use already
try {
if (websrvPort != null) {
checkRunning(websrvPort);
}
if (rmiPort != null) {
checkRunning(rmiPort);
}
if (xmlrpcPort != null) {
checkRunning(xmlrpcPort);
}
if (ajp13Port != null) {
checkRunning(ajp13Port);
}
} catch (Exception running) {
System.out.println(running.getMessage());
System.exit(1);
}
// get hopHome from property file
if (homeDir == null) {
homeDir = sysProps.getProperty("hophome");
}
if (homeDir == null) {
homeDir = new File(propfile).getParent();
}
// create hopHome File object
hopHome = new File(homeDir);
// try to transform hopHome directory to its cononical representation
try {
hopHome = hopHome.getCanonicalFile();
} catch (IOException iox) {
System.err.println("Error calling getCanonicalFile() on hopHome: " + iox);
}
// set the current working directory to the helma home dir.
// note that this is not a real cwd, which is not supported
// by java. It makes sure relative to absolute path name
// conversion is done right, so for Helma code, this should
// work.
System.setProperty("user.dir", hopHome.getPath());
// from now on it's safe to call getLogger() because hopHome is set up
String startMessage = "Starting Helma " + version + " on Java " +
System.getProperty("java.version");
getLogger().log(startMessage);
// also print a msg to System.out
System.out.println(startMessage);
getLogger().log("propfile = " + propfile);
getLogger().log("hopHome = " + hopHome);
File helper = new File(hopHome, "db.properties");
dbPropfile = helper.getAbsolutePath();
dbProps = new SystemProperties(dbPropfile);
DbSource.setDefaultProps(dbProps);
getLogger().log("dbPropfile = " + dbPropfile);
appsPropfile = sysProps.getProperty("appsPropFile");
if ((appsPropfile != null) && !"".equals(appsPropfile.trim())) {
helper = new File(appsPropfile);
} else {
helper = new File(hopHome, "apps.properties");
}
appsPropfile = helper.getAbsolutePath();
appsProps = new SystemProperties(appsPropfile);
getLogger().log("appsPropfile = " + appsPropfile);
paranoid = "true".equalsIgnoreCase(sysProps.getProperty("paranoid"));
String language = sysProps.getProperty("language");
String country = sysProps.getProperty("country");
String timezone = sysProps.getProperty("timezone");
if ((language != null) && (country != null)) {
Locale.setDefault(new Locale(language, country));
}
if (timezone != null) {
TimeZone.setDefault(TimeZone.getTimeZone(timezone));
}
getLogger().log("Locale = " + Locale.getDefault());
getLogger().log("TimeZone = " +
TimeZone.getDefault().getDisplayName(Locale.getDefault()));
dbSources = new Hashtable();
// try to load the extensions
extensions = new Vector();
if (sysProps.getProperty("extensions") != null) {
StringTokenizer tok = new StringTokenizer(sysProps.getProperty("extensions"),
",");
while (tok.hasMoreTokens()) {
String extClassName = tok.nextToken().trim();
try {
Class extClass = Class.forName(extClassName);
HelmaExtension ext = (HelmaExtension) extClass.newInstance();
ext.init(this);
extensions.add(ext);
getLogger().log("Loaded: " + extClassName);
} catch (Throwable e) {
getLogger().log("Error loading extension " + extClassName + ": " + e.toString());
}
}
}
}
/**
* static main entry point.
*/
public static void main(String[] args) throws IOException {
// check if we are running on a Java 2 VM - otherwise exit with an error message
String javaVersion = System.getProperty("java.version");
if ((javaVersion == null) || javaVersion.startsWith("1.1") ||
javaVersion.startsWith("1.0")) {
System.err.println("This version of Helma requires Java 1.2 or greater.");
if (javaVersion == null) { // don't think this will ever happen, but you never know
System.err.println("Your Java Runtime did not provide a version number. Please update to a more recent version.");
} else {
System.err.println("Your Java Runtime is version " + javaVersion +
". Please update to a more recent version.");
}
System.exit(1);
}
// create new server instance
server = new Server(args);
// start the server main thread
server.start();
}
protected void start() {
// Start running, finishing setup and then entering a loop to check changes
// in the apps.properties file.
mainThread = new Thread(this);
mainThread.start();
}
protected void stop() {
mainThread = null;
}
/**
* The main method of the Server. Basically, we set up Applications and than
* periodically check for changes in the apps.properties file, shutting down
* apps or starting new ones.
*/
public void run() {
try {
if ((websrvPort != null) || (ajp13Port != null)) {
http = new HttpServer();
// disable Jetty logging FIXME: seems to be a jetty bug; as soon
// as the logging is disabled, the more is logged
Log.instance().disableLog();
Log.instance().add(new LogSink() {
public String getOptions() {
return null;
}
public void log(String formattedLog) {
}
public void log(String tag, Object msg, Frame frame, long time) {
}
public void setOptions(String options) {
}
public boolean isStarted() {
return true;
}
public void start() {
}
public void stop() {
}
});
}
// start embedded web server if port is specified
if (websrvPort != null) {
http.addListener(websrvPort);
}
// activate the ajp13-listener
if (ajp13Port != null) {
// create AJP13Listener
ajp13 = new AJP13Listener(ajp13Port);
ajp13.setHttpServer(http);
String jkallow = sysProps.getProperty("allowAJP13");
// by default the AJP13-connection just accepts requests from 127.0.0.1
if (jkallow == null) {
jkallow = "127.0.0.1";
}
StringTokenizer st = new StringTokenizer(jkallow, " ,;");
String[] jkallowarr = new String[st.countTokens()];
int cnt = 0;
while (st.hasMoreTokens()) {
jkallowarr[cnt] = st.nextToken();
cnt++;
}
ajp13.setRemoteServers(jkallowarr);
getLogger().log("Starting AJP13-Listener on port " + (ajp13Port));
}
if (xmlrpcPort != null) {
String xmlparser = sysProps.getProperty("xmlparser");
if (xmlparser != null) {
XmlRpc.setDriver(xmlparser);
}
if (xmlrpcPort.getInetAddress() != null) {
xmlrpc = new WebServer(xmlrpcPort.getPort(), xmlrpcPort.getInetAddress());
} else {
xmlrpc = new WebServer(xmlrpcPort.getPort());
}
if (paranoid) {
xmlrpc.setParanoid(true);
String xallow = sysProps.getProperty("allowXmlRpc");
if (xallow != null) {
StringTokenizer st = new StringTokenizer(xallow, " ,;");
while (st.hasMoreTokens())
xmlrpc.acceptClient(st.nextToken());
}
}
getLogger().log("Starting XML-RPC server on port " + (xmlrpcPort));
}
if (rmiPort != null) {
if (paranoid) {
HelmaSocketFactory factory = new HelmaSocketFactory();
String rallow = sysProps.getProperty("allowWeb");
if (rallow == null) {
rallow = sysProps.getProperty("allowRMI");
}
if (rallow != null) {
StringTokenizer st = new StringTokenizer(rallow, " ,;");
while (st.hasMoreTokens())
factory.addAddress(st.nextToken());
}
RMISocketFactory.setSocketFactory(factory);
}
getLogger().log("Starting RMI server on port " + rmiPort);
LocateRegistry.createRegistry(rmiPort.getPort());
// create application manager which binds to the given RMI port
appManager = new ApplicationManager(hopHome, appsProps, this, rmiPort.getPort());
} else {
// create application manager with RMI port 0
appManager = new ApplicationManager(hopHome, appsProps, this, 0);
}
if (xmlrpc != null) {
xmlrpc.addHandler("$default", appManager);
}
// add shutdown hook to close running apps and servers on exit
Runtime.getRuntime().addShutdownHook(new HelmaShutdownHook(appManager));
} catch (Exception gx) {
getLogger().log("Error initializing embedded database: " + gx);
gx.printStackTrace();
return;
}
// set the security manager.
// the default implementation is helma.main.HelmaSecurityManager.
try {
String secManClass = sysProps.getProperty("securityManager");
if (secManClass != null) {
SecurityManager secMan = (SecurityManager) Class.forName(secManClass)
.newInstance();
System.setSecurityManager(secMan);
getLogger().log("Setting security manager to " + secManClass);
}
} catch (Exception x) {
getLogger().log("Error setting security manager: " + x);
}
// start applications
appManager.startAll();
// start embedded web server
if (http != null) {
try {
http.start();
} catch (MultiException m) {
getLogger().log("Error starting embedded web server: " + m);
}
}
if (ajp13 != null) {
try {
ajp13.start();
} catch (Exception m) {
getLogger().log("Error starting AJP13 listener: " + m);
}
}
while (Thread.currentThread() == mainThread) {
try {
Thread.sleep(3000L);
} catch (InterruptedException ie) {
}
try {
appManager.checkForChanges();
} catch (Exception x) {
getLogger().log("Caught in app manager loop: " + x);
}
}
}
/**
* Get an Iterator over the applications currently running on this Server.
*/
public Object[] getApplications() {
return appManager.getApplications();
}
/**
* Get an Application by name
*/
public Application getApplication(String name) {
return appManager.getApplication(name);
}
/**
* Get a logger to use for output in this server.
*/
public static Logger getLogger() {
if (logger == null) {
String logDir = sysProps.getProperty("logdir", "log");
if ("console".equalsIgnoreCase(logDir)) {
logger = new Logger(System.out);
} else {
File helper = new File(logDir);
if ((hopHome != null) && !helper.isAbsolute()) {
helper = new File(hopHome, logDir);
}
logDir = helper.getAbsolutePath();
logger = Logger.getLogger(logDir, "hop");
}
}
return logger;
}
/**
* Get the Home directory of this server.
*/
public File getHopHome() {
return hopHome;
}
/**
* Get the main Server instance.
*/
public static Server getServer() {
return server;
}
/**
* Get the Server's XML-RPC web server.
*/
public static WebServer getXmlRpcServer() {
return server.xmlrpc;
}
/**
* A primitive method to check whether a server is already running on our port.
*/
private void checkRunning(InetAddrPort addrPort) throws Exception {
InetAddress addr = addrPort.getInetAddress();
if (addr == null) {
addr = InetAddress.getLocalHost();
}
try {
new Socket(addr, addrPort.getPort());
} catch (IOException x) {
// we couldn't connect to the socket because no server
// is running on it yet. Everything's ok.
return;
}
// if we got so far, another server is already running on this port and db
throw new Exception("Error: Server already running on this port: " + addrPort);
}
/**
*
*
* @param key ...
*
* @return ...
*/
public String getProperty(String key) {
return (String) sysProps.get(key);
}
/**
*
*
* @return ...
*/
public SystemProperties getProperties() {
return sysProps;
}
/**
*
*
* @return ...
*/
public SystemProperties getDbProperties() {
return dbProps;
}
/**
*
*
* @return ...
*/
public File getAppsHome() {
String appHome = sysProps.getProperty("appHome", "");
if (appHome.trim().length() != 0) {
return new File(appHome);
} else {
return new File(hopHome, "apps");
}
}
/**
*
*
* @return ...
*/
public File getDbHome() {
String dbHome = sysProps.getProperty("dbHome", "");
if (dbHome.trim().length() != 0) {
return new File(dbHome);
} else {
return new File(hopHome, "db");
}
}
/**
*
*
* @return ...
*/
public Vector getExtensions() {
return extensions;
}
/**
*
*
* @param name ...
*/
public void startApplication(String name) {
appManager.start(name);
appManager.register(name);
}
/**
*
*
* @param name ...
*/
public void stopApplication(String name) {
appManager.stop(name);
}
/**
* method from helma.framework.IPathElement
*/
public String getElementName() {
return "root";
}
/**
* method from helma.framework.IPathElement,
* returning active applications
*/
public IPathElement getChildElement(String name) {
return appManager.getApplication(name);
}
/**
* method from helma.framework.IPathElement
*/
public IPathElement getParentElement() {
return null;
}
/**
* method from helma.framework.IPathElement
*/
public String getPrototype() {
return "root";
}
}

View file

@ -1,52 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.main.launcher;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.CodeSource;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Policy;
import java.util.Hashtable;
/**
* ClassLoader that is able to exclude certain packages from loading.
*/
public class FilteredClassLoader extends URLClassLoader {
/**
* Create a server wide class loader that doesn't see the scripting engine(s)
* embedded in helma.jar. These files should be loaded by the per-application
* class loaders so that special security policies can be applied to them and
* so that they can load classes from jar files in the app directories.
*/
public FilteredClassLoader(URL[] urls) {
super(urls, null);
}
/**
* Mask classes that implement the scripting engine(s) contained in helma.jar
*/
protected Class findClass(String name) throws ClassNotFoundException {
if ((name != null) && (name.startsWith("helma")) &&
(name.endsWith("PhantomEngine"))) {
throw new ClassNotFoundException(name);
}
return super.findClass(name);
}
}

View file

@ -1,152 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.main.launcher;
import java.io.File;
import java.io.FilenameFilter;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.security.Policy;
import java.util.ArrayList;
/**
* Helma bootstrap class. Figures out Helma home directory, sets up class path and
* lauchnes main class. This class must be invoked from a jar file in order to work.
*/
public class Main {
public static final String[] jars = {
"helma.jar", "jetty.jar", "crimson.jar",
"xmlrpc.jar", "servlet.jar", "regexp.jar",
"mail.jar", "activation.jar",
"netcomponents.jar", "jimi.jar",
"apache-dom.jar", "jdom.jar"
};
/**
*
*
* @param args ...
*
* @throws Exception ...
*/
public static void main(String[] args) throws Exception {
// check if home directory is set via command line arg. If not,
// we'll get it from the location of the jar file this class
// has been loaded from.
String installDir = null;
// first, try to get helma home dir from command line options
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-i") && ((i + 1) < args.length)) {
installDir = args[i + 1];
}
}
URLClassLoader apploader = (URLClassLoader) ClassLoader.getSystemClassLoader();
// try to get Helma installation directory
if (installDir == null) {
try {
URL launcherUrl = apploader.findResource("helma/main/launcher/Main.class");
// this is a JAR URL of the form
// jar:<url>!/{entry}
// we strip away the jar: prefix and the !/{entry} suffix
// to get the original jar file URL
String jarUrl = launcherUrl.toString();
if (!jarUrl.startsWith("jar:") || jarUrl.indexOf("!") < 0) {
throw new RuntimeException(" Unable to get JAR URL from "+jarUrl);
}
jarUrl = jarUrl.substring(4);
int excl = jarUrl.indexOf("!");
jarUrl = jarUrl.substring(0, excl);
launcherUrl = new URL(jarUrl);
File f = new File(launcherUrl.getPath());
installDir = f.getParentFile().getCanonicalPath();
} catch (Exception x) {
// unable to get Helma installation dir from launcher jar
System.err.println("Unable to get Helma installation directory: ");
System.err.println(x.getMessage());
System.exit(2);
}
}
// decode installDir in case it is URL-encoded
installDir = URLDecoder.decode(installDir);
// set up the class path
File libdir = new File(installDir, "lib");
ArrayList jarlist = new ArrayList();
for (int i = 0; i < jars.length; i++) {
File jar = new File(libdir, jars[i]);
jarlist.add(new URL("file:" + jar.getAbsolutePath()));
}
// add all jar files from the lib/ext directory
File extdir = new File(libdir, "ext");
File[] files = extdir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
String n = name.toLowerCase();
return n.endsWith(".jar") || n.endsWith(".zip");
}
});
if (files != null) {
for (int i = 0; i < files.length; i++) {
// WORKAROUND: add the files in lib/ext before
// lib/apache-dom.jar, since otherwise putting a full version
// of Xerces in lib/ext would cause a version conflict with the
// xerces classes in lib/apache-dom.jar. Generally, having some pieces
// of Xerces in lib/apache-dom.jar is kind of problematic.
jarlist.add(jars.length - 3, new URL("file:" +
files[i].getAbsolutePath()));
System.err.println("Adding to classpath: " + files[i].getAbsolutePath());
}
}
URL[] urls = new URL[jarlist.size()];
jarlist.toArray(urls);
FilteredClassLoader loader = new FilteredClassLoader(urls);
// set the new class loader as context class loader
Thread.currentThread().setContextClassLoader(loader);
// get the main server class
Class clazz = loader.loadClass("helma.main.Server");
Class[] cargs = new Class[] { args.getClass() };
Method main = clazz.getMethod("main", cargs);
Object[] nargs = new Object[] { args };
// run
main.invoke(null, nargs);
}
}

View file

@ -1,3 +0,0 @@
Main-Class: helma.main.launcher.Main

View file

@ -1,33 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.objectmodel;
/**
* Thrown when more than one thrad tries to modify a Node. The evaluator
* will normally catch this and try again after a period of time.
*/
public class ConcurrencyException extends RuntimeException {
/**
* Creates a new ConcurrencyException object.
*
* @param msg ...
*/
public ConcurrencyException(String msg) {
super(msg);
}
}

View file

@ -1,32 +0,0 @@
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile$
* $Author$
* $Revision$
* $Date$
*/
package helma.objectmodel;
/**
* Thrown on any kind of Database-Error
*/
public class DatabaseException extends RuntimeException {
/**
* Creates a new DatabaseException object.
*
* @param msg ...
*/
public DatabaseException(String msg) {
super(msg);
}
}

Some files were not shown because too many files have changed in this diff Show more