diff --git a/rapla-source-1.8.2/.classpath b/rapla-source-1.8.2/.classpath new file mode 100644 index 0000000..616d858 --- /dev/null +++ b/rapla-source-1.8.2/.classpath @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rapla-source-1.8.2/.gitignore b/rapla-source-1.8.2/.gitignore new file mode 100644 index 0000000..d28b952 --- /dev/null +++ b/rapla-source-1.8.2/.gitignore @@ -0,0 +1 @@ +/eclipse-build diff --git a/rapla-source-1.8.2/.project b/rapla-source-1.8.2/.project new file mode 100644 index 0000000..8292662 --- /dev/null +++ b/rapla-source-1.8.2/.project @@ -0,0 +1,17 @@ + + + rapla + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/rapla-source-1.8.2/.settings/org.eclipse.jdt.core.prefs b/rapla-source-1.8.2/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..838bd9d --- /dev/null +++ b/rapla-source-1.8.2/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/rapla-source-1.8.2/INSTALL.txt b/rapla-source-1.8.2/INSTALL.txt new file mode 100644 index 0000000..e743148 --- /dev/null +++ b/rapla-source-1.8.2/INSTALL.txt @@ -0,0 +1,49 @@ +This is the INSTALLING-GUIDE for the Rapla-BINARY-DISTRIBUTION + +You will find more information on our documentation pages on +http://code.google.com/p/rapla/ + +if you have downloaded the SOURCE-DISTRIBUTION you have to +!!! BUILD A BINARY-DISTRIBUTION first !!! +For more information read README-BUILD.txt. + +Requirements: + +You need JAVA: JRE 1.6 at least (1.7 recommended). +You can download it from java.com + +* The SDK works for the binary and source distribution but is very + large + +* The JRE will only work for the binary distribution (Compiler + missing) but is much smaller + + +STARTING RAPLA: + +Start rapla.exe (rapla.sh under Unix). + +To start Rapla from the command-line, you may to set the java command +in your PATH-Variable (if its not already there), + +Example: +setenv PATH $PATH:/usr/local/java/bin (Unix) +set PATH=%PATH%:c:\Programme\Java\jre\bin (Windows) + +Then type: + +rapla.sh (Unix) +rapla.bat (XP/Vista/7/8). +call rapla.bat (win NT/2000) + + +For more information visit the documentation pages on + +http://code.google.com/p/rapla/ + + +Acknowledgment +--------------- + +Rapla includes free software developed from other organizations and third parties. +For a complete list of all external libraries, take a look at legal/readme.txt diff --git a/rapla-source-1.8.2/README-Build.txt b/rapla-source-1.8.2/README-Build.txt new file mode 100644 index 0000000..9722155 --- /dev/null +++ b/rapla-source-1.8.2/README-Build.txt @@ -0,0 +1,37 @@ +This README is for building rapla from source. You will find more information and the rapla sources on + +http://code.google.com/p/rapla/ + +We recommend reading the faqs and the development documents under https://code.google.com/p/rapla/wiki/ for more information. +especially the http://code.google.com/p/rapla/wiki/BuildGuide + +We use the ant tool for our build process. Ant is the java-equivalent to make +Look at jakarta.apache.org/ant for more information. If you don't want +to use Ant read the FAQS and developers doc for alternative building. + + +Use the following batch files to start the ant.jar included with +the rapla source distribution. + +build.sh (Linux/Unix) +build.bat (Win) + +Calling build with no arguments will create a binary-distribution +in the sub-folder dist. There you will find the scripts to start rapla. (SEE INSTALL.txt) + + +You can call build with different arguments, e.g.: + + choose-target Executes the target specified in build.properties. + (default) Default target is dist-bin. + + dist-bin Creates a new Binary-Distribution in the folder dist. + build Builds a new rapla.war in the build sub-folder + clean Deletes the build sub-folder + clean-dist Deletes the dist sub-folder + javadocs create the Javadoc in the build sub-folder + +Pass the target as a parameter to ant +e.g. build.sh dist-bin + +For a complete list of all targets use the -projecthelp option diff --git a/rapla-source-1.8.2/README-Server.txt b/rapla-source-1.8.2/README-Server.txt new file mode 100644 index 0000000..41e3bc7 --- /dev/null +++ b/rapla-source-1.8.2/README-Server.txt @@ -0,0 +1,153 @@ +This README is for running Rapla as server. You will find more information on our +documentation pages on + +http://code.google.com/p/rapla/ + + +The Rapla server: +--------------------------- + +Download the binary-distribution or build one with "build dist-bin" + +You can start it with: + +raplaserver.bat (Windows) +raplaserver.sh run (Unix) + +If you want to install Rapla-Server as a SERVICE on Win NT/2000/XP/Vista/7 or linux +use the scripts in the service/bin folder to test/install/uninstall rapla as a service. + +You can also try the script service/bin/TestWrapper instead of raplaserver if it fails +because java command is not found. + +With a running server point your browser to +http://localhost:8051 + +You should see the rapla welcome screen. Click on start with webstart +and the webstart client should launch. If not launched automatically, +you should choose the webstart program from your +java installation (e.g. C:\Program Files (x86)\Java\jre7\bin\javaws.exe under Windows). + +You can login with username "admin" and empty password + +Thats it. + +Installing into another servlet container +----------------------------------------- + +If you want to use another servlet container (e.g. tomcat) you can +copy the rapla.war in the webapps folder to the webapps folder of +your servlet container. + +You need to set a jndi entry jdbc/rapladb in the servlet container if you are using a database +or resource/raplafile if you are using the file, see contexts/rapla.xml for the setting in jetty. + +See the documentation of your servelt-container for more details about how to set both entries from contexts/rapla.xml +in the container of your choice. + +Installing in Apache or IIS +---------------------------- + +You can install Jetty with apache or IIS by adding +the AJP13 listener in etc/jetty.xml. + +See http://www.eclipse.org/jetty/ for more information + +Troubleshooting: +---------------- +1. The most commen error will be long stacktrace with + "Caused by: java.net.BindException: Could not bind to port 8051" + somewhere hidden between the lines. This means that either another + rapla server is running (so stop or kill this process) or that this + port is blocked by another application. You need to configure + another the port in etc/jetty.xml + + + + + + +2. look in the troubleshooting faq under http://code.google.com/p/rapla/ + +3. Post a question to rapla-developers@lists.sourceforge.net + + +Running Multiple Rapla servers: +------------------------------- + +There is no Problem running multiple rapla servers on one computer. You just need to copy the contexts/rapla entry folder and rename it to another name and edit the entries + +Considering the original rapla.xml + / + + + raplafile + /data/data.xml + true + + + jdbc/rapladb + + + jdbc:hsqldb:data/rapla-hsqldb + db_user + your_pwd + + + + + + + rapladatasource + + raplafile + true + + + If you want a second instance running on a different context. e.g. secondRapla.xml + + /secondRapla + + + raplafile + /data/secondRapla_data.xml + true + + + jdbc/rapladb + + + jdbc:hsqldb:data/secondRapla-hsqldb + db_user + your_pwd + + + + + + + rapladatasource + + raplafile + true + + + + + +Now you should have two applications running +http://localhost:8051/ +http://localhost:8051/secondRapla/ + + +Acknowledgment +--------------- + +Rapla includes free software developed from other organizations and third parties. +For a complete list of all external libraries, take a look at legal/readme.txt + + diff --git a/rapla-source-1.8.2/bin/ant b/rapla-source-1.8.2/bin/ant new file mode 100644 index 0000000..edf97b6 --- /dev/null +++ b/rapla-source-1.8.2/bin/ant @@ -0,0 +1,302 @@ +#! /bin/sh + +# Copyright 2001-2004 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Extract launch and ant arguments, (see details below). +ant_exec_args= +no_config=false +use_jikes_default=false +ant_exec_debug=false +show_help=false +for arg in "$@" ; do + if [ "$arg" = "--noconfig" ] ; then + no_config=true + elif [ "$arg" = "--usejikes" ] ; then + use_jikes_default=true + elif [ "$arg" = "--execdebug" ] ; then + ant_exec_debug=true + elif [ my"$arg" = my"--h" -o my"$arg" = my"--help" ] ; then + show_help=true + ant_exec_args="$ant_exec_args -h" + else + if [ my"$arg" = my"-h" -o my"$arg" = my"-help" ] ; then + show_help=true + fi + ant_exec_args="$ant_exec_args \"$arg\"" + fi +done + +# Source/default ant configuration +if $no_config ; then + rpm_mode=false + usejikes=$use_jikes_default +else + # load system-wide ant configuration + if [ -f "/etc/ant.conf" ] ; then + . /etc/ant.conf + fi + + # load user ant configuration + if [ -f "$HOME/.ant/ant.conf" ] ; then + . $HOME/.ant/ant.conf + fi + if [ -f "$HOME/.antrc" ] ; then + . "$HOME/.antrc" + fi + + # provide default configuration values + if [ -z "$rpm_mode" ] ; then + rpm_mode=false + fi + if [ -z "$usejikes" ] ; then + usejikes=$use_jikes_default + fi +fi + +# Setup Java environment in rpm mode +if $rpm_mode ; then + if [ -f /usr/share/java-utils/java-functions ] ; then + . /usr/share/java-utils/java-functions + set_jvm + set_javacmd + fi +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +case "`uname`" in + CYGWIN*) cygwin=true ;; + Darwin*) darwin=true + if [ -z "$JAVA_HOME" ] ; then + JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home + fi + ;; +esac + +if [ -z "$ANT_HOME" -o ! -d "$ANT_HOME" ] ; then + # try to find ANT + if [ -d /opt/ant ] ; then + ANT_HOME=/opt/ant + fi + + if [ -d "${HOME}/opt/ant" ] ; then + ANT_HOME="${HOME}/opt/ant" + fi + + ## resolve links - $0 may be a link to ant's home + PRG="$0" + progname=`basename "$0"` + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi + done + + ANT_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + ANT_HOME=`cd "$ANT_HOME" && pwd` +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$ANT_HOME" ] && + ANT_HOME=`cygpath --unix "$ANT_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# set ANT_LIB location +ANT_LIB="${ANT_HOME}/lib" + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD=`which java 2> /dev/null ` + if [ -z "$JAVACMD" ] ; then + JAVACMD=java + fi + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." + echo " We cannot execute $JAVACMD" + exit 1 +fi + +# Build local classpath using just the launcher in non-rpm mode or +# use the Jpackage helper in rpm mode with basic and default jars +# specified in the ant.conf configuration. Because the launcher is +# used, libraries linked in ANT_HOME will also be include, but this +# is discouraged as it is not java-version safe. A user should +# request optional jars and their dependencies via the OPT_JAR_LIST +# variable +if $rpm_mode && [ -f /usr/bin/build-classpath ] ; then + LOCALCLASSPATH="$(/usr/bin/build-classpath ant ant-launcher jaxp_parser_impl xml-commons-apis)" + # If the user requested to try to add some other jars to the classpath + if [ -n "$OPT_JAR_LIST" ] ; then + _OPTCLASSPATH="$(/usr/bin/build-classpath $OPT_JAR_LIST 2> /dev/null)" + if [ -n "$_OPTCLASSPATH" ] ; then + LOCALCLASSPATH="$LOCALCLASSPATH:$_OPTCLASSPATH" + fi + fi + + # Explicitly add javac path to classpath, assume JAVA_HOME set + # properly in rpm mode + if [ -f "$JAVA_HOME/lib/tools.jar" ] ; then + LOCALCLASSPATH="$LOCALCLASSPATH:$JAVA_HOME/lib/tools.jar" + fi + if [ -f "$JAVA_HOME/lib/classes.zip" ] ; then + LOCALCLASSPATH="$LOCALCLASSPATH:$JAVA_HOME/lib/classes.zip" + fi + + # if CLASSPATH_OVERRIDE env var is set, LOCALCLASSPATH will be + # user CLASSPATH first and ant-found jars after. + # In that case, the user CLASSPATH will override ant-found jars + # + # if CLASSPATH_OVERRIDE is not set, we'll have the normal behaviour + # with ant-found jars first and user CLASSPATH after + if [ -n "$CLASSPATH" ] ; then + # merge local and specified classpath + if [ -z "$LOCALCLASSPATH" ] ; then + LOCALCLASSPATH="$CLASSPATH" + elif [ -n "$CLASSPATH_OVERRIDE" ] ; then + LOCALCLASSPATH="$CLASSPATH:$LOCALCLASSPATH" + else + LOCALCLASSPATH="$LOCALCLASSPATH:$CLASSPATH" + fi + + # remove class path from launcher -lib option + CLASSPATH="" + fi +else + # not using rpm_mode; use launcher to determine classpaths + if [ -z "$LOCALCLASSPATH" ] ; then + LOCALCLASSPATH=$ANT_LIB/ant-launcher.jar + else + LOCALCLASSPATH=$ANT_LIB/ant-launcher.jar:$LOCALCLASSPATH + fi +fi + +if [ -n "$JAVA_HOME" ] ; then + # OSX hack to make Ant work with jikes + if $darwin ; then + OSXHACK="${JAVA_HOME}/../Classes" + if [ -d "${OSXHACK}" ] ; then + for i in "${OSXHACK}"/*.jar + do + JIKESPATH="$JIKESPATH:$i" + done + fi + fi +fi + +# Allow Jikes support (off by default) +if $usejikes; then + ANT_OPTS="$ANT_OPTS -Dbuild.compiler=jikes" +fi + +# For Cygwin, switch paths to appropriate format before running java +if $cygwin; then + if [ "$OS" = "Windows_NT" ] && cygpath -m .>/dev/null 2>/dev/null ; then + format=mixed + else + format=windows + fi + ANT_HOME=`cygpath --$format "$ANT_HOME"` + ANT_LIB=`cygpath --$format "$ANT_LIB"` + JAVA_HOME=`cygpath --$format "$JAVA_HOME"` + LOCALCLASSPATH=`cygpath --path --$format "$LOCALCLASSPATH"` + if [ -n "$CLASSPATH" ] ; then + CLASSPATH=`cygpath --path --$format "$CLASSPATH"` + fi + CYGHOME=`cygpath --$format "$HOME"` +fi + +# Show script help if requested +if $show_help ; then + echo $0 '[script options] [options] [target [target2 [target3] ..]]' + echo 'Script Options:' + echo ' --help, --h print this message and ant help' + echo ' --noconfig suppress sourcing of /etc/ant.conf,' + echo ' $HOME/.ant/ant.conf, and $HOME/.antrc' + echo ' configuration files' + echo ' --usejikes enable use of jikes by default, unless' + echo ' set explicitly in configuration files' + echo ' --execdebug print ant exec line generated by this' + echo ' launch script' + echo ' ' +fi +# add a second backslash to variables terminated by a backslash under cygwin +if $cygwin; then + case "$ANT_HOME" in + *\\ ) + ANT_HOME="$ANT_HOME\\" + ;; + esac + case "$CYGHOME" in + *\\ ) + CYGHOME="$CYGHOME\\" + ;; + esac + case "$JIKESPATH" in + *\\ ) + JIKESPATH="$JIKESPATH\\" + ;; + esac + case "$LOCALCLASSPATH" in + *\\ ) + LOCALCLASSPATH="$LOCALCLASSPATH\\" + ;; + esac + case "$CLASSPATH" in + *\\ ) + CLASSPATH="$CLASSPATH\\" + ;; + esac +fi +# Execute ant using eval/exec to preserve spaces in paths, +# java options, and ant args +ant_sys_opts= +if [ -n "$CYGHOME" ]; then + if [ -n "$JIKESPATH" ]; then + ant_sys_opts="-Djikes.class.path=\"$JIKESPATH\" -Dcygwin.user.home=\"$CYGHOME\"" + else + ant_sys_opts="-Dcygwin.user.home=\"$CYGHOME\"" + fi +else + if [ -n "$JIKESPATH" ]; then + ant_sys_opts="-Djikes.class.path=\"$JIKESPATH\"" + fi +fi +ant_exec_command="exec \"$JAVACMD\" $ANT_OPTS -classpath \"$LOCALCLASSPATH\" -Dant.home=\"$ANT_HOME\" -Dant.library.dir=\"$ANT_LIB\" $ant_sys_opts org.apache.tools.ant.launch.Launcher $ANT_ARGS -lib \"$CLASSPATH\" $ant_exec_args" +if $ant_exec_debug ; then + echo $ant_exec_command +fi +eval $ant_exec_command diff --git a/rapla-source-1.8.2/bin/ant.bat b/rapla-source-1.8.2/bin/ant.bat new file mode 100644 index 0000000..7e2379a --- /dev/null +++ b/rapla-source-1.8.2/bin/ant.bat @@ -0,0 +1,106 @@ +@echo off + +REM Copyright 2001,2004 The Apache Software Foundation +REM +REM Licensed under the Apache License, Version 2.0 (the "License"); +REM you may not use this file except in compliance with the License. +REM You may obtain a copy of the License at +REM +REM http://www.apache.org/licenses/LICENSE-2.0 +REM +REM Unless required by applicable law or agreed to in writing, software +REM distributed under the License is distributed on an "AS IS" BASIS, +REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +REM See the License for the specific language governing permissions and +REM limitations under the License. + +if exist "%HOME%\antrc_pre.bat" call "%HOME%\antrc_pre.bat" + +if "%OS%"=="Windows_NT" @setlocal + +rem %~dp0 is expanded pathname of the current script under NT +set DEFAULT_ANT_HOME=%~dp0.. + +if "%ANT_HOME%"=="" set ANT_HOME=%DEFAULT_ANT_HOME% +set DEFAULT_ANT_HOME= + +rem Slurp the command line arguments. This loop allows for an unlimited number +rem of arguments (up to the command line limit, anyway). +set ANT_CMD_LINE_ARGS=%1 +if ""%1""=="""" goto doneStart +shift +:setupArgs +if ""%1""=="""" goto doneStart +set ANT_CMD_LINE_ARGS=%ANT_CMD_LINE_ARGS% %1 +shift +goto setupArgs +rem This label provides a place for the argument list loop to break out +rem and for NT handling to skip to. + +:doneStart +rem find ANT_HOME if it does not exist due to either an invalid value passed +rem by the user or the %0 problem on Windows 9x +if exist "%ANT_HOME%\lib\ant.jar" goto checkJava + +rem check for ant in Program Files +if not exist "%ProgramFiles%\ant" goto checkSystemDrive +set ANT_HOME=%ProgramFiles%\ant +goto checkJava + +:checkSystemDrive +rem check for ant in root directory of system drive +if not exist %SystemDrive%\ant\lib\ant.jar goto checkCDrive +set ANT_HOME=%SystemDrive%\ant +goto checkJava + +:checkCDrive +rem check for ant in C:\ant for Win9X users +if not exist C:\ant\lib\ant.jar goto noAntHome +set ANT_HOME=C:\ant +goto checkJava + +:noAntHome +echo ANT_HOME is set incorrectly or ant could not be located. Please set ANT_HOME. +goto end + +:checkJava +set _JAVACMD=%JAVACMD% + +if "%JAVA_HOME%" == "" goto noJavaHome +if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome +if "%_JAVACMD%" == "" set _JAVACMD=%JAVA_HOME%\bin\java.exe +goto checkJikes + +:noJavaHome +if "%_JAVACMD%" == "" set _JAVACMD=java.exe + +:checkJikes +if not "%JIKESPATH%"=="" goto runAntWithJikes + +:runAnt +if not "%CLASSPATH%"=="" goto runAntWithClasspath +"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% %ANT_CMD_LINE_ARGS% +goto end + +:runAntWithClasspath +"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% -lib "%CLASSPATH%" %ANT_CMD_LINE_ARGS% +goto end + +:runAntWithJikes +if not "%CLASSPATH%"=="" goto runAntWithJikesAndClasspath +"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" "-Djikes.class.path=%JIKESPATH%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% %ANT_CMD_LINE_ARGS% +goto end + +:runAntWithJikesAndClasspath +"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" "-Djikes.class.path=%JIKESPATH%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% -lib "%CLASSPATH%" %ANT_CMD_LINE_ARGS% +goto end + +:end +set _JAVACMD= +set ANT_CMD_LINE_ARGS= + +if "%OS%"=="Windows_NT" @endlocal + +:mainEnd +if exist "%HOME%\antrc_post.bat" call "%HOME%\antrc_post.bat" + diff --git a/rapla-source-1.8.2/bin/ant.cmd b/rapla-source-1.8.2/bin/ant.cmd new file mode 100644 index 0000000..94b5a45 --- /dev/null +++ b/rapla-source-1.8.2/bin/ant.cmd @@ -0,0 +1,92 @@ +/* + Copyright 2003-2004 The Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Run ant +*/ + +'@echo off' +parse arg mode envarg '::' antarg + +if mode\='.' & mode\='..' & mode\='/' then do + envarg = mode envarg + mode = '' +end + +if antarg = '' then do + antarg = envarg + envarg = '' +end + +x = setlocal() + +env="OS2ENVIRONMENT" +antenv = _getenv_('antenv') +if _testenv_() = 0 then interpret 'call "' || antenv || '"' '"' || envarg || '"' + +if mode = '' then mode = _getenv_('ANT_MODE' '..') +if mode \= '/' then do + runrc = _getenv_('runrc') + antrc = _getenv_('antrc' 'antrc.cmd') + if mode = '..' then mode = '-r' + else mode = '' + interpret 'call "' || runrc || '"' antrc '"' || mode || '"' +end + +if _testenv_() = 0 then do + say 'Ant environment is not set properly' + x = endlocal() + exit 16 +end + +settings = '-Dant.home=' || ANT_HOME '-Djava.home=' || JAVA_HOME + +java = _getenv_('javacmd' 'java') +opts = value('ANT_OPTS',,env) +args = value('ANT_ARGS',,env) +lcp = value('LOCALCLASSPATH',,env) +cp = value('CLASSPATH',,env) +if value('ANT_USE_CP',,env) \= '' then do + if lcp \= '' & right(lcp, 1) \= ';' then lcp = lcp || ';' + lcp = lcp || cp + 'SET CLASSPATH=' +end +if lcp\='' then lcp = '-classpath' lcp + +cmd = java opts lcp '-jar' ANT_HOME ||'\lib\ant-launcher.jar' settings args antarg +launcher = stream(ANT_HOME ||'\lib\ant-launcher.jar', 'C', 'query exists') +if launcher = '' then entry = 'org.apache.tools.ant.Main' +else entry = 'org.apache.tools.ant.launch.Launcher' +java opts lcp entry settings args antarg + +x = endlocal() + +return rc + +_testenv_: procedure expose env ANT_HOME JAVA_HOME +ANT_HOME = value('ANT_HOME',,env) +if ANT_HOME = '' then return 0 +JAVA_HOME = value('JAVA_HOME',,env) +if JAVA_HOME = '' then return 0 +cp = translate(value('CLASSPATH',,env)) +if pos(translate(ANT_HOME), cp) = 0 then return 0 +if pos(translate(JAVA_HOME), cp) = 0 then return 0 +return 1 + +_getenv_: procedure expose env +parse arg envar default +if default = '' then default = envar +var = value(translate(envar),,env) +if var = '' then var = default +return var diff --git a/rapla-source-1.8.2/bin/antRun b/rapla-source-1.8.2/bin/antRun new file mode 100644 index 0000000..baddd71 --- /dev/null +++ b/rapla-source-1.8.2/bin/antRun @@ -0,0 +1,26 @@ +#!/bin/sh + +# +# Copyright 2001-2002,2004 The Apache Software Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +# Args: DIR command +cd "$1" +CMD="$2" +shift +shift + +exec "$CMD" "$@" diff --git a/rapla-source-1.8.2/bin/antRun.bat b/rapla-source-1.8.2/bin/antRun.bat new file mode 100644 index 0000000..204d9e3 --- /dev/null +++ b/rapla-source-1.8.2/bin/antRun.bat @@ -0,0 +1,45 @@ +@echo off + +REM +REM Copyright 2001-2002,2004 The Apache Software Foundation +REM +REM Licensed under the Apache License, Version 2.0 (the "License"); +REM you may not use this file except in compliance with the License. +REM You may obtain a copy of the License at +REM +REM http://www.apache.org/licenses/LICENSE-2.0 +REM +REM Unless required by applicable law or agreed to in writing, software +REM distributed under the License is distributed on an "AS IS" BASIS, +REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +REM See the License for the specific language governing permissions and +REM limitations under the License. +REM +REM + +if "%OS%"=="Windows_NT" @setlocal + +if ""%1""=="""" goto runCommand + +rem Change drive and directory to %1 +if "%OS%"=="Windows_NT" cd /d ""%1"" +if not "%OS%"=="Windows_NT" cd ""%1"" +shift + +rem Slurp the command line arguments. This loop allows for an unlimited number +rem of agruments (up to the command line limit, anyway). +set ANT_RUN_CMD=%1 +if ""%1""=="""" goto runCommand +shift +:loop +if ""%1""=="""" goto runCommand +set ANT_RUN_CMD=%ANT_RUN_CMD% %1 +shift +goto loop + +:runCommand +rem echo %ANT_RUN_CMD% +%ANT_RUN_CMD% + +if "%OS%"=="Windows_NT" @endlocal + diff --git a/rapla-source-1.8.2/bin/antenv.cmd b/rapla-source-1.8.2/bin/antenv.cmd new file mode 100644 index 0000000..05efa85 --- /dev/null +++ b/rapla-source-1.8.2/bin/antenv.cmd @@ -0,0 +1,99 @@ +/* + Copyright 2003-2004 The Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Ant environment +*/ + +'@echo off' +call RxFuncAdd "SysLoadFuncs", "RexxUtil", "SysLoadFuncs" +call SysLoadFuncs + +/* Prepare the parameters for later use */ +parse arg argv +mode = '' +args = '' +opts = '' +cp = '' +lcp = '' + +do i = 1 to words(argv) + param = word(argv, i) + select + when param='-lcp' then mode = 'l' + when param='-cp' | param='-classpath' then mode = 'c' + when abbrev('-opts', param, 4) then mode = 'o' + when abbrev('-args', param, 4) then mode = 'a' + otherwise + select + when mode = 'a' then args = space(args param, 1) + when mode = 'c' then cp = space(cp param, 1) + when mode = 'l' then lcp = space(lcp param, 1) + when mode = 'o' then opts = space(opts param, 1) + otherwise + say 'Option' param 'ignored' + end + end +end + +env="OS2ENVIRONMENT" +antconf = _getenv_('antconf' 'antconf.cmd') +runrc = _getenv_('runrc') +interpret 'call "' || runrc || '"' '"' || antconf || '"' 'ETC' +ANT_HOME = value('ANT_HOME',,env) +JAVA_HOME = value('JAVA_HOME',,env) +classpath = value('CLASSPATH',,env) +classes = stream(JAVA_HOME || "\lib\classes.zip", "C", "QUERY EXISTS") +if classes \= '' then classpath = prepend(classpath classes) +classes = stream(JAVA_HOME || "\lib\tools.jar", "C", "QUERY EXISTS") +if classes \= '' then classpath = prepend(classpath classes) + +classpath = prepend(classpath ANT_HOME || '\lib\ant-launcher.jar') +'SET CLASSPATH=' || classpath + +/* Setting classpathes, options and arguments */ +envset = _getenv_('envset') +if cp\='' then interpret 'call "' || envset || '"' '"; CLASSPATH"' '"' || cp || '"' +if lcp\='' then interpret 'call "' || envset || '"' '"; LOCALCLASSPATH"' '"' || lcp || '"' +if opts\='' then interpret 'call "' || envset || '"' '"-D ANT_OPTS"' '"' || opts || '"' +if args\='' then interpret 'call "' || envset || '"' '"ANT_ARGS"' '"' || args || '"' + +exit 0 + +addpath: procedure +parse arg path elem +if elem = '' then do + if path\='' & right(path, 1)\=';' then path = path || ';' + return path +end +if substr(path, length(path)) = ';' then glue = '' +else glue = ';' +if pos(translate(elem), translate(path)) = 0 then path = path || glue || elem || ';' +return path + +prepend: procedure +parse arg path elem +if elem = '' then do + if path\='' & right(path, 1)\=';' then path = path || ';' + return path +end +if pos(translate(elem), translate(path)) = 0 then path = elem || ';' || path +return path + +_getenv_: procedure expose env +parse arg envar default +if default = '' then default = envar +var = value(translate(envar),,env) +if var = '' then var = default +return var diff --git a/rapla-source-1.8.2/bin/envset.cmd b/rapla-source-1.8.2/bin/envset.cmd new file mode 100644 index 0000000..8fbd4dd --- /dev/null +++ b/rapla-source-1.8.2/bin/envset.cmd @@ -0,0 +1,130 @@ +/* + + Copyright 2003-2004 The Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +SET environment variables +First optional parameter: + ; parameters are considered parts of a path variable, semicolons are + appended to each element if not already present + -D parameters are properties for Java or Makefile etc., -D will be + prepended and the parameters will be separated by a space + =D the same as above but equal sign is not required + , parameters should be comma separated in the environment variable + - parameters should be separated by the next parameter + Other values mean that the first parameter is missing and the environment + variable will be set to the space separated parameters + +Second parameter: name of the environment variable + +Next parameters: values +; implies that the equal sign is considered a part of the parameter and is +not interpreted + +-D requires parameters in the form name=value. If the equal sign is not found, +the parameters are changed to name=expanded_name + +Other options have optional equal sign. If it is found, only the part after +the equal sign will be oprionally expanded. + +If the parameter is the minus sign, the next parameter will not be expanded. +If the parameter is a single dot, it will be replaced with the value of the +environment variable as it existed before envset was invoked. + +For other parameters the batch looks for the environment variable with the +same name (in uppercase). If it is found, it forms the expanded_name. If +the environment variable with such a name does not exist, the expanded_name +will hold the parameter name without case conversion. +*/ + +parse arg mode envar args + +equal = 0 +sep = ' ' + +/* Parse command line parameters */ +select + when mode='-' then do + sep = envar + parse var args envar args + end + when mode=';' then do + sep = '' + equal = -1 + end + when mode='-D' then equal = 1 + when mode='=D' then mode = '-D' + when mode=',' then sep = ',' +otherwise + args = envar args + envar = mode + mode = '' +end + +env = 'OS2ENVIRONMENT' +envar = translate(envar) +orig = value(envar,,env) +newval = '' +expand = 1 + +/* for each parameter... */ +do i = 1 to words(args) + if expand > 0 & word(args, i) = '-' then expand = 0 + else call addval word(args, i) +end + +/* Optionally enclose path variable by quotes */ +if mode = ';' & pos(' ', newval) > 0 then newval = '"' || newval || '"' + +/* Set the new value, 'SET' cannot be used since it does not allow '=' */ +x = value(envar, newval, env) +exit 0 + +addval: procedure expose sep equal orig expand newval mode env +parse arg var + +if var = '.' then expvar = orig +else do + if equal >= 0 then do + parse var var name '=' val + if val = '' then var = name + else var = val + end + if expand = 0 then expvar = var + else expvar = value(translate(var),,env) + if expvar = '' then expvar = var + if equal >= 0 then do + if val = '' then do + parse var expvar key '=' val + if val <> '' then name = key + else do + if equal > 0 then val = key + else name = key + end + end + else val = expvar + if pos(' ', val) > 0 | pos('=', val) > 0 then val = '"' || val || '"' + if val = '' then expvar = name + else expvar = name || '=' || val + end + if mode = '-D' then expvar = '-D' || expvar + if mode = ';' then do + if right(expvar, 1) <> ';' then expvar = expvar || ';' + end +end + +if newval = '' then newval = expvar +else newval = newval || sep || expvar +expand = 1 +return diff --git a/rapla-source-1.8.2/bin/lcp.bat b/rapla-source-1.8.2/bin/lcp.bat new file mode 100644 index 0000000..6a1f679 --- /dev/null +++ b/rapla-source-1.8.2/bin/lcp.bat @@ -0,0 +1,30 @@ +REM +REM Copyright 2001-2004 The Apache Software Foundation +REM +REM Licensed under the Apache License, Version 2.0 (the "License"); +REM you may not use this file except in compliance with the License. +REM You may obtain a copy of the License at +REM +REM http://www.apache.org/licenses/LICENSE-2.0 +REM +REM Unless required by applicable law or agreed to in writing, software +REM distributed under the License is distributed on an "AS IS" BASIS, +REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +REM See the License for the specific language governing permissions and +REM limitations under the License. +REM +REM + +set _CLASSPATHCOMPONENT=%1 +if ""%1""=="""" goto gotAllArgs +shift + +:argCheck +if ""%1""=="""" goto gotAllArgs +set _CLASSPATHCOMPONENT=%_CLASSPATHCOMPONENT% %1 +shift +goto argCheck + +:gotAllArgs +set LOCALCLASSPATH=%_CLASSPATHCOMPONENT%;%LOCALCLASSPATH% + diff --git a/rapla-source-1.8.2/bin/runrc.cmd b/rapla-source-1.8.2/bin/runrc.cmd new file mode 100644 index 0000000..acdf724 --- /dev/null +++ b/rapla-source-1.8.2/bin/runrc.cmd @@ -0,0 +1,59 @@ +/* + Copyright 2003-2004 The Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Run RC file, name is in the first arg, second arg is either PATH + ENV or -r or nothing +*/ + +parse arg name path rest + +if name = '' then do + say 'RC file name is missing' + exit 1 +end + +if rest \= '' then do + say 'Too many parameters' + exit 1 +end + +call runit name path +exit 0 + +runit: procedure +parse arg name path dir + +if path \= '' & path \= '-r' then do + dir = value(translate(path),,'OS2ENVIRONMENT') + if dir = '' then return + dir = translate(dir, '\', '/') /* change UNIX-like path to OS/2 */ +end + +if dir = '' then dir = directory() + +if path = '-r' then do /* recursive call */ + subdir = filespec('path', dir) + if subdir \= '\' then do + subdir = left(subdir, length(subdir)-1) + call runit name path filespec('drive', dir) || subdir + end +end + +/* Look for the file and run it */ +if right(dir, 1) \= '\' then dir = dir || '\' +rcfile = stream(dir || name, 'c', 'query exists') +if rcfile \= '' then interpret 'call "' || rcfile || '"' + +return diff --git a/rapla-source-1.8.2/build.bat b/rapla-source-1.8.2/build.bat new file mode 100644 index 0000000..4174471 --- /dev/null +++ b/rapla-source-1.8.2/build.bat @@ -0,0 +1,13 @@ +@echo off +:: ------------------------------------------------------------------------- +:: build.bat Skript for Rapla +:: +:: +:: Usage: +:: for a list of all available build-targets type +:: .\build.bat -projecthelp +if not "%ANT_HOME%" =="" goto gotAntHome +set ANT_HOME=. +:gotAntHome +call %ANT_HOME%\bin\ant.bat %1 %2 %3 %4 %5 %6 +pause diff --git a/rapla-source-1.8.2/build.properties.template b/rapla-source-1.8.2/build.properties.template new file mode 100644 index 0000000..6d157b9 --- /dev/null +++ b/rapla-source-1.8.2/build.properties.template @@ -0,0 +1,22 @@ +# You can modify this settings to configure the build + +#Set the target that will be run by default +target=dist-bin + +#use this to perform a clean before each build +#clean.everytime + +#The base folder where all plugin source projects are located +plugin.base=${main.dir}/.. +#You can choose plugin directories to include in the build +#plugin.includes=rapla.demo-p,rapla.periodwizard-p +#plugin.includes=rapla.nothing-p +plugin.includes=rapla.* + +#Class for testing rapla when using the "test" target +#test.class=org.rapla.entities.PreferencesTest + +#Path and password to the keystore used for signing +keystore.file=raplaselfsigned.ks +keystore.password=raplaselfsigned +#keystore.keypass= diff --git a/rapla-source-1.8.2/build.sh b/rapla-source-1.8.2/build.sh new file mode 100644 index 0000000..fe85d15 --- /dev/null +++ b/rapla-source-1.8.2/build.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# Usage: +# +# for a list of all available build-targets type +# ./build.sh -projecthelp +# +chmod u+x ./bin/antRun +chmod u+x ./bin/ant +export ANT_HOME=. +$PWD/bin/ant -logger org.apache.tools.ant.NoBannerLogger -emacs $@ diff --git a/rapla-source-1.8.2/build.xml b/rapla-source-1.8.2/build.xml new file mode 100644 index 0000000..1109f0d --- /dev/null +++ b/rapla-source-1.8.2/build.xml @@ -0,0 +1,1066 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + +
+
+ + + + + + + +
+ + + + +
+ + + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${prop.dist.contents} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/rapla-source-1.8.2/buildplugin.xml b/rapla-source-1.8.2/buildplugin.xml new file mode 100644 index 0000000..3e3e314 --- /dev/null +++ b/rapla-source-1.8.2/buildplugin.xml @@ -0,0 +1,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ diff --git a/rapla-source-1.8.2/contexts/rapla-develop.xml b/rapla-source-1.8.2/contexts/rapla-develop.xml new file mode 100644 index 0000000..d589286 --- /dev/null +++ b/rapla-source-1.8.2/contexts/rapla-develop.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + /war + + + + + / + + + raplafile + /data/data.xml + true + + + + rapla_development + true + true + + + + jdbc/rapladb + + + + + jdbc:hsqldb:/data/rapla-hsqldb + db_user + your_pwd + + + + + + + + + + + + rapladatasource + + raplafile + true + + + + + + /etc/webdefault.xml + 10000000 + true + true + true + + + + org.eclipse.jetty.webapp.WebInfConfiguration + org.eclipse.jetty.webapp.WebXmlConfiguration + org.eclipse.jetty.webapp.MetaInfConfiguration + org.eclipse.jetty.webapp.FragmentConfiguration + org.eclipse.jetty.plus.webapp.EnvConfiguration + org.eclipse.jetty.webapp.JettyWebXmlConfiguration + org.eclipse.jetty.webapp.TagLibConfiguration + org.eclipse.jetty.plus.webapp.PlusConfiguration + + + + diff --git a/rapla-source-1.8.2/contexts/rapla.xml_ b/rapla-source-1.8.2/contexts/rapla.xml_ new file mode 100644 index 0000000..a5ac1a4 --- /dev/null +++ b/rapla-source-1.8.2/contexts/rapla.xml_ @@ -0,0 +1,84 @@ + + + + + /webapps/rapla.war + / + + + + + raplafile + /data/data.xml + true + + + + + jdbc/rapladb + + + + + jdbc:hsqldb:/data/rapla-hsqldb + db_user + your_pwd + + + + + + + + + + + + + rapladatasource + + raplafile + true + + + + + + + /etc/webdefault.xml + + 10000000 + true + true + true + false + + + + org.eclipse.jetty.webapp.WebInfConfiguration + org.eclipse.jetty.webapp.WebXmlConfiguration + org.eclipse.jetty.webapp.MetaInfConfiguration + org.eclipse.jetty.webapp.FragmentConfiguration + org.eclipse.jetty.plus.webapp.EnvConfiguration + org.eclipse.jetty.webapp.JettyWebXmlConfiguration + org.eclipse.jetty.webapp.TagLibConfiguration + org.eclipse.jetty.plus.webapp.PlusConfiguration + + + + diff --git a/rapla-source-1.8.2/data/data.xml b/rapla-source-1.8.2/data/data.xml new file mode 100644 index 0000000..5bcc0aa --- /dev/null +++ b/rapla-source-1.8.2/data/data.xml @@ -0,0 +1,114 @@ + + + + + user-groups + + See events of other users + + + create events + + + + + + + + Resource + + {name} + resource + automatic + + + Name + + + + + + + + + + Person + + {surname} {firstname} + person + + + surname + + + + First name + + + + Email + + + + + + + + + + Event + + {name} + reservation + + + eventname + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + test + + + + + + + + + + diff --git a/rapla-source-1.8.2/doc.properties b/rapla-source-1.8.2/doc.properties new file mode 100644 index 0000000..2da538f --- /dev/null +++ b/rapla-source-1.8.2/doc.properties @@ -0,0 +1,8 @@ +doc.name=rapla +doc.version=1.8.2 +doc.date=${TODAY} +doc.year=2000-2015 +doc.copyright=Rapla Team +doc.developer-list-link=http://lists.sourceforge.net/lists/listinfo/rapla-developers +doc.developer-list=rapla-developers@lists.sourceforge.net +doc.homepage=http://code.google.com/p/rapla diff --git a/rapla-source-1.8.2/etc/jetty.xml b/rapla-source-1.8.2/etc/jetty.xml new file mode 100644 index 0000000..d7bceb1 --- /dev/null +++ b/rapla-source-1.8.2/etc/jetty.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + 2 + 50 + + + + + + + + + + + + + + + 30000 + 2 + 8443 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /resources/logback-access.xml + + + + + + + + + + + + + + /contexts + 1 + + + + + + + + + + + true + + true + + diff --git a/rapla-source-1.8.2/etc/webdefault.xml b/rapla-source-1.8.2/etc/webdefault.xml new file mode 100644 index 0000000..4120faf --- /dev/null +++ b/rapla-source-1.8.2/etc/webdefault.xml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + Default web.xml file. + This file is applied to a Web application before it's own WEB_INF/web.xml file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + default + org.eclipse.jetty.servlet.DefaultServlet + + acceptRanges + true + + + dirAllowed + true + + + redirectWelcome + false + + + maxCacheSize + 2000000 + + + maxCachedFileSize + 254000 + + + maxCachedFiles + 1000 + + + gzip + false + + + useFileMappedBuffer + false + + 0 + + + default / + + + + + + + + 30 + + + + + + + + + + + + + index.html + index.htm + index.jsp + + + + + arISO-8859-6 + beISO-8859-5 + bgISO-8859-5 + caISO-8859-1 + csISO-8859-2 + daISO-8859-1 + deISO-8859-1 + elISO-8859-7 + enISO-8859-1 + esISO-8859-1 + etISO-8859-1 + fiISO-8859-1 + frISO-8859-1 + hrISO-8859-2 + huISO-8859-2 + isISO-8859-1 + itISO-8859-1 + iwISO-8859-8 + jaShift_JIS + koEUC-KR + ltISO-8859-2 + lvISO-8859-2 + mkISO-8859-5 + nlISO-8859-1 + noISO-8859-1 + plISO-8859-2 + ptISO-8859-1 + roISO-8859-2 + ruISO-8859-5 + shISO-8859-5 + skISO-8859-2 + slISO-8859-2 + sqISO-8859-2 + srISO-8859-5 + svISO-8859-1 + trISO-8859-9 + ukISO-8859-5 + zhGB2312 + zh_TWBig5 + + + + + + diff --git a/rapla-source-1.8.2/legal/license.txt b/rapla-source-1.8.2/legal/license.txt new file mode 100644 index 0000000..e629796 --- /dev/null +++ b/rapla-source-1.8.2/legal/license.txt @@ -0,0 +1,676 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, 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 +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + + diff --git a/rapla-source-1.8.2/legal/license_GPL2_with_classpath_exception.txt b/rapla-source-1.8.2/legal/license_GPL2_with_classpath_exception.txt new file mode 100644 index 0000000..79c6b4e --- /dev/null +++ b/rapla-source-1.8.2/legal/license_GPL2_with_classpath_exception.txt @@ -0,0 +1,363 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 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. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, 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 or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +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 give any other recipients of the Program a copy of this License +along with the Program. + +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 Program or any portion +of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +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 Program, 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 Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) 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; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, 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 executable. However, as a +special exception, the source code 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. + +If distribution of executable or 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 counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program 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. + + 5. 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 Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program 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 to +this License. + + 7. 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 Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program 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 Program. + +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. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program 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. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 Program +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 Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, 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 + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), 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 Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. 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. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; 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. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + + +"CLASSPATH" EXCEPTION TO THE GPL VERSION 2 + +Certain source files distributed by Oracle are subject to the following clarification +and special exception to the GPL Version 2, but only where Oracle has expressly included +in the particular source file's header the words "Oracle designates this particular +file as subject to the "Classpath" exception as provided by Oracle in the License +file that accompanied this code." + +Linking this library statically or dynamically with other modules is making a combined +work based on this library. Thus, the terms and conditions of the +GNU General Public License Version 2 cover the whole combination. + +As a special exception, the copyright holders of this library give you permission +to link this library with independent modules to produce an executable, regardless +of the license terms of these independent modules, and to copy and distribute the +resulting executable under terms of your choice, provided that you also meet, +for each linked independent module, the terms and conditions of the license of that module. +An independent module is a module which is not derived from or based on this library. +If you modify this library, you may extend this exception to your version of the library, +but you are not obligated to do so. If you do not wish to do so, +delete this exception statement from your version. diff --git a/rapla-source-1.8.2/legal/license_LGPL.txt b/rapla-source-1.8.2/legal/license_LGPL.txt new file mode 100644 index 0000000..89315f4 --- /dev/null +++ b/rapla-source-1.8.2/legal/license_LGPL.txt @@ -0,0 +1,437 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 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 library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + 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 Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, 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 or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the 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 a program 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. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. +. + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + 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, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. +. + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +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 compile 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) 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. + + c) 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. + + d) 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 source code 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 to +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 Library 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 diff --git a/rapla-source-1.8.2/legal/license_apache.txt b/rapla-source-1.8.2/legal/license_apache.txt new file mode 100644 index 0000000..d6b7856 --- /dev/null +++ b/rapla-source-1.8.2/legal/license_apache.txt @@ -0,0 +1,219 @@ +Some files use code from different Apache projects. +The source code of these files contains the appropriate copyright notices +as described in the Appendix of http://www.apache.org/licenses/LICENSE-2.0 +This is a copy of the text that can be found at that specific URL: + +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + * You must give any other recipients of the Work or + Derivative Works a copy of this License; and + * You must cause any modified files to carry prominent notices + stating that You changed the files; and + * You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + * If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/rapla-source-1.8.2/legal/license_iCal4j.txt b/rapla-source-1.8.2/legal/license_iCal4j.txt new file mode 100644 index 0000000..527aecf --- /dev/null +++ b/rapla-source-1.8.2/legal/license_iCal4j.txt @@ -0,0 +1,33 @@ +================== + iCal4j - License +================== + +Copyright (c) 2012, Ben Fortuna +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + o Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + + o 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. + + o Neither the name of Ben Fortuna nor the names of any other contributors +may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. diff --git a/rapla-source-1.8.2/legal/readme.txt b/rapla-source-1.8.2/legal/readme.txt new file mode 100644 index 0000000..a9668f6 --- /dev/null +++ b/rapla-source-1.8.2/legal/readme.txt @@ -0,0 +1,22 @@ +The Rapla project uses the following libraries from other software-projects: + +Library:----------from:----------------License------Get the source from: + +ant Apache Foundation Apache 2.0 ant.apache.org +avalon-jars Apache Foundation Apache 2.0 avalon.apache.org +commons-jars Apache Foundation Apache 2.0 commons.apache.org +itext iText Software LGPL 2.0 github.com/ymasory/ +cl-leak-prevent mjiderhamn Apache 2.0 https://github.com/mjiderhamn/classloader-leak-prevention +ical4j Micronode ical4j (BSD) build.mnode.org/projects/ical4j/ +jetty Eclipse Foundation Apache 2.0 www.eclipse.org/jetty/ +mailapi Oracle GPL 2.0 java.net/projects/javamail +servlet-api Apache Apache 2.0 svn.apache.org/repos/asf/tomcat/tc7.0.x/trunk/java/javax/servlet/ +supercvs Kasper Apache 2.0 supercsv.sourceforge.net +service wrapper tanukisoftware GPL 2.0 wrapper.tanukisoftware.com + +Most icons were taken from the eclipse project (www.eclipse.org) which are licensed under +the eclipse public license 1.1 +Some icons were taken from +- wm-icons.sourceforge.net (GPL LICENSE) + +Look for the full license texts in the legal folder of the rapla distribution. diff --git a/rapla-source-1.8.2/legal/wrapper-community-license-1.1.txt b/rapla-source-1.8.2/legal/wrapper-community-license-1.1.txt new file mode 100644 index 0000000..dc02512 --- /dev/null +++ b/rapla-source-1.8.2/legal/wrapper-community-license-1.1.txt @@ -0,0 +1,396 @@ +---------------------------------------------------------------------- +----------------- ----------------- + Tanuki Software, Ltd. + Community Software License Agreement + Version 1.1 + +IMPORTANT-READ CAREFULLY: This license agreement is a legal agreement +between you ("Licensee") and Tanuki Software, Ltd. ("TSI"), which +includes computer software, associated media, printed materials, and +may include online or electronic documentation ( Software ). PLEASE +READ THIS AGREEMENT CAREFULLY BEFORE YOU INSTALL, COPY, DOWNLOAD OR +USE THE SOFTWARE ACCOMPANYING THIS PACKAGE. + +Section 1 - Grant of License + +Community editions of the Software are made available on the GNU +General Public License, Version 2 ("GPLv2"), included in Section 4 of +this license document. All sections of the Community Software License +Agreement must be complied with in addition to those of the GPLv2. + + +Section 2 - Definitions + +2.1. "Community Edition" shall mean versions of the Software Program +distributed in source form under this license agreement, and all new +releases, corrections, enhancements and updates to the Software +Program, which TSI makes generally available under this agreement. + +2.2. "Documentation" shall mean the contents of the website +describing the functionality and use of the Software Program, located +at http://wrapper.tanukisoftware.org + +2.3. "Product" shall mean the computer programs, that are provided by +Licensee to Licensee customers or potential customers, and that +contain both the Software Program as a component of the Product, and a +component or components (other than the Software Program) that provide +the material functionality of the Product. If the Product is released +in source form, the Software Program or any of its components may only +be included in executable form. + +2.4. "Software Program" shall mean the computer software and license +file provided by TSI under this Agreement, including all new releases, +corrections, enhancements and updates to such computer software, which +TSI makes generally available and which Licensee receive pursuant to +Licensee subscription to TSIMS. Some specific features or platforms +may not be enabled if they do not fall under the feature set(s) +covered by the specific license fees paid. + +2.5 "End User" shall mean the customers of the Licensee or any +recipient of the Product whether or not any payment is made to use +the Product. + + +Section 3 - Licensee Obligations + +A copy of this license must be distributed in full with the Product +in a location that is obvious to any End User. + +In accordance with Section 4, the full source code of all components +of the Product must be made available to any and all End Users. + +Licensee may extend and/or modify the Software Program and distribute +under the terms of this agreement provided that the copyright notice +and license information displayed in the console and log files are +not obfuscated or obstructed in any way. + + +Section 4 - GPLv2 License Agreement + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + + Everyone is permitted to copy and distribute verbatim copies of + this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your + freedom to share and change it. By contrast, the GNU General + Public License is intended to guarantee your freedom to share and + change free software--to make sure the software is free for all + its users. This General Public License applies to most of the Free + Software Foundation's software and to any other program whose + authors commit to using it. (Some other Free Software Foundation + software is covered by the GNU Library General Public License + instead.) You can apply it to your programs, too. + + When we speak of free software, we are referring to freedom, 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 or + use pieces of it in new free programs; and that you know you can + do these things. + + To protect your rights, we need to make restrictions that forbid + anyone to deny you these rights or to ask you to surrender the + rights. These restrictions translate to certain responsibilities + for you if you distribute copies of the software, or if you modify + it. + + For example, if you distribute copies of such a program, whether + gratis or for a fee, you must give the recipients all the rights + that you have. You must make sure that they, too, receive or can + get the source code. And you must show them these terms so they + know their rights. + + We protect your rights with two steps: + + (1) copyright the software, and + (2) offer you this license which gives you legal permission to + copy, distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make + certain that everyone understands that there is no warranty for + this free software. If the software is modified by someone else + and passed on, we want its recipients to know that what they have + is not the original, so that any problems introduced by others + will not reflect on the original authors' reputations. + + Finally, any free program is threatened constantly by software + patents. We wish to avoid the danger that redistributors of a free + program will individually obtain patent licenses, in effect making + the program proprietary. To prevent this, we have made it clear + that any patent must be licensed for everyone's free use or not + licensed at all. + + The precise terms and conditions for copying, distribution and + modification follow. + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which + contains a notice placed by the copyright holder saying it may be + distributed under the terms of this General Public License. The + "Program", below, refers to any such program or work, and a "work + based on the Program" means either the Program or any derivative + work under copyright law: that is to say, a work containing the + Program or a portion of it, either verbatim or with modifications + and/or translated into another language. (Hereinafter, translation + is included without limitation in the term "modification".) Each + licensee is addressed as "you". + + Activities other than copying, distribution and modification are + not covered by this License; they are outside its scope. The act + of running the Program is not restricted, and the output from the + Program is covered only if its contents constitute a work based on + the Program (independent of having been made by running the + Program). Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's + 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 give any other recipients of the + Program a copy of this License along with the Program. + + 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 Program or any + portion of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but does + not normally print such an announcement, your work based on the + Program is not required to print an announcement.) + + These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the + Program, 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 Program, 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 Program. + + In addition, mere aggregation of another work not based on the + Program with the Program (or with a work based on the Program) on + a volume of a storage or distribution medium does not bring the + other work under the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, + under Section 2) in object code or executable form under the terms + of Sections 1 and 2 above provided that you also do one of the + following: + + a) 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; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + + The source code for a work means the preferred form of the work + for making modifications to it. For an executable work, 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 executable. + However, as a special exception, the source code 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. + + If distribution of executable or 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 counts as + distribution of the source code, even though third parties are not + compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program + except as expressly provided under this License. Any attempt + otherwise to copy, modify, sublicense or distribute the Program 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. + + 5. 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 Program or its derivative works. These actions + are prohibited by law if you do not accept this License. + Therefore, by modifying or distributing the Program (or any work + based on the Program), you indicate your acceptance of this + License to do so, and all its terms and conditions for copying, + distributing or modifying the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on + the Program), the recipient automatically receives a license from + the original licensor to copy, distribute or modify the Program + 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 to this License. + + 7. 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 + Program at all. For example, if a patent license would not permit + royalty-free redistribution of the Program 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 Program. + + 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. + + 8. If the distribution and/or use of the Program is restricted in + certain countries either by patents or by copyrighted interfaces, + the original copyright holder who places the Program 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. + + 9. The Free Software Foundation may publish revised and/or new + versions of the 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 + Program 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 Program + does not specify a version number of this License, you may choose + any version ever published by the Free Software Foundation. + + 10. If you wish to incorporate parts of the Program into other + free programs whose distribution conditions are different, 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 + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO + WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE + LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS + AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE + DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR + OR CORRECTION. + + 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY + OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + +Section 4 - 3rd Party Components + +(1) The Software Program includes software and documentation components +developed in part by Silver Egg Technology, Inc.("SET") prior to 2001 +and released under the following license. + + Copyright (c) 2001 Silver Egg Technology + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sub-license, and/or + sell copies of the Software, and to permit persons to whom the + Software 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 the Software. + + 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 + NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS 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 THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + diff --git a/rapla-source-1.8.2/lib/ant-junit.jar b/rapla-source-1.8.2/lib/ant-junit.jar new file mode 100644 index 0000000..9150813 Binary files /dev/null and b/rapla-source-1.8.2/lib/ant-junit.jar differ diff --git a/rapla-source-1.8.2/lib/ant-launcher.jar b/rapla-source-1.8.2/lib/ant-launcher.jar new file mode 100644 index 0000000..97c2262 Binary files /dev/null and b/rapla-source-1.8.2/lib/ant-launcher.jar differ diff --git a/rapla-source-1.8.2/lib/ant.jar b/rapla-source-1.8.2/lib/ant.jar new file mode 100644 index 0000000..24641e7 Binary files /dev/null and b/rapla-source-1.8.2/lib/ant.jar differ diff --git a/rapla-source-1.8.2/lib/common/COMMON-LIBRARIES.txt b/rapla-source-1.8.2/lib/common/COMMON-LIBRARIES.txt new file mode 100644 index 0000000..db90a2f --- /dev/null +++ b/rapla-source-1.8.2/lib/common/COMMON-LIBRARIES.txt @@ -0,0 +1 @@ +Place in this folder all jars that should be used by the client and the server application. diff --git a/rapla-source-1.8.2/lib/common/gson-2.3.1.jar b/rapla-source-1.8.2/lib/common/gson-2.3.1.jar new file mode 100644 index 0000000..250132c Binary files /dev/null and b/rapla-source-1.8.2/lib/common/gson-2.3.1.jar differ diff --git a/rapla-source-1.8.2/lib/common/iText-4.2.0-com.itextpdf.jar b/rapla-source-1.8.2/lib/common/iText-4.2.0-com.itextpdf.jar new file mode 100644 index 0000000..af75b58 Binary files /dev/null and b/rapla-source-1.8.2/lib/common/iText-4.2.0-com.itextpdf.jar differ diff --git a/rapla-source-1.8.2/lib/common/javax.inject.jar b/rapla-source-1.8.2/lib/common/javax.inject.jar new file mode 100644 index 0000000..a9dfb86 Binary files /dev/null and b/rapla-source-1.8.2/lib/common/javax.inject.jar differ diff --git a/rapla-source-1.8.2/lib/common/super-csv-2.0.1.jar b/rapla-source-1.8.2/lib/common/super-csv-2.0.1.jar new file mode 100644 index 0000000..8840933 Binary files /dev/null and b/rapla-source-1.8.2/lib/common/super-csv-2.0.1.jar differ diff --git a/rapla-source-1.8.2/lib/ext/hsqldb-2.3.2.jar b/rapla-source-1.8.2/lib/ext/hsqldb-2.3.2.jar new file mode 100644 index 0000000..f931a45 Binary files /dev/null and b/rapla-source-1.8.2/lib/ext/hsqldb-2.3.2.jar differ diff --git a/rapla-source-1.8.2/lib/jetty-continuation-8.1.16.v20140903.jar b/rapla-source-1.8.2/lib/jetty-continuation-8.1.16.v20140903.jar new file mode 100644 index 0000000..ce1acb1 Binary files /dev/null and b/rapla-source-1.8.2/lib/jetty-continuation-8.1.16.v20140903.jar differ diff --git a/rapla-source-1.8.2/lib/jetty-deploy-8.1.16.v20140903.jar b/rapla-source-1.8.2/lib/jetty-deploy-8.1.16.v20140903.jar new file mode 100644 index 0000000..d3339b0 Binary files /dev/null and b/rapla-source-1.8.2/lib/jetty-deploy-8.1.16.v20140903.jar differ diff --git a/rapla-source-1.8.2/lib/jetty-http-8.1.16.v20140903.jar b/rapla-source-1.8.2/lib/jetty-http-8.1.16.v20140903.jar new file mode 100644 index 0000000..30189c7 Binary files /dev/null and b/rapla-source-1.8.2/lib/jetty-http-8.1.16.v20140903.jar differ diff --git a/rapla-source-1.8.2/lib/jetty-io-8.1.16.v20140903.jar b/rapla-source-1.8.2/lib/jetty-io-8.1.16.v20140903.jar new file mode 100644 index 0000000..a9afd7c Binary files /dev/null and b/rapla-source-1.8.2/lib/jetty-io-8.1.16.v20140903.jar differ diff --git a/rapla-source-1.8.2/lib/jetty-jndi-8.1.16.v20140903.jar b/rapla-source-1.8.2/lib/jetty-jndi-8.1.16.v20140903.jar new file mode 100644 index 0000000..aa76c9f Binary files /dev/null and b/rapla-source-1.8.2/lib/jetty-jndi-8.1.16.v20140903.jar differ diff --git a/rapla-source-1.8.2/lib/jetty-plus-8.1.16.v20140903.jar b/rapla-source-1.8.2/lib/jetty-plus-8.1.16.v20140903.jar new file mode 100644 index 0000000..871074a Binary files /dev/null and b/rapla-source-1.8.2/lib/jetty-plus-8.1.16.v20140903.jar differ diff --git a/rapla-source-1.8.2/lib/jetty-security-8.1.16.v20140903.jar b/rapla-source-1.8.2/lib/jetty-security-8.1.16.v20140903.jar new file mode 100644 index 0000000..e5bde43 Binary files /dev/null and b/rapla-source-1.8.2/lib/jetty-security-8.1.16.v20140903.jar differ diff --git a/rapla-source-1.8.2/lib/jetty-server-8.1.16.v20140903.jar b/rapla-source-1.8.2/lib/jetty-server-8.1.16.v20140903.jar new file mode 100644 index 0000000..ae8ac55 Binary files /dev/null and b/rapla-source-1.8.2/lib/jetty-server-8.1.16.v20140903.jar differ diff --git a/rapla-source-1.8.2/lib/jetty-servlet-8.1.16.v20140903.jar b/rapla-source-1.8.2/lib/jetty-servlet-8.1.16.v20140903.jar new file mode 100644 index 0000000..eb2fa57 Binary files /dev/null and b/rapla-source-1.8.2/lib/jetty-servlet-8.1.16.v20140903.jar differ diff --git a/rapla-source-1.8.2/lib/jetty-util-8.1.16.v20140903.jar b/rapla-source-1.8.2/lib/jetty-util-8.1.16.v20140903.jar new file mode 100644 index 0000000..5c3c346 Binary files /dev/null and b/rapla-source-1.8.2/lib/jetty-util-8.1.16.v20140903.jar differ diff --git a/rapla-source-1.8.2/lib/jetty-webapp-8.1.16.v20140903.jar b/rapla-source-1.8.2/lib/jetty-webapp-8.1.16.v20140903.jar new file mode 100644 index 0000000..85fd7e0 Binary files /dev/null and b/rapla-source-1.8.2/lib/jetty-webapp-8.1.16.v20140903.jar differ diff --git a/rapla-source-1.8.2/lib/jetty-xml-8.1.16.v20140903.jar b/rapla-source-1.8.2/lib/jetty-xml-8.1.16.v20140903.jar new file mode 100644 index 0000000..1e485de Binary files /dev/null and b/rapla-source-1.8.2/lib/jetty-xml-8.1.16.v20140903.jar differ diff --git a/rapla-source-1.8.2/lib/logging/commons-compiler-2.7.0.jar b/rapla-source-1.8.2/lib/logging/commons-compiler-2.7.0.jar new file mode 100644 index 0000000..f4068da Binary files /dev/null and b/rapla-source-1.8.2/lib/logging/commons-compiler-2.7.0.jar differ diff --git a/rapla-source-1.8.2/lib/logging/janino-2.7.0.jar b/rapla-source-1.8.2/lib/logging/janino-2.7.0.jar new file mode 100644 index 0000000..ceac6ad Binary files /dev/null and b/rapla-source-1.8.2/lib/logging/janino-2.7.0.jar differ diff --git a/rapla-source-1.8.2/lib/logging/jcl-over-slf4j-1.7.5.jar b/rapla-source-1.8.2/lib/logging/jcl-over-slf4j-1.7.5.jar new file mode 100644 index 0000000..a80e4f1 Binary files /dev/null and b/rapla-source-1.8.2/lib/logging/jcl-over-slf4j-1.7.5.jar differ diff --git a/rapla-source-1.8.2/lib/logging/jul-to-slf4j-1.7.5.jar b/rapla-source-1.8.2/lib/logging/jul-to-slf4j-1.7.5.jar new file mode 100644 index 0000000..5b95ad2 Binary files /dev/null and b/rapla-source-1.8.2/lib/logging/jul-to-slf4j-1.7.5.jar differ diff --git a/rapla-source-1.8.2/lib/logging/logback-access-1.0.13.jar b/rapla-source-1.8.2/lib/logging/logback-access-1.0.13.jar new file mode 100644 index 0000000..a0d58d2 Binary files /dev/null and b/rapla-source-1.8.2/lib/logging/logback-access-1.0.13.jar differ diff --git a/rapla-source-1.8.2/lib/logging/logback-classic-1.0.13.jar b/rapla-source-1.8.2/lib/logging/logback-classic-1.0.13.jar new file mode 100644 index 0000000..3685d68 Binary files /dev/null and b/rapla-source-1.8.2/lib/logging/logback-classic-1.0.13.jar differ diff --git a/rapla-source-1.8.2/lib/logging/logback-core-1.0.13.jar b/rapla-source-1.8.2/lib/logging/logback-core-1.0.13.jar new file mode 100644 index 0000000..79d12ab Binary files /dev/null and b/rapla-source-1.8.2/lib/logging/logback-core-1.0.13.jar differ diff --git a/rapla-source-1.8.2/lib/logging/slf4j-api-1.7.5.jar b/rapla-source-1.8.2/lib/logging/slf4j-api-1.7.5.jar new file mode 100644 index 0000000..8766455 Binary files /dev/null and b/rapla-source-1.8.2/lib/logging/slf4j-api-1.7.5.jar differ diff --git a/rapla-source-1.8.2/lib/server/SERVER-LIBRARIES.txt b/rapla-source-1.8.2/lib/server/SERVER-LIBRARIES.txt new file mode 100644 index 0000000..d20de8f --- /dev/null +++ b/rapla-source-1.8.2/lib/server/SERVER-LIBRARIES.txt @@ -0,0 +1 @@ +Place in this folder all jars that should only be used by the server application. diff --git a/rapla-source-1.8.2/lib/server/backport-util-concurrent-3.1.jar b/rapla-source-1.8.2/lib/server/backport-util-concurrent-3.1.jar new file mode 100644 index 0000000..3a4c279 Binary files /dev/null and b/rapla-source-1.8.2/lib/server/backport-util-concurrent-3.1.jar differ diff --git a/rapla-source-1.8.2/lib/server/commons-codec-1.8.jar b/rapla-source-1.8.2/lib/server/commons-codec-1.8.jar new file mode 100644 index 0000000..32f84c9 Binary files /dev/null and b/rapla-source-1.8.2/lib/server/commons-codec-1.8.jar differ diff --git a/rapla-source-1.8.2/lib/server/commons-collections4-4.0.jar b/rapla-source-1.8.2/lib/server/commons-collections4-4.0.jar new file mode 100644 index 0000000..4fb2b11 Binary files /dev/null and b/rapla-source-1.8.2/lib/server/commons-collections4-4.0.jar differ diff --git a/rapla-source-1.8.2/lib/server/commons-lang-2.6.jar b/rapla-source-1.8.2/lib/server/commons-lang-2.6.jar new file mode 100644 index 0000000..98467d3 Binary files /dev/null and b/rapla-source-1.8.2/lib/server/commons-lang-2.6.jar differ diff --git a/rapla-source-1.8.2/lib/server/commons-logging-1.1.3.jar b/rapla-source-1.8.2/lib/server/commons-logging-1.1.3.jar new file mode 100644 index 0000000..ab51254 Binary files /dev/null and b/rapla-source-1.8.2/lib/server/commons-logging-1.1.3.jar differ diff --git a/rapla-source-1.8.2/lib/server/ical4j-1.0.6.jar b/rapla-source-1.8.2/lib/server/ical4j-1.0.6.jar new file mode 100644 index 0000000..90ca63b Binary files /dev/null and b/rapla-source-1.8.2/lib/server/ical4j-1.0.6.jar differ diff --git a/rapla-source-1.8.2/lib/server/mailapi-1.4.7.jar b/rapla-source-1.8.2/lib/server/mailapi-1.4.7.jar new file mode 100644 index 0000000..38bcc17 Binary files /dev/null and b/rapla-source-1.8.2/lib/server/mailapi-1.4.7.jar differ diff --git a/rapla-source-1.8.2/lib/server/smtp-1.4.7.jar b/rapla-source-1.8.2/lib/server/smtp-1.4.7.jar new file mode 100644 index 0000000..51d3421 Binary files /dev/null and b/rapla-source-1.8.2/lib/server/smtp-1.4.7.jar differ diff --git a/rapla-source-1.8.2/lib/servlet-api-3.0.jar b/rapla-source-1.8.2/lib/servlet-api-3.0.jar new file mode 100644 index 0000000..b135409 Binary files /dev/null and b/rapla-source-1.8.2/lib/servlet-api-3.0.jar differ diff --git a/rapla-source-1.8.2/lib/test-only/junit-3.8.jar b/rapla-source-1.8.2/lib/test-only/junit-3.8.jar new file mode 100644 index 0000000..674d71e Binary files /dev/null and b/rapla-source-1.8.2/lib/test-only/junit-3.8.jar differ diff --git a/rapla-source-1.8.2/logs/rapla.log b/rapla-source-1.8.2/logs/rapla.log new file mode 100644 index 0000000..90aa3d0 --- /dev/null +++ b/rapla-source-1.8.2/logs/rapla.log @@ -0,0 +1,110 @@ +15:58:33.785 266 [main] INFO org.eclipse.jetty.server.Server - jetty-8.1.16.v20140903 +15:58:33.825 306 [main] INFO o.e.j.d.p.ScanningAppProvider - Deployment monitor C:\Users\kcs11006\Downloads\rapla-source-1.8.2\contexts at interval 1 +15:58:33.829 310 [main] INFO o.e.jetty.deploy.DeploymentManager - Deployable added: C:\Users\kcs11006\Downloads\rapla-source-1.8.2\contexts\rapla-develop.xml +15:58:34.030 511 [main] INFO rapla - Init RaplaServlet +15:58:34.032 513 [main] INFO rapla - Passed JNDI Environment rapladatasource=raplafile env_rapladb=org.hsqldb.jdbc.JDBCDataSource@29626d54 env_raplafile=C:\Users\kcs11006\Downloads\rapla-source-1.8.2/data/data.xml +15:58:34.036 517 [main] INFO rapla - Logging via SLF4J API. +15:58:34.061 542 [main] INFO rapla - Configured Locale= en_US +15:58:34.170 651 [main] INFO rapla - Config=file:/C:/Users/kcs11006/Downloads/rapla-source-1.8.2/war/WEB-INF/raplaserver.xconf +15:58:34.170 651 [main] INFO rapla - Rapla.Version=@doc.version@ +15:58:34.171 652 [main] INFO rapla - Rapla.Build=@doc.buildtime@ +15:58:34.171 652 [main] INFO rapla - Timezone America/New_York +15:58:34.176 657 [main] INFO rapla - Java.Version=1.8.0_51 +15:58:34.226 707 [main] INFO rapla.server.serverfacade - Using rapladatasource raplafile +15:58:34.242 723 [main] INFO rapla.raplafile - Connecting: file:/C:/Users/kcs11006/Downloads/rapla-source-1.8.2/data/data.xml +15:58:34.261 742 [main] WARN rapla.raplafile - Data file not found file:/C:/Users/kcs11006/Downloads/rapla-source-1.8.2/data/data.xml creating default system. +15:58:39.276 5757 [main] INFO rapla.raplafile - Conflict initialization found 0 conflicts and took 0ms. +15:58:39.278 5759 [main] INFO rapla.server.plugin - Installed plugin org.rapla.plugin.weekview.server.WeekViewServerPlugin +15:58:39.279 5760 [main] INFO rapla.server.plugin - Installed plugin org.rapla.plugin.urlencryption.server.UrlEncryptionServerPlugin +15:58:39.279 5760 [main] INFO rapla.server.plugin - Installed plugin org.rapla.plugin.timeslot.server.TimeslotServerPlugin +15:58:39.279 5760 [main] INFO rapla.server.plugin - Installed plugin org.rapla.plugin.tableview.internal.server.TableViewServerPlugin +15:58:39.280 5761 [main] INFO rapla.server.plugin - Installed plugin org.rapla.plugin.notification.server.NotificationServerPlugin +15:58:39.280 5761 [main] INFO rapla.server.plugin - Installed plugin org.rapla.plugin.monthview.server.MonthViewServerPlugin +15:58:39.280 5761 [main] INFO rapla.server.plugin - Installed plugin org.rapla.plugin.mail.server.MailServerPlugin +15:58:39.280 5761 [main] INFO rapla.server.plugin - Installed plugin org.rapla.plugin.jndi.server.JNDIServerPlugin +15:58:39.281 5762 [main] INFO rapla.server.plugin - Installed plugin org.rapla.plugin.ical.server.ImportFromICalServerPlugin +15:58:39.281 5762 [main] INFO rapla.server.plugin - Installed plugin org.rapla.plugin.export2ical.server.Export2iCalServerPlugin +15:58:39.281 5762 [main] INFO rapla.server.plugin - Installed plugin org.rapla.plugin.eventtimecalculator.server.EventTimeCalculatorServerPlugin +15:58:39.281 5762 [main] INFO rapla.server.plugin - Installed plugin org.rapla.plugin.dayresource.server.DayResourceViewServerPlugin +15:58:39.282 5763 [main] INFO rapla.server.plugin - Installed plugin org.rapla.plugin.compactweekview.server.CompactWeekViewServerPlugin +15:58:39.282 5763 [main] INFO rapla.server.plugin - Installed plugin org.rapla.plugin.autoexport.server.AutoExportServerPlugin +15:58:39.282 5763 [main] INFO rapla.server.plugin - Installed plugin org.rapla.plugin.archiver.server.ArchiverServerPlugin +15:58:39.286 5767 [main] INFO rapla.server - Generating new root key. This can take a while. +15:58:39.855 6336 [main] INFO rapla.server - Root key generated +15:58:39.869 6350 [main] INFO rapla.raplafile - Creating directory C:\Users\kcs11006\Downloads\rapla-source-1.8.2\data +15:58:40.082 6563 [main] INFO rapla - Rapla server started +15:58:40.092 6573 [main] INFO rapla.client - Starting gui +15:58:40.114 6595 [main] INFO rapla.client.facade - Using rapladatasource remotestore +15:58:40.124 6605 [main] INFO rapla.remotestore - Connecting to server and starting login.. +15:58:40.125 6606 [main] INFO rapla.remotestore - login successfull +15:58:40.126 6607 [main] INFO rapla.client.facade - Login admin +15:58:40.129 6610 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.weekview.WeekViewPlugin +15:58:40.129 6610 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.urlencryption.UrlEncryptionPlugin +15:58:40.129 6610 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.timeslot.TimeslotPlugin +15:58:40.130 6611 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.tempatewizard.TempateWizardPlugin +15:58:40.130 6611 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.tableview.internal.TableViewPlugin +15:58:40.130 6611 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.setowner.SetOwnerPlugin +15:58:40.130 6611 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.rightsreport.RightsReportPlugin +15:58:40.130 6611 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.periodcopy.PeriodCopyPlugin +15:58:40.131 6612 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.notification.NotificationPlugin +15:58:40.131 6612 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.monthview.MonthViewPlugin +15:58:40.131 6612 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.mail.MailPlugin +15:58:40.131 6612 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.jndi.JNDIPlugin +15:58:40.131 6612 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.ical.ImportFromICalPlugin +15:58:40.132 6613 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.export2ical.Export2iCalPlugin +15:58:40.132 6613 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.eventtimecalculator.EventTimeCalculatorPlugin +15:58:40.132 6613 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.defaultwizard.DefaultWizardPlugin +15:58:40.132 6613 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.dayresource.DayResourceViewPlugin +15:58:40.132 6613 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.compactweekview.CompactWeekViewPlugin +15:58:40.132 6613 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.autoexport.AutoExportPlugin +15:58:40.133 6614 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.archiver.ArchiverPlugin +15:58:40.133 6614 [main] INFO rapla.client.plugin - Installed plugin org.rapla.plugin.appointmentcounter.AppointmentCounterPlugin +15:58:53.188 19669 [AWT-EventQueue-0] INFO rapla.client.facade - Logout u405db03-812f-4ff7-b52c-5423a7951cf4 +15:58:53.189 19670 [AWT-EventQueue-0] INFO rapla.remotestore - Disconnecting from server +15:58:53.189 19670 [AWT-EventQueue-0] INFO rapla.server.session.login - Request Logout admin +15:58:53.194 19675 [main] INFO rapla - Shutting down rapla-container +15:58:53.194 19675 [main] INFO rapla - Stopping scheduler thread. +15:58:53.195 19676 [main] INFO rapla - Stopped scheduler thread. +15:58:53.245 19726 [main] INFO rapla.raplafile - Disconnecting: file:/C:/Users/kcs11006/Downloads/rapla-source-1.8.2/data/data.xml +15:58:53.245 19726 [main] INFO rapla.server - Storage service stopped +15:58:58.327 24808 [main] INFO o.e.j.server.handler.ContextHandler - stopped o.e.j.w.WebAppContext{/,[file:/C:/Users/kcs11006/Downloads/rapla-source-1.8.2/war/]} +15:58:58.328 24809 [SeedGenerator Thread] ERROR rapla.client - uncaught exception +java.lang.ThreadDeath: null + at java.lang.Thread.stop(Unknown Source) ~[na:1.8.0_51] + at se.jiderhamn.classloader.leak.prevention.ClassLoaderLeakPreventor.stopThreads(ClassLoaderLeakPreventor.java:915) ~[eclipse-build/:na] + at se.jiderhamn.classloader.leak.prevention.ClassLoaderLeakPreventor.contextDestroyed(ClassLoaderLeakPreventor.java:426) ~[eclipse-build/:na] + at org.eclipse.jetty.server.handler.ContextHandler.doStop(ContextHandler.java:823) ~[jetty-server-8.1.16.v20140903.jar:8.1.16.v20140903] + at org.eclipse.jetty.servlet.ServletContextHandler.doStop(ServletContextHandler.java:160) ~[jetty-servlet-8.1.16.v20140903.jar:8.1.16.v20140903] + at org.eclipse.jetty.webapp.WebAppContext.doStop(WebAppContext.java:518) ~[jetty-webapp-8.1.16.v20140903.jar:8.1.16.v20140903] + at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:89) ~[jetty-util-8.1.16.v20140903.jar:8.1.16.v20140903] + at org.eclipse.jetty.server.handler.HandlerCollection.doStop(HandlerCollection.java:250) ~[jetty-server-8.1.16.v20140903.jar:8.1.16.v20140903] + at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:89) ~[jetty-util-8.1.16.v20140903.jar:8.1.16.v20140903] + at org.eclipse.jetty.server.handler.HandlerCollection.doStop(HandlerCollection.java:250) ~[jetty-server-8.1.16.v20140903.jar:8.1.16.v20140903] + at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:89) ~[jetty-util-8.1.16.v20140903.jar:8.1.16.v20140903] + at org.eclipse.jetty.server.handler.HandlerWrapper.doStop(HandlerWrapper.java:107) ~[jetty-server-8.1.16.v20140903.jar:8.1.16.v20140903] + at org.eclipse.jetty.server.Server.doStop(Server.java:343) ~[jetty-server-8.1.16.v20140903.jar:8.1.16.v20140903] + at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:89) ~[jetty-util-8.1.16.v20140903.jar:8.1.16.v20140903] + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_51] + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_51] + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_51] + at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_51] + at org.rapla.bootstrap.CustomJettyStarter$2$1.invoke(CustomJettyStarter.java:278) ~[eclipse-build/:na] + at com.sun.proxy.$Proxy0.lifeCycleStarted(Unknown Source) ~[na:na] + at org.eclipse.jetty.util.component.AbstractLifeCycle.setStarted(AbstractLifeCycle.java:174) ~[jetty-util-8.1.16.v20140903.jar:8.1.16.v20140903] + at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:65) ~[jetty-util-8.1.16.v20140903.jar:8.1.16.v20140903] + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_51] + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_51] + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_51] + at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_51] + at org.rapla.bootstrap.CustomJettyStarter$2.run(CustomJettyStarter.java:339) ~[eclipse-build/:na] + at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_51] + at org.rapla.bootstrap.CustomJettyStarter.start(CustomJettyStarter.java:193) ~[eclipse-build/:na] + at org.rapla.bootstrap.CustomJettyStarter.main(CustomJettyStarter.java:53) ~[eclipse-build/:na] + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_51] + at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_51] + at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_51] + at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_51] + at org.rapla.bootstrap.RaplaLoader.startMain(RaplaLoader.java:135) ~[eclipse-build/:na] + at org.rapla.bootstrap.RaplaLoader.start(RaplaLoader.java:99) ~[eclipse-build/:na] + at org.rapla.bootstrap.RaplaJettyLoader.main(RaplaJettyLoader.java:30) ~[eclipse-build/:na] + at org.rapla.bootstrap.RaplaStandaloneLoader.main(RaplaStandaloneLoader.java:17) ~[eclipse-build/:na] diff --git a/rapla-source-1.8.2/logs/rapla_calls.log b/rapla-source-1.8.2/logs/rapla_calls.log new file mode 100644 index 0000000..e69de29 diff --git a/rapla-source-1.8.2/logs/rapla_client.csv b/rapla-source-1.8.2/logs/rapla_client.csv new file mode 100644 index 0000000..e69de29 diff --git a/rapla-source-1.8.2/logs/request.log b/rapla-source-1.8.2/logs/request.log new file mode 100644 index 0000000..e69de29 diff --git a/rapla-source-1.8.2/raplaselfsigned.ks b/rapla-source-1.8.2/raplaselfsigned.ks new file mode 100644 index 0000000..6b4491e Binary files /dev/null and b/rapla-source-1.8.2/raplaselfsigned.ks differ diff --git a/rapla-source-1.8.2/resources/logback-access.xml b/rapla-source-1.8.2/resources/logback-access.xml new file mode 100644 index 0000000..582855f --- /dev/null +++ b/rapla-source-1.8.2/resources/logback-access.xml @@ -0,0 +1,18 @@ + + + ${jetty.home}/logs/request.log + + + ${jetty.home}/logs/request_%d{yyyy-MM-dd}.log + 5 + true + + + + %h %l %u %user %date "%r" %s %b + + + + + + diff --git a/rapla-source-1.8.2/resources/logback.xml b/rapla-source-1.8.2/resources/logback.xml new file mode 100644 index 0000000..0a16f10 --- /dev/null +++ b/rapla-source-1.8.2/resources/logback.xml @@ -0,0 +1,129 @@ + + + + + System.out + + DEBUG + ACCEPT + + + INFO + ACCEPT + DENY + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %class{0}.%method %logger{36} - %msg%n + + + + + System.err + + WARN + + + %d{HH:mm:ss.SSS} [%thread] %-5level %class{0}.%method %logger{36} - %msg%n + + + + + ${jetty.home}/logs/rapla.log + + + ${jetty.home}/logs/rapla_%d{yyyy-MM-dd}.log + 30 + true + + + + %d{HH:mm:ss.SSS} %-4relative [%thread] %-5level %logger{35} - %msg%n + + + + + + + + ${jetty.home}/logs/rapla_calls.log + + + ${jetty.home}/logs/rapla_calls%d{yyyy-MM-dd}.log + 2 + true + + + + %d{HH:mm:ss.SSS} %-4relative [%thread] %-5level %logger{35} - %msg%n + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${jetty.home}/logs/rapla_client.csv + + + ${jetty.home}/logs/rapla_client%d{yyyy-MM-dd}.csv + 30 + true + + + %d{HH:mm:ss.SSS};%msg%n + + + + + + + + \ No newline at end of file diff --git a/rapla-source-1.8.2/service/bin/InstallTestWrapper-NT.bat b/rapla-source-1.8.2/service/bin/InstallTestWrapper-NT.bat new file mode 100644 index 0000000..fbdd3a6 --- /dev/null +++ b/rapla-source-1.8.2/service/bin/InstallTestWrapper-NT.bat @@ -0,0 +1,113 @@ +@echo off +setlocal + +rem +rem Copyright (c) 1999, 2012 Tanuki Software, Ltd. +rem http://www.tanukisoftware.com +rem All rights reserved. +rem +rem This software is the proprietary information of Tanuki Software. +rem You shall use it only in accordance with the terms of the +rem license agreement you entered into with Tanuki Software. +rem http://wrapper.tanukisoftware.com/doc/english/licenseOverview.html +rem +rem Java Service Wrapper general passthrough startup script. +rem + +rem ----------------------------------------------------------------------------- +rem These settings can be modified to fit the needs of your application +rem Optimized for use with version 3.5.17 of the Wrapper. + +rem The base name for the Wrapper binary. +set _WRAPPER_BASE=wrapper + +rem The name and location of the Wrapper configuration file. This will be used +rem if the user does not specify a configuration file as the first parameter to +rem this script. It will not be possible to specify a configuration file on the +rem command line if _PASS_THROUGH is set. +set _WRAPPER_CONF_DEFAULT=../conf/wrapper.conf + +rem Makes it possible to override the Wrapper configuration file by specifying it +rem as the first parameter. +rem set _WRAPPER_CONF_OVERRIDE=true + +rem _PASS_THROUGH tells the script to pass all parameters through to the JVM as +rem is. +set _PASS_THROUGH=true + +rem Do not modify anything beyond this point +rem ----------------------------------------------------------------------------- + +rem +rem Resolve the real path of the wrapper.exe +rem For non NT systems, the _REALPATH and _WRAPPER_CONF values +rem can be hard-coded below and the following test removed. +rem +if "%OS%"=="Windows_NT" goto nt +echo This script only works with NT-based versions of Windows. +goto :eof + +:nt +rem +rem Find the application home. +rem +rem %~dp0 is location of current script under NT +set _REALPATH=%~dp0 + +rem +rem Decide on the specific Wrapper binary to use (See delta-pack) +rem +if "%PROCESSOR_ARCHITEW6432%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="IA64" goto ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-32.exe +goto search +:amd64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-64.exe +goto search +:ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-ia-64.exe +goto search +:search +set _WRAPPER_EXE=%_WRAPPER_L_EXE% +if exist "%_WRAPPER_EXE%" goto conf +set _WRAPPER_EXE=%_REALPATH%%_WRAPPER_BASE%.exe +if exist "%_WRAPPER_EXE%" goto conf +echo Unable to locate a Wrapper executable using any of the following names: +echo %_WRAPPER_L_EXE% +echo %_WRAPPER_EXE% +pause +goto :eof + +rem +rem Find the wrapper.conf +rem +:conf +if not [%_WRAPPER_CONF_OVERRIDE%]==[] ( + set _WRAPPER_CONF="%~f1" + if not [%_WRAPPER_CONF%]==[""] ( + shift + goto :startup + ) +) +set _WRAPPER_CONF="%_WRAPPER_CONF_DEFAULT%" + +rem +rem Start the Wrapper +rem +:startup + +rem Collect an parameters +:parameters +set _PARAMETERS=%_PARAMETERS% %1 +shift +if not [%1]==[] goto :parameters + +if [%_PASS_THROUGH%]==[] ( + "%_WRAPPER_EXE%" -i %_WRAPPER_CONF% +) else ( + "%_WRAPPER_EXE%" -i %_WRAPPER_CONF% -- %_PARAMETERS% +) +if not errorlevel 1 goto :eof +pause + diff --git a/rapla-source-1.8.2/service/bin/PauseTestWrapper-NT.bat b/rapla-source-1.8.2/service/bin/PauseTestWrapper-NT.bat new file mode 100644 index 0000000..64b403d --- /dev/null +++ b/rapla-source-1.8.2/service/bin/PauseTestWrapper-NT.bat @@ -0,0 +1,100 @@ +@echo off +setlocal + +rem +rem Copyright (c) 1999, 2012 Tanuki Software, Ltd. +rem http://www.tanukisoftware.com +rem All rights reserved. +rem +rem This software is the proprietary information of Tanuki Software. +rem You shall use it only in accordance with the terms of the +rem license agreement you entered into with Tanuki Software. +rem http://wrapper.tanukisoftware.com/doc/english/licenseOverview.html +rem +rem Java Service Wrapper general startup script. +rem + +rem ----------------------------------------------------------------------------- +rem These settings can be modified to fit the needs of your application +rem Optimized for use with version 3.5.17 of the Wrapper. + +rem The base name for the Wrapper binary. +set _WRAPPER_BASE=wrapper + +rem The name and location of the Wrapper configuration file. This will be used +rem if the user does not specify a configuration file as the first parameter to +rem this script. +set _WRAPPER_CONF_DEFAULT=../conf/wrapper.conf + +rem Makes it possible to override the Wrapper configuration file by specifying it +rem as the first parameter. +rem set _WRAPPER_CONF_OVERRIDE=true + +rem Note that it is only possible to pass parameters through to the JVM when +rem installing the service, or when running in a console. + +rem Do not modify anything beyond this point +rem ----------------------------------------------------------------------------- + +rem +rem Resolve the real path of the wrapper.exe +rem For non NT systems, the _REALPATH and _WRAPPER_CONF values +rem can be hard-coded below and the following test removed. +rem +if "%OS%"=="Windows_NT" goto nt +echo This script only works with NT-based versions of Windows. +goto :eof + +:nt +rem +rem Find the application home. +rem +rem %~dp0 is location of current script under NT +set _REALPATH=%~dp0 + +rem +rem Decide on the specific Wrapper binary to use (See delta-pack) +rem +if "%PROCESSOR_ARCHITEW6432%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="IA64" goto ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-32.exe +goto search +:amd64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-64.exe +goto search +:ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-ia-64.exe +goto search +:search +set _WRAPPER_EXE=%_WRAPPER_L_EXE% +if exist "%_WRAPPER_EXE%" goto conf +set _WRAPPER_EXE=%_REALPATH%%_WRAPPER_BASE%.exe +if exist "%_WRAPPER_EXE%" goto conf +echo Unable to locate a Wrapper executable using any of the following names: +echo %_WRAPPER_L_EXE% +echo %_WRAPPER_EXE% +pause +goto :eof + +rem +rem Find the wrapper.conf +rem +:conf +if not [%_WRAPPER_CONF_OVERRIDE%]==[] ( + set _WRAPPER_CONF="%~f1" + if not [%_WRAPPER_CONF%]==[""] ( + shift + goto :startup + ) +) +set _WRAPPER_CONF="%_WRAPPER_CONF_DEFAULT%" + +rem +rem Start the Wrapper +rem +:startup +"%_WRAPPER_EXE%" -a %_WRAPPER_CONF% +if not errorlevel 1 goto :eof +pause + diff --git a/rapla-source-1.8.2/service/bin/QueryTestWrapper-NT.bat b/rapla-source-1.8.2/service/bin/QueryTestWrapper-NT.bat new file mode 100644 index 0000000..ffb7191 --- /dev/null +++ b/rapla-source-1.8.2/service/bin/QueryTestWrapper-NT.bat @@ -0,0 +1,98 @@ +@echo off +setlocal + +rem +rem Copyright (c) 1999, 2012 Tanuki Software, Ltd. +rem http://www.tanukisoftware.com +rem All rights reserved. +rem +rem This software is the proprietary information of Tanuki Software. +rem You shall use it only in accordance with the terms of the +rem license agreement you entered into with Tanuki Software. +rem http://wrapper.tanukisoftware.com/doc/english/licenseOverview.html +rem +rem Java Service Wrapper general startup script. +rem + +rem ----------------------------------------------------------------------------- +rem These settings can be modified to fit the needs of your application +rem Optimized for use with version 3.5.17 of the Wrapper. + +rem The base name for the Wrapper binary. +set _WRAPPER_BASE=wrapper + +rem The name and location of the Wrapper configuration file. This will be used +rem if the user does not specify a configuration file as the first parameter to +rem this script. +set _WRAPPER_CONF_DEFAULT=../conf/wrapper.conf + +rem Makes it possible to override the Wrapper configuration file by specifying it +rem as the first parameter. +rem set _WRAPPER_CONF_OVERRIDE=true + +rem Note that it is only possible to pass parameters through to the JVM when +rem installing the service, or when running in a console. + +rem Do not modify anything beyond this point +rem ----------------------------------------------------------------------------- + +rem +rem Resolve the real path of the wrapper.exe +rem For non NT systems, the _REALPATH and _WRAPPER_CONF values +rem can be hard-coded below and the following test removed. +rem +if "%OS%"=="Windows_NT" goto nt +echo This script only works with NT-based versions of Windows. +goto :eof + +:nt +rem +rem Find the application home. +rem +rem %~dp0 is location of current script under NT +set _REALPATH=%~dp0 + +rem +rem Decide on the specific Wrapper binary to use (See delta-pack) +rem +if "%PROCESSOR_ARCHITEW6432%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="IA64" goto ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-32.exe +goto search +:amd64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-64.exe +goto search +:ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-ia-64.exe +goto search +:search +set _WRAPPER_EXE=%_WRAPPER_L_EXE% +if exist "%_WRAPPER_EXE%" goto conf +set _WRAPPER_EXE=%_REALPATH%%_WRAPPER_BASE%.exe +if exist "%_WRAPPER_EXE%" goto conf +echo Unable to locate a Wrapper executable using any of the following names: +echo %_WRAPPER_L_EXE% +echo %_WRAPPER_EXE% +pause +goto :eof + +rem +rem Find the wrapper.conf +rem +:conf +if not [%_WRAPPER_CONF_OVERRIDE%]==[] ( + set _WRAPPER_CONF="%~f1" + if not [%_WRAPPER_CONF%]==[""] ( + shift + goto :startup + ) +) +set _WRAPPER_CONF="%_WRAPPER_CONF_DEFAULT%" + +rem +rem Start the Wrapper +rem +:startup +"%_WRAPPER_EXE%" -q %_WRAPPER_CONF% +pause diff --git a/rapla-source-1.8.2/service/bin/ResumeTestWrapper-NT.bat b/rapla-source-1.8.2/service/bin/ResumeTestWrapper-NT.bat new file mode 100644 index 0000000..41abe5c --- /dev/null +++ b/rapla-source-1.8.2/service/bin/ResumeTestWrapper-NT.bat @@ -0,0 +1,100 @@ +@echo off +setlocal + +rem +rem Copyright (c) 1999, 2012 Tanuki Software, Ltd. +rem http://www.tanukisoftware.com +rem All rights reserved. +rem +rem This software is the proprietary information of Tanuki Software. +rem You shall use it only in accordance with the terms of the +rem license agreement you entered into with Tanuki Software. +rem http://wrapper.tanukisoftware.com/doc/english/licenseOverview.html +rem +rem Java Service Wrapper general startup script. +rem + +rem ----------------------------------------------------------------------------- +rem These settings can be modified to fit the needs of your application +rem Optimized for use with version 3.5.17 of the Wrapper. + +rem The base name for the Wrapper binary. +set _WRAPPER_BASE=wrapper + +rem The name and location of the Wrapper configuration file. This will be used +rem if the user does not specify a configuration file as the first parameter to +rem this script. +set _WRAPPER_CONF_DEFAULT=../conf/wrapper.conf + +rem Makes it possible to override the Wrapper configuration file by specifying it +rem as the first parameter. +rem set _WRAPPER_CONF_OVERRIDE=true + +rem Note that it is only possible to pass parameters through to the JVM when +rem installing the service, or when running in a console. + +rem Do not modify anything beyond this point +rem ----------------------------------------------------------------------------- + +rem +rem Resolve the real path of the wrapper.exe +rem For non NT systems, the _REALPATH and _WRAPPER_CONF values +rem can be hard-coded below and the following test removed. +rem +if "%OS%"=="Windows_NT" goto nt +echo This script only works with NT-based versions of Windows. +goto :eof + +:nt +rem +rem Find the application home. +rem +rem %~dp0 is location of current script under NT +set _REALPATH=%~dp0 + +rem +rem Decide on the specific Wrapper binary to use (See delta-pack) +rem +if "%PROCESSOR_ARCHITEW6432%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="IA64" goto ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-32.exe +goto search +:amd64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-64.exe +goto search +:ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-ia-64.exe +goto search +:search +set _WRAPPER_EXE=%_WRAPPER_L_EXE% +if exist "%_WRAPPER_EXE%" goto conf +set _WRAPPER_EXE=%_REALPATH%%_WRAPPER_BASE%.exe +if exist "%_WRAPPER_EXE%" goto conf +echo Unable to locate a Wrapper executable using any of the following names: +echo %_WRAPPER_L_EXE% +echo %_WRAPPER_EXE% +pause +goto :eof + +rem +rem Find the wrapper.conf +rem +:conf +if not [%_WRAPPER_CONF_OVERRIDE%]==[] ( + set _WRAPPER_CONF="%~f1" + if not [%_WRAPPER_CONF%]==[""] ( + shift + goto :startup + ) +) +set _WRAPPER_CONF="%_WRAPPER_CONF_DEFAULT%" + +rem +rem Start the Wrapper +rem +:startup +"%_WRAPPER_EXE%" -e %_WRAPPER_CONF% +if not errorlevel 1 goto :eof +pause + diff --git a/rapla-source-1.8.2/service/bin/StartTestWrapper-NT.bat b/rapla-source-1.8.2/service/bin/StartTestWrapper-NT.bat new file mode 100644 index 0000000..330d48a --- /dev/null +++ b/rapla-source-1.8.2/service/bin/StartTestWrapper-NT.bat @@ -0,0 +1,100 @@ +@echo off +setlocal + +rem +rem Copyright (c) 1999, 2012 Tanuki Software, Ltd. +rem http://www.tanukisoftware.com +rem All rights reserved. +rem +rem This software is the proprietary information of Tanuki Software. +rem You shall use it only in accordance with the terms of the +rem license agreement you entered into with Tanuki Software. +rem http://wrapper.tanukisoftware.com/doc/english/licenseOverview.html +rem +rem Java Service Wrapper general startup script. +rem + +rem ----------------------------------------------------------------------------- +rem These settings can be modified to fit the needs of your application +rem Optimized for use with version 3.5.17 of the Wrapper. + +rem The base name for the Wrapper binary. +set _WRAPPER_BASE=wrapper + +rem The name and location of the Wrapper configuration file. This will be used +rem if the user does not specify a configuration file as the first parameter to +rem this script. +set _WRAPPER_CONF_DEFAULT=../conf/wrapper.conf + +rem Makes it possible to override the Wrapper configuration file by specifying it +rem as the first parameter. +rem set _WRAPPER_CONF_OVERRIDE=true + +rem Note that it is only possible to pass parameters through to the JVM when +rem installing the service, or when running in a console. + +rem Do not modify anything beyond this point +rem ----------------------------------------------------------------------------- + +rem +rem Resolve the real path of the wrapper.exe +rem For non NT systems, the _REALPATH and _WRAPPER_CONF values +rem can be hard-coded below and the following test removed. +rem +if "%OS%"=="Windows_NT" goto nt +echo This script only works with NT-based versions of Windows. +goto :eof + +:nt +rem +rem Find the application home. +rem +rem %~dp0 is location of current script under NT +set _REALPATH=%~dp0 + +rem +rem Decide on the specific Wrapper binary to use (See delta-pack) +rem +if "%PROCESSOR_ARCHITEW6432%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="IA64" goto ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-32.exe +goto search +:amd64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-64.exe +goto search +:ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-ia-64.exe +goto search +:search +set _WRAPPER_EXE=%_WRAPPER_L_EXE% +if exist "%_WRAPPER_EXE%" goto conf +set _WRAPPER_EXE=%_REALPATH%%_WRAPPER_BASE%.exe +if exist "%_WRAPPER_EXE%" goto conf +echo Unable to locate a Wrapper executable using any of the following names: +echo %_WRAPPER_L_EXE% +echo %_WRAPPER_EXE% +pause +goto :eof + +rem +rem Find the wrapper.conf +rem +:conf +if not [%_WRAPPER_CONF_OVERRIDE%]==[] ( + set _WRAPPER_CONF="%~f1" + if not [%_WRAPPER_CONF%]==[""] ( + shift + goto :startup + ) +) +set _WRAPPER_CONF="%_WRAPPER_CONF_DEFAULT%" + +rem +rem Start the Wrapper +rem +:startup +"%_WRAPPER_EXE%" -t %_WRAPPER_CONF% +if not errorlevel 1 goto :eof +pause + diff --git a/rapla-source-1.8.2/service/bin/StopTestWrapper-NT.bat b/rapla-source-1.8.2/service/bin/StopTestWrapper-NT.bat new file mode 100644 index 0000000..7395fe0 --- /dev/null +++ b/rapla-source-1.8.2/service/bin/StopTestWrapper-NT.bat @@ -0,0 +1,100 @@ +@echo off +setlocal + +rem +rem Copyright (c) 1999, 2012 Tanuki Software, Ltd. +rem http://www.tanukisoftware.com +rem All rights reserved. +rem +rem This software is the proprietary information of Tanuki Software. +rem You shall use it only in accordance with the terms of the +rem license agreement you entered into with Tanuki Software. +rem http://wrapper.tanukisoftware.com/doc/english/licenseOverview.html +rem +rem Java Service Wrapper general startup script. +rem + +rem ----------------------------------------------------------------------------- +rem These settings can be modified to fit the needs of your application +rem Optimized for use with version 3.5.17 of the Wrapper. + +rem The base name for the Wrapper binary. +set _WRAPPER_BASE=wrapper + +rem The name and location of the Wrapper configuration file. This will be used +rem if the user does not specify a configuration file as the first parameter to +rem this script. +set _WRAPPER_CONF_DEFAULT=../conf/wrapper.conf + +rem Makes it possible to override the Wrapper configuration file by specifying it +rem as the first parameter. +rem set _WRAPPER_CONF_OVERRIDE=true + +rem Note that it is only possible to pass parameters through to the JVM when +rem installing the service, or when running in a console. + +rem Do not modify anything beyond this point +rem ----------------------------------------------------------------------------- + +rem +rem Resolve the real path of the wrapper.exe +rem For non NT systems, the _REALPATH and _WRAPPER_CONF values +rem can be hard-coded below and the following test removed. +rem +if "%OS%"=="Windows_NT" goto nt +echo This script only works with NT-based versions of Windows. +goto :eof + +:nt +rem +rem Find the application home. +rem +rem %~dp0 is location of current script under NT +set _REALPATH=%~dp0 + +rem +rem Decide on the specific Wrapper binary to use (See delta-pack) +rem +if "%PROCESSOR_ARCHITEW6432%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="IA64" goto ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-32.exe +goto search +:amd64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-64.exe +goto search +:ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-ia-64.exe +goto search +:search +set _WRAPPER_EXE=%_WRAPPER_L_EXE% +if exist "%_WRAPPER_EXE%" goto conf +set _WRAPPER_EXE=%_REALPATH%%_WRAPPER_BASE%.exe +if exist "%_WRAPPER_EXE%" goto conf +echo Unable to locate a Wrapper executable using any of the following names: +echo %_WRAPPER_L_EXE% +echo %_WRAPPER_EXE% +pause +goto :eof + +rem +rem Find the wrapper.conf +rem +:conf +if not [%_WRAPPER_CONF_OVERRIDE%]==[] ( + set _WRAPPER_CONF="%~f1" + if not [%_WRAPPER_CONF%]==[""] ( + shift + goto :startup + ) +) +set _WRAPPER_CONF="%_WRAPPER_CONF_DEFAULT%" + +rem +rem Start the Wrapper +rem +:startup +"%_WRAPPER_EXE%" -p %_WRAPPER_CONF% +if not errorlevel 1 goto :eof +pause + diff --git a/rapla-source-1.8.2/service/bin/TestWrapper.bat b/rapla-source-1.8.2/service/bin/TestWrapper.bat new file mode 100644 index 0000000..8b0e230 --- /dev/null +++ b/rapla-source-1.8.2/service/bin/TestWrapper.bat @@ -0,0 +1,121 @@ +@echo off +setlocal + +rem +rem Copyright (c) 1999, 2012 Tanuki Software, Ltd. +rem http://www.tanukisoftware.com +rem All rights reserved. +rem +rem This software is the proprietary information of Tanuki Software. +rem You shall use it only in accordance with the terms of the +rem license agreement you entered into with Tanuki Software. +rem http://wrapper.tanukisoftware.com/doc/english/licenseOverview.html +rem +rem Java Service Wrapper general passthrough startup script. +rem + +rem ----------------------------------------------------------------------------- +rem These settings can be modified to fit the needs of your application +rem Optimized for use with version 3.5.17 of the Wrapper. +rem +rem ******************************************************************** +rem NOTE - This script has been modified to run the TestWrapper sample +rem application and should NOT be used as a base for your own +rem applications. All of the documentation assumes that you are +rem working from the default source script: +rem WRAPPER_HOME/src/bin/App.bat.in +rem ******************************************************************** + +rem The base name for the Wrapper binary. +set _WRAPPER_BASE=wrapper + +rem The name and location of the Wrapper configuration file. This will be used +rem if the user does not specify a configuration file as the first parameter to +rem this script. It will not be possible to specify a configuration file on the +rem command line if _PASS_THROUGH is set. +set _WRAPPER_CONF_DEFAULT=../conf/wrapper.conf + +rem Makes it possible to override the Wrapper configuration file by specifying it +rem as the first parameter. +rem set _WRAPPER_CONF_OVERRIDE=true + +rem _PASS_THROUGH tells the script to pass all parameters through to the JVM as +rem is. +set _PASS_THROUGH=true + +rem Do not modify anything beyond this point +rem ----------------------------------------------------------------------------- + +rem +rem Resolve the real path of the wrapper.exe +rem For non NT systems, the _REALPATH and _WRAPPER_CONF values +rem can be hard-coded below and the following test removed. +rem +if "%OS%"=="Windows_NT" goto nt +echo This script only works with NT-based versions of Windows. +goto :eof + +:nt +rem +rem Find the application home. +rem +rem %~dp0 is location of current script under NT +set _REALPATH=%~dp0 + +rem +rem Decide on the specific Wrapper binary to use (See delta-pack) +rem +if "%PROCESSOR_ARCHITEW6432%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="IA64" goto ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-32.exe +goto search +:amd64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-64.exe +goto search +:ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-ia-64.exe +goto search +:search +set _WRAPPER_EXE=%_WRAPPER_L_EXE% +if exist "%_WRAPPER_EXE%" goto conf +set _WRAPPER_EXE=%_REALPATH%%_WRAPPER_BASE%.exe +if exist "%_WRAPPER_EXE%" goto conf +echo Unable to locate a Wrapper executable using any of the following names: +echo %_WRAPPER_L_EXE% +echo %_WRAPPER_EXE% +pause +goto :eof + +rem +rem Find the wrapper.conf +rem +:conf +if not [%_WRAPPER_CONF_OVERRIDE%]==[] ( + set _WRAPPER_CONF="%~f1" + if not [%_WRAPPER_CONF%]==[""] ( + shift + goto :startup + ) +) +set _WRAPPER_CONF="%_WRAPPER_CONF_DEFAULT%" + +rem +rem Start the Wrapper +rem +:startup + +rem Collect an parameters +:parameters +set _PARAMETERS=%_PARAMETERS% %1 +shift +if not [%1]==[] goto :parameters + +if [%_PASS_THROUGH%]==[] ( + "%_WRAPPER_EXE%" -c %_WRAPPER_CONF% +) else ( + "%_WRAPPER_EXE%" -c %_WRAPPER_CONF% -- %_PARAMETERS% +) +if not errorlevel 1 goto :eof +pause + diff --git a/rapla-source-1.8.2/service/bin/TestWrapperCommand.bat b/rapla-source-1.8.2/service/bin/TestWrapperCommand.bat new file mode 100644 index 0000000..0903866 --- /dev/null +++ b/rapla-source-1.8.2/service/bin/TestWrapperCommand.bat @@ -0,0 +1,153 @@ +@echo off +setlocal + +rem +rem Copyright (c) 1999, 2012 Tanuki Software, Ltd. +rem http://www.tanukisoftware.com +rem All rights reserved. +rem +rem This software is the proprietary information of Tanuki Software. +rem You shall use it only in accordance with the terms of the +rem license agreement you entered into with Tanuki Software. +rem http://wrapper.tanukisoftware.com/doc/english/licenseOverview.html +rem +rem Java Service Wrapper command based script. +rem + +rem ----------------------------------------------------------------------------- +rem These settings can be modified to fit the needs of your application +rem Optimized for use with version 3.5.17 of the Wrapper. + +rem The base name for the Wrapper binary. +set _WRAPPER_BASE=wrapper + +rem The name and location of the Wrapper configuration file. +rem (Do not remove quotes.) +set _WRAPPER_CONF="../conf/wrapper.conf" + +rem _FIXED_COMMAND tells the script to use a hard coded command rather than +rem expecting the first parameter of the command line to be the command. +rem By default the command will will be expected to be the first parameter. +rem set _FIXED_COMMAND=console + +rem _PASS_THROUGH tells the script to pass all parameters through to the JVM +rem as is. If _FIXED_COMMAND is specified then all parameters will be passed. +rem If not set then all parameters starting with the second will be passed. +set _PASS_THROUGH=true + +rem Do not modify anything beyond this point +rem ----------------------------------------------------------------------------- + +if "%OS%"=="Windows_NT" goto nt +echo This script only works with NT-based versions of Windows. +goto :eof + +:nt +rem Find the application home. +rem %~dp0 is location of current script under NT +set _REALPATH=%~dp0 + +rem +rem Decide on the specific Wrapper binary to use (See delta-pack) +rem +if "%PROCESSOR_ARCHITEW6432%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="IA64" goto ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-32.exe +goto search +:amd64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-64.exe +goto search +:ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-ia-64.exe +goto search +:search + +set _WRAPPER_EXE=%_WRAPPER_L_EXE% +if exist "%_WRAPPER_EXE%" goto conf +set _WRAPPER_EXE=%_REALPATH%%_WRAPPER_BASE%.exe +if exist "%_WRAPPER_EXE%" goto conf +echo Unable to locate a Wrapper executable using any of the following names: +echo %_WRAPPER_L_EXE% +echo %_WRAPPER_EXE% +pause +goto :eof + +:conf +if not [%_FIXED_COMMAND%]==[] ( + set _COMMAND=%_FIXED_COMMAND% +) else ( + set _COMMAND=%1 + shift +) + +rem Collect all parameters +:parameters +set _PARAMETERS=%_PARAMETERS% %1 +shift +if not [%1]==[] goto parameters + +:callcommand +rem +rem Run the application. +rem At runtime, the current directory will be that of wrapper.exe +rem +set _MATCHED=true +if [%_COMMAND%]==[console] ( + if [%_PASS_THROUGH%]==[] ( + "%_WRAPPER_EXE%" -c "%_WRAPPER_CONF%" %_PARAMETERS% + ) else ( + "%_WRAPPER_EXE%" -c "%_WRAPPER_CONF%" -- %_PARAMETERS% + ) +) else if [%_COMMAND%]==[start] ( + call :start +) else if [%_COMMAND%]==[stop] ( + call :stop +) else if [%_COMMAND%]==[install] ( + if [%_PASS_THROUGH%]==[] ( + "%_WRAPPER_EXE%" -i "%_WRAPPER_CONF%" %_PARAMETERS% + ) else ( + "%_WRAPPER_EXE%" -i "%_WRAPPER_CONF%" -- %_PARAMETERS% + ) +) else if [%_COMMAND%]==[pause] ( + "%_WRAPPER_EXE%" -a "%_WRAPPER_CONF%" +) else if [%_COMMAND%]==[resume] ( + "%_WRAPPER_EXE%" -e "%_WRAPPER_CONF%" +) else if [%_COMMAND%]==[status] ( + "%_WRAPPER_EXE%" -q "%_WRAPPER_CONF%" +) else if [%_COMMAND%]==[remove] ( + "%_WRAPPER_EXE%" -r "%_WRAPPER_CONF%" +) else if [%_COMMAND%]==[restart] ( + call :stop + call :start +) else ( + set _MATCHED= + goto showusage +) + +if errorlevel 1 ( + if [%_MATCHED%]==[] goto showusage +) +goto :eof + +:showusage +rem A command was not specified, or it was now known. +if not [%_COMMAND%]==[] ( + echo Unknown command: %_COMMAND% + echo. +) +if [%_PASS_THROUGH%]==[] ( + echo Usage: %0 [ console : start : pause : resume : stop : restart : install : remove : status ] +) else ( + echo Usage: %0 [ console {JavaAppArgs} : start : pause : resume : stop : restart : install {JavaAppArgs} : remove : status ] +) +pause +goto :eof + + +:start + "%_WRAPPER_EXE%" -t "%_WRAPPER_CONF%" + goto :eof +:stop + "%_WRAPPER_EXE%" -p "%_WRAPPER_CONF%" + goto :eof diff --git a/rapla-source-1.8.2/service/bin/UninstallTestWrapper-NT.bat b/rapla-source-1.8.2/service/bin/UninstallTestWrapper-NT.bat new file mode 100644 index 0000000..f6ae553 --- /dev/null +++ b/rapla-source-1.8.2/service/bin/UninstallTestWrapper-NT.bat @@ -0,0 +1,100 @@ +@echo off +setlocal + +rem +rem Copyright (c) 1999, 2012 Tanuki Software, Ltd. +rem http://www.tanukisoftware.com +rem All rights reserved. +rem +rem This software is the proprietary information of Tanuki Software. +rem You shall use it only in accordance with the terms of the +rem license agreement you entered into with Tanuki Software. +rem http://wrapper.tanukisoftware.com/doc/english/licenseOverview.html +rem +rem Java Service Wrapper general startup script. +rem + +rem ----------------------------------------------------------------------------- +rem These settings can be modified to fit the needs of your application +rem Optimized for use with version 3.5.17 of the Wrapper. + +rem The base name for the Wrapper binary. +set _WRAPPER_BASE=wrapper + +rem The name and location of the Wrapper configuration file. This will be used +rem if the user does not specify a configuration file as the first parameter to +rem this script. +set _WRAPPER_CONF_DEFAULT=../conf/wrapper.conf + +rem Makes it possible to override the Wrapper configuration file by specifying it +rem as the first parameter. +rem set _WRAPPER_CONF_OVERRIDE=true + +rem Note that it is only possible to pass parameters through to the JVM when +rem installing the service, or when running in a console. + +rem Do not modify anything beyond this point +rem ----------------------------------------------------------------------------- + +rem +rem Resolve the real path of the wrapper.exe +rem For non NT systems, the _REALPATH and _WRAPPER_CONF values +rem can be hard-coded below and the following test removed. +rem +if "%OS%"=="Windows_NT" goto nt +echo This script only works with NT-based versions of Windows. +goto :eof + +:nt +rem +rem Find the application home. +rem +rem %~dp0 is location of current script under NT +set _REALPATH=%~dp0 + +rem +rem Decide on the specific Wrapper binary to use (See delta-pack) +rem +if "%PROCESSOR_ARCHITEW6432%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="AMD64" goto amd64 +if "%PROCESSOR_ARCHITECTURE%"=="IA64" goto ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-32.exe +goto search +:amd64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-x86-64.exe +goto search +:ia64 +set _WRAPPER_L_EXE=%_REALPATH%%_WRAPPER_BASE%-windows-ia-64.exe +goto search +:search +set _WRAPPER_EXE=%_WRAPPER_L_EXE% +if exist "%_WRAPPER_EXE%" goto conf +set _WRAPPER_EXE=%_REALPATH%%_WRAPPER_BASE%.exe +if exist "%_WRAPPER_EXE%" goto conf +echo Unable to locate a Wrapper executable using any of the following names: +echo %_WRAPPER_L_EXE% +echo %_WRAPPER_EXE% +pause +goto :eof + +rem +rem Find the wrapper.conf +rem +:conf +if not [%_WRAPPER_CONF_OVERRIDE%]==[] ( + set _WRAPPER_CONF="%~f1" + if not [%_WRAPPER_CONF%]==[""] ( + shift + goto :startup + ) +) +set _WRAPPER_CONF="%_WRAPPER_CONF_DEFAULT%" + +rem +rem Start the Wrapper +rem +:startup +"%_WRAPPER_EXE%" -r %_WRAPPER_CONF% +if not errorlevel 1 goto :eof +pause + diff --git a/rapla-source-1.8.2/service/bin/testwrapper b/rapla-source-1.8.2/service/bin/testwrapper new file mode 100644 index 0000000..a612859 --- /dev/null +++ b/rapla-source-1.8.2/service/bin/testwrapper @@ -0,0 +1,1629 @@ +#! /bin/sh + +# +# Copyright (c) 1999, 2012 Tanuki Software, Ltd. +# http://www.tanukisoftware.com +# All rights reserved. +# +# This software is the proprietary information of Tanuki Software. +# You shall use it only in accordance with the terms of the +# license agreement you entered into with Tanuki Software. +# http://wrapper.tanukisoftware.com/doc/english/licenseOverview.html +# +# Java Service Wrapper sh script. Suitable for starting and stopping +# wrapped Java applications on UNIX platforms. +# + +#----------------------------------------------------------------------------- +# These settings can be modified to fit the needs of your application +# Optimized for use with version 3.5.17 of the Wrapper. + +#******************************************************************** +# NOTE - This script has been modified to run the TestWrapper sample +# application and should NOT be used as a base for your own +# applications. All of the documentation assumes that you are +# working from the default source script: +# WRAPPER_HOME/src/bin/sh.script.in +#******************************************************************** + +# Application +APP_NAME="testwrapper" +APP_LONG_NAME="Test Wrapper Sample Application" + +# Wrapper +WRAPPER_CMD="./wrapper" +WRAPPER_CONF="../conf/wrapper.conf" + +# Priority at which to run the wrapper. See "man nice" for valid priorities. +# nice is only used if a priority is specified. +PRIORITY= + +# Location of the pid file. +PIDDIR="." + +# FIXED_COMMAND tells the script to use a hard coded action rather than +# expecting the first parameter of the command line to be the command. +# By default the command will will be expected to be the first parameter. +#FIXED_COMMAND=console + +# PASS_THROUGH tells the script to pass all arguments through to the JVM +# as is. If FIXED_COMMAND is specified then all arguments will be passed. +# If not set then all arguments starting with the second will be passed. +PASS_THROUGH=true + +# If uncommented, causes the Wrapper to be shutdown using an anchor file. +# When launched with the 'start' command, it will also ignore all INT and +# TERM signals. +#IGNORE_SIGNALS=true + +# Wrapper will start the JVM asynchronously. Your application may have some +# initialization tasks and it may be desirable to wait a few seconds +# before returning. For example, to delay the invocation of following +# startup scripts. Setting WAIT_AFTER_STARTUP to a positive number will +# cause the start command to delay for the indicated period of time +# (in seconds). +# +WAIT_AFTER_STARTUP=0 + +# If set, wait for the wrapper to report that the daemon has started +WAIT_FOR_STARTED_STATUS=true +WAIT_FOR_STARTED_TIMEOUT=120 + +# If set, the status, start_msg and stop_msg commands will print out detailed +# state information on the Wrapper and Java processes. +#DETAIL_STATUS=true + +# If set, the 'pause' and 'resume' commands will be enabled. These make it +# possible to pause the JVM or Java application without completely stopping +# the Wrapper. See the wrapper.pausable and wrapper.pausable.stop_jvm +# properties for more information. +#PAUSABLE=true + +# If specified, the Wrapper will be run as the specified user. +# IMPORTANT - Make sure that the user has the required privileges to write +# the PID file and wrapper.log files. Failure to be able to write the log +# file will cause the Wrapper to exit without any way to write out an error +# message. +# NOTE - This will set the user which is used to run the Wrapper as well as +# the JVM and is not useful in situations where a privileged resource or +# port needs to be allocated prior to the user being changed. +#RUN_AS_USER= + +# By default we show a detailed usage block. Uncomment to show brief usage. +#BRIEF_USAGE=true + +# flag for using upstart when installing (rather than init.d rc.d) +USE_UPSTART= + +# When installing on On Mac OSX platforms, the following domain will be used to +# prefix the plist file name. +PLIST_DOMAIN=org.tanukisoftware.wrapper + +# The following two lines are used by the chkconfig command. Change as is +# appropriate for your application. They should remain commented. +# chkconfig: 2345 20 80 +# description: Test Wrapper Sample Application + +# Initialization block for the install_initd and remove_initd scripts used by +# SUSE linux distributions. +### BEGIN INIT INFO +# Provides: testwrapper +# Required-Start: $local_fs $network $syslog +# Should-Start: +# Required-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Test Wrapper Sample Application +# Description: Test Wrapper Sample Application Description +### END INIT INFO + +# Do not modify anything beyond this point +#----------------------------------------------------------------------------- + +if [ -n "$FIXED_COMMAND" ] +then + COMMAND="$FIXED_COMMAND" +else + COMMAND="$1" +fi + + +# Required for HP-UX Startup +if [ `uname -s` = "HP-UX" -o `uname -s` = "HP-UX64" ] ; then + PATH=$PATH:/usr/bin +fi + +# Get the fully qualified path to the script +case $0 in + /*) + SCRIPT="$0" + ;; + *) + PWD=`pwd` + SCRIPT="$PWD/$0" + ;; +esac + +# Resolve the true real path without any sym links. +CHANGED=true +while [ "X$CHANGED" != "X" ] +do + # Change spaces to ":" so the tokens can be parsed. + SAFESCRIPT=`echo $SCRIPT | sed -e 's; ;:;g'` + # Get the real path to this script, resolving any symbolic links + TOKENS=`echo $SAFESCRIPT | sed -e 's;/; ;g'` + REALPATH= + for C in $TOKENS; do + # Change any ":" in the token back to a space. + C=`echo $C | sed -e 's;:; ;g'` + REALPATH="$REALPATH/$C" + # If REALPATH is a sym link, resolve it. Loop for nested links. + while [ -h "$REALPATH" ] ; do + LS="`ls -ld "$REALPATH"`" + LINK="`expr "$LS" : '.*-> \(.*\)$'`" + if expr "$LINK" : '/.*' > /dev/null; then + # LINK is absolute. + REALPATH="$LINK" + else + # LINK is relative. + REALPATH="`dirname "$REALPATH"`""/$LINK" + fi + done + done + + if [ "$REALPATH" = "$SCRIPT" ] + then + CHANGED="" + else + SCRIPT="$REALPATH" + fi +done + +# Get the location of the script. +REALDIR=`dirname "$REALPATH"` +# Normalize the path +REALDIR=`cd "${REALDIR}"; pwd` + +# If the PIDDIR is relative, set its value relative to the full REALPATH to avoid problems if +# the working directory is later changed. +FIRST_CHAR=`echo $PIDDIR | cut -c1,1` +if [ "$FIRST_CHAR" != "/" ] +then + PIDDIR=$REALDIR/$PIDDIR +fi +# Same test for WRAPPER_CMD +FIRST_CHAR=`echo $WRAPPER_CMD | cut -c1,1` +if [ "$FIRST_CHAR" != "/" ] +then + WRAPPER_CMD=$REALDIR/$WRAPPER_CMD +fi +# Same test for WRAPPER_CONF +FIRST_CHAR=`echo $WRAPPER_CONF | cut -c1,1` +if [ "$FIRST_CHAR" != "/" ] +then + WRAPPER_CONF=$REALDIR/$WRAPPER_CONF +fi + +# Process ID +ANCHORFILE="$PIDDIR/$APP_NAME.anchor" +COMMANDFILE="$PIDDIR/$APP_NAME.command" +STATUSFILE="$PIDDIR/$APP_NAME.status" +JAVASTATUSFILE="$PIDDIR/$APP_NAME.java.status" +PIDFILE="$PIDDIR/$APP_NAME.pid" +LOCKDIR="/var/lock/subsys" +LOCKFILE="$LOCKDIR/$APP_NAME" +pid="" + +# Resolve the location of the 'ps' command +PSEXE="/usr/ucb/ps" + if [ ! -x "$PSEXE" ] + then + PSEXE="/usr/bin/ps" + if [ ! -x "$PSEXE" ] + then + PSEXE="/bin/ps" + if [ ! -x "$PSEXE" ] + then + eval echo `gettext 'Unable to locate "ps".'` + eval echo `gettext 'Please report this message along with the location of the command on your system.'` + exit 1 + fi + fi + fi + +TREXE="/usr/bin/tr" +if [ ! -x "$TREXE" ] +then + TREXE="/bin/tr" + if [ ! -x "$TREXE" ] + then + eval echo `gettext 'Unable to locate "tr".'` + eval echo `gettext 'Please report this message along with the location of the command on your system.'` + exit 1 + fi +fi +# Resolve the os +DIST_OS=`uname -s | $TREXE "[A-Z]" "[a-z]" | $TREXE -d ' '` +case "$DIST_OS" in + 'sunos') + DIST_OS="solaris" + ;; + 'hp-ux' | 'hp-ux64') + # HP-UX needs the XPG4 version of ps (for -o args) + DIST_OS="hpux" + UNIX95="" + export UNIX95 + ;; + 'darwin') + DIST_OS="macosx" + ;; + 'unix_sv') + DIST_OS="unixware" + ;; + 'os/390') + DIST_OS="zos" + ;; +esac + +# Resolve the architecture +if [ "$DIST_OS" = "macosx" ] +then + OS_VER=`sw_vers | grep 'ProductVersion:' | grep -o '[0-9]*\.[0-9]*\.[0-9]*'` + DIST_ARCH="universal" + if [[ "$OS_VER" < "10.5.0" ]] + then + DIST_BITS="32" + else + if [ "X`sysctl -n hw.cpu64bit_capable`" == "X1" ] + then + DIST_BITS="64" + else + DIST_BITS="32" + fi + fi + APP_PLIST_BASE=${PLIST_DOMAIN}.${APP_NAME} + APP_PLIST=${APP_PLIST_BASE}.plist +else + DIST_ARCH= + DIST_ARCH=`uname -p 2>/dev/null | $TREXE "[A-Z]" "[a-z]" | $TREXE -d ' '` + if [ "X$DIST_ARCH" = "X" ] + then + DIST_ARCH="unknown" + fi + if [ "$DIST_ARCH" = "unknown" ] + then + DIST_ARCH=`uname -m 2>/dev/null | $TREXE "[A-Z]" "[a-z]" | $TREXE -d ' '` + fi + case "$DIST_ARCH" in + 'athlon' | 'i386' | 'i486' | 'i586' | 'i686') + DIST_ARCH="x86" + if [ "${DIST_OS}" = "solaris" ] ; then + DIST_BITS=`isainfo -b` + else + DIST_BITS="32" + fi + ;; + 'amd64' | 'x86_64') + DIST_ARCH="x86" + DIST_BITS="64" + ;; + 'ia32') + DIST_ARCH="ia" + DIST_BITS="32" + ;; + 'ia64' | 'ia64n' | 'ia64w') + DIST_ARCH="ia" + DIST_BITS="64" + ;; + 'ip27') + DIST_ARCH="mips" + DIST_BITS="32" + ;; + 'power' | 'powerpc' | 'power_pc' | 'ppc64') + if [ "${DIST_ARCH}" = "ppc64" ] ; then + DIST_BITS="64" + else + DIST_BITS="32" + fi + DIST_ARCH="ppc" + if [ "${DIST_OS}" = "aix" ] ; then + if [ `getconf KERNEL_BITMODE` -eq 64 ]; then + DIST_BITS="64" + else + DIST_BITS="32" + fi + fi + ;; + 'pa_risc' | 'pa-risc') + DIST_ARCH="parisc" + if [ `getconf KERNEL_BITS` -eq 64 ]; then + DIST_BITS="64" + else + DIST_BITS="32" + fi + ;; + 'sun4u' | 'sparcv9' | 'sparc') + DIST_ARCH="sparc" + DIST_BITS=`isainfo -b` + ;; + '9000/800' | '9000/785') + DIST_ARCH="parisc" + if [ `getconf KERNEL_BITS` -eq 64 ]; then + DIST_BITS="64" + else + DIST_BITS="32" + fi + ;; + '2064' | '2066' | '2084' | '2086' | '2094' | '2096' | '2097' | '2098' | '2817') + DIST_ARCH="390" + DIST_BITS="64" + ;; + armv*) + if [ -z "`readelf -A /proc/self/exe | grep Tag_ABI_VFP_args`" ] ; then + DIST_ARCH="armel" + DIST_BITS="32" + else + DIST_ARCH="armhf" + DIST_BITS="32" + fi + ;; + esac +fi + +# OSX always places Java in the same location so we can reliably set JAVA_HOME +if [ "$DIST_OS" = "macosx" ] +then + if [ -z "$JAVA_HOME" ]; then + JAVA_HOME="/Library/Java/Home"; export JAVA_HOME + fi +fi + +# Test Echo +ECHOTEST=`echo -n "x"` +if [ "$ECHOTEST" = "x" ] +then + ECHOOPT="-n " +else + ECHOOPT="" +fi + + +gettext() { + "$WRAPPER_CMD" --translate "$1" "$WRAPPER_CONF" 2>/dev/null + if [ $? != 0 ] ; then + echo "$1" + fi +} + +outputFile() { + if [ -f "$1" ] + then + eval echo `gettext ' $1 Found but not executable.'`; + else + echo " $1" + fi +} + +# Decide on the wrapper binary to use. +# If the bits of the OS could be detected, we will try to look for the +# binary with the correct bits value. If it doesn't exist, fall back +# and look for the 32-bit binary. If that doesn't exist either then +# look for the default. +WRAPPER_TEST_CMD="" +if [ -f "$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-$DIST_BITS" ] +then + WRAPPER_TEST_CMD="$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-$DIST_BITS" + if [ ! -x "$WRAPPER_TEST_CMD" ] + then + chmod +x "$WRAPPER_TEST_CMD" 2>/dev/null + fi + if [ -x "$WRAPPER_TEST_CMD" ] + then + WRAPPER_CMD="$WRAPPER_TEST_CMD" + else + outputFile "$WRAPPER_TEST_CMD" + WRAPPER_TEST_CMD="" + fi +fi +if [ -f "$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-32" -a -z "$WRAPPER_TEST_CMD" ] +then + WRAPPER_TEST_CMD="$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-32" + if [ ! -x "$WRAPPER_TEST_CMD" ] + then + chmod +x "$WRAPPER_TEST_CMD" 2>/dev/null + fi + if [ -x "$WRAPPER_TEST_CMD" ] + then + WRAPPER_CMD="$WRAPPER_TEST_CMD" + else + outputFile "$WRAPPER_TEST_CMD" + WRAPPER_TEST_CMD="" + fi +fi +if [ -f "$WRAPPER_CMD" -a -z "$WRAPPER_TEST_CMD" ] +then + WRAPPER_TEST_CMD="$WRAPPER_CMD" + if [ ! -x "$WRAPPER_TEST_CMD" ] + then + chmod +x "$WRAPPER_TEST_CMD" 2>/dev/null + fi + if [ -x "$WRAPPER_TEST_CMD" ] + then + WRAPPER_CMD="$WRAPPER_TEST_CMD" + else + outputFile "$WRAPPER_TEST_CMD" + WRAPPER_TEST_CMD="" + fi +fi +if [ -z "$WRAPPER_TEST_CMD" ] +then + eval echo `gettext 'Unable to locate any of the following binaries:'` + outputFile "$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-$DIST_BITS" + if [ ! "$DIST_BITS" = "32" ] + then + outputFile "$WRAPPER_CMD-$DIST_OS-$DIST_ARCH-32" + fi + outputFile "$WRAPPER_CMD" + + exit 1 +fi + + +# Build the nice clause +if [ "X$PRIORITY" = "X" ] +then + CMDNICE="" +else + CMDNICE="nice -$PRIORITY" +fi + +# Build the anchor file clause. +if [ "X$IGNORE_SIGNALS" = "X" ] +then + ANCHORPROP= + IGNOREPROP= +else + ANCHORPROP=wrapper.anchorfile=\"$ANCHORFILE\" + IGNOREPROP=wrapper.ignore_signals=TRUE +fi + +# Build the status file clause. +if [ "X$DETAIL_STATUS$WAIT_FOR_STARTED_STATUS" = "X" ] +then + STATUSPROP= +else + STATUSPROP="wrapper.statusfile=\"$STATUSFILE\" wrapper.java.statusfile=\"$JAVASTATUSFILE\"" +fi + +# Build the command file clause. +if [ -n "$PAUSABLE" ] +then + COMMANDPROP="wrapper.commandfile=\"$COMMANDFILE\" wrapper.pausable=TRUE" +else + COMMANDPROP= +fi + +if [ ! -n "$WAIT_FOR_STARTED_STATUS" ] +then + WAIT_FOR_STARTED_STATUS=true +fi + +if [ $WAIT_FOR_STARTED_STATUS = true ] ; then + DETAIL_STATUS=true +fi + + +# Build the lock file clause. Only create a lock file if the lock directory exists on this platform. +LOCKPROP= +if [ -d $LOCKDIR ] +then + if [ -w $LOCKDIR ] + then + LOCKPROP=wrapper.lockfile=\"$LOCKFILE\" + fi +fi + +prepAdditionalParams() { + ADDITIONAL_PARA="" + if [ -n "$PASS_THROUGH" ] ; then + ADDITIONAL_PARA="--" + fi + while [ -n "$1" ] ; do + ADDITIONAL_PARA="$ADDITIONAL_PARA \"$1\"" + shift + done +} + +checkUser() { + # $1 touchLock flag + # $2.. [command] args + + # Check the configured user. If necessary rerun this script as the desired user. + if [ "X$RUN_AS_USER" != "X" ] + then + # Resolve the location of the 'id' command + IDEXE="/usr/xpg4/bin/id" + if [ ! -x "$IDEXE" ] + then + IDEXE="/usr/bin/id" + if [ ! -x "$IDEXE" ] + then + eval echo `gettext 'Unable to locate "id".'` + eval echo `gettext 'Please report this message along with the location of the command on your system.'` + exit 1 + fi + fi + + if [ "`$IDEXE -u -n`" = "$RUN_AS_USER" ] + then + # Already running as the configured user. Avoid password prompts by not calling su. + RUN_AS_USER="" + fi + fi + if [ "X$RUN_AS_USER" != "X" ] + then + if [ "`$IDEXE -u -n "$RUN_AS_USER" 2>/dev/null`" != "$RUN_AS_USER" ] + then + eval echo `gettext 'User $RUN_AS_USER does not exist.'` + exit 1 + fi + + # If LOCKPROP and $RUN_AS_USER are defined then the new user will most likely not be + # able to create the lock file. The Wrapper will be able to update this file once it + # is created but will not be able to delete it on shutdown. If $1 is set then + # the lock file should be created for the current command + if [ "X$LOCKPROP" != "X" ] + then + if [ "X$1" != "X" ] + then + # Resolve the primary group + RUN_AS_GROUP=`groups $RUN_AS_USER | awk '{print $3}' | tail -1` + if [ "X$RUN_AS_GROUP" = "X" ] + then + RUN_AS_GROUP=$RUN_AS_USER + fi + touch $LOCKFILE + chown $RUN_AS_USER:$RUN_AS_GROUP $LOCKFILE + fi + fi + + # Still want to change users, recurse. This means that the user will only be + # prompted for a password once. Variables shifted by 1 + shift + + # Wrap the parameters so they can be passed. + ADDITIONAL_PARA="" + while [ -n "$1" ] ; do + ADDITIONAL_PARA="$ADDITIONAL_PARA \"$1\"" + shift + done + + # Use "runuser" if this exists. runuser should be used on RedHat in preference to su. + # + if test -f "/sbin/runuser" + then + /sbin/runuser - $RUN_AS_USER -c "\"$REALPATH\" $ADDITIONAL_PARA" + else + su - $RUN_AS_USER -c "\"$REALPATH\" $ADDITIONAL_PARA" + fi + RUN_AS_USER_EXITCODE=$? + # Now that we are the original user again, we may need to clean up the lock file. + if [ "X$LOCKPROP" != "X" ] + then + getpid + if [ "X$pid" = "X" ] + then + # Wrapper is not running so make sure the lock file is deleted. + if [ -f "$LOCKFILE" ] + then + rm "$LOCKFILE" + fi + fi + fi + + exit $RUN_AS_USER_EXITCODE + fi +} + +getpid() { + pid="" + if [ -f "$PIDFILE" ] + then + if [ -r "$PIDFILE" ] + then + pid=`cat "$PIDFILE"` + if [ "X$pid" != "X" ] + then + # It is possible that 'a' process with the pid exists but that it is not the + # correct process. This can happen in a number of cases, but the most + # common is during system startup after an unclean shutdown. + # The ps statement below looks for the specific wrapper command running as + # the pid. If it is not found then the pid file is considered to be stale. + case "$DIST_OS" in + 'freebsd') + pidtest=`$PSEXE -p $pid -o args | tail -1` + if [ "X$pidtest" = "XCOMMAND" ] + then + pidtest="" + fi + ;; + 'macosx') + pidtest=`$PSEXE -ww -p $pid -o command | grep -F "$WRAPPER_CMD" | tail -1` + ;; + 'solaris') + if [ -f "/usr/bin/pargs" ] + then + pidtest=`pargs $pid | fgrep "$WRAPPER_CMD" | tail -1` + else + case "$PSEXE" in + '/usr/ucb/ps') + pidtest=`$PSEXE -auxww $pid | fgrep "$WRAPPER_CMD" | tail -1` + ;; + '/usr/bin/ps') + TRUNCATED_CMD=`$PSEXE -o comm -p $pid | tail -1` + COUNT=`echo $TRUNCATED_CMD | wc -m` + COUNT=`echo ${COUNT}` + COUNT=`expr $COUNT - 1` + TRUNCATED_CMD=`echo $WRAPPER_CMD | cut -c1-$COUNT` + pidtest=`$PSEXE -o comm -p $pid | fgrep "$TRUNCATED_CMD" | tail -1` + ;; + '/bin/ps') + TRUNCATED_CMD=`$PSEXE -o comm -p $pid | tail -1` + COUNT=`echo $TRUNCATED_CMD | wc -m` + COUNT=`echo ${COUNT}` + COUNT=`expr $COUNT - 1` + TRUNCATED_CMD=`echo $WRAPPER_CMD | cut -c1-$COUNT` + pidtest=`$PSEXE -o comm -p $pid | fgrep "$TRUNCATED_CMD" | tail -1` + ;; + *) + echo "Unsupported ps command $PSEXE" + exit 1 + ;; + esac + fi + ;; + 'hpux') + pidtest=`$PSEXE -p $pid -x -o args | grep -F "$WRAPPER_CMD" | tail -1` + ;; + *) + pidtest=`$PSEXE -p $pid -o args | grep -F "$WRAPPER_CMD" | tail -1` + ;; + esac + + if [ "X$pidtest" = "X" ] + then + # This is a stale pid file. + rm -f "$PIDFILE" + eval echo `gettext 'Removed stale pid file: $PIDFILE'` + pid="" + fi + fi + else + eval echo `gettext 'Cannot read $PIDFILE.'` + exit 1 + fi + fi +} + +getstatus() { + STATUS= + if [ -f "$STATUSFILE" ] + then + if [ -r "$STATUSFILE" ] + then + STATUS=`cat "$STATUSFILE"` + fi + fi + if [ "X$STATUS" = "X" ] + then + STATUS="Unknown" + fi + + JAVASTATUS= + if [ -f "$JAVASTATUSFILE" ] + then + if [ -r "$JAVASTATUSFILE" ] + then + JAVASTATUS=`cat "$JAVASTATUSFILE"` + fi + fi + if [ "X$JAVASTATUS" = "X" ] + then + JAVASTATUS="Unknown" + fi +} + +testpid() { + case "$DIST_OS" in + 'solaris') + case "$PSEXE" in + '/usr/ucb/ps') + pid=`$PSEXE $pid | grep $pid | grep -v grep | awk '{print $1}' | tail -1` + ;; + '/usr/bin/ps') + pid=`$PSEXE -p $pid | grep $pid | grep -v grep | awk '{print $1}' | tail -1` + ;; + '/bin/ps') + pid=`$PSEXE -p $pid | grep $pid | grep -v grep | awk '{print $1}' | tail -1` + ;; + *) + echo "Unsupported ps command $PSEXE" + exit 1 + ;; + esac + ;; + *) + pid=`$PSEXE -p $pid | grep $pid | grep -v grep | awk '{print $1}' | tail -1` 2>/dev/null + ;; + esac + if [ "X$pid" = "X" ] + then + # Process is gone so remove the pid file. + rm -f "$PIDFILE" + pid="" + fi +} + +launchdtrap() { + stopit + exit +} + +waitforwrapperstop() { + getpid + while [ "X$pid" != "X" ] ; do + sleep 1 + getpid + done +} + +launchinternal() { + getpid + trap launchdtrap TERM + if [ "X$pid" = "X" ] + then + prepAdditionalParams "$@" + + # The string passed to eval must handles spaces in paths correctly. + COMMAND_LINE="$CMDNICE \"$WRAPPER_CMD\" \"$WRAPPER_CONF\" wrapper.syslog.ident=\"$APP_NAME\" wrapper.pidfile=\"$PIDFILE\" wrapper.name=\"$APP_NAME\" wrapper.displayname=\"$APP_LONG_NAME\" wrapper.daemonize=TRUE $ANCHORPROP $IGNOREPROP $STATUSPROP $COMMANDPROP $LOCKPROP wrapper.script.version=3.5.17 $ADDITIONAL_PARA" + eval $COMMAND_LINE + else + eval echo `gettext '$APP_LONG_NAME is already running.'` + exit 1 + fi + # launchd expects that this script stay up and running so we need to do our own monitoring of the Wrapper process. + if [ $WAIT_FOR_STARTED_STATUS = true ] + then + waitforwrapperstop + fi +} + +console() { + eval echo `gettext 'Running $APP_LONG_NAME...'` + getpid + if [ "X$pid" = "X" ] + then + trap '' 3 + + prepAdditionalParams "$@" + + # The string passed to eval must handles spaces in paths correctly. + COMMAND_LINE="$CMDNICE \"$WRAPPER_CMD\" \"$WRAPPER_CONF\" wrapper.syslog.ident=\"$APP_NAME\" wrapper.pidfile=\"$PIDFILE\" wrapper.name=\"$APP_NAME\" wrapper.displayname=\"$APP_LONG_NAME\" $ANCHORPROP $STATUSPROP $COMMANDPROP $LOCKPROP wrapper.script.version=3.5.17 $ADDITIONAL_PARA" + eval $COMMAND_LINE + else + eval echo `gettext '$APP_LONG_NAME is already running.'` + exit 1 + fi +} + +waitforjavastartup() { + getstatus + eval echo $ECHOOPT `gettext 'Waiting for $APP_LONG_NAME...'` + + # Wait until the timeout or we have something besides Unknown. + counter=15 + while [ "$JAVASTATUS" = "Unknown" -a $counter -gt 0 -a -n "$JAVASTATUS" ] ; do + echo $ECHOOPT"." + sleep 1 + getstatus + counter=`expr $counter - 1` + done + + if [ -n "$WAIT_FOR_STARTED_TIMEOUT" ] ; then + counter=$WAIT_FOR_STARTED_TIMEOUT + else + counter=120 + fi + while [ "$JAVASTATUS" != "STARTED" -a "$JAVASTATUS" != "Unknown" -a $counter -gt 0 -a -n "$JAVASTATUS" ] ; do + echo $ECHOOPT"." + sleep 1 + getstatus + counter=`expr $counter - 1` + done + if [ "X$ECHOOPT" != "X" ] ; then + echo "" + fi +} + +startwait() { + if [ $WAIT_FOR_STARTED_STATUS = true ] + then + waitforjavastartup + fi + # Sleep for a few seconds to allow for intialization if required + # then test to make sure we're still running. + # + i=0 + while [ $i -lt $WAIT_AFTER_STARTUP ] + do + sleep 1 + echo $ECHOOPT"." + i=`expr $i + 1` + done + if [ $WAIT_AFTER_STARTUP -gt 0 -o $WAIT_FOR_STARTED_STATUS = true ] + then + getpid + if [ "X$pid" = "X" ] + then + eval echo `gettext ' WARNING: $APP_LONG_NAME may have failed to start.'` + exit 1 + else + eval echo `gettext ' running: PID:$pid'` + fi + else + echo "" + fi +} + +macosxstart() { + # The daemon has been installed. + eval echo `gettext 'Starting $APP_LONG_NAME. Detected Mac OSX and installed launchd daemon.'` + if [ `id | sed 's/^uid=//;s/(.*$//'` != "0" ] ; then + eval echo `gettext 'Must be root to perform this action.'` + exit 1 + fi + + getpid + if [ "X$pid" != "X" ] ; then + eval echo `gettext '$APP_LONG_NAME is already running.'` + exit 1 + fi + + # If the daemon was just installed, it may not be loaded. + LOADED_PLIST=`launchctl list | grep ${APP_PLIST_BASE}` + if [ "X${LOADED_PLIST}" = "X" ] ; then + launchctl load /Library/LaunchDaemons/${APP_PLIST} + fi + # If launchd is set to run the daemon already at Load, we don't need to call start + getpid + if [ "X$pid" == "X" ] ; then + launchctl start ${APP_PLIST_BASE} + fi + + startwait +} + +upstartstart() { + # The daemon has been installed. + eval echo `gettext 'Starting $APP_LONG_NAME. Detected Linux and installed upstart.'` + if [ `id | sed 's/^uid=//;s/(.*$//'` != "0" ] ; then + eval echo `gettext 'Must be root to perform this action.'` + exit 1 + fi + + getpid + if [ "X$pid" != "X" ] ; then + eval echo `gettext '$APP_LONG_NAME is already running.'` + exit 1 + fi + + /sbin/start ${APP_NAME} + + startwait +} + +start() { + eval echo `gettext 'Starting $APP_LONG_NAME...'` + getpid + if [ "X$pid" = "X" ] + then + prepAdditionalParams "$@" + + # The string passed to eval must handles spaces in paths correctly. + COMMAND_LINE="$CMDNICE \"$WRAPPER_CMD\" \"$WRAPPER_CONF\" wrapper.syslog.ident=\"$APP_NAME\" wrapper.pidfile=\"$PIDFILE\" wrapper.name=\"$APP_NAME\" wrapper.displayname=\"$APP_LONG_NAME\" wrapper.daemonize=TRUE $ANCHORPROP $IGNOREPROP $STATUSPROP $COMMANDPROP $LOCKPROP wrapper.script.version=3.5.17 $ADDITIONAL_PARA" + eval $COMMAND_LINE + else + eval echo `gettext '$APP_LONG_NAME is already running.'` + exit 1 + fi + + startwait +} + +stopit() { + # $1 exit if down flag + + eval echo `gettext 'Stopping $APP_LONG_NAME...'` + getpid + if [ "X$pid" = "X" ] + then + eval echo `gettext '$APP_LONG_NAME was not running.'` + if [ "X$1" = "X1" ] + then + exit 1 + fi + else + if [ "X$IGNORE_SIGNALS" = "X" ] + then + # Running so try to stop it. + kill $pid + if [ $? -ne 0 ] + then + # An explanation for the failure should have been given + eval echo `gettext 'Unable to stop $APP_LONG_NAME.'` + exit 1 + fi + else + rm -f "$ANCHORFILE" + if [ -f "$ANCHORFILE" ] + then + # An explanation for the failure should have been given + eval echo `gettext 'Unable to stop $APP_LONG_NAME.'` + exit 1 + fi + fi + + # We can not predict how long it will take for the wrapper to + # actually stop as it depends on settings in wrapper.conf. + # Loop until it does. + savepid=$pid + CNT=0 + TOTCNT=0 + while [ "X$pid" != "X" ] + do + # Show a waiting message every 5 seconds. + if [ "$CNT" -lt "5" ] + then + CNT=`expr $CNT + 1` + else + eval echo `gettext 'Waiting for $APP_LONG_NAME to exit...'` + CNT=0 + fi + TOTCNT=`expr $TOTCNT + 1` + + sleep 1 + + testpid + done + + pid=$savepid + testpid + if [ "X$pid" != "X" ] + then + eval echo `gettext 'Failed to stop $APP_LONG_NAME.'` + exit 1 + else + eval echo `gettext 'Stopped $APP_LONG_NAME.'` + fi + fi +} + +pause() { + eval echo `gettext 'Pausing $APP_LONG_NAME.'` +} + +resume() { + eval echo `gettext 'Resuming $APP_LONG_NAME.'` +} + +status() { + getpid + if [ "X$pid" = "X" ] + then + eval echo `gettext '$APP_LONG_NAME is not running.'` + exit 1 + else + if [ "X$DETAIL_STATUS" = "X" ] + then + eval echo `gettext '$APP_LONG_NAME is running: PID:$pid'` + else + getstatus + eval echo `gettext '$APP_LONG_NAME is running: PID:$pid, Wrapper:$STATUS, Java:$JAVASTATUS'` + fi + exit 0 + fi +} + +installUpstart() { + eval echo `gettext ' Installing the $APP_LONG_NAME daemon using upstart..'` + if [ -f "${REALDIR}/${APP_NAME}.install" ] ; then + eval echo `gettext ' a custom upstart conf file ${APP_NAME}.install found'` + cp "${REALDIR}/${APP_NAME}.install" "/etc/init/${APP_NAME}.conf" + else + eval echo `gettext ' creating default upstart conf file..'` + echo "# ${APP_NAME} - ${APP_LONG_NAME}" > "/etc/init/${APP_NAME}.conf" + echo "description \"${APP_LONG_NAME}\"" >> "/etc/init/${APP_NAME}.conf" + echo "author \"Tanuki Software Ltd. \"" >> "/etc/init/${APP_NAME}.conf" + echo "start on runlevel [2345]" >> "/etc/init/${APP_NAME}.conf" + echo "stop on runlevel [!2345]" >> "/etc/init/${APP_NAME}.conf" + echo "env LANG=${LANG}" >> "/etc/init/${APP_NAME}.conf" + echo "exec \"${REALPATH}\" upstartinternal" >> "/etc/init/${APP_NAME}.conf" + fi +} + +installdaemon() { + if [ `id | sed 's/^uid=//;s/(.*$//'` != "0" ] ; then + eval echo `gettext 'Must be root to perform this action.'` + exit 1 + else + APP_NAME_LOWER=`echo "$APP_NAME" | $TREXE "[A-Z]" "[a-z]"` + if [ "$DIST_OS" = "solaris" ] ; then + eval echo `gettext 'Detected Solaris:'` + if [ -f "/etc/init.d/$APP_NAME" -o -L "/etc/init.d/$APP_NAME"] ; then + eval echo `gettext ' The $APP_LONG_NAME daemon is already installed.'` + exit 1 + else + eval echo `gettext ' Installing the $APP_LONG_NAME daemon..'` + ln -s "$REALPATH" "/etc/init.d/$APP_NAME" + ln -s "/etc/init.d/$APP_NAME" "/etc/rc3.d/K20$APP_NAME_LOWER" + ln -s "/etc/init.d/$APP_NAME" "/etc/rc3.d/S20$APP_NAME_LOWER" + fi + elif [ "$DIST_OS" = "linux" ] ; then + if [ -f /etc/redhat-release -o -f /etc/redhat_version -o -f /etc/fedora-release ] ; then + eval echo `gettext 'Detected RHEL or Fedora:'` + if [ -f "/etc/init.d/$APP_NAME" -o -L "/etc/init.d/$APP_NAME" -o -f "/etc/init/${APP_NAME}.conf" ] ; then + eval echo `gettext ' The $APP_LONG_NAME daemon is already installed.'` + exit 1 + else + if [ -n "$USE_UPSTART" -a -d "/etc/init" ] ; then + installUpstart + else + eval echo `gettext ' Installing the $APP_LONG_NAME daemon..'` + ln -s "$REALPATH" "/etc/init.d/$APP_NAME" + /sbin/chkconfig --add "$APP_NAME" + /sbin/chkconfig "$APP_NAME" on + fi + fi + elif [ -f /etc/SuSE-release ] ; then + eval echo `gettext 'Detected SuSE or SLES:'` + if [ -f "/etc/init.d/$APP_NAME" -o -L "/etc/init.d/$APP_NAME" ] ; then + eval echo `gettext ' The $APP_LONG_NAME daemon is already installed.'` + exit 1 + else + eval echo `gettext ' Installing the $APP_LONG_NAME daemon..'` + ln -s "$REALPATH" "/etc/init.d/$APP_NAME" + insserv "/etc/init.d/$APP_NAME" + fi + elif [ -f /etc/lsb-release ] ; then + eval echo `gettext 'Detected Ubuntu:'` + if [ -f "/etc/init.d/$APP_NAME" -o -L "/etc/init.d/$APP_NAME" -o -f "/etc/init/${APP_NAME}.conf" ] ; then + eval echo `gettext ' The $APP_LONG_NAME daemon is already installed.'` + exit 1 + else + if [ -n "$USE_UPSTART" -a -d "/etc/init" ] ; then + installUpstart + else + eval echo `gettext ' Installing the $APP_LONG_NAME daemon using init.d..'` + ln -s "$REALPATH" "/etc/init.d/$APP_NAME" + update-rc.d "$APP_NAME" defaults + fi + fi + else + eval echo `gettext 'Detected Linux:'` + if [ -f "/etc/init.d/$APP_NAME" -o -L "/etc/init.d/$APP_NAME" ] ; then + eval echo `gettext ' The $APP_LONG_NAME daemon is already installed.'` + exit 1 + else + eval echo `gettext ' Installing the $APP_LONG_NAME daemon..'` + ln -s "$REALPATH" /etc/init.d/$APP_NAME + ln -s "/etc/init.d/$APP_NAME" "/etc/rc3.d/K20$APP_NAME_LOWER" + ln -s "/etc/init.d/$APP_NAME" "/etc/rc3.d/S20$APP_NAME_LOWER" + ln -s "/etc/init.d/$APP_NAME" "/etc/rc5.d/S20$APP_NAME_LOWER" + ln -s "/etc/init.d/$APP_NAME" "/etc/rc5.d/K20$APP_NAME_LOWER" + fi + fi + elif [ "$DIST_OS" = "hpux" ] ; then + eval echo `gettext 'Detected HP-UX:'` + if [ -f "/sbin/init.d/$APP_NAME" -o -L "/sbin/init.d/$APP_NAME" ] ; then + eval echo `gettext ' The $APP_LONG_NAME daemon is already installed.'` + exit 1 + else + eval echo `gettext ' Installing the $APP_LONG_NAME daemon..'` + ln -s "$REALPATH" "/sbin/init.d/$APP_NAME" + ln -s "/sbin/init.d/$APP_NAME" "/sbin/rc3.d/K20$APP_NAME_LOWER" + ln -s "/sbin/init.d/$APP_NAME" "/sbin/rc3.d/S20$APP_NAME_LOWER" + fi + elif [ "$DIST_OS" = "aix" ] ; then + eval echo `gettext 'Detected AIX:'` + if [ -f "/etc/rc.d/init.d/$APP_NAME" ] ; then + eval echo `gettext ' The $APP_LONG_NAME daemon is already installed as rc.d script.'` + exit 1 + elif [ -n "`/usr/sbin/lsitab $APP_NAME`" -a -n "`/usr/bin/lssrc -S -s $APP_NAME`" ] ; then + eval echo `gettext ' The $APP_LONG_NAME daemon is already installed as SRC service.'` + exit 1 + else + eval echo `gettext ' Installing the $APP_LONG_NAME daemon..'` + if [ -n "`/usr/sbin/lsitab install_assist`" ] ; then + eval echo `gettext ' The task /usr/sbin/install_assist was found in the inittab, this might cause problems for all subsequent tasks to launch at this process is known to block the init task. Please make sure this task is not needed anymore and remove/deactivate it.'` + fi + /usr/bin/mkssys -s "$APP_NAME" -p "$REALPATH" -a "launchdinternal" -u 0 -f 9 -n 15 -S + /usr/sbin/mkitab "$APP_NAME":2:once:"/usr/bin/startsrc -s \"${APP_NAME}\" >/dev/console 2>&1" + + fi + elif [ "$DIST_OS" = "freebsd" ] ; then + eval echo `gettext 'Detected FreeBSD:'` + if [ -f "/etc/rc.d/$APP_NAME" -o -L "/etc/rc.d/$APP_NAME" ] ; then + eval echo `gettext ' The $APP_LONG_NAME daemon is already installed.'` + exit 1 + else + eval echo `gettext ' Installing the $APP_LONG_NAME daemon..'` + sed -i .bak "/${APP_NAME}_enable=\"YES\"/d" /etc/rc.conf + if [ -f "${REALDIR}/${APP_NAME}.install" ] ; then + ln -s "${REALDIR}/${APP_NAME}.install" "/etc/rc.d/$APP_NAME" + else + echo '#!/bin/sh' > "/etc/rc.d/$APP_NAME" + echo "#" >> "/etc/rc.d/$APP_NAME" + echo "# PROVIDE: $APP_NAME" >> "/etc/rc.d/$APP_NAME" + echo "# REQUIRE: NETWORKING" >> "/etc/rc.d/$APP_NAME" + echo "# KEYWORD: shutdown" >> "/etc/rc.d/$APP_NAME" + echo ". /etc/rc.subr" >> "/etc/rc.d/$APP_NAME" + echo "name=\"$APP_NAME\"" >> "/etc/rc.d/$APP_NAME" + echo "rcvar=\`set_rcvar\`" >> "/etc/rc.d/$APP_NAME" + echo "command=\"${REALPATH}\"" >> "/etc/rc.d/$APP_NAME" + echo 'start_cmd="${name}_start"' >> "/etc/rc.d/$APP_NAME" + echo 'load_rc_config $name' >> "/etc/rc.d/$APP_NAME" + echo 'status_cmd="${name}_status"' >> "/etc/rc.d/$APP_NAME" + echo 'stop_cmd="${name}_stop"' >> "/etc/rc.d/$APP_NAME" + echo "${APP_NAME}_status() {" >> "/etc/rc.d/$APP_NAME" + echo '${command} status' >> "/etc/rc.d/$APP_NAME" + echo '}' >> "/etc/rc.d/$APP_NAME" + echo "${APP_NAME}_stop() {" >> "/etc/rc.d/$APP_NAME" + echo '${command} stop' >> "/etc/rc.d/$APP_NAME" + echo '}' >> "/etc/rc.d/$APP_NAME" + echo "${APP_NAME}_start() {" >> "/etc/rc.d/$APP_NAME" + echo '${command} start' >> "/etc/rc.d/$APP_NAME" + echo '}' >> "/etc/rc.d/$APP_NAME" + echo 'run_rc_command "$1"' >> "/etc/rc.d/$APP_NAME" + fi + echo "${APP_NAME}_enable=\"YES\"" >> /etc/rc.conf + chmod 555 "/etc/rc.d/$APP_NAME" + fi + elif [ "$DIST_OS" = "macosx" ] ; then + eval echo `gettext 'Detected Mac OSX:'` + if [ -f "/Library/LaunchDaemons/${APP_PLIST}" -o -L "/Library/LaunchDaemons/${APP_PLIST}" ] ; then + eval echo `gettext ' The $APP_LONG_NAME daemon is already installed.'` + exit 1 + else + eval echo `gettext ' Installing the $APP_LONG_NAME daemon..'` + if [ -f "${REALDIR}/${APP_PLIST}" ] ; then + ln -s "${REALDIR}/${APP_PLIST}" "/Library/LaunchDaemons/${APP_PLIST}" + else + echo "" > "/Library/LaunchDaemons/${APP_PLIST}" + echo "> "/Library/LaunchDaemons/${APP_PLIST}" + echo "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" >> "/Library/LaunchDaemons/${APP_PLIST}" + echo "" >> "/Library/LaunchDaemons/${APP_PLIST}" + echo " " >> "/Library/LaunchDaemons/${APP_PLIST}" + echo " Label" >> "/Library/LaunchDaemons/${APP_PLIST}" + echo " ${APP_PLIST_BASE}" >> "/Library/LaunchDaemons/${APP_PLIST}" + echo " ProgramArguments" >> "/Library/LaunchDaemons/${APP_PLIST}" + echo " " >> "/Library/LaunchDaemons/${APP_PLIST}" + echo " ${REALPATH}" >> "/Library/LaunchDaemons/${APP_PLIST}" + echo " launchdinternal" >> "/Library/LaunchDaemons/${APP_PLIST}" + echo " " >> "/Library/LaunchDaemons/${APP_PLIST}" + echo " OnDemand" >> "/Library/LaunchDaemons/${APP_PLIST}" + echo " " >> "/Library/LaunchDaemons/${APP_PLIST}" + echo " RunAtLoad" >> "/Library/LaunchDaemons/${APP_PLIST}" + echo " " >> "/Library/LaunchDaemons/${APP_PLIST}" + if [ "X$RUN_AS_USER" != "X" ] ; then + echo " UserName" >> "/Library/LaunchDaemons/${APP_PLIST}" + echo " ${RUN_AS_USER}" >> "/Library/LaunchDaemons/${APP_PLIST}" + fi + echo " " >> "/Library/LaunchDaemons/${APP_PLIST}" + echo "" >> "/Library/LaunchDaemons/${APP_PLIST}" + fi + chmod 555 "/Library/LaunchDaemons/${APP_PLIST}" + fi + elif [ "$DIST_OS" = "zos" ] ; then + eval echo `gettext 'Detected z/OS:'` + if [ -f /etc/rc.bak ] ; then + eval echo `gettext ' The $APP_LONG_NAME daemon is already installed.'` + exit 1 + else + eval echo `gettext ' Installing the $APP_LONG_NAME daemon..'` + cp /etc/rc /etc/rc.bak + sed "s:echo /etc/rc script executed, \`date\`::g" /etc/rc.bak > /etc/rc + echo "_BPX_JOBNAME='${APP_NAME}' \"${REALDIR}/${APP_NAME}\" start" >>/etc/rc + echo '/etc/rc script executed, `date`' >>/etc/rc + fi + else + eval echo `gettext 'Install not currently supported for $DIST_OS'` + exit 1 + fi + fi +} + +removedaemon() { + if [ `id | sed 's/^uid=//;s/(.*$//'` != "0" ] ; then + eval echo `gettext 'Must be root to perform this action.'` + exit 1 + else + APP_NAME_LOWER=`echo "$APP_NAME" | $TREXE "[A-Z]" "[a-z]"` + if [ "$DIST_OS" = "solaris" ] ; then + eval echo `gettext 'Detected Solaris:'` + if [ -f "/etc/init.d/$APP_NAME" -o -L "/etc/init.d/$APP_NAME" ] ; then + stopit "0" + eval echo `gettext ' Removing $APP_LONG_NAME daemon...'` + for i in "/etc/rc3.d/S20$APP_NAME_LOWER" "/etc/rc3.d/K20$APP_NAME_LOWER" "/etc/init.d/$APP_NAME" + do + rm -f $i + done + else + eval echo `gettext ' The $APP_LONG_NAME daemon is not currently installed.'` + exit 1 + fi + elif [ "$DIST_OS" = "linux" ] ; then + if [ -f /etc/redhat-release -o -f /etc/redhat_version -o -f /etc/fedora-release ] ; then + eval echo `gettext 'Detected RHEL or Fedora:'` + if [ -f "/etc/init.d/$APP_NAME" -o -L "/etc/init.d/$APP_NAME" ] ; then + stopit "0" + eval echo `gettext ' Removing $APP_LONG_NAME daemon...'` + /sbin/chkconfig "$APP_NAME" off + /sbin/chkconfig --del "$APP_NAME" + rm -f "/etc/init.d/$APP_NAME" + elif [ -f "/etc/init/${APP_NAME}.conf" ] ; then + stopit "0" + eval echo `gettext ' Removing $APP_LONG_NAME daemon from upstart...'` + rm "/etc/init/${APP_NAME}.conf" + else + eval echo `gettext ' The $APP_LONG_NAME daemon is not currently installed.'` + exit 1 + fi + elif [ -f /etc/SuSE-release ] ; then + eval echo `gettext 'Detected SuSE or SLES:'` + if [ -f "/etc/init.d/$APP_NAME" -o -L "/etc/init.d/$APP_NAME" ] ; then + stopit "0" + eval echo `gettext ' Removing $APP_LONG_NAME daemon...'` + insserv -r "/etc/init.d/$APP_NAME" + rm -f "/etc/init.d/$APP_NAME" + else + eval echo `gettext ' The $APP_LONG_NAME daemon is not currently installed.'` + exit 1 + fi + elif [ -f /etc/lsb-release ] ; then + eval echo `gettext 'Detected Ubuntu:'` + if [ -f "/etc/init.d/$APP_NAME" -o -L "/etc/init.d/$APP_NAME" ] ; then + stopit "0" + eval echo `gettext ' Removing $APP_LONG_NAME daemon from init.d...'` + update-rc.d -f "$APP_NAME" remove + rm -f "/etc/init.d/$APP_NAME" + elif [ -f "/etc/init/${APP_NAME}.conf" ] ; then + stopit "0" + eval echo `gettext ' Removing $APP_LONG_NAME daemon from upstart...'` + rm "/etc/init/${APP_NAME}.conf" + else + eval echo `gettext ' The $APP_LONG_NAME daemon is not currently installed.'` + exit 1 + fi + else + eval echo `gettext 'Detected Linux:'` + if [ -f "/etc/init.d/$APP_NAME" -o -L "/etc/init.d/$APP_NAME" ] ; then + stopit "0" + eval echo `gettext ' Removing $APP_LONG_NAME daemon...'` + for i in "/etc/rc3.d/K20$APP_NAME_LOWER" "/etc/rc5.d/K20$APP_NAME_LOWER" "/etc/rc3.d/S20$APP_NAME_LOWER" "/etc/init.d/$APP_NAME" "/etc/rc5.d/S20$APP_NAME_LOWER" + do + rm -f $i + done + else + eval echo `gettext ' The $APP_LONG_NAME daemon is not currently installed.'` + exit 1 + fi + fi + elif [ "$DIST_OS" = "hpux" ] ; then + eval echo `gettext 'Detected HP-UX:'` + if [ -f "/sbin/init.d/$APP_NAME" -o -L "/sbin/init.d/$APP_NAME" ] ; then + stopit "0" + eval echo `gettext ' Removing $APP_LONG_NAME daemon...'` + for i in "/sbin/rc3.d/K20$APP_NAME_LOWER" "/sbin/rc3.d/S20$APP_NAME_LOWER" "/sbin/init.d/$APP_NAME" + do + rm -f $i + done + else + eval echo `gettext ' The $APP_LONG_NAME daemon is not currently installed.'` + exit 1 + fi + elif [ "$DIST_OS" = "aix" ] ; then + eval echo `gettext 'Detected AIX:'` + if [ -f "/etc/rc.d/init.d/$APP_NAME" -o -L "/etc/rc.d/init.d/$APP_NAME" -o -n "`/usr/sbin/lsitab $APP_NAME`" -o -n "`/usr/bin/lssrc -S -s $APP_NAME`" ] ; then + stopit "0" + eval echo `gettext ' Removing $APP_LONG_NAME daemon...'` + if [ -f "/etc/rc.d/init.d/$APP_NAME" -o -L "/etc/rc.d/init.d/$APP_NAME" ] ; then + for i in "/etc/rc.d/rc2.d/S20$APP_NAME_LOWER" "/etc/rc.d/rc2.d/K20$APP_NAME_LOWER" "/etc/rc.d/init.d/$APP_NAME" + do + rm -f $i + done + fi + if [ -n "`/usr/sbin/lsitab $APP_NAME`" -o -n "`/usr/bin/lssrc -S -s $APP_NAME`" ] ; then + /usr/sbin/rmitab $APP_NAME + /usr/bin/rmssys -s $APP_NAME + fi + else + eval echo `gettext ' The $APP_LONG_NAME daemon is not currently installed.'` + exit 1 + fi + elif [ "$DIST_OS" = "freebsd" ] ; then + eval echo `gettext 'Detected FreeBSD:'` + if [ -f "/etc/rc.d/$APP_NAME" -o -L "/etc/rc.d/$APP_NAME" ] ; then + stopit "0" + eval echo `gettext ' Removing $APP_LONG_NAME daemon...'` + for i in "/etc/rc.d/$APP_NAME" + do + rm -f $i + done + sed -i .bak "/${APP_NAME}_enable=\"YES\"/d" /etc/rc.conf + else + eval echo `gettext ' The $APP_LONG_NAME daemon is not currently installed.'` + exit 1 + fi + elif [ "$DIST_OS" = "macosx" ] ; then + eval echo `gettext 'Detected Mac OSX:'` + if [ -f "/Library/LaunchDaemons/${APP_PLIST}" -o -L "/Library/LaunchDaemons/${APP_PLIST}" ] ; then + stopit "0" + eval echo `gettext ' Removing $APP_LONG_NAME daemon...'` + # Make sure the plist is installed + LOADED_PLIST=`launchctl list | grep ${APP_PLIST_BASE}` + if [ "X${LOADED_PLIST}" != "X" ] ; then + launchctl unload "/Library/LaunchDaemons/${APP_PLIST}" + fi + rm -f "/Library/LaunchDaemons/${APP_PLIST}" + else + eval echo `gettext ' The $APP_LONG_NAME daemon is not currently installed.'` + exit 1 + fi + elif [ "$DIST_OS" = "zos" ] ; then + eval echo `gettext 'Detected z/OS:'` + if [ -f /etc/rc.bak ] ; then + stopit "0" + eval echo `gettext ' Removing $APP_LONG_NAME daemon...'` + cp /etc/rc /etc/rc.bak + sed "s/_BPX_JOBNAME=\'APP_NAME\'.*//g" /etc/rc.bak > /etc/rc + rm /etc/rc.bak + else + eval echo `gettext ' The $APP_LONG_NAME daemon is not currently installed.'` + exit 1 + fi + else + eval echo `gettext 'Remove not currently supported for $DIST_OS'` + exit 1 + fi + fi +} + +dump() { + eval echo `gettext 'Dumping $APP_LONG_NAME...'` + getpid + if [ "X$pid" = "X" ] + then + eval echo `gettext '$APP_LONG_NAME was not running.'` + else + kill -3 $pid + + if [ $? -ne 0 ] + then + eval echo `gettext 'Failed to dump $APP_LONG_NAME.'` + exit 1 + else + eval echo `gettext 'Dumped $APP_LONG_NAME.'` + fi + fi +} + +# Used by HP-UX init scripts. +startmsg() { + getpid + if [ "X$pid" = "X" ] + then + eval echo `gettext 'Starting $APP_LONG_NAME... Wrapper:Stopped'` + else + if [ "X$DETAIL_STATUS" = "X" ] + then + eval echo `gettext 'Starting $APP_LONG_NAME... Wrapper:Running'` + else + getstatus + eval echo `gettext 'Starting $APP_LONG_NAME... Wrapper:$STATUS, Java:$JAVASTATUS'` + fi + fi +} + +# Used by HP-UX init scripts. +stopmsg() { + getpid + if [ "X$pid" = "X" ] + then + eval echo `gettext 'Stopping $APP_LONG_NAME... Wrapper:Stopped'` + else + if [ "X$DETAIL_STATUS" = "X" ] + then + eval echo `gettext 'Stopping $APP_LONG_NAME... Wrapper:Running'` + else + getstatus + eval echo `gettext 'Stopping $APP_LONG_NAME... Wrapper:$STATUS, Java:$JAVASTATUS'` + fi + fi +} + +showUsage() { + # $1 bad command + + if [ -n "$1" ] + then + eval echo `gettext 'Unexpected command: $1'` + echo ""; + fi + + eval MSG=`gettext 'Usage: '` + if [ -n "$FIXED_COMMAND" ] ; then + if [ -n "$PASS_THROUGH" ] ; then + echo "${MSG} $0 {JavaAppArgs}" + else + echo "${MSG} $0" + fi + else + if [ -n "$PAUSABLE" ] ; then + if [ -n "$PASS_THROUGH" ] ; then + echo "${MSG} $0 [ console {JavaAppArgs} | start {JavaAppArgs} | stop | restart {JavaAppArgs} | condrestart {JavaAppArgs} | pause | resume | status | install | remove | dump ]" + else + echo "${MSG} $0 [ console | start | stop | restart | condrestart | pause | resume | status | install | remove | dump ]" + fi + else + if [ -n "$PASS_THROUGH" ] ; then + echo "${MSG} $0 [ console {JavaAppArgs} | start {JavaAppArgs} | stop | restart {JavaAppArgs} | condrestart {JavaAppArgs} | status | install | remove | dump ]" + else + echo "${MSG} $0 [ console | start | stop | restart | condrestart | status | install | remove | dump ]" + fi + fi + fi + + if [ ! -n "$BRIEF_USAGE" ] + then + echo ""; + if [ ! -n "$FIXED_COMMAND" ] ; then + echo "`gettext 'Commands:'`" + echo "`gettext ' console Launch in the current console.'`" + echo "`gettext ' start Start in the background as a daemon process.'`" + echo "`gettext ' stop Stop if running as a daemon or in another console.'`" + echo "`gettext ' restart Stop if running and then start.'`" + echo "`gettext ' condrestart Restart only if already running.'`" + if [ -n "$PAUSABLE" ] ; then + echo "`gettext ' pause Pause if running.'`" + echo "`gettext ' resume Resume if paused.'`" + fi + echo "`gettext ' status Query the current status.'`" + echo "`gettext ' install Install to start automatically when system boots.'`" + echo "`gettext ' remove Uninstall.'`" + echo "`gettext ' dump Request a Java thread dump if running.'`" + echo ""; + fi + if [ -n "$PASS_THROUGH" ] ; then + echo "`gettext 'JavaAppArgs: Zero or more arguments which will be passed to the Java application.'`" + echo ""; + fi + fi + + exit 1 +} + +docommand() { + case "$COMMAND" in + 'console') + checkUser touchlock "$@" + if [ ! -n "$FIXED_COMMAND" ] ; then + shift + fi + console "$@" + ;; + + 'start') + if [ "$DIST_OS" = "macosx" -a -f "/Library/LaunchDaemons/${APP_PLIST}" ] ; then + macosxstart + elif [ "$DIST_OS" = "linux" -a -f "/etc/init/${APP_NAME}.conf" ] ; then + upstartstart + else + checkUser touchlock "$@" + if [ ! -n "$FIXED_COMMAND" ] ; then + shift + fi + start "$@" + fi + ;; + + 'stop') + checkUser "" "$COMMAND" + stopit "0" + ;; + + 'restart') + checkUser touchlock "$COMMAND" + if [ ! -n "$FIXED_COMMAND" ] ; then + shift + fi + stopit "0" + start "$@" + ;; + + 'condrestart') + checkUser touchlock "$COMMAND" + if [ ! -n "$FIXED_COMMAND" ] ; then + shift + fi + stopit "1" + start "$@" + ;; + + 'pause') + if [ -n "$PAUSABLE" ] + then + pause + else + showUsage "$COMMAND" + fi + ;; + + 'resume') + if [ -n "$PAUSABLE" ] + then + resume + else + showUsage "$COMMAND" + fi + ;; + + 'status') + status + ;; + + 'install') + installdaemon + ;; + + 'remove') + removedaemon + ;; + + 'dump') + checkUser "" "$COMMAND" + dump + ;; + + 'start_msg') + # Internal command called by launchd on HP-UX. + checkUser "" "$COMMAND" + startmsg + ;; + + 'stop_msg') + # Internal command called by launchd on HP-UX. + checkUser "" "$COMMAND" + stopmsg + ;; + + 'launchdinternal' | 'upstartinternal') + if [ ! "$DIST_OS" = "macosx" -o ! -f "/Library/LaunchDaemons/${APP_PLIST}" ] ; then + checkUser touchlock "$@" + fi + # Internal command called by launchd on Max OSX. + # We do not want to call checkUser here as it is handled in the launchd plist file. Doing it here would confuse launchd. + if [ ! -n "$FIXED_COMMAND" ] ; then + shift + fi + launchinternal "$@" + ;; + + *) + showUsage "$COMMAND" + ;; + esac +} + +docommand "$@" + +exit 0 diff --git a/rapla-source-1.8.2/service/bin/wrapper b/rapla-source-1.8.2/service/bin/wrapper new file mode 100644 index 0000000..e13f909 Binary files /dev/null and b/rapla-source-1.8.2/service/bin/wrapper differ diff --git a/rapla-source-1.8.2/service/bin/wrapper.exe b/rapla-source-1.8.2/service/bin/wrapper.exe new file mode 100644 index 0000000..8a7d74a Binary files /dev/null and b/rapla-source-1.8.2/service/bin/wrapper.exe differ diff --git a/rapla-source-1.8.2/service/conf/wrapper.conf b/rapla-source-1.8.2/service/conf/wrapper.conf new file mode 100644 index 0000000..3fafe31 --- /dev/null +++ b/rapla-source-1.8.2/service/conf/wrapper.conf @@ -0,0 +1,212 @@ +#encoding=UTF-8 +# Configuration files must begin with a line specifying the encoding +# of the the file. + +#******************************************************************** +# Wrapper License Properties (Ignored by Community Edition) +#******************************************************************** +# Professional and Standard Editions of the Wrapper require a valid +# License Key to start. Licenses can be purchased or a trial license +# requested on the following pages: +# http://wrapper.tanukisoftware.com/purchase +# http://wrapper.tanukisoftware.com/trial + +# Include file problems can be debugged by removing the first '#' +# from the following line: +##include.debug + +# The Wrapper will look for either of the following optional files for a +# valid License Key. License Key properties can optionally be included +# directly in this configuration file. +#include ../conf/wrapper-license.conf +#include ../conf/wrapper-license-%WRAPPER_HOST_NAME%.conf + +# The following property will output information about which License Key(s) +# are being found, and can aid in resolving any licensing problems. +#wrapper.license.debug=FALSE + +#******************************************************************** +# Wrapper Localization +#******************************************************************** +# Specify the locale which the Wrapper should use. By default the system +# locale is used. +#wrapper.lang=en_US # en_US or ja_JP + +# Specify the location of the Wrapper's language resources. If these are +# missing, the Wrapper will default to the en_US locale. +wrapper.lang.folder=../lang + +#******************************************************************** +# Wrapper Java Properties +#******************************************************************** +# Java Application +# Locate the java binary on the system PATH: +wrapper.java.command=java +# Specify a specific java binary: +#set.JAVA_HOME=/java/path +#wrapper.java.command=%JAVA_HOME%/bin/java + +# Tell the Wrapper to log the full generated Java command line. +#wrapper.java.command.loglevel=INFO + +# Java Main class. This class must implement the WrapperListener interface +# or guarantee that the WrapperManager class is initialized. Helper +# classes are provided to do this for you. See the Integration section +# of the documentation for details. +wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp + +# Java Classpath (include wrapper.jar) Add class path elements as +# needed starting from 1 +wrapper.java.classpath.1=../../raplabootstrap.jar +wrapper.java.classpath.2=../lib/wrapper.jar + +# Java Library Path (location of Wrapper.DLL or libwrapper.so) +wrapper.java.library.path.1=../lib + +# Java Bits. On applicable platforms, tells the JVM to run in 32 or 64-bit mode. +wrapper.java.additional.auto_bits=TRUE + +# Java Additional Parameters +# wrapper.java.additional.1= + +# Initial Java Heap Size (in MB) +#wrapper.java.initmemory=3 + +# Maximum Java Heap Size (in MB) +#wrapper.java.maxmemory=64 + +# Application parameters. Add parameters as needed starting from 1 +wrapper.app.parameter.1=org.rapla.bootstrap.RaplaServerAsServiceLoader + +#******************************************************************** +# Wrapper Logging Properties +#******************************************************************** +# Enables Debug output from the Wrapper. +# wrapper.debug=TRUE + +# Format of output for the console. (See docs for formats) +wrapper.console.format=PM + +# Log Level for console output. (See docs for log levels) +wrapper.console.loglevel=INFO + +# Log file to use for wrapper output logging. +wrapper.logfile=../../logs/wrapper.log + +# Format of output for the log file. (See docs for formats) +wrapper.logfile.format=LPTM + +# Log Level for log file output. (See docs for log levels) +wrapper.logfile.loglevel=WARN + +# Maximum size that the log file will be allowed to grow to before +# the log is rolled. Size is specified in bytes. The default value +# of 0, disables log rolling. May abbreviate with the 'k' (kb) or +# 'm' (mb) suffix. For example: 10m = 10 megabytes. +wrapper.logfile.maxsize=10m + +# Maximum number of rolled log files which will be allowed before old +# files are deleted. The default value of 0 implies no limit. +wrapper.logfile.maxfiles=10 + +# Log Level for sys/event log output. (See docs for log levels) +wrapper.syslog.loglevel=WARN + +#******************************************************************** +# Wrapper General Properties +#******************************************************************** +# Allow for the use of non-contiguous numbered properties +wrapper.ignore_sequence_gaps=TRUE + +# Do not start if the pid file already exists. +wrapper.pidfile.strict=TRUE + +# Title to use when running as a console +wrapper.console.title=Rapla + +#******************************************************************** +# Wrapper JVM Checks +#******************************************************************** +# Detect DeadLocked Threads in the JVM. (Requires Standard Edition) +wrapper.check.deadlock=TRUE +wrapper.check.deadlock.interval=10 +wrapper.check.deadlock.action=RESTART +wrapper.check.deadlock.output=FULL + +# Out Of Memory detection. +# (Ignore output from dumping the configuration to the console. This is only needed by the TestWrapper sample application.) +wrapper.filter.trigger.999=wrapper.filter.trigger.*java.lang.OutOfMemoryError +wrapper.filter.allow_wildcards.999=TRUE +wrapper.filter.action.999=NONE +# Ignore -verbose:class output to avoid false positives. +wrapper.filter.trigger.1000=[Loaded java.lang.OutOfMemoryError +wrapper.filter.action.1000=NONE +# (Simple match) +wrapper.filter.trigger.1001=java.lang.OutOfMemoryError +# (Only match text in stack traces if -XX:+PrintClassHistogram is being used.) +#wrapper.filter.trigger.1001=Exception in thread "*" java.lang.OutOfMemoryError +#wrapper.filter.allow_wildcards.1001=TRUE +wrapper.filter.action.1001=RESTART +wrapper.filter.message.1001=The JVM has run out of memory. + +#******************************************************************** +# Wrapper Email Notifications. (Requires Professional Edition) +#******************************************************************** +# Common Event Email settings. +#wrapper.event.default.email.debug=TRUE +#wrapper.event.default.email.smtp.host= +#wrapper.event.default.email.smtp.port=25 +#wrapper.event.default.email.subject=[%WRAPPER_HOSTNAME%:%WRAPPER_NAME%:%WRAPPER_EVENT_NAME%] Event Notification +#wrapper.event.default.email.sender= +#wrapper.event.default.email.recipient= + +# Configure the log attached to event emails. +#wrapper.event.default.email.attach_log=TRUE +#wrapper.event.default.email.maillog.lines=50 +#wrapper.event.default.email.maillog.format=LPTM +#wrapper.event.default.email.maillog.loglevel=INFO + +# Enable specific event emails. +#wrapper.event.wrapper_start.email=TRUE +#wrapper.event.jvm_prelaunch.email=TRUE +#wrapper.event.jvm_start.email=TRUE +#wrapper.event.jvm_started.email=TRUE +#wrapper.event.jvm_deadlock.email=TRUE +#wrapper.event.jvm_stop.email=TRUE +#wrapper.event.jvm_stopped.email=TRUE +#wrapper.event.jvm_restart.email=TRUE +#wrapper.event.jvm_failed_invocation.email=TRUE +#wrapper.event.jvm_max_failed_invocations.email=TRUE +#wrapper.event.jvm_kill.email=TRUE +#wrapper.event.jvm_killed.email=TRUE +#wrapper.event.jvm_unexpected_exit.email=TRUE +#wrapper.event.wrapper_stop.email=TRUE + +# Specify custom mail content +wrapper.event.jvm_restart.email.body=The JVM was restarted.\n\nPlease check on its status.\n + +#******************************************************************** +# Wrapper Windows NT/2000/XP Service Properties +#******************************************************************** +# WARNING - Do not modify any of these properties when an application +# using this configuration file has been installed as a service. +# Please uninstall the service before modifying this section. The +# service can then be reinstalled. + +# Name of the service +wrapper.name=Raplaxxxxxxxx + +# Display name of the service +wrapper.displayname=Rapla Server +# Description of the service +wrapper.description=Rapla resource-management server + +# Service dependencies. Add dependencies as needed starting from 1 +wrapper.ntservice.dependency.1= + +# Mode in which the service is installed. AUTO_START, DELAY_START or DEMAND_START +wrapper.ntservice.starttype=AUTO_START + +# Allow the service to interact with the desktop. +wrapper.ntservice.interactive=false + diff --git a/rapla-source-1.8.2/service/doc/readme.txt b/rapla-source-1.8.2/service/doc/readme.txt new file mode 100644 index 0000000..6332f32 --- /dev/null +++ b/rapla-source-1.8.2/service/doc/readme.txt @@ -0,0 +1,7 @@ +Java Service Wrapper + +Complete documentation can be found online: +http://wrapper.tanukisoftware.org + +Java docs are available online as well: +http://wrapper.tanukisoftware.org/jdoc/index.html diff --git a/rapla-source-1.8.2/service/lib/libwrapper.so b/rapla-source-1.8.2/service/lib/libwrapper.so new file mode 100644 index 0000000..f521b4e Binary files /dev/null and b/rapla-source-1.8.2/service/lib/libwrapper.so differ diff --git a/rapla-source-1.8.2/service/lib/wrapper.dll b/rapla-source-1.8.2/service/lib/wrapper.dll new file mode 100644 index 0000000..c17b464 Binary files /dev/null and b/rapla-source-1.8.2/service/lib/wrapper.dll differ diff --git a/rapla-source-1.8.2/service/lib/wrapper.jar b/rapla-source-1.8.2/service/lib/wrapper.jar new file mode 100644 index 0000000..838403e Binary files /dev/null and b/rapla-source-1.8.2/service/lib/wrapper.jar differ diff --git a/rapla-source-1.8.2/src/commons-logging.properties b/rapla-source-1.8.2/src/commons-logging.properties new file mode 100644 index 0000000..350677e --- /dev/null +++ b/rapla-source-1.8.2/src/commons-logging.properties @@ -0,0 +1 @@ +org.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog diff --git a/rapla-source-1.8.2/src/ical4j.properties b/rapla-source-1.8.2/src/ical4j.properties new file mode 100644 index 0000000..af7262d --- /dev/null +++ b/rapla-source-1.8.2/src/ical4j.properties @@ -0,0 +1 @@ +net.fortuna.ical4j.timezone.update.enabled=false diff --git a/rapla-source-1.8.2/src/org/rapla/AppointmentFormaterImpl.java b/rapla-source-1.8.2/src/org/rapla/AppointmentFormaterImpl.java new file mode 100644 index 0000000..70e80d5 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/AppointmentFormaterImpl.java @@ -0,0 +1,354 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +import org.rapla.components.util.DateTools; +import org.rapla.components.xmlbundle.I18nBundle; +import org.rapla.entities.domain.Appointment; +import org.rapla.entities.domain.AppointmentFormater; +import org.rapla.entities.domain.Period; +import org.rapla.entities.domain.Repeating; +import org.rapla.facade.RaplaComponent; +import org.rapla.framework.RaplaContext; +import org.rapla.framework.RaplaException; +import org.rapla.framework.RaplaLocale; + +/** default implementation of appointment formater */ +public class AppointmentFormaterImpl + implements + AppointmentFormater +{ + I18nBundle i18n; + RaplaLocale loc; + + public AppointmentFormaterImpl(RaplaContext context) throws RaplaException + { + i18n = context.lookup(RaplaComponent.RAPLA_RESOURCES); + loc = context.lookup(RaplaLocale.class); + } + + protected RaplaLocale getRaplaLocale() { + return loc; + } + + protected I18nBundle getI18n() { + return i18n; + } + + protected String getString(String key) { + return i18n.getString(key); + } + + + public String getShortSummary(Appointment appointment) { + String time = loc.formatTime(appointment.getStart()); + Repeating repeating = appointment.getRepeating(); + final boolean wholeDaysSet = appointment.isWholeDaysSet(); + final String timeString = wholeDaysSet ? "" :" " + time; + String weekday = loc.getWeekday(appointment.getStart()); + if (repeating != null) { + if (repeating.isWeekly()) { + return weekday + timeString; + } + if (repeating.isDaily()) + return getString("daily") + " " + time; + if (repeating.isMonthly()) + return getWeekdayOfMonth( appointment.getStart() ) + weekday + timeString; + if (repeating.isYearly()) + return getDayOfMonth( appointment.getStart() ) + loc.getMonth(appointment.getStart()) +" " + timeString; + } + String date = loc.formatDate(appointment.getStart()); + return weekday + " " +date + " " + timeString; + } + + public String getVeryShortSummary(Appointment appointment) { + Repeating repeating = appointment.getRepeating(); + if (repeating != null) { + if (repeating.isWeekly()) + return getRaplaLocale().getWeekday(appointment.getStart()); + if (repeating.isDaily()) { + String time = getRaplaLocale().formatTime(appointment.getStart()); + return time; + } + if (repeating.isMonthly()) + { + return getRaplaLocale().getWeekday(appointment.getStart()); + } + } + String date = getRaplaLocale().formatDateShort(appointment.getStart()); + return date; + } + + public String getSummary( Appointment a ) { + StringBuffer buf = new StringBuffer(); + Repeating repeating = a.getRepeating(); + final boolean wholeDaysSet = a.isWholeDaysSet(); + Date start = a.getStart(); + Date end = a.getEnd(); + if ( repeating == null ) + { + buf.append( loc.getWeekday( start ) ); + buf.append( ' ' ); + buf.append( loc.formatDate( start ) ); + if (!wholeDaysSet && !( end.equals( DateTools.cutDate(end)) && start.equals(DateTools.cutDate( start)))) + { + buf.append( ' ' ); + buf.append( loc.formatTime( start ) ); + + if ( isSameDay( start, end ) || (end.equals( DateTools.cutDate(end)) && isSameDay( DateTools.fillDate( start), end)) ) + { + buf.append( '-' ); + } + else + { + buf.append( " - " ); + buf.append( loc.getWeekday( end ) ); + buf.append( ' ' ); + buf.append( loc.formatDate( end ) ); + buf.append( ' ' ); + } + buf.append( loc.formatTime( end ) ); + } + else if ( end.getTime() - start.getTime() > DateTools.MILLISECONDS_PER_DAY) + { + buf.append( " - " ); + buf.append( loc.getWeekday( DateTools.addDays(end,-1 )) ); + buf.append( ' ' ); + buf.append( loc.formatDate( DateTools.addDays(end,-1 )) ); + } + } + else if ( repeating.isWeekly() || repeating.isMonthly() || repeating.isYearly()) + { + if( repeating.isMonthly()) + { + buf.append( getWeekdayOfMonth( start )); + } + if (repeating.isYearly()) + { + buf.append( getDayOfMonth( start ) ); + buf.append( loc.getMonth( start ) ); + } + else + { + buf.append( loc.getWeekday( start ) ); + } + if (wholeDaysSet) + { + if ( end.getTime() - start.getTime() > DateTools.MILLISECONDS_PER_DAY) + { + if ( end.getTime() - start.getTime() <= DateTools.MILLISECONDS_PER_DAY * 6 ) + { + buf.append( " - " ); + buf.append( loc.getWeekday( end ) ); + } + else + { + buf.append( ' ' ); + buf.append( loc.formatDate( start ) ); + buf.append( " - " ); + buf.append( loc.getWeekday( end ) ); + buf.append( ' ' ); + buf.append( loc.formatDate( end ) ); + } + } + } + else + { + buf.append( ' ' ); + if ( isSameDay( start, end ) ) + { + buf.append( loc.formatTime( start ) ); + buf.append( '-' ); + buf.append( loc.formatTime( end ) ); + } + else if ( end.getTime() - start.getTime() <= DateTools.MILLISECONDS_PER_DAY * 6 ) + { + buf.append( loc.formatTime( start ) ); + buf.append( " - " ); + buf.append( loc.getWeekday( end ) ); + buf.append( ' ' ); + buf.append( loc.formatTime( end ) ); + } + else + { + buf.append( loc.formatDate( start ) ); + buf.append( ' ' ); + buf.append( loc.formatTime( start ) ); + buf.append( " - " ); + buf.append( loc.getWeekday( end ) ); + buf.append( ' ' ); + buf.append( loc.formatDate( end ) ); + buf.append( ' ' ); + buf.append( loc.formatTime( end ) ); + } + } + + if ( repeating.isWeekly()) + { + buf.append( ' ' ); + buf.append( getInterval( repeating ) ); + } + if ( repeating.isMonthly()) + { + buf.append(" " + getString("monthly")); + } + if ( repeating.isYearly()) + { + buf.append(" " + getString("yearly")); + } + } + + else if ( repeating.isDaily() ) + { + + long days =(end.getTime() - start.getTime()) / (DateTools.MILLISECONDS_PER_HOUR * 24 ); + if ( !a.isWholeDaysSet()) + { + buf.append( loc.formatTime( start ) ); + if ( days <1) + { + buf.append( '-' ); + buf.append( loc.formatTime( end ) ); + } + buf.append( ' ' ); + } + buf.append( getInterval( repeating ) ); + } + return buf.toString(); + } + + private String getWeekdayOfMonth( Date date ) + { + StringBuffer b = new StringBuffer(); + int numb = DateTools.getDayOfWeekInMonth( date ); + b.append( String.valueOf(numb)); + b.append( '.'); + b.append( ' '); + return b.toString(); + } + + private String getDayOfMonth( Date date ) + { + StringBuffer b = new StringBuffer(); + int numb = DateTools.getDayOfMonth( date ); + b.append( String.valueOf(numb)); + b.append( '.'); + b.append( ' '); + return b.toString(); + } + + private boolean isSameDay( Date d1, Date d2 ) { + return DateTools.isSameDay(d1, d2); + } + + public String getExceptionSummary( Repeating r ) { + StringBuffer buf = new StringBuffer(); + buf.append(getString("appointment.exceptions")); + buf.append(": "); + Date[] exc = r.getExceptions(); + for ( int i=0;i0) + buf.append(", "); + buf.append( getRaplaLocale().formatDate( exc[i] ) ); + } + return buf.toString(); + } + + private String getInterval( Repeating r ) { + StringBuffer buf = new StringBuffer(); + if ( r.getInterval() == 1 ) { + buf.append( getString( r.getType().toString() ) ); + } else { + String fString ="weekly"; + if ( r.isWeekly() ) { + fString = getString( "weeks" ); + } + if ( r.isDaily() ) { + fString = getString( "days" ); + } + buf.append( getI18n().format( "interval.format", "" + r.getInterval(), fString ) ); + } + return buf.toString(); + } + + private boolean isPeriodicaly(Period period, Repeating r) { + Appointment a = r.getAppointment(); + if (r.getEnd().after( period.getEnd() ) ) + return false; + if ( r.isWeekly() ) + { + return + ( DateTools.cutDate(a.getStart().getTime()) - period.getStart().getTime() ) + <= DateTools.MILLISECONDS_PER_DAY * 6 + && + ( DateTools.cutDate(period.getEnd().getTime()) - r.getEnd().getTime() ) + <= DateTools.MILLISECONDS_PER_DAY * 6 + ; + } + else if ( r.isDaily() ) + { + return + isSameDay( a.getStart(), period.getStart() ) + && + isSameDay( r.getEnd(), period.getEnd() ) + ; + } + return false; + } + + public String getSummary( Repeating r , List periods) { + if ( r.getEnd() != null && !r.isFixedNumber() ) + { + Iterator it = periods.iterator(); + while ( it.hasNext() ) { + Period period = it.next(); + if ( isPeriodicaly(period, r)) + return getI18n().format("in_period.format" + ,period.getName(loc.getLocale()) + ); + } + } + return getSummary(r); + } + + public String getSummary( Repeating r ) { + Appointment a = r.getAppointment(); + StringBuffer buf = new StringBuffer(); + String startDate = loc.formatDate( a.getStart() ); + buf.append( getI18n().format("format.repeat_from", startDate) ); + buf.append( ' ' ); + // print end date, when end is given + if ( r.getEnd() != null) { + String endDate = loc.formatDate( DateTools.subDay(r.getEnd()) ); + buf.append( getI18n().format("format.repeat_until", endDate) ); + buf.append( ' ' ); + } + + // print number of repeating if number is gt 0 and fixed times + if ( r.getNumber()>=0 && r.isFixedNumber() ) { + buf.append( getI18n().format("format.repeat_n_times", String.valueOf(r.getNumber())) ); + buf.append( ' ' ); + } + // print never ending if end is null + if (r.getEnd() == null ){ + buf.append( getString("repeating.forever") ); + buf.append( ' ' ); + } + + return buf.toString(); + } + +} diff --git a/rapla-source-1.8.2/src/org/rapla/ConnectInfo.java b/rapla-source-1.8.2/src/org/rapla/ConnectInfo.java new file mode 100644 index 0000000..deb2e56 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/ConnectInfo.java @@ -0,0 +1,35 @@ +package org.rapla; + +import java.util.Arrays; +/** Object that encapsulates the login information. + * For admin users it is possible to connect as an other user. + */ +public class ConnectInfo { + String username; + char[] password; + String connectAs; + public ConnectInfo(String username, char[] password, String connectAs) { + this.username = username; + this.password = password; + this.connectAs = connectAs; + } + + public ConnectInfo(String username, char[] password) { + this( username, password, null); + } + + public String getUsername() { + return username; + } + public char[] getPassword() { + return password; + } + public String getConnectAs() { + return connectAs; + } + + @Override + public String toString() { + return "ReconnectInfo [username=" + username + ", password=" + Arrays.toString(password) + ", connectAs=" + connectAs + "]"; + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/MyResources.xml b/rapla-source-1.8.2/src/org/rapla/MyResources.xml new file mode 100644 index 0000000..c6de8b9 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/MyResources.xml @@ -0,0 +1,8 @@ + + + + + + Hello {0}, enjoy yourself! + + diff --git a/rapla-source-1.8.2/src/org/rapla/RaplaMainContainer.java b/rapla-source-1.8.2/src/org/rapla/RaplaMainContainer.java new file mode 100644 index 0000000..1e88197 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/RaplaMainContainer.java @@ -0,0 +1,381 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla; + +import java.io.BufferedReader; +import java.io.File; +import java.io.InputStreamReader; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.net.MalformedURLException; +import java.net.URL; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Date; +import java.util.Enumeration; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.TimeZone; + +import org.rapla.components.util.CommandScheduler; +import org.rapla.components.util.IOUtil; +import org.rapla.components.util.xml.RaplaNonValidatedInput; +import org.rapla.components.xmlbundle.CompoundI18n; +import org.rapla.components.xmlbundle.I18nBundle; +import org.rapla.components.xmlbundle.LocaleSelector; +import org.rapla.components.xmlbundle.impl.I18nBundleImpl; +import org.rapla.entities.domain.AppointmentFormater; +import org.rapla.entities.dynamictype.internal.AttributeImpl; +import org.rapla.facade.CalendarOptions; +import org.rapla.facade.RaplaComponent; +import org.rapla.facade.internal.CalendarOptionsImpl; +import org.rapla.framework.Configuration; +import org.rapla.framework.Provider; +import org.rapla.framework.RaplaContext; +import org.rapla.framework.RaplaContextException; +import org.rapla.framework.RaplaDefaultContext; +import org.rapla.framework.RaplaLocale; +import org.rapla.framework.ServiceListCreator; +import org.rapla.framework.StartupEnvironment; +import org.rapla.framework.TypedComponentRole; +import org.rapla.framework.internal.ComponentInfo; +import org.rapla.framework.internal.ConfigTools; +import org.rapla.framework.internal.ContainerImpl; +import org.rapla.framework.internal.RaplaJDKLoggingAdapter; +import org.rapla.framework.internal.RaplaLocaleImpl; +import org.rapla.framework.internal.RaplaMetaConfigInfo; +import org.rapla.framework.logger.Logger; +import org.rapla.rest.gwtjsonrpc.common.FutureResult; +import org.rapla.storage.dbrm.RaplaHTTPConnector; +import org.rapla.storage.dbrm.RemoteConnectionInfo; +import org.rapla.storage.dbrm.RemoteMethodStub; +import org.rapla.storage.dbrm.RemoteServer; +import org.rapla.storage.dbrm.RemoteServiceCaller; +import org.rapla.storage.dbrm.StatusUpdater; +import org.rapla.storage.dbrm.StatusUpdater.Status; +/** +The Rapla Main Container class for the basic container for Rapla specific services and the rapla plugin architecture. +The rapla container has only one instance at runtime. Configuration of the RaplaMainContainer is done in the rapla*.xconf +files. Typical configurations of the MainContainer are + +
    +
  1. Client: A ClientContainerService, one facade and a remote storage ( automaticaly pointing to the download server in webstart mode)
  2. +
  3. Server: A ServerContainerService (providing a facade) a messaging server for handling the connections with the clients, a storage (file or db) and an extra service for importing and exporting in the db
  4. +
  5. Standalone: A ClientContainerService (with preconfigured auto admin login) and a ServerContainerService that is directly connected to the client without http communication.
  6. +
  7. Embedded: Configuration example follows.
  8. +
+

+Configuration of the main container is usually done via the raplaserver.xconf +

+

+The Main Container provides the following Services to all RaplaComponents +

+
    +
  • I18nBundle
  • +
  • AppointmentFormater
  • +
  • RaplaLocale
  • +
  • LocaleSelector
  • +
  • RaplaMainContainer.PLUGIN_LIST (A list of all available plugins)
  • +
+ + @see I18nBundle + @see RaplaLocale + @see AppointmentFormater + @see LocaleSelector + */ +final public class RaplaMainContainer extends ContainerImpl +{ + public static final TypedComponentRole RAPLA_MAIN_CONFIGURATION = new TypedComponentRole("org.rapla.MainConfiguration"); + public static final TypedComponentRole DOWNLOAD_SERVER = new TypedComponentRole("download-server"); + public static final TypedComponentRole DOWNLOAD_URL = new TypedComponentRole("download-url"); + public static final TypedComponentRole ENV_RAPLADATASOURCE = new TypedComponentRole("env.rapladatasource"); + public static final TypedComponentRole ENV_RAPLAFILE = new TypedComponentRole("env.raplafile"); + public static final TypedComponentRole ENV_RAPLADB= new TypedComponentRole("env.rapladb"); + public static final TypedComponentRole ENV_RAPLAMAIL= new TypedComponentRole("env.raplamail"); + public static final TypedComponentRole ENV_DEVELOPMENT = new TypedComponentRole("env.development"); + + public static final TypedComponentRole TIMESTAMP = new TypedComponentRole("timestamp"); + public static final TypedComponentRole CONTEXT_ROOT = new TypedComponentRole("context-root"); + public final static TypedComponentRole> PLUGIN_LIST = new TypedComponentRole>("plugin-list"); + public final static TypedComponentRole TITLE = new TypedComponentRole("org.rapla.title"); + public final static TypedComponentRole TIMEZONE = new TypedComponentRole("org.rapla.timezone"); + Logger callLogger; + + public RaplaMainContainer() throws Exception { + this(new RaplaStartupEnvironment()); + } + + public RaplaMainContainer(StartupEnvironment env) throws Exception { + this( env, new RaplaDefaultContext() ); + } + + public RaplaMainContainer( StartupEnvironment env, RaplaContext context) throws Exception + { + this( env,context,createRaplaLogger()); + } + + RemoteConnectionInfo globalConnectInfo; + CommandScheduler commandQueue; + I18nBundle i18n; + RaplaHTTPConnector connector; + + + public RaplaMainContainer( StartupEnvironment env, RaplaContext context,Logger logger) throws Exception{ + super( context, env.getStartupConfiguration(),logger ); + addContainerProvidedComponentInstance( StartupEnvironment.class, env); + addContainerProvidedComponentInstance( DOWNLOAD_SERVER, env.getDownloadURL().getHost()); + addContainerProvidedComponentInstance( DOWNLOAD_URL, env.getDownloadURL()); + commandQueue = createCommandQueue(); + addContainerProvidedComponentInstance( CommandScheduler.class, commandQueue); + addContainerProvidedComponentInstance( RemoteServiceCaller.class, new RemoteServiceCaller() { + + @Override + public T getRemoteMethod(Class a) throws RaplaContextException { + return RaplaMainContainer.this.getRemoteMethod(getContext(), a); + } + } ); + + if (env.getContextRootURL() != null) + { + File file = IOUtil.getFileFrom( env.getContextRootURL()); + addContainerProvidedComponentInstance( CONTEXT_ROOT, file.getPath()); + } + addContainerProvidedComponentInstance( TIMESTAMP, new Object() { + + public String toString() { + DateFormat formatter = new SimpleDateFormat("yyyyMMdd-HHmmss"); + String formatNow = formatter.format(new Date()); + return formatNow; + } + + }); + initialize(); + } + + private static Logger createRaplaLogger() + { + Logger logger; + try { + RaplaMainContainer.class.getClassLoader().loadClass("org.slf4j.Logger"); + @SuppressWarnings("unchecked") + Provider logManager = (Provider) RaplaMainContainer.class.getClassLoader().loadClass("org.rapla.framework.internal.Slf4jAdapter").newInstance(); + logger = logManager.get(); + logger.info("Logging via SLF4J API."); + } catch (Throwable e1) { + Provider logManager = new RaplaJDKLoggingAdapter( ); + logger = logManager.get(); + logger.info("Logging via java.util.logging API. " + e1.toString()); + } + return logger; + } + + protected Map getComponentInfos() { + return new RaplaMetaConfigInfo(); + } + + private void initialize() throws Exception { + + Logger logger = getLogger(); + int startupMode = getStartupEnvironment().getStartupMode(); + logger.debug("----------- Rapla startup mode = " + startupMode); + RaplaLocaleImpl raplaLocale = new RaplaLocaleImpl(m_config.getChild("locale"), logger); + + Configuration localeConfig = m_config.getChild("locale"); + CalendarOptions calendarOptions = new CalendarOptionsImpl(localeConfig); + addContainerProvidedComponentInstance( CalendarOptions.class, calendarOptions ); + addContainerProvidedComponentInstance( RAPLA_MAIN_CONFIGURATION, m_config ); + addContainerProvidedComponent( RaplaNonValidatedInput.class, ConfigTools.RaplaReaderImpl.class); + + // Startup mode= EMBEDDED = 0, CONSOLE = 1, WEBSTART = 2, APPLET = 3, SERVLET = 4 + addContainerProvidedComponentInstance( RaplaLocale.class,raplaLocale); + addContainerProvidedComponentInstance( LocaleSelector.class,raplaLocale.getLocaleSelector()); + + m_config.getChildren("rapla-client"); + + String defaultBundleName = m_config.getChild("default-bundle").getValue( null); + // Override the intern Resource Bundle with user provided + Configuration parentConfig = I18nBundleImpl.createConfig( RaplaComponent.RAPLA_RESOURCES.getId() ); + if ( defaultBundleName!=null) { + I18nBundleImpl i18n = new I18nBundleImpl( getContext(), I18nBundleImpl.createConfig( defaultBundleName ), logger); + String parentId = i18n.getParentId(); + if ( parentId != null && parentId.equals(RaplaComponent.RAPLA_RESOURCES.getId())) + { + I18nBundleImpl parent = new I18nBundleImpl( getContext(), parentConfig, logger); + I18nBundle compound = new CompoundI18n( i18n, parent); + addContainerProvidedComponentInstance(RaplaComponent.RAPLA_RESOURCES, compound); + } + else + { + addContainerProvidedComponent(RaplaComponent.RAPLA_RESOURCES,I18nBundleImpl.class, parentConfig); + } + } + else + { + addContainerProvidedComponent(RaplaComponent.RAPLA_RESOURCES,I18nBundleImpl.class, parentConfig); + } + + addContainerProvidedComponentInstance( AppointmentFormater.class, new AppointmentFormaterImpl( getContext())); + + + // Discover and register the plugins for Rapla + + Set pluginNames = new LinkedHashSet(); + + boolean isDevelopment = getContext().has(RaplaMainContainer.ENV_DEVELOPMENT) && getContext().lookup( RaplaMainContainer.ENV_DEVELOPMENT); + Enumeration pluginEnum = ConfigTools.class.getClassLoader().getResources("META-INF/rapla-plugin.list"); + if (!pluginEnum.hasMoreElements() || isDevelopment) + { + Collection result = ServiceListCreator.findPluginClasses(logger); + pluginNames.addAll(result); + } + + while ( pluginEnum.hasMoreElements() ) { + BufferedReader reader = new BufferedReader(new InputStreamReader((pluginEnum.nextElement()).openStream())); + while ( true ) { + String plugin = reader.readLine(); + if ( plugin == null) + break; + pluginNames.add(plugin); + } + } + + addContainerProvidedComponentInstance( PLUGIN_LIST, pluginNames); + logger.info("Config=" + getStartupEnvironment().getConfigURL()); + + i18n = getContext().lookup(RaplaComponent.RAPLA_RESOURCES); + String version = i18n.getString( "rapla.version" ); + logger.info("Rapla.Version=" + version); + version = i18n.getString( "rapla.build" ); + logger.info("Rapla.Build=" + version); + logger.info("Timezone " + TimeZone.getDefault().getID()); + AttributeImpl.TRUE_TRANSLATION.setName(i18n.getLang(), i18n.getString("yes")); + AttributeImpl.FALSE_TRANSLATION.setName(i18n.getLang(), i18n.getString("no")); + try { + version = System.getProperty("java.version"); + logger.info("Java.Version=" + version); + } catch (SecurityException ex) { + version = "-"; + logger.warn("Permission to system property java.version is denied!"); + } + callLogger =logger.getChildLogger("call"); + String errorString = i18n.format("error.connect", getStartupEnvironment().getDownloadURL()) + " "; + connector = new RaplaHTTPConnector( commandQueue, errorString); + } + + public void dispose() { + getLogger().info("Shutting down rapla-container"); + if ( commandQueue != null) + { + ((DefaultScheduler)commandQueue).cancel(); + } + super.dispose(); + } + + + public T getRemoteMethod(final RaplaContext context,final Class a) throws RaplaContextException + { + if (context.has( RemoteMethodStub.class)) + { + RemoteMethodStub server = context.lookup(RemoteMethodStub.class); + return server.getWebserviceLocalStub(a); + } + + InvocationHandler proxy = new InvocationHandler() + { + RemoteConnectionInfo localConnectInfo; + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable + { + if ( method.getName().equals("setConnectInfo") && method.getParameterTypes()[0].equals(RemoteConnectionInfo.class)) + { + localConnectInfo = (RemoteConnectionInfo) args[0]; + if ( globalConnectInfo == null) + { + globalConnectInfo =localConnectInfo; + } + return null; + } + + RemoteConnectionInfo remoteConnectionInfo = localConnectInfo != null ? localConnectInfo : globalConnectInfo; + if ( remoteConnectionInfo == null) + { + throw new IllegalStateException("you need to call setConnectInfo first"); + } + Class returnType = method.getReturnType(); + String methodName = method.getName(); + final URL server; + try + { + server = new URL( remoteConnectionInfo.getServerURL()); + } + catch (MalformedURLException e) + { + throw new RaplaContextException(e.getMessage()); + } + StatusUpdater statusUpdater = remoteConnectionInfo.getStatusUpdater(); + if ( statusUpdater != null) + { + statusUpdater.setStatus( Status.BUSY ); + } + FutureResult result; + try + { + result = call( a, methodName, args, remoteConnectionInfo); + if (callLogger.isDebugEnabled()) + { + callLogger.debug("Calling " + server + " " + a.getName() + "."+methodName); + } + } + finally + { + if ( statusUpdater != null) + { + statusUpdater.setStatus( Status.READY ); + } + } + if ( !FutureResult.class.isAssignableFrom(returnType)) + { + return result.get(); + } + return result; + } + }; + ClassLoader classLoader = a.getClassLoader(); + @SuppressWarnings("unchecked") + Class[] interfaces = new Class[] {a}; + @SuppressWarnings("unchecked") + T proxyInstance = (T)Proxy.newProxyInstance(classLoader, interfaces, proxy); + return proxyInstance; + } + + + private FutureResult call(Class service, String methodName,Object[] args,RemoteConnectionInfo connectionInfo) throws NoSuchMethodException, SecurityException { + ConnectInfo connectInfo = connectionInfo.getConnectInfo(); + if ( connectInfo !=null) + { + Method method = RemoteServer.class.getMethod("login", String.class, String.class,String.class); + connector.setReAuthentication(RemoteServer.class, method, new Object[] {connectInfo.getUsername(), new String(connectInfo.getPassword()), connectInfo.getConnectAs()}); + } + FutureResult result =connector.call(service, methodName, args, connectionInfo); + return result; + } + + + + + + } + diff --git a/rapla-source-1.8.2/src/org/rapla/RaplaResources.xml b/rapla-source-1.8.2/src/org/rapla/RaplaResources.xml new file mode 100644 index 0000000..e7e39d6 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/RaplaResources.xml @@ -0,0 +1,5497 @@ + + + + + + + @doc.version@ + + + + @doc.buildtime@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Apply + Übernehmen + Valider + Aplicar + Použít + Toepassen + Zastosuj + Aplicar + Aseta + + + Go back + Zurück + Retour + Volver + Zpět + Sluit + Wstecz + Voltar + Takaisin + + + Cancel + Abbrechen + Annuler + Cancelar + Zrušit + Annuleren + Anuluj + Cancelar + Peru + + + Continue + Weiter + Suivant + Continuar + Pokračovat + Verder + Kontynuuj + Continuar + Jatka + + + Error + Fehler + Erreur + Error + Chyba + Fout + Błąd + Erro + Virhe + + + Exception + Ausnahme-Fehler + Exception + Excepción + Vyjímka + Uitzondering + Wyjątek + Exceção + Poikkeus + + + OK + OK + OK + OK + Budiž + OK + OK + Ok + OK + + + Warning + Warnung + Attention + Atención + Varování! + Waarschuwing + Uwaga + Atenção! + Varoitus + + + + + + Abort + Abbrechen + Annuler + Anular + Ukončit + Annuleren + Porzuć + Abortar + Keskeytä + + + Add + Hinzufügen + Insérer + Añadir + Přidat + Toevoegen + Dodaj + Adicionar + Lisää + + + Add to + Hinzufügen zu + Insérer à + Añadir a + Přidat do + Toevoegen aan + Dodaj do + Adicionar a + Lisää + + + Change + Ändern + Modifier + Modificar + Změnit + Wijzig + Zmień + Modificar + Muuta + + + Confirm + Bestätigen + Confirmer + Confirmar + Potvrdit + Bevestig + Akceptuj + Confirmar + Vahvista + + + Color + Farbe + Couleur + Color + Barva + Kleur + Kolor + Cor + Väri + + + Cut + Ausschneiden + Couper + Cortar + Vyjmutí + Knippen + Wytnij + Cortar + Leikata + + + Copy + Kopieren + Copier + Copiar + Kopie + Kopieer + Kopiuj + Copiar + Kopioi + + + Copy to Clipboard + In die Zwischenablage + Copier vers le presse papier + Copiar al portapapeles + Kopírovat do schránky + Kopieër naar plakbord + Kopiuj do schowka + Copiar para Área de Transferência + Kopioi leikepöydälle + + + Close + Schließen + Fermer + Cerrar + Zavřít + Sluit + Zamknij + Fechar + Sulje + + + Create + Erstellen + Créer + Crear + Vytvořit + Aanmaken + Utwórz + Criar + Luo + + + Delete + Löschen + Effacer + Borrar + Smazat + Verwijderen + Usuń + Deletar + Poista + + + Delete Selection + Auswahl löschen + Effacer la sélection + Borrar la selección + Smazat výběr + Verwijder selectie + Usuń Wybór + Deletar Seleção + Poista valinta + + + Edit + Bearbeiten + Modifier + Editar + Upravit + Bewerk + Edytuj + Editar + Muokkaa + + + Exit + Beenden + Quitter + Salir + Odejít + Sluiten + Wyjście + Sair + Poistu + + + Publish + Veröffentlichen + Publier + Publicar + Publikuj + publikovat + Publiceer + Publicar + Julkaise + + + Export + Export + Exporter + Exportar + Export + Exporteer + Eksportuj + Exportar + Vie + + + Insert + Einfügen + Insérer + Insertar + Vložit + Toevoegen + Wstaw + Inserir + Aseta + + + Import + Import + Importer + Importar + Import + Importeer + Importuj + Importar + Tuo + + + Keep + Beibehalten + Conserver + Conservar + Podržet + Bewaar + Zachowaj + Manter + Säilytä + + + Load + Laden + Charger + Cargar + Nahrát + Laad + Wczytaj + Carregar + Lataa + + + Login + Login + Connexion + Acceso + Login + Aanmelden + Zaloguj + Entrar + Kirjaudu sisään + + + Logout + Logout + Quitter + Salir + Odhlásit + Afmelden + Wyloguj + Sair + Kirjaudu ulos + + + Move + Verschieben + Déplacer + Mover + Přesunout + Verplaats + Przenieś + Mover + Siirrä + + + New + Neu + Nouveau + Nuevo + Nový + Nieuw + Nowy + Novo + Uusi + + + Paste + Einfügen + Coller + Pegar + Vložit + Plakken + Wklej + Colar + Liitä + + + Paste As + Einfügen als + Coller comme + Pegar como + Vložit vše + Plakken als + Wklej jako + Colar Como + Liitä määräten + + + Paste into existing event + Einfügen in bestehende Veranstaltung + Coller en événement existant + Pegar en evento existente + Vložit do existující událost + Plak in bestaande reservatie + Wklej do istniejącego wydarzenie + Colar em evento existente + Liitä olemassaolevaan tapahtumaan + + + Print + Drucken + Imprimer + Imprimir + Tisknout + Afdrukken + Drukuj + Imprimir + Tulosta + + + Print to File + In Datei drucken + Imprimer vers Fichier + Imprimir en Fichero + Tisk do souboru + Afdrukken naar bestand + Drukuj do pliku + Imprimir em Arquivo + Tulosta tiedostoon + + + Refresh + Aktualisieren + Actualiser + Actualizar + Obnovit + Actualiseren + Odśwież + Atualizar + Päivitä + + + Remove + Entfernen + Effacer + Eliminar + Odstranit + Verwijderen + Usuń + Remover + Poista + + + Root + Wurzel + Racine + Raíz + root + Oorsprong + Korzeń + Juuri + + + Save + Speichern + Sauvegarder + Guardar + Uložit + Opslaan + Zapisz + Salvar + Tallenna + + + saved + gespeichert + sauvegardé + guardado + Uložit + Opgeslagen + zapisano. + Salvo + tallennettu + + + File saved + Datei gespeichert + Fichier sauvegardé + Fichero guardado + Uložit soubor + Bestand opgeslagen + Zapisano Plik + Arquivo salvo + Tiedosto tallennettu + + + Show As + Anzeigen als + Afficher + Mostrar como + Ukaž vše + Type + Wyświetl jako + Mostrar Como + Näkymä + + + View + Anzeige + Affichage + Ver + Pohled + Toon + Widok + Vizualizar + Näytä + + + Name for the view + Name der Ansicht + Nom de la vue + Nombre de la vista + Naam kalender + Nazwa widoku + Nome da Vizualização + Näkymän nimi + + + + + All users + alle Benutzer + Tous les utilisateurs + Todos los usuarios + Všichni uživatelé + Alle gebruikers + Wszyscy użytkownicy + Todos Usuários + Kaikki käyttäjät + + + Alteration + Änderung + Modification + Modificación + Změna + Wijziging + Zmiana + Alteração + Vaihtelu + + + and + und + et + y + a + en + i + e + ja + + + Attribute + Attribut + Attribut + Atributo + Vlastnost + Attribuut + Atrybut + Atributo + Attribuutti + + + Attributes + Attribute + Attributs + Atributos + Potvrdit + Attributen + Atrybuty + Atributos + Attribuutit + + + Calendar + Kalender + Calendrier + Calendario + Kalendář + Kalender + Kalendarz + Calendário + Kalenteri + + + Categories + Kategorien + Catégories + Categorías + Seznam kategorií + Klassement + Kategorie + Categorias + Kategoriat + + + Category + Kategorie + Catégorie + Categoría + Kategorie + Klassement + Kategoria + Categoria + Kategoria + + + Categorization + Kategoriesierung + Regroupement + Categorisering + Kategoriointi + + + Changes + Änderungen + Modifications + Modificaciones + Změny + Wijzigingen + Zmiany + Modificações + Muutokset + + + Class + Klasse + Classe + Clase + Třída + Klasse + Klasa + Classe + Luokka + + + Classification + Klassifizierung + Classification + Clasificación + Hodnocení + Klassificatie + Klasyfikacja + Classificação + Luokitus + + + Connection with server + Verbindung mit dem Server + Connexion au serveur + conexión a servidor + Verbinding met de Server + Połączenie z serwerem + Conexão com o Servidor + Yhteys palvelimeen + + + Constraints + Einschränkungen + Contraintes + Restricciones + Omezení + Beperkingen + Ograniczenia + Restrições + Rajoitukset + + + + Created at + erstellt am + Créé le + Creado el + Vytvořeno + Geregisteerd op + Stworzono w + Criado em + Luotu + + + Customized + benutzerdefiniert + Personnalisé + Específico + Přizpůsobený + Aangepast door + Dostosowany + Customizado + Kustomoitu + + + Date + Datum + Date + Fecha + Datum + Datum + Data + Data + Päiväys + + + Default + Standard + Défaut + Estándar + Výchozí + Standaard + Domyślne + Padrão + Oletus + + + Destination + Ziel + Destination + Destino + Cíl + Naar + Miejsce docelowe + Destino + Kohde + + + Element key + Elementschlüssel + Clé d'élément + Clave de elemento + Klíč elementu + Elementsleutel + Klucz + Elemento Chave + Elementin avain + + + Email + Email + Email + Email + e-mail + Email + e-mail + E-mail + Sähköposti + + + End time + Endzeit + Heure de fin + Hora final + Čas ukončení + tot + Czas zakończenia + Hora do término + Lopetusaika + + + End + Ende + Fin + Fin + Konec + Einde + Koniec + Fim + Loppu + + + Filter + Filter + Filtre + Filtro + Filter + Filtr + Filtro + Suodatin + + + test + Test + Teste + testi + + + Fixed Date + festes Datum + Date fixe + Fecha fija + Pevný datum + Vaste datum + Ustalona data + Data Fixa + Kiinteä päivämäärä + + + for + für + pour + para + Pro + voor + dla / na + para + mille: + + + Go to Date + Datum anzeigen + Atteindre la date + Ir a la fecha + Jít na datum + Ga naar datum + Idź do daty + Vá para Data + Mene päivämäärään + + + Group + Gruppe + Groupe + Grupo + Skupina + Groep + Grupa + Grupo + Ryhmä + + + Groups + Gruppen + Groupes + Grupos + Skupiny + Groepen + Grupy + Grupos + Ryhmät + + + Help + Hilfe + Aide + Ayuda + Pomoc + Help + Pomoc + Ajuda + Apua + + + Hierarchy + Hierarchie + Hiérarchie + Jerarquía + Hierarchie + Hierarchie + Hierarchia + Hierarquia + Hierarkia + + + About Rapla... + Info + Information + Info + Informace + Informatie + O Rapla + Sobre o Rapla + Tietoja Raplasta + + + Not visible + nicht sichtbar + Non visible + no visible + neviditeně + Onzichtbaar + Ukryty + Invisível + Ei näkyvä + + + transparent + transparent + transparent + transparente + průhledný + Transparant zichtbaar + przezroczysty + Transparente + läpinäkyvä + + + disabled + ausgeschaltet + Désactivé + Uitgeschakeld + zablokowane + Desabilitado + pois päältä + + + Not visible.
Access to the reservation info is restricted.
+ Nicht sichtbar.
Der Zugriff auf die Reservierungsinformation ist eingeschränkt.
+ Non visible.
L'accès aux détails de la réservation est restreint.
+ No visible.
El acceso a la información de la reserva está restringido.
+ Skrytá položka.
Přístup k rezervačním informacím je zakázán.
+ Gewijgerd.
Toegang tot de boekings informatie is beperkt.
+ Ukryty.
Dostęp do informacji o rezerwacji jest zastrzeżony.
+ Não visível.
O acesso a informação reservada é restrito.
+ Ei näkyvissä.
Pääsy varaustietoihin on rajoitettu
+
+ + Not currently selected.
Unselect "Only Own Reservations" or change your filter settings.
+ Nicht ausgewählt.
Schalten Sie "nur eigene Reservierungen" aus oder ändern Sie die Filtereinstellungen.
+ Actuellement non sélectionné.
Dé-sélectionnez "Seulement mes réservations" ou changez les réglages du filtre.
+ Actualmente no seleccionado.
Desmarca "Sólo mis reservas" o cambia las configuraciones de los filtros.
+ Položka není v této chvíli vybrána.
Odstraňte volbu "Moje rezervace", nebo změňte nastavení vašeho filtru.
+ "Enkel eigen reservaties" afvinken in "Weergave" of wijzig de "Filter" instellingen. + Nie wybrano.
Odznacz opcję "Pokaż tylko moje rezerwacje" lub zmień ustawienia filtru.
+ Atualmente não selecionado.
Desmarque a opção "Apenas Reservas Próprias" ou modifique a configuração do filtro.
+ Ei valittuna.
Poista valinta "Vain omat varaukset" tai muuta suodatusasetuksia
+
+ + Key + Schlüssel + Clé + Clave + Klíč + Sleutel + Klucz + Chave + Avain + + + Language + Sprache + Langue + Idioma + Jazyk + Taal + Język + Idioma + Kieli + + + Last changed + zuletzt geändert am + Dernière modification le + Última modificación el + Naposledy změněno + Aangepast op + Ostatnia zmiana + Modificado pela última vez + Viimeksi muutettu + + + Last changed by + zuletzt geändert von + Dernière modification par + Última modificación + Naposledy změnil uživatel: + Laatst gewijzigd door + Ostatnio zmienione przez + Modificado pela última vez por + Muuttanut viimeksi: + + + Legend + Legende + Légende + Leyenda + Legenda + Legende + Legenda + Legenda + Seloste + + + Level + Level + Niveau + Nivel + Úroveň + Niveau + Poziom + Nível + Taso + + + Nothing selected + Nichts ausgewählt + Aucune sélection + Nada seleccionado + Není vybrána žádná položka + Niets geselecteerd + Nic nie wybrano + Nenhum item selecionado + Ei mitään valittuna + + + select nothing + nichts auswählen + ne rien sélectionner + Seleccionar nada + vybrat nic + Selecteer niets + wybierz nic + Limpar seleção + älä valitse mitään + + + select everything + alles auswählen + sélectionner tout + Seleccionar nada + vybrat vše + Selecteer alles + wybierz wszystko + Selecionar tudo + valitse kaikki + + + Name + Name + Nom + Nombre + Jméno + Naam + Nazwa + Nome + Nimi + + + Never + nie + Jamais + Nunca + Nikdy + nooit + Nigdy + Nunca + Ei koskaan + + + Every time + immer + Toujours + Siempre + pokaždé + onbeperkt + Zawsze + Toda hora + Joka kerta + + + No + Nein + Non + No + Ne + Nee + Nie + Não + Ei + + + No classification + keine Klassifizierung + Pas de classification + Sin clasificación + Neklasifikováno + Geen Classificatie + Brak klasyfikacji + Sem classificação + Ei luokitusta + + + Options + Einstellungen + Options + Opciones + Volby + Opties + Opcje + Opções + Asetukset + + + or + oder + ou + o + nebo + of + lub + Ou + tai + + + Open + offen + Ouvrir + Abrir + Otevřít + Onbepaald + Otwórz + Abrir + Avaa + + + Permissions + Zugriffsrechte + Permissions + Permisos + Přístupová práva + Toestemmingen + Uprawnienia + Permissões + käyttöoikeudet + + + Preferences + Einstellungen + Préférence + Preferencias + Předvolby + Voorkeuren + Preferencje + Preferências + Asetukset + + + Question + Frage + Question + Pregunta + Otázka + Vraag + Pytanie + Pergunta + Kysymys + + + Report + Report + Rapport + Informe + Report + Rapport + Raport + Relatório + Raportti + + + Calendar settings + Kalendareinstellungen + Réglages du calendrier + la configuración del calendario + nastavení pohledu + Kalender instellingen + Ustawienia Kalendarza + Configurações do Calendário + Kalenterin asetukset + + + Search + Suche + Rechercher + Buscar + Hledat + Opzoeken + Szukaj + Buscar + Etsi + + + Select + auswählen + Sélectionner + Seleccionar + Vybrat + Selecteer + Wybierz + Selecionar + Valitse + + + Selected + ausgewählt + Sélectionné + Seleccionado + Vybráno + Geselecteerd + Wybrane + Selecionado + Valittu + + + Selection + Auswahl + Sélection + Selección + Výběr + Selecteer voorkeur + Wybór + Seleção + Valinta + + + Source + Quelle + Source + Fuente + Zdroj + Van + Źródło + Fonte + Lähde + + + Start time + Startzeit + Heure de début + Hora de inicio + Počáteční čas + van + Czas rozpoczęcia + Hora de início + Aloitusaika + + + + Start + Beginn + Début + Inicio + Počáteční datum + Start + Początek + Início + Aloitus + + + Table + Tabelle + Table + Tabla + tabule + Lijst + Tabela + Tabela + Taulukko + + + Today + Heute + Aujourd'hui + Hoy + Dnes + Vandaag + Dziś + Hoje + Tänään + + + at + um + à + a las + v + van + o + Em + milloin: + + + until + bis + jusqu'à + hasta + do + tot + do + Até + kunnes + + + Total occurances + Gesamtanzahl Termine + Nombre d'occurrences + Número de apariciones + celkem záznamů + Totaal aantal + Suma wystąpień + Total de ocorrências + Esiintymiä yhteensä + + + Translation + Übersetzung + Traduction + Traducción + překlad + Vertaling + Tłumaczenie + Tradução + Käännös + + + Width + Breite + Largeur + Ancho + šířka + Breedte + Szerokość + Largura + Leveys + + + Yes + Ja + Oui + + ano + Ja + Tak + Sim + Kyllä + + + x Days in advance + x Tage im Voraus + x jours en avance + x días de antelación + x dní předem + x dagen op voorhand + x dni wcześniej + x Dias antes + x Päivää etukäteen + + + Server + Server + Serveur + Servidor + Server + Server + Serwer + Servidores + Palvelin + + + File + Datei + Fichier + Fichero + Soubor + Bestand + Plik + Arquivo + Tiedosto + + + with + mit + avec + con + s + met + z + com + minkä kanssa: + + + + warnings + Warnungen + avertissements + advertencias + pozor + Waarschuwingen + poszlaka + advertencias + varoitukset + + + + + WARNING: Conflicts found! + WARNUNG: Konflikte gefunden! + ATTENTION : Conflits trouvés ! + ¡ATENCIÓN : Se han encontrado conflictos! + POZOR: Nalezen konflikt ! + WAARSCHUWING: Conflict gevonden! + UWAGA: Wykryto konflikt! + Atenção: Conflitos encontrados! + VAROITUS: Ristiriitoja löydetty! + + + WARNING: The same appointment exists multiple times [{0}]! + WARNUNG: Den gleichen Termin gibt es mehrmals [{0}]! + ATTENTION : La même réservation existe plusieurs fois [{0}]! + ¡ATENCIÓN : La misma reserva existe en múltiples ocasiones [{0}]! + POZOR: Stejné ujednání existuje ve více časech [{0}]! + WAARSCHUWING: Dezelfde afspraak bestaat meerdere keren: [{0}]! + UWAGA: Ten sam termin występuje kilkukrotnie [{0}]! + Atenção: Compromisso duplicado [{0}]! + VAROITUS: Sama ajanvaraus esiintyy useita kertoja [{0}]! + + + + + WARNUNG: {0} wird nicht in der Kalenderansicht angezeigt. Sind die eingestellten Ressourcen und Attribute korrekt? + WARNING: {0} will not be displayed in the calendar view. Are the selected resources and attributes correct? + + + + You have no permissions to reserve/change [{0}] an appointment [{1}]! + Sie haben keine Zugriffsrechte um [{0}] an dem Termin [{1}] zu reservieren/ändern! + Vous ne disposez pas des droits suffisants pour effectuer/modifier [{0}] la réservation [{1}] + ¡No tiene permisos suficientes para efectuar/modificar [{0}] la reserva [{1}]! + Nemáte pověření rezervovat/měnit [{0}] v ujednání vaci [{1}]! + Plannen of wijzigen van [{0}] in reservatie [{1}] is niet toegestaan! + Nie masz uprawnień do zmiany/ustalenia [{0}] terminu [{1}]! + Você não tem permissão para reservar/modificar [{0}] um compromisso [{1}]! + Sinulla ei ole oikeuksia varata/muuttaa [{0}] ajanvarausta [{1}]! + + + User ''{0}'' is not allowed to modify the object ''{1}''. + Benutzer ''{0}'' hat keine Schreibberechtigung für das Objekt ''{1}''. + L''utilisateur ''{0}'' n''est pas autorisé à modifier l''objet ''{1}''. + Usuario ''{0}'' no está permitido modificar el objeto ''{1}''. + Uživatel ''{0}'' není dovoleno měnit objekt ''{1}''. + Gebruiker ''{0}'' is niet gemachtigd om object ''{1}'' te wijzigen. + Użytkownikowi ''{0}'' nie wolno modyfikować obiektu ''{1}''. + Usuário ''{0}'' sem permissão para modificar o objeto ''{1}''. + Käyttäjällä ''{0}'' ei ole lupaa muuttaa kohdetta ''{1}''. + + + User ''{0}'' is not allowed to administer the object ''{1}''. + Benutzer ''{0}'' hat keine Adminberechtigung für das Objekt ''{1}''. + L'utilisateur ''{0}'' n'est pas administrateur de l'objet ''{1}''. + Käyttäjällä ''{0}'' ei ole lupaa hallinnoida kohdetta ''{1}''. + + + User ''{0}'' is not allowed to read the object ''{1}''. + Benutzer ''{0}'' hat keine Leseberechtigung für das Objekt ''{1}''. + L''utilisateur ''{0}'' n''est pas autorisé à lire l''objet ''{1}''. + Usuario ''{0}'' no está permitido leer el objeto ''{1}''. + Uživatel ''{0}'' není dovoleno číst objekt ''{1}''. + Gebruiker ''{0}'' is niet gemachtigd om object ''{1}'' te lezen. + Użytkownikowi ''{0}'' nie wolno odczytać obiektu ''{1}''. + Usuário ''{0}'' sem permissão para ler o objeto ''{1}''. + Käyttäjällä ''{0}'' ei ole lupaa lukea kohdetta ''{1}''. + + + User ''{0}'' is not allowed to create the object ''{1}''. + Benutzer ''{0}'' ist nicht erlaubt, das Objekt ''{1}'' su erstellen. + L''utilisateur ''{0}'' n''est pas autorisé à créer l''objet ''{1}''. + Usuario ''{0}'' no se le permite crear el objeto ''{1}''. + Uživatel ''{0}'' není dovoleno vytvořit objekt ''{1}''. + Gebruiker ''{0}'' is niet gemachtigd om object ''{1}'' aan te maken. + Użytkownikowi ''{0}'' nie wolno utworzyć obiektu ''{1}''. + Usuário ''{0}'' sem permissão para criar o objeto ''{1}''. + Käyttäjällä ''{0}'' ei ole lupaa luoda kohdetta ''{1}''. + + + You have no permissions to create conflicts for [{0}]! + Sie haben keine Zugriffsrechte um Konflikte für [{0}] zu erzeugen! + Vous ne disposez pas des droits suffisants pour créer des conflits pour [{0}] ! + ¡No tiene permisos suficientes para crear conflictos para [{0}]! + Nemáte pověření vytvořit konflikt pro [{0}] ! + Aanmaken van conflicten voor [{0}], is niet toegestaan! + Nie masz uprawnień do tworzenia konfliktów w [{0}]! + Você não tem permissão para criar conflitos para [{0}]! + Sinulla ei ole lupaa luoda ristiriitoja [{0}]:lle! + + + Period is shorter than 1 week! + Der Zeitraum is kürzer als eine Woche! + La période est inférieure à une semaine ! + ¡El periodo es inferior a una semana! + Doba je kratší než 1 týden! + Periode minder dan 1 week! + Okres jest krótszy niż 1 tydzień! + Período é menor que 1 semana! + Ajanjakso on lyhyempi kuin 1 viikko! + + + The event you are editing has been changed. + The data displayed in this window will be refreshed. + Die Veranstaltung, die gerade bearbeitet + wird, wurde geändert. Das Bearbeitungsfenster wird aktualisiert. + L'événement que vous éditez a été modifié. + Les informations affichées dans la fenêtre vont être rafraichies. + El evento que está editando ha sido modificado. + La información que aparece en esta ventana será actualizada. + Editovaná položka bude změněna. Zobrazené informace budou obnoveny. + De reservatie die je bewerkt is ondertussen gewijzigd. + De gegevens werden terug opgehaald. + Edytowane wydarzenie zostało zmienione. + Dane w tym oknie zostaną zaktualizowane. + O evento que você está editando foi alterado. + Os dados exibidos nesta janela serão atualizados. + Tapahtumaa jota muokkaat, on muutettu. + Tässä ikkunassa näkyvät tiedot päivitetään. + + + + The event you are editing has been deleted. + Die Veranstaltung die gerade bearbeitet + wird, wurde gelöscht. + L'événement que vous éditez vient d'être effacé. + El evento que está editando ha sido eliminado + Editovaná položka bude smazána. + De reservatie die je bewerkt, werd verwijderd. + Edytowane wydarzenie zostało usunięte. + O evento que você está editando foi excluído. + Tapahtuma jota muokkaat on poistettu. + + + You have not selected any resources/persons! + Sie haben keine Ressourcen/Personen ausgewählt! + Vous n'avez pas sélectionné de ressource/personne ! + ¡No ha seleccionado ningún(a) recurso/persona + Nejsou označeny žádné prostředky/osoby! + Er zijn geen personen / middelen geselecteerd! + Nie wybrano żadnych zasobów/osób! + Você não selecionou quaisquer recursos/pessoas! + Et ole valinnut yhtään resurssia/henkilöä! + + + + The object "{0}" you are editing has been changed outside the window. + The current editing will be aborted. + Das Objekt "{0}", das gerade bearbeitet + wird, wurde geändert. Der aktuelle Editiervorgang wird abgebrochen. + + L''objet "{0}" que vous éditez a été modifié hors de la fenêtre. + Cette édition va être interrompue. + El objeto "{0}" que está editando ha sido modificado fuera de la ventana + La edición actual va a ser interrumpida. + Objekt "{0}" který je editován bude změněn mimo okno. Současná editace bude přerušena. + Het object "{0}" dat je bewerkt, werd gewijzigd. Bewerken wordt onderbroken. + Edytowany przez Ciebie obiekt "{0}" został zmieniony poza tym oknem. + Obecne zmiany zostaną porzucone. + O objeto "{0}" que você está editando foi alterado em outra janela. + A edição atual será cancelada. + Kohdetta "{0}" jota muokkaat, on muutettu tämän ikkunan ulkopuolella. + Nykyinen muokkaus keskeytetään. + + + + Login failed! + Fehlerhafter Login! + Erreur dans le Login ! + ¡Error al acceder al sistema! + Špatný login! + Aanmelding geweigerd! + Błąd logowania! + Falha no login + Kirjautuminen epäonnistui! + + + Connection to [{0}] failed! Maybe the host is down and you could try later! + Verbindung mit [{0}] fehlgeschlagen! Vielleicht ist der Rechner nicht erreichbar. Versuchen Sie es zu einen späteren Zeitpunkt erneut! + La connexion vers [{0}] a échoué ! Le serveur n''est peut être pas disponible. Essayez plus tard. + ¡La conexión a [{0}] ha fallado! El servidor puede no estar disponible. Inténtelo más tarde. + Připojení k [{0}] je špatné! Možná je vypnutý server. Zkuste to později. + Verbinding met [{0}] is verbroken, de server is niet beschikbaar, contacteer de Rapla beheerder of probeer later! + Nie udało się połączyć z {0}! Być może host jest wyłączony. Spróbuj ponownie później. + Conexão para [{0}] falhou! O servidor pode não estar disponível. Tente mais tarde! + Yhteys [{0}] epäonnistui! Isäntäpalvelin on ehkä kaatunut. Yritä uudestaan myöhemmin! + + + No or closed connection to [{0}]. Rapla is restarting. + Keine oder unterbrochene Verbindung zu [{0}]. Rapla startet erneut. + Pas ou plus de connexion vers [{0}]. Rapla sera redémarré. + Sin conexión a [{0}]. Rapla está reiniciando. + Neexistuje nebo nefunguje spojení [{0}]. Rapla restartování. + Geen of een gesloten connectie naar [{0}]. Rapla opnieuw opstart. + Brak lub utracone połączenie z {0}. Rapla zostanie uruchomiona ponownie. + Sem conexão para [{0}]. Rapla está reiniciando. + Ei yhteyttä tai yhteys katkaistu [{0}]. Rapla käynnistyy uudelleen. + + + At least one type is required. + Es muss mindestens ein Typ vorhanden sein! + Au moins un type doit être disponible ! + ¡Al menos un tipo debe estar disponible! + Je požadován alespoň jeden typ. + Minimaal 1 persoon/middel map is vereist. + Przynajmniej jeden typ jest wymagany. + Pelo menos um tipo é obrigatório. + Vähintään yksi tyyppi vaaditaan. + + + You have to enter a title for your event! + Sie müssen einen Titel für Ihre Veranstaltung angeben! + Vous devez donner un titre à cet événement ! + ¡Debe introducir un título para su evento! + Vložit nadpis události! + Een titel opgeven voor de reservatie! + Podaj nazwę dla wydarzenia! + Você deve fornecer um título para o evento! + Tapahtumalle täytyy antaa otsikko! + + + You need to provide a name! + Sie müssen einen Namen angeben! + Vous devez donner un nom ! + ¡Debe dar un nombre! + Nutné poskytnout jméno + Je moet een naam opgeven! + Wpisz nazwę! + Você deve fornecer um nome! + Sinun täytyy tarjota nimi! + + + You need to provide at least 1 administrator name! + Rapla benötigt mindestens 1 Administrator! + Rapla nécessite au moins 1 administrateur ! + Rapla requiere por lo menos un administrador! + Rapla vyžaduje alespoň 1 správce! + Rapla vereist minstens 1 administrator! + Rapla wymaga co najmniej 1 nazwy administratora! + Você deve fornecer pelo menos 1 administrador! + Sinun täytyy tarjota ainakin 1 ylläpitäjän nimi! + + + You need to provide an entry for: {0} + Sie müssen einen Eintrag angeben für: {0} + Vous devez fournir une donnée pour : {0} + Debe dar un : {0} + Nutné poskytnout přístup pro: + Je moet de gegevens opgeven voor: {0} + Musisz podać pozycję w: {0} + Você deve fornecer uma entrada para: {0} + Sinun täytyy tarjota merkintä: {0} + + + You need to provide a key: {0} + Sie müssen einen Schlüssel angeben: {0} + Vous devez donner une clé pour : {0} + Debe dar una clave para : {0} + Nutné poskytnout klíč: + Een sleutel is verplicht: {0} + Musisz podać klucz: {0} + Você deve fornecer uma chave para: {0} + Sinun täytyy tarjota avain: {0} + + + "{0}" is not a valid key! + Note: You can only use a combination of max. 50 letters, digits or one of the + following characters {1}. The key must start with {2} or a letter! Example: room_size + + "{0}" ist kein gültiger Schlüssel! + Note: Sie können nur eine Kombination von max. 50 Buchstaben, Ziffern oder einer der + Folgende Zeichen {1}. Der Schlüssel muss mit {2} oder einem Buchstaben beginnen! Beispiel: Anzahl_Plätze + + "{0}" n''est pas une clé valide! + Note: Vous pouvez utiliser une combinaison d''un max. de 50 lettres, chiffres ou caractères suivants {1}. La clé doit commencer par {2} ou une lettre! Exemple: Nombre_de_places + + ¡"{0}" no es una clave válida! + Nota : Sólo se puede utilizar una combinación de max. 50 letras, dígitos o uno de los + siguientes caracteres {1}. La clave debe comenzar con {2} o una carta! Ejemplo: Número_de_plazas + + "{0}" je neplatný klíč!
+ Note: Můžete použít pouze v kombinaci s Max. 50 písmen, číslice nebo jeden z + tyto znaky {1}. Klíč musí začínat {2} nebo dopis! Např.: mistnost_velikost +
+ "{0}" is een ongeldige sleutel! + Nota: Maximaal 50 letters, cijfers of {1} beginnend met {2} of een letter! + + "{0}" jest nieprawidłowym kluczem! + Wskazówka: Możesz użyć kominacji maks. 50 liter, cyfr oraz jednego z tych znaków {1}. Klucz musi zaczynać się od {2} lub od litery! Przykład: ilość_miejsc + + "{0}" não é uma chave válida! + Nota: Você pode usar apenas uma combinação de, no máximo, 50 letras, números ou + um dos seguintes caracteres {1}. A chave deve começar com {2} ou uma letra! + "{0}" ei ole pätevä avain! + Huom: Voit käyttää ainoastaan 50:n kirjaimen, numeron tai seuraavien merkkien yhdistelmää + {1}. Avaimen täytyy alkaa {2} tai kirjaimella! Esim: huone_koko + +
+ + An event has to consist of at least one appointment! + Eine Veranstaltung muss aus mindestens einem Termin bestehen! + Un événement est constitué d'au moins une réservation ! + ¡Un evento ha de tener al menos una cita! + Akce musí sestávat nejméně z jedné schůzky! + Een event moet ten minste 1 reservatie hebben! + Wydarzenie musi mieć choć jeden termin. + Um evento consiste de, no mínimo, um compromisso! + Tapahtuman täytyy muodostua vähintään yhdestä ajanvarauksesta! + + + Dependencies exist for these objects + Für folgende Objekte bestehen noch Abhängigkeiten + Des dépendances existent pour ces objets + Existen dependencias para estos objetos + Závislosti existují pro jiný objekt + Afhankelijkheden bestaan voor deze referentie + Istnieją zależności dla tych obiektów + Existem dependências para este objetos + Näillä kohteilla on riippuvuuksia + + + The name "{0}" is already + taken. Please choose a different name! + Der Name "{0}" ist schon + vergeben. Bitte wählen Sie einen Anderen! + Le nom "{0}" est déjà utilisé. Choisissez-en un autre ! + ¡El nombre "{0}" ya está en uso. Por favor, escoja un nombre diferente! + Jméno "{0}" je využíváno. Vyber jiné! + De naam "{0}" is reeds in gebruik. Kies een andere naam! + Nazwa "{0}" jest już zajęta. Wybierz inną. + O nome "{0}" já está sendo usado. Favor escolha um nome diferente! + Nimi "{0}" on jo + varattu. Valitse toinen nimi! + + + The object {0} couldn''t be modified. It was recently modified by someone else. + There was a newer version in the storage. + Das Objekt {0} konnte nicht verändert werden. Es wurde kürzlich verändert, denn + es gibt schon eine neuere Version. + L''objet {0} n''a pu être modifié. Il était en cours de modification par quelqu''un d''autre. + Une autre version existe. + El objeto {0} no ha podido ser modificado. Ha sido modificado recientemente por otra persona. + Existe en memoria una versión más reciente del mismo. + Objekt {0} nemohl být upraven. Byl upraven nedávno někým jiým. + {0} is recentelijk gewijzigd, een nieuwere versie is beschikbaar. Probeer later. + Nie można zmodyfikować {0}. Obiekt został niedawno zmieniony przez inną osobę. Istnieje nowsza wersja obiektu w pamięci. + O objeto {0} não pode ser modificado. Recentemente foi modificado por alguém. + Existe uma versão mais recente armazenada. + Kohdetta {0} ei voitu muokata. Joku toinen on hiljattain muokannut sitä + ja siitä löytyi uudempi versio. + + + Aktuallisieren Sie die Rapla-Version {0} auf {1}. Nutzen Sie den Webstart-Link auf {2} + Update your rapla version from {0} to {1}. Use the webstart link on {2} + Merci de mettre à jour votre version de Rapla de {0} à {1}. Utilisez le bouton webstart à l'adresse {2} + + + The passwords don't match! + Die Passwörter stimmen nicht überein! + Les mots de passe ne sont pas concordants ! + ¡Las palabras de paso no coinciden! + Heslo neodpovídá + De paswoorden verschillen! + Hasła nie zgadzają się! + As senhas são diferentes! + Salasanat eivät vastaa toisiaan! + + + Wrong password! + Falsches Passwort! + Mauvais mot de passe ! + ¡Palabra de paso incorrecta! + Špatné heslo! + Verkeerd paswoord! + Błędne hasło! + Senha incorreta! + Väärä salasana! + + + You can''t delete [{0}], because you are currently using this account! + Sie können [{0}] nicht löschen, weil Sie diesen Account benutzen! + Vous ne pouvez effacer [{0}], parce que vous utilisez actuellement ce compte ! + ¡No puede borrar [{0}], porque está usando esa cuenta en estos momentos! + Nemůžete smazat [{0}], protože výběr využívá tento účet! + Je kan [{0}] niet verwijderen,omdat je deze momenteel in gebruik hebt! + Nie możesz usunąć [{0}], ponieważ obecnie używasz tego konta! + Você não pode excluir [{0}], porque você está usando esta conta! + Et voi poistaa [{0}], koska käytät tiliä parhaillaan! + + + Database update failed. All changes were canceled. + Während der Speicherung in der Datenbank + ist ein Fehler aufgetreten. Alle Änderungen wurden rückgängig + gemacht! + L'actualisation de la base de données a échoué. + Toutes les modifications seront perdues ! + La actualización de la base de datos ha fallado. + Se han cancelado todas las modificaciones + Databáze se neobnovila. Všechny změny zrušeny. + Wijzigen niet mogelijk. Probeer later nogmaals. + Błąd aktualizacji bazy. Wszystkie zmiany zostały utracone. + Falha ao atualizar banco de dados. Todas as modificações foram cancelas. + Tietokannan päivitys epäonnistui. Kaikki muutokset ovat peruuntuneet. + + + Error! Database update failed. Because + your database doesn't support transactions, that could lead to + serious failures. Please contact your administrator + immediately! + Achtung! Während der Speicherung in der + Datenbank ist ein Fehler aufgetreten. Da die verwendete + Datenbank keine Transaktionen unterstützt kann dies zu + schwerwiegenden Fehlern in der Applikation fhren. Bitte setzten + Sie sich umgehend mit dem zuständigen Adminstrator in Verbindung! + + Attention ! Une erreur est survenue pendant l'actualisation de la base de données. Votre base de données refuse cette transaction. Prévenez immédiatement votre administrateur ! + ¡Atención! La actualización de la base de datos ha fallado. Puesto + que su base de datos no soporta transacciones, esto puedo ocasionar errores serios. Por favor, contacte + con su administrador inmediatamente! + Chyba! Databáze se neobnovila. Protože databáze nepodporuje transakci, chyba by se mohla opakovat, informujte administrátora + Fout! Databank wijziging. Databank ondersteund geen transacties. + Dit kan tot serieuze fouten leiden.Neem onmiddelijk contact met de Rapla beheerder! + Błąd! Aktualizacja bazy nie powiodła się. + Twoja baza nie obsługuje transakcji, co może prowadzić + do poważnych błędów. Jak najszybciej kontaktuj się + ze swoim administratorem! + Erro! Atualização no banco de dados falhou, porque seu banco de dados não suporta transações que poderiam levar a falhas graves. + Por favor, contate imediatamente o administrador. + Virhe! Tietokannan päivitys epäonnistui. Koska + tietokantasi ei tue transaktioita, se voi johtaa + vakaviin vikoihin. Ota heti yhteyttä ylläpitäjään! + immediately! + + + Error! Referenced object [{0}] not found in store. It was probably recently removed. + Achtung! Referenziertes Object [{0}] konnte nicht gefunden werden. Es wurde wahrscheinlich kürzlich von jemand gelöscht. + Attention! L''objet référencé [{0}] n''a pu être trouvé. Il a probablement été effacé récemment. + ¡Atención! No se pudo encontrar el objeto referenciado [{0}]. Probablemente se eliminó recientemente. + Chyba! Zmíněný objekt [{0}] se nenalézá v databázi. Pravděpodobně byl odstraněn. + Fout! Gevraagd object [{0}] niet gevonden. Waarschijnlijk recentelijk verwijderd. + Nie można znaleźć obiektu [{0}]. Prawdopodobnie został niedawno usunięty. + Erro! Objeto referenciado [{0}] não foi encontrado na base. Provavelmente foi removido recentemente. + Virhe! Viitattua kohdetta [{0}] ei löytynyt tallennettuna. Se on varmaankin poistettu lähiaikoina. + + + + Choose root category: + Wurzelkategorie auswählen + Sélectionner la catégorie racine : + Seleccionar la categoría raíz + Vyber hlavní kategorii: + Wybierz kategorię główną (korzeń): + Escolha a categoria principal: + Valitse juurikategoria: + + + Type + Typ + Type + Tipo + Typ + Folder + Typ + Tipo + Tyyppi + + + Type name + Name des Typs + Nom du type + Nombre de tipo + Jméno typu + Naam folder + Nazwa typu + Nome do tipo + Tyypin nimi + + + Enclose the key names in {} to insert attributes, e.g. {myKey} + Umklammern sie die Schlüsselnamen mit {} um Attribute einzufügen, Bsp. {name} + Mettez la clé entre {} pour insérer des attributs, par ex. {maclé} + Meta la clave entre {} para insertar los atributos, por ejemplo {miClave} + Uzavřené klíčové jméno v {} k vložení vlastnosti, např. {jméno} + Sleutelnamen tussen {} plaatsen; {[function(]name[,arg0,arg1)]} function = substring, key, parent + Nazwy klucza powinny znajdować się w {} np. {mójKlucz}. + Coloque as chaves entre {} para inserir atributos, por exemplo {chave} + Laita avainten nimien ympärille {} asettaaksesi attribuutteja, esim: {minunAvain} + + + Displayed name format + Anzeigeformatierung + Mettre en forme l'affichage + Formato de nombre visualizado + Zobrazovaný formát jména + Titel formaat + Format wyświetlanej nazwy + Formato de exibição do nome + Nimen muotoilu + + + + You need a color attribute for this setting. Do you want to create it? + Sie brauchen ein Farbattribute für diese Einstellung. Wollen Sie es erzeugen? + Vous devez définir un attribut de couleur pour ce réglage. Voulez vous le créer ? + Een kleur attribuut is nodig voor deze instelling. Wil je deze nu definiëren? + Potrzebujesz koloru atrybutu do tego ustawienia. Chesz go stworzyć? + Você precisa de uma atributo de cor para esta definição! Você deseja criá-lo? + Tarvitset väriattribuutin tälle asetukselle. Haluatko luoda sen? + + + No color selection + Keine Farbwahl + Pas de sélection de couleur + No hay selección de colores + Žádný výběr barev + Geen kleur selectie + Brak wyboru koloru + Nenhuma cor selecionada + Ei värivalintaa + + + + Automatic color selection + Automatische Farbwahl + Sélection automatique des couleurs + Selección automática del color + Automatický výběr barev + Automatische kleur selectie + Automatyczny wybór koloru + Seleção de cor automática + Automaattinen värin valinta + + + attribute preference "color" + Attributeinstellung "color" + Attribut préférence "color" + Atributo Preferencia "color" + Vlastnost Předvolby "color" + Attribuut Voorkeuren "color" + Atrybut Preferencje "color" + Atributo Preferências "color" + Attribuutti-valinta "color" + + + Type + Typ + Type + Tipo + Typ + Type + Typ + Tipo + Tyyppi + + + Types + Typen + Types + Tipos + Typy + Types + Typy + Tipos + Tyypit + + + + Yes|No + Ja|Nein + Oui|Non + Sí|No + Ano|Ne + Ja|Neen + Tak|Nie + Sim|Não + Kyllä|Ei + + + Category + Kategorie + Catégorie + Categoría + Kategorie + Klassement + Kategoria + Categoria + Kategoria + + + Resource + Ressource + Ressource + Recurso + Prostředek + Middel + Zasób + Recurso + Resurssi + + + Date + Datum + Date + Fecha + Datum + Datum + Data + Data + Päivämäärä + + + Integer + Ganze Zahl + Nombre entier + Número entero + Číslo + Getal + Liczba całkowita + Inteiro + Kokonaisluku + + + Text + Text + Texte + Texto + Text + Tekst + Tekst + Texto + Teksti + + + Edit View + Bearbeitungsansicht + Écran de modification + Vista de modificación + Upravit pohled + Toon als + Widok edycji + Tela de edição + Muokkaa näkymää + + + Main View + Hauptansicht + Écran principal + Vista principal + Hlavní pohled + Hoofd informatie + Widok główny + Tela principal + Päänäkymä + + + Additional Information + zusätzliche Informationen + Informations complémentaires + Información complementaria + Doplňující informace + Extra informatie + Dodatkowe informacje + Informação adicional + Lisätiedot + + + invisible + nicht sichtbar + invisible + Invisible + Skrytý + Onzichtbare info + niewidoczny + invisível + näkymätön + + + Expected rows + Zeilenanzahl + Nombre de lignes + Número de líneas + Očekávaná řadka + Aantal rijen + Liczba oczekiwanych wierszy + Número de linhas + Rivien lukumäärä + + + + Expected columns + Spaltenbreite + Nombre de colonnes + Número de columnas + Aantal kolommen + Liczba oczekiwanych kolumn + Número de colunas + Sarakkeiden lukumäärä + + + + + User + Benutzer + Utilisateur + Usuario + Uživatel + Gebruiker + Użytkownik + Usuário + Käyttäjä + + + Users + Benutzer + Utilisateurs + Usuarios + Uživatelé + Gebruikers + Użytkownicy + Usuários + Käyttäjät + + + Switch to + wechsle zu + Changer pour + Cambiar a + Přepni k + Aanmelden als + Przełącz na + Mudar para + Vaihda + + + switch back + wechsle zurück + Revenir vers + Volver a ser administrador + Přepni zpět + Naar vorige gebruiker + Przełącz z powrotem + Voltar + vaihda takaisin + + + Username + Benutzername + Nom d'utilisateur + Nombre de usuario + Uživatelské jméno + Gebruiker + Nazwa użytkownika + Nome de usuário + Käyttäjänimi + + + bind with person + Mit Person verbinden + connecter une personne + connectar con persona + Verbinden met persoon + Sklej z osobą + ligar com pessoa + kytkeydy henkilöön + + + Administrator + Administrator + Administrateur + Administrador + Administrátor + Beheerder + Administrator + Administrador + Ylläpitäjä + + + You have adminstrator privileges! + Sie haben Administrationsrechte! + Vous disposez des droits d'administrateur ! + ¡Dispone de derechos de administrador! + Máte administrátorská práva! + Beheerder + Masz uprawnienia administratora! + Você tem privilégios de administrador + Sinulla on ylläpitäjän oikeudet! + + + Administration + Administration + Administration + Administración + Administrace + Systeem beheer + Administracja + Administração + Ylläpito + + + Password + Passwort + Mot de passe + Palabra de paso + Heslo + Paswoord + Hasło + Senha + Salasana + + + Old password + Altes Passwort + Ancien mot de passe + Antigüa palabra de paso + Staré heslo + Oud paswoord + Stare hasło + Senha antiga + Vanha salasana + + + New password + Neues Passwort + Nouveau mot de passe + Nueva palabra de paso + Nové heslo + Nieuw paswoord + Nowe hasło + Senha nova + Uusi salasana + + + Password verification + Passwort Verifikation + Vérification du mot de passe + Verificación de palabra de paso + Heslo ověřeno + Paswoord controle + Weryfikacja hasła + Verificação de senha + Salasanan vahvistus + + + + + change email + Email ändern + Changer l'adresse mail + Wijzig email + Zmień e-mail + Alterar e-mail + Vaihda sähköpostiosoitetta + + + send code + Code senden + Envoyer un code + Verzend beveiligingscode + Wyślij kod + Enviar código + lähetä koodi + + + validate + validieren + valider + Valideer + Weryfikuj + Validar + validoi + + + New email: + Neue Email: + Nouvel Email : + Nieuw email adres: + Nowy e-mail: + Novo e-mail + Uusi sähköpostiosoite: + + + Securitycode: + Sicherheitscode: + Code de sécurité : + Beveiligingscode: + Kod zabezpieczający: + Código de segurança + Turvakoodi: + + + (A security code will be sent + (Zur angegeben Email-Adresse wird ein Code gesendet, + (Un code de sécurité va être envoyé + (Kod zabezpieczający zostanie wysłany + (Um código de segurança será enviado + (Turvakoodi lähetetään + + + to the email-adress stated besides.) + der im unteren Feld verifiziert werden muss.) + à l'adresse indiquée.) + na adres e-mail podany obok.) + para o e-mail indicado ao lado.) + ilmoitettuun sähköpostiosoitteeseen.) + + + Please enter the received code here: + Bitte geben Sie den erhaltenen Code hier ein: + Merci d'entrer le code de sécurité ici : + Ontvangen beveiligingscode: + Podaj otrzymany kod zabezpieczający: + Digite o código recebido aqui: + Kirjoita saatu koodi tähän: + + + Dear user + Sehr geehrte/r User + Cher utilisateur + Beste + Drogi Użytkowniku + Caro usuário + Hyvä käyttäjä + + + a security code has been requested for your email adress. + ein Sicherheitscode wurde für Ihre Emailadresse angefordert. + un code de sécurité a été demandé pour votre adresse mail + Een beveiligingscode is nodig voor je email adres. + zażądano kodu zabezpieczającego dal tego adresu e-mail. + um código de segurança foi solicitado pelo seu e-mail + turvakoodi on pyydetty sähköpostiosoitteeseesi. + + + If you haven't requested this security code, please contact your system administrator. + Sollten Sie diesen Sicherheitscode nicht angefordert haben, wenden sie sich bitte an Ihren Systemadministrator. + Si vous n'avez pas demandé ce code de sécurité, contactez votre administrateur. + Indien je geen beveiligingscode gevraagd hebt, neem dan contact met de systeem beheerder. + Jeśli to nie Ty zażądałeś/aś tego kodu, skontaktuj się z administratorem systemu. + Se você não tiver solicitado o código de segurança, entre em contato com o administrador do sistema. + Jos et ole pyytänyt tätä turvakoodia, ota yhteyttä järjestelmän ylläpitäjään. + + + This email has been sent by the following system: + Diese Email wurde vom System + Cet email a été envoyé par : + Deze mail werd verstuurd door: + Ten e-mail został wysłany przez następujący system: + Este e-mail foi enviado pelo seguinte sistema: + Tämä sähköposti on lähetetty seuraavalla järjestelmällä: + + + under the following URL: + unter der URL + A l'adresse + met URL + pod tym adresem URL: + comm a seguinte URL: + URL-osoitteesta: + + + person resource: + Personenressource: + Personne ressource : + Persoon: + recursos humanos: + Henkilöresurssi: + + + connect + verbinden + Connecter + Aanmelden + Połącz + conectar + yhdistä + + + + disconnect + lösen + Déconnecter + Afmelden + Rozłącz + desconectar + katkaise yhteys + + + + Personal options + Persönliche Einstellungen + Préférences personnelles + Persoonlijke instellingen + Ustawienia osobiste + Opções pessoais + Henkilökohtaiset asetukset + + + + Please enter your name and firstname: + Bitte geben Sie Vor- und Zuname ein: + Merci de renseigner votre nom et prénom : + Wijzig persoonlijk instellingen: + Proszę wprowadź swoje nazwisko i imię: + Digite seu nome e sobrenome + Ole hyvä ja anna etu- ja sukunimesi: + + + + "The stated code doesn't match the code in the email. " + "Der angegebene Code entspricht nicht dem Code in der Email." + Le code renseigné ne correspond pas à celui envoyé dans l'email. + "De beveiligingscode is verschillend van deze in de verstuurde mail." + "O código indicado não corresponde ao código no e-mail." + Ilmoitettu koodi ei vastaa koodia sähköpostissa. + + + + The stated code is not a number. + Der angegegebene Code ist keine Zahl. + Le code indiqué n'est pas un nombre. + De beveiligingscode moet een nummer zijn. + Podany kod nie jest liczbą. + O código indicado não é um número. + Ilmoitettu koodi ei ole numero. + + + Confirming will actually change your password. + Durch das bestätigen wird ihr Passwort geändert. + Confirmer va changer votre mot de passe. + Bevestiging zal het paswoord wijzigen. + Zatwierdzenie naprawdę zmieni hasło. + Confirmando vai realmente mudar sua senha. + Vahvistaminen muuttaa salasanasi. + + + + + Person + Person + Personne + Persona + Osoba + Persoon + Osoba + Pessoa + Henkilö + + + + Persons + Personen + Personnes + Personas + Osoby + Personen + Osoby + Pessoas + Henkilöt + + + Person type + Personentyp + Type de personne + Tipo de persona + Druh osoby + Type: Persoon + Typ osoby + Tipo de pessoa + Henkilötyyppi + + + Person Types + Personentypen + Types de personne + Tipos de personas + Druh osob + Type: Personen + Typy osób + Tipos de pessoa + Henkilötyypit + + + surname + Nachname + Nom + Apellidos + Jméno + Naam + Nazwisko + Sobrenome + sukunimi + + + + First name + Vorname + Prénom + Nombre + První jméno + Voornaam + Imię + Nome + Etunimi + + + + + Event + Veranstaltung + Événement + Evento + Událost + Reservatie + Wydarzenie + Evento + Tapahtuma + + + Event + Veranstaltung + Événement + Evento + Událost + Reservatie + Wydarzenie + Evento + Tapahtuma + + + New Event... + Neue Veranstaltung + Nouvel événement + nuevo evento + Nová událost + Nieuwe reservatie ... + Nowe wydarzenie + Novo evento + Uusi tapahtuma... + + + + eventname + Veranstaltungsname + Nom de l'événement + Nombre del evento + Název události + Reservatie naam + Nazwa wydarzenia + Nome do evento + tapahtuman nimi + + + + Events + Veranstaltungen + Événements + Eventos + Události + Reservaties + Wydarzenia + Eventos + Tapahtumat + + + Events and resources + Veranstaltungen und Ressourcen + Événements/Ressources + Eventos/Recursos + Události/Prostředky + Reservaties en Middelen + Rezerwacje/Zasoby + Eventos e recursos + Tapahtumat ja resurssit + + + + Event Type + Veranstaltungstyp + Type d'événement + Tipo de evento + Druh události + Event type + Typ Rezerwacji + Tipo de evento + Tapahtumatyyppi + + + Edit own + eigene bearbeiten + Modifier les siennes + modificar las propias + Změň majitele + bewerk eigen + Edytuj swoje + Editar próprio + Muokkaa omaa + + + Appointments: + Termine: + Réservations : + Citas: + Sjednaný: + Reservaties: + Terminy: + Compromissos + Ajanvaraukset: + + + Allocations: + Belegungen: + Allocations : + Asignaciones : + Rozvržení: + Bezetting: + Przydział zasobów: + Alocações: + Varaukset: + + + allocation + Belegung + allocation + asignaciones + rozvržení + bezetting + przydział zasobów + alocações + varaus + + + Reserved by + reserviert von + Réservé par + Reservado por + Rezervace od + Gereserveerd door + Zarezerwowane przez + Reservado por + Varannut + + + Registered by + Eingetragen von + Enregistré par + Registrado por + Registrovaný od + Geregistreerd door + Zarejestrowany przez + Registrado por + Rekisteröinyt + + + + Day of week + Wochentag + Jour de la semaine + Día de la semana + Den v týdnu + Weekdag + Dzień tygodnia + Dia da semana + Viikonpäivä + + + Duration + Zeitdauer + Durée + Duración + Trvání + Tijdsduur + Czas trwania + Duração + Kesto + + + Interval + Zeitraum + Intervalle + Intervalo + Interval + Interval + Interwał + Intervalo + Aikaväli + + + Same day + am selben Tag + Même jour + mismo día + Stejný den + zelfde dag + Ten sam dzień + Mesmo dia + Sama päivä + + + Next day + am nächsten Tag + Jour suivant + día siguiente + Další den + volgende dag + Następny dzień + Dia seguinte + Seuraava päivä + + + on day x + am Tag x + le jour x + el día x + Za den x + op dag x + dnia x + no dia x + päivänä x + + + Day(s) + Tag(e) + Jour(s) + Día(s) + Den + dag(en) + Dzień(dni) + Dia(s) + Päivä(t) + + + New appointment + neuer Termin + Nouvelle réservation + Nueva cita + Nová rezervace + Nieuwe afspraak + Nowy termin + Novo compromisso + Uusi ajanvaraus + + + Appointment + Termin + Réservation + Reserva + Rezervace + Afspraak + Termin + Compromisso + Ajanvaraus + + + Appointment List + Terminliste + Liste des réservations + Lista de citas + Seznam rezervací + Lijst afspraken + Lista terminów + Lista de compromissos + Ajanvarausluettelo + + + Appointments + Termine + Réservations + Citas + Rezervace + Afspraken + Terminy + Compromissos + Ajanvaraukset + + + Change appointment + Termin ändern + Modifier la réservation + Modificar la reserva + Změna rezervace + Wijzig afspraak + Edytuj termin + Alterar compromisso + Vaihda ajanvarausta + + + No repeating + Einzeltermin + Unique + Única + Bez opakování + Eénmalig + Bez powtarzania + Sem repetir + Ei toistuva + + + Repeating + Wiederholung + Répéter + Repetir + Opakování + Herhaling + Powtarzające się + Repetir + Toistuva + + + Weekly + wöchentlich + Hebdomadaire + Semanal + Týdně + Wekelijks + Co tydzień + Semanal + Viikottain + + + Daily + täglich + Quotidien + A diario + Po dnech + Dagelijks + Codziennie + Diário + Päivittäin + + + Monthly + monatlich + Mensuel + mensual + Maandelijks + Co miesiąc + Mensal + Kuukausittain + + + Yearly + jährlich + Annuel + anual + Jaarlijks + Co rok + Anual + Vuosittain + + + Every {0} {1} + Alle {0} {1} + Tous/toutes les {0} {1} + Cada {0} {1} + Každý {0} {1} + Elke {0} {1} + W każdy {0} {1} + Cada {0} {1} + Joka {0} {1} + + + Week + Woche + Semaine + Semana + Týden + Week + Tydzień + Semana + Viikko + + + cw {0,date,w} + KW {0,date,w} + S{0,date,w} + se {0,date,w} + T{0,date,w} + WK{0,date,w} + T{0,date,w} + CS {0,date,w} + kv {0,date,w} + + + Day/Resource + Tag/Ressource + Jour/Ressource + Día/Recurso + Den/Prostředek + Dag/Middel + Dzień/Zasób + Dia/Recurso + Päivä/Resurssi + + + Week/Resource + Woche/Ressource + Semaine/Ressource + Semana/Recurso + Celý/Prostředek + Week/Middel + Tydzień/Zasób + Semana/Recursos + Viikko/Resurssi + + + Day program + Tagesprogramm + Programme de la journée + Día de programa de + denní program + Dag programma + Program dnia + Programa do dia + Päiväohjelma + + + Week program + Wochenprogramm + Programme de la semaine + Semana del programa + týdenní program + Week programma + Program tygodnia + Programa da semana + Viikko-ohjelma + + + + Hour + Std. + Heure + Hora + Uur + Godzina + Hora + Tunti + + + hr + Std. + Heure + Hora + Uur + Godz. + Hora + h + + + hrs + Std. + Heures + Horas + Uren + Godz. + Horas + h + + + Hours + Std. + Heures + Horas + Uren + Godziny + Horas + Tuntia + + + + Minutes + Minuten + Minutes + Minutos + Minuten + Minuty + Minutos + Minuuttia + + + + Minute + Minute + Minute + Minuto + Minuut + Minuta + Minuto + Minuutti + + + mins + Min. + Min. + Min. + Min. + Min. + Min. + min. + + + Second + Sekunde + Seconde + secundo + Seconde + Sekunda + Segundo + Sekunti + + + Seconds + Sekunden + Secondes + secundos + Seconden + Sekundy + Segundos + Sekuntia + + + Day + Tag + Jour + Día + Den + Dag + Dzień + Dia + Päivä + + + Days + Tage + Jours + días + Dny + Dagen + Dni + Dias + Päivää + + + Weeks + Wochen + Semaines + semanas + Týdny + Weken + Tygodnie + Semanas + Viikkoa + + + Month + Monat + Mois + Mes + Měsíc + Maand + Miesiąc + Mês + Kuukausi + + + Years + Jare + Années + Años + Jaren + Lata + Anos + Vuotta + + + Year + Jaar + Année + Año + Jaar + Rok + Ano + Vuosi + + + Months + Monate + Mois + Meses + Měsíce + Maanden + Miesiące + Meses + Kuukautta + + + Repeats forever + Kein Ende + Répéter indéfiniment + indefinido + Nemá konec + tot ? + Powtarzaj bez końca + Repetir sempre + Toistuu jatkuvasti + + + from the + ab dem + à partir de + a partir de + z + van + od + a partir de + alkaen + + + until + bis zum + jusqu'à + hasta + Dokud + tot en met + do + até + kunnes + + + x times + x Mal + x fois + x veces + x krát + x-Maal + x razy + x vezes + x kertaa + + + Repeat + wiederhole + répéter + repite + Opakuj + herhaal + Powtórz + Repetir + Toista + + + every + Jeden + chaque + Cada + Pokaždé + Elke + Każdy + Cada + joka + + + . + . + . + . + . + -(ste/de) + . + . + . + + + Repeat {0} times + wiederhole {0} Mal + répéter {0} fois + repite {0} veces + Opakuj {0} krát + {0}X + Powtórz {0} razy + Repetir {0} vezes + Toista {0} kertaa + + + from {0} + ab dem {0} + à partir du {0} + a partir de {0} + Z {0} + van {0} + od {0} + a partir de {0} + alkaen {0} + + + until {0} + bis zum {0} + jusqu''au {0} + hasta {0} + Dokud {0} + tot en met {0} + do {0} + até {0} + kunnes {0} + + + {0} Exceptions: + {0} Exceptions: + {0} Exceptions : + {0} Excepciones : + {0} Vyjímka: + {0} Uitzonderingen + {0} Wyjątki: + {0} Exceções: + {0} Poikkeukset: + + + Rule: + Regel: + Règle : + Regla : + Pravidlo: + Regel: + Reguła: + Regra: + Sääntö: + + + Exceptions + Ausnahmen + Exceptions + Excepciones + Vyjímka + Uitzonderingen + Wyjątki + Exceções + Poikkeukset + + + No exceptions: + Keine Ausnahmen: + Sans exception + Sin excepciones + Bez vyjímky + Geen uitzonderingen: + Bez wyjątków: + Sem exceções + Ei poikkeuksia: + + + Exceptions: + Ausnahmen: + Exceptions : + Excepciones : + Vyjímka: + Uitgezonderd: + Wyjątki: + Exceções + Poikkeukset: + + + Exception days: + Ausgenommene Tage: + Jours d'exceptions : + Días de excepciones + Vyjímečné dny: + Uitzonderings dagen: + Wyłączone dni: + Exceto dias: + Poikkeuspäivät: + + + free appointment >> + Freier Termin >> + Recherche disponibilité + Zoek vrije afspraak >> + vapaa aika + + + Convert to single events + In Einzeltermine umwandeln + Convertir en événements uniques + Convertir a los eventos individuales + Prevést na jednorázové akce + Converteren naar éénmalige events + Przekształć w wydarzenia jednorazowe + Converter para eventos individuais + Muuta yksittäisiksi tapahtumiksi + + + What do you want to delete? + Was wollen Sie löschen? + Que voulez-vous supprimer ? + ¿Qué es lo que desea eliminar? + Co chcete smazat? + Wat wil je verwijderen? + Co chcesz usunąć? + O que você deseja excluir? + Mitä haluat poistaa? + + + What do you want to copy? + Was wollen Sie kopieren? + Que voulez-vous copier ? + ¿Qué es lo que desea copiar? + Co chcete kopírovat? + Wat wil kopiëren? + Co chcesz skopiować? + O que você deseja copiar? + Mitä haluat kopioida? + + + + What do you want to cut? + Was wollen Sie ausschneiden? + Que voulez-vous couper ? + ¿Qué es lo que desea cortar? + Co chcete vyjmutí? + Wat wil knippen? + Co chcesz wytnij? + O que você deseja cortar? + Mitä haluat laikata? + + + + What do you want to move? + Was wollen Sie verschieben? + Que voulez-vous déplacer ? + ¿Qué es lo que desea desplazar? + Co chcete přesunout? + Wat wil verplaatsen? + Co chcesz przenieść? + O que você deseja mover? + Mitä haluat siirtää? + + + For what do you want to change the allocation + Für was wollen Sie die Belegung ändern? + Pour quel partie de l'événement voulez vous modifier l'allocation ? + Dla czego chcesz zmienić przydział? + Por qual motivo você deseja modificar a atribuição? + Mille haluat vaihtaa varausta? + + + appointment on {0} + Termin am {0} + celle-ci {0} + reserva del {0} + termín {0} + Afspraak op {0} + termin {0} + Compromisso em + ajanvaraus {0} + + + Series + Serie + Série + Serie + Série + Serie + Serie + Série + Sarja + + + Resource + Ressource + Ressource + Recurso + Prostředek + Middel + Zasób + Recurso + Resurssi + + + + Resources + Ressourcen + Ressources + Recursos + Prostředky + Middelen + Zasoby + Recursos + Resurssit + + + Resource type + Ressourcentyp + Type de ressource + Tipo de recurso + Typ prostředku + Type: Middel + Rodzaj zasobu + Tipo de Recurso + Resurssityyppi + + + Resource types + Ressourcentypen + Types de ressources + Tipos de recursos + Typy prostředků + Middel type + Rodzaje zasobów + Tipos de Recursos + Resurssityypit + + + Resource selection + Ressourcenauswahl + Sélection des ressources + Selección de recursos + Označené prostředky + Keuze middel + Zaznaczenie zasobu + Seleção de Recurso + Resurssivalinta + + + + Change allocation + Belegung ändern + Modifier l'allocation + Modificar la asignación + Vyměněný rozvržení + Wijzig toewijzing + Zmień przydział + Modificar atribuição + Vaihda varausta + + + Resources and persons + Ressourcen und Personen + Ressources et Personnes + Recursos y personas + Prostředky a osoby + Middelen&Personen + Zasoby i Osoby + Recursos e Pessoas + Resurssit ja henkilöt + + + Hold back conflicts + Unterdrücke Konflikte + Ne pas tenir compte des conflits + No tener en cuenta los conflictos + Návrat před konflikt + Conflicten onderdrukken + Ignoruj konflikty + Ingnorar conflitos + Salli ristiriidat + + + Selectable on + auswählbar an + Possible le + Seleccionable en + Označitelný v + Beschikbaar voor + Dostępne w + Selecionável em + Mahdollista valita + + + Selectable + auswählbar + Sélectionnable le + Seleccionable + Označitelný + Beschikbaarbaar + Dostępne + Selecionável + Valitse + + + Selected on + ausgewählt an + Sélectionné le + Seleccionado en + Označený v + Geselecteerd voor + Wybrane na + Selecionado em + Valittu + + + Every appointment + allen Terminen + Toutes les réservations + Todas las citas + Všechny ujednání + Alle afspraken + Każdy termin + Todos os compromissos + Valittuina aikoina + + + No appointment + keinem Termin + Pas de réservation + Ninguna cita + Nesjednáno + Geen afspraak + Brak rezerwacji + Nenhum compromisso + Ei ajanvarausta + + + Allocatable in the given timeframe + Belegbar in folgendem Zeitraum + Peut être alloué pendant la période + Puede ser asignado en el periodo + Výběr daný do časového rámce + Beschikbaarheid + Dostępne w okresie + Pode ser atribuido no período + Varattavissa valitun ajan puitteissa + + + Access + Zugriff + Accès + Acceso + Přístupný + Toegang + Dostęp + Acesso + Pääsy + + + Edit + bearbeiten + modifier + editar + upravit + Bewerk + edytuj + editar + Muokkaa + + + Denied + gesperrt + Interdit + Denegado + Zamítnuto + Verboden + Odrzucono + Negado + Evätty + + + Show {0} + {0} anzeigen + Voir {0} + Toon {0} + Näytä {0} + + + + read (no allocations) + lesen (keine Belegungen) + lire (les allocations) + leer (sin asignaciones) + číst (no rozvržení) + Lezen (zonder Toewijzing) + ler (sin atribuições) + lue (ei varauksia) + + + read allocations + Belegungen lesen + lire allocations + leer asignaciones + číst rozvržení + Lezen toewijzing + ler atribuições + lue varauksia + + + read + lesen + lire + leer + číst + Lezen + odczytać bez przydziałów + ler + lue + + + + create {0} + erstelle {0} + créer {0} + crear {0} + vytvořit {0} + Aanmaken {0} + utwórz {0} + criar {0} + luo {0} + + + allocate + belegen + allouer + asignar + alokovat + Toewijzen + przydzielać zasoby + atribuir + varaa + + + allocate & create conflicts + belegen & Konflikte erzeugen + allouer & Créer des conflits + asignar y crear conflictos + alokovat & vytvářet konflikty + Toewijzen & conflicten aanmaken + przydzielać zasoby i tworzyć konflikty + atribuir e criar conflitos + varaa & luo ristiriitoja + + + administrator + administration + administrateur + administrador + administrátorské + Beheren + administratora + administrador + ylläpitäjä + + + + Start of {0} + Start {0} + Début {0} + Inicio de {0} + Začátek {0} + Start van {0} + Początek {0} + Início de {0} + Alkaa + + + End of {0} + Ende {0} + Fin {0} + Fin de {0} + Konec {0} + Einde van {0} + Koniec {0} + Fim de {0} + Loppuu + + + {0}.week {1} + {0}.Wo {1} + {0}.Sem. {1} + {0}.Sem. {1} + {0}.týden {1} + Week {0} van {1} + {0} tyg. {1} + {0}.semana {1} + {0}.viikko {1} + + + Select period + Zeitraum auswählen + Sélectionner la période + Seleccionar el periodo + Označ periodu + Kies periode + Wybierz okres + Selecionar período + Valitse ajanjakso + + + Period + Zeitraum + Période + Periodo + Perioda + Periode + Okres + Período + Ajanjakso + + + Period + Zeitraum + Période + Periodo + Perioda + Periode + Okres + Período + Ajanjakso + + + in period {0} + im Zeitraum {0} + dans la période {0} + dentro del periodo {0} + V periodě {0} + in periode {0} + w okresie {0} + No período + ajanjaksossa {0} + + + Periods + Zeiträume + Périodes + Periodos + Periody + Periode + Okresy + Períodos + Ajanjaksot + + + + Conflicts + Konflikte + Conflits + Conflictos + Konflikt + Conflict + Konflikty + Conflitos + Ristiriidat + + + Conflicts ({0}) + Konflikte ({0}) + Conflits ({0}) + Conflictos ({0}) + Konflikt ({0}) + Conflict ({0}) + Konflikty ({0}) + Conflitos ({0}) + Ristiriidat ({0}) + + + disabled conflicts ({0}) + ausgeschaltete Konflikte ({0}) + Conflits désactivés ({0}) + ristiriitoja pois päältä ({0}) + + + disable conflicts + Konflikte ausschalten + ristiriidat pois päältä + + + enable conflicts + Konflikte einschalten + ristiriidat päälle + + + + + + The GNU-license + Die GNU-Lizenz + La licence GNU + La licencia GNU + GNU Licence + GNU Licentie + Licencja GNU + Licensa GNU + GNU-lisenssi + + + + New category + Neue Kategorie + Nouvelle catégorie + Nueva categoría + Nová kategorie + Nieuw klassement + Nowa kategoria + Nova Categoria + Uusi kategoria + + + New sub-category + Neue Unter-Kategorie + Nouvelle sous-catégorie + Nueva sub-categoría + Nová podkategorie + Nieuw onderklassement + Nowa podkategoria + Nova subcategoria + Uusi alakategoria + + + + Delete? + Löschen? + Effacer ? + ¿Borrar? + Smazat? + Verwijderen? + Usunąć? + Excluir? + Poista? + + + You will delete the following objects: + Sie löschen die folgenden Objekte: + Vous allez effacer les objets suivants : + Budeš mazat následující objekt + Volgende onderdelen worden verwijderd: + Następujące elementy zostaną usunięte: + Os seguintes objetos serão deletados: + Poistat seuraavat kohteet: + + + Yes, delete it! + Löschen!! + Oui, effacer ! + Sí, borrar + Ano, smaž to!! + OK + Tak, usuń! + Ok, pode excluir! + Kyllä, poista! + + + Don't delete it! + NICHT ausführen!! + Annuler la commande ! + ¡No, no lo hagas! + Ne, nedělej to!! + Annuleren + Nie usuwaj! + Não excluir + Ei, älä poista! + + + + Quit Rapla? + Rapla beenden? + Quitter Rapla ? + ¿Abandonar Rapla? + Ukončit Rapla? + Rapla beëindigen + Zakończyć Rapla? + Sair do Rapla? + Sulje Rapla? + + + Do you really want to quit Rapla? + Wollen Sie Rapla beenden? + Souhaitez vous réellement quitter Rapla ? + ¿Desea realmente abandonar Rapla? + Opravdu chcete ukončit plánování ? + Planning beëindigen? + Czy na pewno chcesz zakończyć Rapla? + Você tem certeza que deseja sair? + Haluatko varmasti sulkea Raplan? + + + Quit Rapla + Rapla beenden? + Quitter Rapla + ¿Abandonar Rapla? + Ukončit systém Rapla + Planning beëindigen + Wyjdź + Sim, pode sair. + Sulje + + + Continue Rapla >> + Weiter planen >> + Continuer Rapla >> + Continuar Rapla >> + Pokračuj v plánování + Terugkeren + Wróć do Rapla >> + Não sair + Älä sulje + + + + Changes not saved! + Änderungen noch nicht gespeichert! + Modifications non sauvegardées ! + ¡Modificaciones no guardadas! + Změny neuloženy! + Wijzigingen + Nie zapisano zmian! + As modificações não foram salvas! + Muutoksia ei ole tallennettu! + + + You have not saved your changes. + Sie haben die vorgenommenen Änderungen noch + nicht gespeichert. + Vous n'avez pas sauvegardé les modifications ! + ¡No ha guardado las modificaciones! + Neuložil(a) jste změny! + De wijzigingen worden niet geregistreerd! + Nie zapisano zmian. + Suas modificações não foram salvas + Et ole tallentanut muutoksiasi! + + + Discard changes + Änderungen verwerfen + Annuler les modifications + Anular las modificaciones + Ignoruj změny + Wijzigingen negeren + Odrzuć zmiany + Descatar modificações + Hylkää muutokset + + + + + Rapla version @doc.version@ + + + Rapla Version @doc.version@ + + + Rapla Version @doc.version@ + + + Rapla Version @doc.version@ + + + Rapla versie @doc.version@ + + + Rapla wersja @doc.version@ + + Versão: @doc.version@ + Rapla versio @doc.version@ + + + + + Rapla version @doc.version@ +
+ (C) Copyright @doc.year@ @doc.copyright@ +

Rapla homepage: @doc.homepage@ +

+

Post your feature requests, questions or bug reports + to our developers mailing list:
+ @doc.developer-list@ +

+

Build-Time: @doc.buildtime@ R@doc.revision@

+

Signature: {0}

+

Java version {1}

+
+ + Rapla Version @doc.version@ +
+ (C) Copyright @doc.year@ @doc.copyright@ +

Rapla-Webseite: @doc.homepage@ +

+

Schicken Sie Ihre Anfordungen, Fragen oder Fehlerreports + an die englischsprachige Entwickler- Mailingliste :
+ @doc.developer-list@ +

+

Version vom: @doc.buildtime@ R@doc.revision@

+

Signatur: {0}

+

Java Version {1}

+
+ + Rapla Version @doc.version@ +
+ (C) Copyright @doc.year@ @doc.copyright@ +

Rapla-Webseite: @doc.homepage@ +

+

Envoyer vos propositions d"évolutions, questions, ou erreurs trouvées + à la Mailingliste anglophone développeurs :
+ @doc.developer-list@ +

+

Version : @doc.buildtime@ R@doc.revision@

+

Signature: {0}

+

Version Java {1}

+
+ + Rapla Version @doc.version@ +
+ (C) Copyright @doc.year@ @doc.copyright@ +

Página de Rapla: @doc.homepage@ +

+

Envía tus propuestas de cambios, preguntas, o errores encontrados + a la lista de correo de nuestros desarrolladores (Inglés de habla):
+ @doc.developer-list@ +

+

Version : @doc.buildtime@ R@doc.revision@

+

Firma: {0}

+

Version Java {1}

+
+ + (C) Copyright @doc.year@ @doc.copyright@
+

Rapla versie @doc.version@
+ Gebouwd op: @doc.buildtime@ R@doc.revision@
+ Ondertekend: {0}
+ Java versie: {1}

+

Rapla homepage: @doc.homepage@
+ Support: @doc.developer-list-link@

+
+ + Rapla wersja @doc.version@ +
+ (C) Copyright @doc.year@ @doc.copyright@ +

Strona domowa Rapla: @doc.homepage@ +

+

Wszelkie prośby, pytania i zgłoszenia błędów prosimy + prosimy kierować na ten adres e-mail:
+ @doc.developer-list@ +

+

Build-Time: @doc.buildtime@ R@doc.revision@

+

Podpis: {0}

+

Java wersja {1}

+
+ + Versão: @doc.version@ +
+ (C) Copyright @doc.year@ @doc.copyright@ +

Site do Rapla: @doc.homepage@ +

+

Faça solicitação de novas funcionalidades, perguntas ou informe + bugs a nossos desenvolvedores através do e-mail:
+ @doc.developer-list@ +

+

Hora do Build: @doc.buildtime@ R@doc.revision@

+

Assinatura: {0}

+

Versão do Java: {1}

+
+ + Rapla versio @doc.version@ +
+ (C) Copyright @doc.year@ @doc.copyright@ +

Rapla kotisivu: @doc.homepage@ +

+

Lähetä ominaisuuspyynnöt, kysymykset tai virheilmoitukset + kehittäjiemme sähköpostilistalle:
+ @doc.developer-list@ +

+

Kehityaika: @doc.buildtime@ R@doc.revision@

+

Allekirjoitus: {0}

+

Java versio {1}

+
+
+ + + + + +

More information:

+

+ Java-Webstart is included in all Java versions since 1.4.0. + To run Rapla, you need Java 1.6 or above, which you can download from + www.oracle.com/technetwork/java +

+

+ Check out Rapla @ Google Project for more information. +

+
+ +

Mehr Informationen:

+

+ Java Webstart ist in allen Java Version seit 1.4.0 enthalten. + Um Rapla zu starten brauchen Sie Java 1.6 oder eine neuere Version. Diese können Sie herunterladen von + www.oracle.com/technetwork/java. +

+

+ Besuchen Sie auch Rapla @ Google Project für mehr Informationen über Rapla. +

+
+ +

Plus d'informations:

+

+ Java-Webstart est inclus dans toutes les versions de Java depuis la 1.4.0. + Pour lancer Rapla, vous avez besoin de Java 1.6 ou supérieur que vous pouvez télécharger depuis + www.oracle.com/technetwork/java. +

+

+ Consultez Rapla @ Google Project pour de plus amples informations. +

+
+ +

Más información:

+

+ Java-Webstart se incluye en todas las versiones de Java desde la 1.4.0. + Para ejecutar Rapla, se necesita Java 1.6 o superior. Se lo puede descargar de + www.oracle.com/technetwork/java. +

+

+ Para más información, visite Rapla @ Google Project. +

+
+ +

Meer informatie:

+ Rapla @ Google Project +
+ +

Więcej informacji:

+

+ Java-Webstart jest zawarta w wersjach Java od 1.4.0 i nowsze. + By uruchomić Rapla, potrzebujesz Java 1.6 lub nowszej, którą możesz pobrać stąd: + www.oracle.com/technetwork/java +

+

+ Sprawdź Rapla @ Google Project po więcej informacji. +

+
+ +

Mais informações:

+

+ Java-Webstart está incluso em todas as versões do Java desde 1.4.0. + Para executar o Rapla, você precisa do Java 1.6 ou superior, onde você pode baixar em: + www.oracle.com/technetwork/java +

+

+ Confira Rapla @ Google Project para mais informação (em inglês). +

+
+ +

Lisätietoja:

+

+ Java-Webstart on sisällytetty kaikkiin Java-versioihin 1.4.0 alkaen. + Käyttääksesi Raplaa, tarvitset vähintään Java-version 1.6, jonka voit ladata: + www.oracle.com/technetwork/java +

+

+ Käy vilkaisemassa Rapla @ Google Project niin saat tietää lisää. +

+
+
+ + + + Start Rapla (with java webstart) + + + Rapla starten (mit Java Webstart) + + + Démarrer Rapla (avec java webstart) + + + iniciar Rapla (con java webstart) + + + Rapla Smart Planning + + + Uruchom Rapla (z Java Webstart) + + + Iniciar Rapla (com o java webstart) + + + Käynnistä Rapla (java webstartilla) + + + + + + Start Rapla (with Java Plugin) + + + Rapla starten (mit Java Plugin) + + + Démarrer Rapla (avec le Plugin Java) + + + iniciar Rapla (con Java-Plugin) + + + Start Rapla planning (Applet) + + + Uruchom Rapla (z Java Plugin) + + + Inicar Rapla (com o Plugin do Java) + + + Käynnistä Rapla (Java-lisäosalla) + + + + + + Server Status + + + Status des Servers + + + État du Serveur + + + Status Serwera + + + Status do Servidor + + + Palvelimen tila + + + + + + Rapla Login + Rapla Login + Login Rapla + Acceso a Rapla + Přihlášení k rezervačnímu systému + Rapla Aanmelden + Logowanie do Rapla + Login Rapla + Rapla Sisäänkirjautuminen + + + Choose your language: + Wählen Sie Ihre Sprache: + Choisissez votre langue : + Escoja su idioma : + Zvolte váš jazyk: + Taalkeuze: + Wybierz swój język: + Escolha o idioma: + Valitse kielesi: + + + + Rapla version @doc.version@ (C) Copyright @doc.year@ @doc.copyright@ +

+ Rapla comes with NO WARRANTY!! + This is free software, you are welcome to redistribute it under certain + conditions.

+
+ + Rapla Version @doc.version@ (C) Copyright @doc.year@ @doc.copyright@ +

Für Rapla besteht KEINE GARANTIE!! + Rapla ist freie Software, die Sie unter bestimmten + Bedingungen weitergeben dürfen.

+
+ + Rapla Version @doc.version@ (C) Copyright @doc.year@ @doc.copyright@ +

Rapla est SANS GARANTIE!! + Rapla est un logiciel libre, que vous pouvez utiliser et distribuer suivant ces conditions.

+
+ + Rapla Version @doc.version@ (C) Copyright @doc.year@ @doc.copyright@ +

¡¡Rapla viene SIN GARANTÍA!! + Rapla es software libre, así que puede usarlo y distribuirlo bajo las siguientes condiciones.

+
+ + Rapla Verze @doc.version@ (C) Copyright @doc.year@ @doc.copyright@ +

Na systém Rapla není poskytována ŽÁDNÁ ZÁRUKA!! + Rapla Toto je volný software a je možné jej rozšiřovat pouze za určitých + podmínek.

+
+ + Rapla versie @doc.version@ : @doc.buildtime@
+ (C) Copyright @doc.year@ @doc.copyright@ +

Rapla wordt geleverd ZONDER GARANTIE.

+ Deze software kan enkel onder bepaalde voorwaarden vrij worden verspreid. +
+ + Rapla wersja @doc.version@ (C) Copyright @doc.year@ @doc.copyright@ +

+ Rapla jest dostarczana BEZ ŻADNEJ GWARANCJI!!! + To jest darmowe oprogramowanie, możesz je rozprowadzać pod pewnymi + warunkami.

+
+ + Rapla versão @doc.version@ (C) Copyright @doc.year@ @doc.copyright@ +

+ Rapla não possui GARANTIA!! + O software é livre e você pode distribuir sob certas + condições.

+
+ + Rapla versio @doc.version@ (C) Copyright @doc.year@ @doc.copyright@ +

+ Raplassa ei ole TAKUUTA!! + Tämä on ilmaisohjelma, saat jakaa sitä tietyin + ehdoin.

+
+
+ + + From all users + Von allen Benutzern + De tous les utilisateurs + De todos los usuarios + Od každého uživatele + Voor alle gebruikers + Wszystkie rezerwacje + De todos os usuários + Kaikilta käyttäjiltä + + + Own events + Eigene Veranstaltungen + Vos propres événements + Sus propios eventos + Moje události + Eigen reservaties + Moje rezerwacje + Eventos próprios + Omat tapahtumat + + + Filter name + Filtername + Nom du filtre + Nombre del filtro + Název filtru + Filter naam + Nazwa filtra + Nome do filtro + Suodattimen nimi + + + is smaller than + ist kleiner als + est plus petit que + es menor que + Je menší, než + kleiner dan + mniejsze niż + É menor que + on pienempi kuin + + + is greater than + ist größer als + est supérieur à + es mayor que + Je větší, než + groter dan + większe niż + É maior que + on suurempi kuin + + + smaller than or equal + ist kleiner gleich + est plus petit ou égal à + es menor o igual que + Je menší nebo rovno + kleiner dan of gelijk + mniejsze niż lub równe + Menor ou igual + pienempi tai yhtä suuri kuin + + + + greater than or equal + ist größer gleich + est supérieur ou égal à + es mayor o igual que + je větší nebo rovno + groter dan of gelijk + większe niż lub równe + Maior ou igual + suurempi tai yhtä suuri kuin + + + + is earlier than + ist früher als + est avant le + es anterior a las + Je dříve, než + vroeger dan + przed + Antes de + on aikaisemmin kuin + + + is later than + ist später als + est après le + es posterior a las + Je později, než + later dan + po + Depois de + on myöhemmin kuin + + + equals + ist gleich + est égal à + es igual a + Je stejný, jako + gelijk aan + dokładnie + Igual + vastaa + + + is not equal to + ist ungleich + est différent de + es desigual + není rovno + ongelijk + jest inny niż + diferente de + ei vastaa + + + contains + enthält + contient + contiene + Obsahuje + bevat + zawiera + Contém + sisältää + + + starts with + beginnt mit + commence par + comienza con + začíná se + start met + zaczyna się od + begynder med + Começa com + alkaa + + + Restrict view of {0} + Anzeige von {0} einschränken + Limiter l''affichage à {0} + Limitar la vista de {0} + Pohled omezený {0} + beperk beeld van {0} + Ogranicz widok {0} + Restringir visualização de {0} + Rajoita näkymää {0} + + + Resources and persons + Ressourcen und Personen + Ressources et personnes + Recursos y personas + Prostředky a osoby + Personen & Materialen + Zasoby i Osoby + Recursos e Pessoas + Resurssit ja henkilöt + + + Only Own Reservations + Nur eigene Reservierungen + Seulement mes réservations + Sólo mis reservas + Moje rezervace + Enkel eigen reservaties + Tylko moje rezerwacje + Apenas reservas próprias + Vain omat varaukset + + + Events from all users + Veranstaltungen von allen Benutzern + Événement de tous les utilisateurs + Eventos de todos los usuarios + Rezervace všech uživatelů + Reservaties van alle gebruikers + Rezerwacje wszystkich + Reservas de todos os usuários + Tapahtumat kaikilta käyttäjiltä + + + Complete time + gesamte Zeit + Période totale + Periodo total + Celkový čas + volledige duur + Całkowity czas + Tempo total + Kokonaisaika + + + All filtered objects. + Alle gefilterten Objekte. + Tous les objets filtrés. + Todos los objetos filtrados. + Všechny filtrované objekty. + alle gefilterde objecten. + Wszystkie filtrowane obiekty. + Todos os objetos filtrados + Kaikki suodatetut kohteet + + + New rule for + neue Regel für + Nouvelle règle pour + Nueva regla para + Nové pravidlo pro + Nieuwe regel + Nowa reguła dla + Nova regra para + Uusi sääntö + + + + + Allocation of {0} + Belegungen von {0} + Allocation de {0} + Asignación de {0} + Umístění {0} + Toewijzing van {0} + Przydzielenie {0} + Alocação de {0} + {0}:n varaus + + + + + Print Preview + Druck Voransicht + Imprimer la prévisualisation + Imprimir la previsualización + Náhled před tiskem + Afdrukvoorbeeld + Podgląd wydruku + Visualizar impressão + Tulostuksen esikatselu + + + Postscript + Postscript + Postscript + Postscript + Postscript + Postscript + Postscript + Postscript + Jälkikirjoitus + + + Choose your save method! + Wählen Sie die Speichermethode! + Choisissez la méthode de sauvegarde ! + Escojer el método de almacenamiento + Vyberte způsob ukládání! + Kies opslag methode! + Wybierz metodę zapisu! + Selecione o método de salvamento! + Valitse tallennusmenetelmä! + + + Printer Preferences + Drucker-Einstellungen + Préférence d'impression + Preferencias de impresión + Vlastnosti tiskárny + Printer voorkeur + Ustawienia drukarki + Preferências de impressão + Tulostimen asetukset + + + Title + Überschrift + Titre + Título + Titul + Titel + Tytuł + Título + Otsikko + + + + Rapla, smart resource and event planning + Rapla, der clevere Ressourcen- und Veranstaltungsplaner + Rapla, le planificateur intelligent + Rapla, el planificador inteligente + Rapla, chytré plánování prostředků a událostí + Rapla, Smart Planning + Rapla, i przydzielanie zasobów + Rapla, planejamento inteligente + Rapla, fiksu resurssien- ja tapahtumien hallinta + + + Rapla + Rapla + Rapla + Rapla + Rapla + Rapla + Rapla + Rapla + + + + Hello {0}, enjoy planning! + Hallo {0}, viel Spaß beim Planen! + Bonjour {0} ! + Hola {0}, ¡disfruta planificando! + Dobrý den, přejeme příjemné plánování! Přihlášen uživatel: {0} + Online: {0} + Witaj, {0}! Przyjemnego planowania! + Olá {0}, planeje com prazer! + Hei {0}, antoisaa järjestelyä! + + + + Database + Datenbasis + Base de données + Base de datos + Databáze + Databank + Baza danych + Banco de dados + Tietokanta + + + Display exceptions in calendar + Zeige Ausnahmen im Kalender + Afficher les exceptions dans le calendrier + Mostrar las excepciones en el calendario + Zobrazit vyjímky v kalendáři + Uitzonderingen + Pokaż wyjątki w kalendarzu + Exibir exceções no calendário + Näytä poikkeukset kalenterissa + + + Display conflicts + Zeige Konflikte + Afficher les conflits + Mostrar las conflictos + Zobrazit vyjímky + Conflicten + Pokaż konflikty + Mostrar conflitos + Näytä ristiriidat + + + Display resource selection + Zeige Ressourcenauswahl + Afficher les ressources + Mostrar los recursos + Zobrazit prostředky + Middelen + Pokaż wybór zasobów + Mostrar seleção de recursos + Näytä resurssivalinta + + + Display mouse-over tips + Zeige mouse-over + Afficher les infos au survol + Mostrar las tips mouse-over + Zobrazit vyjímky v mouse-over + Tips + Pokazuj podpowiedzi po najechaniu myszką + Mostrar dicas + Näytä mouseover-vinkit + + + Exclude days + Tage ausschließen + Excluir dias + Exclure des jours + Uitgesloten dagen: + Wyłącz dni + Excluir dias + Älä sisällytä päiviä + + + Events not matched by filter + Ausgefilterte Veranstaltungen + Eventos que no coincidan con filtro + Événements non couverts par le filtre + Uitgefilterde reservaties + Zdarzenia odfiltrowane + Eventos que não coincidam com o filtro + Tapahtumat eivät vastaa suodatinta + + + Rows per hour + Zeilen pro Stunden + Lignes par heure + Líneas por hora + Počet řádků na hodinu + Tijdsdelen per uur: + Podziałka godzin + Linhas por hora + Riviä per tunti + + + Restart Rapla client + Rapla neu starten + Redémarrer Rapla + Reiniciar el cliente Rapla + Restart klienta + Herstart gebruiker + Uruchom Rapla ponownie + Reiniciar Rapla + Käynnistä Rapla uudelleen + + + Restart Server + Server neu starten + Redémarrer le serveur + Reiniciar el servidor + Restart serveru + Herstart Rapla server + Uruchom serwer ponownie + Reiniciar Servidor + Käynnistä palvelin uudelleen + + + Load data + Daten neu laden + Recharger les données + Recargar los datos + Znovu načíst data + herladen gegevens + Odśwież dane + Carregar dados + Lataa tiedot + + + + + New Event: {0} + Neue Veranstaltung: {0} + Nouvel événement : {0} + Nuevo evento : {0} + Nová událost: {0} + Nieuw reservatie {0} + Nowe rezerwacja: {0} + Novo evento: {0} + Uusi tapahtuma: {0} + + + Edit event: {0} + Veranstaltung bearbeiten: {0} + Modifier l''événement: {0} + Modificar el evento : {0} + Upravit událost: {0} + Bewerk reservatie {0} + Edytuj rezerwacja: {0} + Editar evento: {0} + Muokkaa tapahtumaa: {0} + + + Edit {0} + {0} bearbeiten + Modifier {0} + Modificar {0} + Upravit {0} + Bewerk {0} + Edytuj {0} + Editar {0} + Muokkaa {0} + + + Delete {0} + {0} löschen + Effacer {0} + Eliminar {0} + Odstranit {0} + Verwijder: {0} + Usuń {0} + Excluir: {0} + Poista {0} + + + Translations for "{0}": + Übersetzungen von "{0}": + Traduction de "{0}": + Traducción de "{0}": + Překlady pro "{0}": + Vertaling voor "{0}": + Tłumaczenia na "(0)": + Traduções para "{0}": + Käännökset "{0}": + + + Change {0} + {0} ändern + Modifier {0} + Modificar {0} + Změnit {0} + Wijzig {0} + Zmień {0} + Modificar {0} + Muuta {0} + + + {0} ! + {0} ! + {0} ! + {0} ! + {0} ! + {0} ! + {0} ! + {0} ! + {0} ! + + + {0}: {1} + {0}: {1} + {0} : {1} + {0} : {1} + {0}: {1} + {0}: {1} + {0}: {1} + {0}: {1} + {0}: {1} + + + all-day + ganztägig + 24h + 24h + 24h + 24u + cały dzień + O dia todo + koko päivä + + + You cannot remove object {0} directly. Please remove it from the parent. + Sie können das Objekt {0} nicht direkt löschen. Bitte entfernen Sie sie aus einer höheren Ebene.. + Vous ne pouvez pas supprimer directement l''objet {0}. Supprimez-le à partir d''un niveau supérieur. + No se puede eliminar directamente el objeto {0}. Por favor, eliminarlo de un nivel superior. + Nemůžete přímo objekt odstranit {0}. Prosím, odstraňte jej z vyšší úrovně. + Ja kan het voorwerp {0} niet rechtstreeks verwijderen. Verwijder deze van een hoger niveau. + Nie można bezpośrednio usunąć obiektu {0}. Proszę usunąć go z wyższego poziomu. + Você não pode remover o objeto {0} diretamente. Por favor remova-o a partir do objeto pai. + Et voi poistaa kohdetta {0} suoraan. Poista se emosta. + + + + You need to restart Rapla/Rapla-server when you change the options! + Starten Sie Rapla/den Rapla Server neu, damit die Veränderungen wirksam werden! + Il est nécessaire de redémarrer Rapla ou le service de Rapla (sur le serveur) après avoir changé les options ! + Om de wijzigingen te activeren moet je Rapla herstarten! + Zmiany zostaną wprowadzone po ponownym uruchomieniu Rapla. + Você precisa reiniciar o Rapla/Servidor do Rapla quando modificar as opções! + Sinun täytyy käynnistää Rapla/Rapla-palvelin uudelleen kun muutat asetuksia! + + + + application title + Titel der Anwendung + Nom de l'application + nombre de la aplicación + název aplikace + Naam van de toepassing + Nazwa aplikacji + Nome da aplicação + sovelluksen nimi + + + timezone + Zeitzone + fuseau horaire + huso horario + časové pásmo + tijdzone + Strefa czasowa + Fuso horário + aikavyöhyke + + + + + Reset + Reset + Réinitialisation + Restablecer + Reset + Terugzetten + Resetuj + Reconfigurar + Oletusarvojen palautus + + + clear + löschen + effacer + restablecer + vymazat + Opschonen + Wyczyść + Limpar + tyhjennä + + + Default Selection + Standardauswahl + Sélection par défaut + Selección por defecto + Výběr výchozí + Standaard Selectie + Wybór domyślny + Seleção Padrão + Oletusvalinta + + + Only 1 event type is allowed. Adjust the filter! + Nur 1 Veranstaltungstyp ist erlaubt. Passen Sie den Filter! + Un seul type d'événement est autorisé. Réglez le filtre ! + Sólo un tipo de evento se permite. Ajuste el filtro! + Pouze 1 typ události je povoleno. Nastavte. filtr! + Enkel 1 type event is toegestaan. Pas de filter aan! + Tylko 1 zdarzenie typu jest dozwolone. Ustaw filtr! + Tylko 1 typ Zdarzenia jest dozwolony. Ustaw filtr! + Apenas 1 tipo de evento é permitido. Ajuste filtro. + Vain 1 tapahtumatyyppi on sallittu. Säädä suodatinta! + + + Include date: {0} + mit Datum: {0} + y compris la date: {0} + incluyendo la fecha: {0} + včetně data: {0} + met datum / interval = {0} + w tym dniu: {0} + Incluir data: {0} + Sisällytä päivämäärä {0} + + + Occupation + Besetzung + Occupation + Ocupación + Obsazenost + Bezetting + Zawód + Ocupação + Ammatti + + + Day 1 of the week + Tag 1 der Woche + 1er jour de la semaine + Día 1 de la semana + 1. den v týdnu + Eerste dag van een week + Pierwszy dzień tygodnia + 1º dia da semana + Viikon ensimmäinen päivä + + + Days in Weekview + Tage in der Wochenansicht + Jours dans la vue semaine + días en vista de la semana + Dny v týdnu zobrazení + Aantal dagen in een week + Dzień w widoku Tygodnia + Dias na visualização da semana + Päiviä viikkonäkymässä + + + Minimum block width + Minimale Blockbreite + Largeur minimale des blocs + Ancho del bloque mínimo + Minimální šířka bloku + Minimum blok breedte + Minimalna szerokość bloku + Largura mínima do bloco + Lohkon minimileveys + + + Redo + Wiederherstellen + Reconstituer + reconstituir + reconstituir + Herdoe + Ponów + reconstituir + Refazer + Tee uudelleen + + + Undo + Zurück + Retour + de vuelta + reconstituir + Ontdoe + Cofnij + reconstituir + Desfazer + Kumoa + + + Show password + zeige Passwort + Montrer le mot de passe + mostrar contraseña + zobrazit heslo + Toon paswoord + Pokaż hasło + Mostrar senha + Näytä salasana + + + + + Benutzergruppen + user-groups + grupos de usuarios + Groupes d'utilisateurs + Gebruikersgroepen + Grupy użytkowników + Grupos de usuários + käyttäjäryhmät + + + Ressourcen eintragen + register resources + registrar recursos + Enregistrer les ressources + Middelen-Personen opslaan + Rejestracja Zasobów + Registrar recursos + Rekisteröi resurssit + + + Einstellungen bearbeiten + modify preferences + modificar las preferencias + Modifier les préférences + Opties wijzigen + Modyfikacja Preferencji + Modificar as preferências + muokkaa valintoja + + + Die Veranstaltungen anderer sehen + See events of other users + Ver eventos de otros usuarios + Voir les événements d'autres utilisateurs + Events bekijken van andere gebruikers + Widok wydarzeń innych użytkowników + Visualizar eventos de outros usuários + Näe muiden käyttäjien tapahtumat + + + Veranstaltungen anlegen + create events + crear eventos + Créer des événements + Reservaties opslaan + Tworzenie wydarzeń + Criar eventos + luo tapahtumia + + + edit templates + Vorlagen bearbeiten + Modifier les modèles + Editar plantillas + Upravovat šablony + Sjablonen bewerken + Edycja szablonów + Editar modelos + muokkaa mallia + + + close template + Vorlage schließen + Fermer le modèle + Cerrar plantilla + Zavřít šablony + Sluit bewerken + Zamykanie szablonów + Fechar modelo + sulje malli + + + New event with template + Neue Veranstaltungen mit Vorlage + Nouvel événement avec modèle + Nuevos eventos con plantilla + Nové události s šablonou + Nieuwe reservatie met sjabloon + Nowe zdarzenia z szablonu + Novo evento a partir de um modelo + Uusi tapahtuma mallilla + + + Fixed time and duration + Vorgegebene Zeit und Dauer + + + + + Export to CSV + Exportiere als CSV + Exporter en CSV + Export to CSV + Export to CSV + Export to CSV + Export do CSV + Exportar para CSV + Vie CSV:hen + + + "User can't delete himself." + Benutzer kann sich nicht löschen. + L'utilisateur ne peut pas se supprimer. + El usuario no puede eliminar a sí mismo. + Uživatel nemůže odstranit sám. + Gebruiker kan zichzelf niet verwijderen. + Użytkownik nie może usunąć sam. + O usuário não pode excluir-se. + "Käyttäjä ei voi poistaa itseään." + + + Displayed name format in resource tree + Anzeigeformatierung im Ressourcenbaum + Format d'affichage du nom dans l'arborescence + Formato de nombre visualizado en el folleto + Zobrazovaný formát jména v příbalové informaci + Weergave naam formaat in de folder + Format wyświetlanej nazwy w ulotce + Formato de exibição do nome no folheto + Resurssipuussa näytettävä nimen muoto + + + Displayed name format in export + Anzeigeformatierung im Export + Mettre en forme l'affichage dans le exporter + Formato de nombre visualizado si exporta + Viennissä näytettävä nimen muoto + + + Is a location + Ist ein Ort + Est un lieu + Es un lugar + Je to místo, + Is een plaats + Jest to miejsce, + É um lugar + On sijainti + + + never + niemals + jamais + nunca + nikdy + nooit + nigdy + nunca + ei koskaan + + + always + immer + toujours + siempre + vždy + altijd + zawsze + sempre + aina + + + not with same event type + nicht mit gleichem Veranstaltungstyp + pas avec le même type d'événement + no con el mismo tipo de evento + Není se stejným typem události + niet met zelfde soort event + nie z samego typu zdarzenia + não com o mesmo tipo de evento + ei saman tapahtumatyypin kanssa + + + + Sort order + Sortierung + Ordre + Orden de Clasificación + Seřadit Objednat + Sorteervolgorde + Sortuj Zamówienie + Ordem de classificação + Järjestys + + + ascending + aufsteigend + Croissant + Ascendente + Vzestupně + Stijgend + rosnąco + ascendente + nouseva + + + descending + absteigend + Décroissant + descendiente + klesající + Dalend + malejąco + descendente + laskeva + + + no sorting + keine Sortierung + pas de tri + sin clasificación + bez třídění + Geen volgorde + bez sortowania + sem classificação + ei järjestelyä + +
\ No newline at end of file diff --git a/rapla-source-1.8.2/src/org/rapla/RaplaStartupEnvironment.java b/rapla-source-1.8.2/src/org/rapla/RaplaStartupEnvironment.java new file mode 100644 index 0000000..f16b807 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/RaplaStartupEnvironment.java @@ -0,0 +1,134 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.rapla.components.util.IOUtil; +import org.rapla.components.util.JNLPUtil; +import org.rapla.framework.Configuration; +import org.rapla.framework.RaplaException; +import org.rapla.framework.StartupEnvironment; +import org.rapla.framework.internal.ConfigTools; +import org.rapla.framework.logger.ConsoleLogger; +import org.rapla.framework.logger.Logger; + +final public class RaplaStartupEnvironment implements StartupEnvironment +{ + private int startupMode = CONSOLE; + //private LoadingProgress progressbar; + private Logger bootstrapLogger = new ConsoleLogger( ConsoleLogger.LEVEL_WARN ); + private URL configURL; + private URL contextRootURL; + private URL downloadURL; + + public Configuration getStartupConfiguration() throws RaplaException + { + return ConfigTools.createConfig( getConfigURL().toExternalForm() ); + } + + public URL getConfigURL() throws RaplaException + { + if ( configURL != null ) + { + return configURL; + } + else + { + return ConfigTools.configFileToURL( null, "rapla.xconf" ); + } + } + + public Logger getBootstrapLogger() + { + return bootstrapLogger; + } + + public void setStartupMode( int startupMode ) + { + this.startupMode = startupMode; + } + + /* (non-Javadoc) + * @see org.rapla.framework.IStartupEnvironment#getStartupMode() + */ + public int getStartupMode() + { + return startupMode; + } + + public void setBootstrapLogger( Logger logger ) + { + bootstrapLogger = logger; + } + + public void setConfigURL( URL configURL ) + { + this.configURL = configURL; + } + + public URL getContextRootURL() throws RaplaException + { + if ( contextRootURL != null ) + return contextRootURL; + return IOUtil.getBase( getConfigURL() ); + } + + public void setContextRootURL(URL contextRootURL) + { + this.contextRootURL = contextRootURL; + } + + public URL getDownloadURL() throws RaplaException + { + if ( downloadURL != null ) + { + return downloadURL; + } + if ( startupMode == WEBSTART ) + { + try + { + return JNLPUtil.getCodeBase(); + } + catch ( Exception e ) + { + throw new RaplaException( e ); + } + } + else + { + URL base = IOUtil.getBase( getConfigURL() ); + if ( base != null) + { + return base; + } + try + { + return new URL( "http://localhost:8051" ); + } + catch ( MalformedURLException e ) + { + throw new RaplaException( "Invalid URL" ); + } + } + } + + public void setDownloadURL( URL downloadURL ) + { + this.downloadURL = downloadURL; + } + +} diff --git a/rapla-source-1.8.2/src/org/rapla/bootstrap/CustomJettyStarter.java b/rapla-source-1.8.2/src/org/rapla/bootstrap/CustomJettyStarter.java new file mode 100644 index 0000000..4dda815 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/bootstrap/CustomJettyStarter.java @@ -0,0 +1,431 @@ +package org.rapla.bootstrap; + +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSession; + +@SuppressWarnings({ "rawtypes", "unchecked" }) +public class CustomJettyStarter +{ + public static final String USAGE = new String ( + "Usage : \n" + + "[-?|-c PATH_TO_CONFIG_FILE] [ACTION]\n" + + "Possible actions:\n" + + " standalone : Starts the rapla-gui with embedded server (this is the default)\n" + + " server : Starts the rapla-server \n" + + " client : Starts the rapla-client \n" + + " import : Import from file into the database\n" + + " export : Export from database into file\n" + + "the config file is jetty.xml generally located in etc/jetty.xml" + ); + + + public static void main(final String[] args) throws Exception + { + String property = System.getProperty("org.rapla.disableHostChecking"); + if ( Boolean.parseBoolean( property)) + { + HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String arg0, SSLSession arg1) { + return true; + } + }); + } + new CustomJettyStarter().start( args); + } + + Class ServerC ; + Class ConfigurationC; + Class ConnectorC; + Class ResourceC; + Class EnvEntryC; + Class LifeCyleC; + Class LifeCyleListenerC; +// Class DeploymentManagerC; +// Class ContextHandlerC; +// Class WebAppContextC; +// Class AppC; +// Class AppProviderC; +// Class ServletHandlerC; +// Class ServletHolderC; + + ClassLoader loader; + Method stopMethod; + Logger logger = Logger.getLogger(getClass().getName()); + String startupMode; + String startupUser; + + /** parse startup parameters. The parse format: +
+    [-?|-c PATH_TO_CONFIG_FILE] [ACTION]
+    
+ Possible map entries: +
    +
  • config: the config-file
  • +
  • action: the start action
  • +
+ + @return a map with the parameter-entries or null if format is invalid or -? is used + */ + public static Map parseParams( String[] args ) + { + boolean bInvalid = false; + Map map = new HashMap(); + String config = null; + String action = null; + + // Investigate the passed arguments + for ( int i = 0; i < args.length; i++ ) + { + String arg = args[i].toLowerCase(); + if ( arg.equals( "-c" ) ) + { + if ( i + 1 == args.length ) + { + bInvalid = true; + break; + } + config = args[++i]; + continue; + } + if ( arg.equals( "-?" ) ) + { + bInvalid = true; + break; + } + if ( arg.substring( 0, 1 ).equals( "-" ) ) + { + bInvalid = true; + break; + } + if (action == null) + { + action = arg; + } + } + + if ( bInvalid ) + { + return null; + } + + if ( config != null ) + map.put( "config", config ); + if ( action != null ) + map.put( "action", action ); + return map; + } + + public void start(final String[] arguments) throws Exception + { + Map parseParams = parseParams(arguments); + String configFiles = parseParams.get("config"); + + if ( configFiles == null) + { + configFiles = "etc/jetty.xml"; + String property = System.getProperty("jetty.home"); + if (property != null) + { + if ( !property.endsWith("/")) + { + property += "/"; + } + configFiles = property + configFiles; + } + } + startupMode =System.getProperty("org.rapla.startupMode"); + if (startupMode == null) + { + startupMode = parseParams.get("action"); + } + if (startupMode == null) + { + startupMode = "standalone"; + } + startupUser =System.getProperty("org.rapla.startupUser"); + + boolean isServer = startupMode.equals("server"); + final boolean removeConnectors = !isServer; + if ( isServer) + { + System.setProperty( "java.awt.headless", "true" ); + } + loader = Thread.currentThread().getContextClassLoader(); + Class LoadingProgressC= null; + final Object progressBar; + + if ( startupMode.equals("standalone" ) || startupMode.equals("client" )) + { + LoadingProgressC = loader.loadClass("org.rapla.bootstrap.LoadingProgress"); + progressBar = LoadingProgressC.getMethod("getInstance").invoke(null); + LoadingProgressC.getMethod("start", int.class, int.class).invoke( progressBar, 1,4); + } + else + { + progressBar = null; + } + final String contextPath = System.getProperty("org.rapla.context",null); + final String downloadUrl = System.getProperty("org.rapla.serverUrl",null); + final String[] jettyArgs = configFiles.split(","); + + + final AtomicReference exception = new AtomicReference(); + AccessController.doPrivileged(new PrivilegedAction() + { + boolean started; + boolean shutdownShouldRun; + public Object run() + { + try + { + Properties properties = new Properties(); + // Add System Properties + Enumeration ensysprop = System.getProperties().propertyNames(); + while (ensysprop.hasMoreElements()) + { + String name = (String)ensysprop.nextElement(); + properties.put(name,System.getProperty(name)); + } + //loader.loadClass("org.rapla.bootstrap.JNDIInit").newInstance(); + ServerC =loader.loadClass("org.eclipse.jetty.server.Server"); + stopMethod = ServerC.getMethod("stop"); + ConfigurationC =loader.loadClass("org.eclipse.jetty.xml.XmlConfiguration"); + ConnectorC = loader.loadClass("org.eclipse.jetty.server.Connector"); + ResourceC = loader.loadClass("org.eclipse.jetty.util.resource.Resource"); + EnvEntryC = loader.loadClass("org.eclipse.jetty.plus.jndi.EnvEntry"); + LifeCyleC = loader.loadClass( "org.eclipse.jetty.util.component.LifeCycle"); + LifeCyleListenerC = loader.loadClass( "org.eclipse.jetty.util.component.LifeCycle$Listener"); +// DeploymentManagerC = loader.loadClass("org.eclipse.jetty.deploy.DeploymentManager"); +// ContextHandlerC = loader.loadClass("org.eclipse.jetty.server.handler.ContextHandler"); +// WebAppContextC = loader.loadClass("org.eclipse.jetty.webapp.WebAppContext"); +// AppC = loader.loadClass("org.eclipse.jetty.deploy.App"); +// AppProviderC = loader.loadClass("org.eclipse.jetty.deploy.AppProvider"); +// ServletHandlerC = loader.loadClass("org.eclipse.jetty.servlet.ServletHandler"); +// ServletHolderC = loader.loadClass("org.eclipse.jetty.servlet.ServletHolder"); + + // For all arguments, load properties or parse XMLs + Object last = null; + Object[] obj = new Object[jettyArgs.length]; + for (int i = 0; i < jettyArgs.length; i++) + { + String configFile = jettyArgs[i]; + Object newResource = ResourceC.getMethod("newResource",String.class).invoke(null,configFile); + if (configFile.toLowerCase(Locale.ENGLISH).endsWith(".properties")) + { + properties.load((InputStream)ResourceC.getMethod("getInputStream").invoke(newResource)); + } + else + { + URL url = (URL)ResourceC.getMethod("getURL").invoke(newResource); + Object configuration = ConfigurationC.getConstructor(URL.class).newInstance(url); + if (last != null) + ((Map)ConfigurationC.getMethod("getIdMap").invoke(configuration)).putAll((Map)ConfigurationC.getMethod("getIdMap").invoke(last)); + if (properties.size() > 0) + { + Map props = new HashMap(); + for (Object key : properties.keySet()) + { + props.put(key.toString(),String.valueOf(properties.get(key))); + } + ((Map)ConfigurationC.getMethod("getProperties").invoke( configuration)).putAll( props); + } + Object configuredObject = ConfigurationC.getMethod("configure").invoke(configuration); + Integer port = null; + if ( ServerC.isInstance(configuredObject)) + { + final Object server = configuredObject; + Object[] connectors = (Object[]) ServerC.getMethod("getConnectors").invoke(server); + + for (Object c: connectors) + { + port = (Integer) ConnectorC.getMethod("getPort").invoke(c); + if ( removeConnectors) + { + ServerC.getMethod("removeConnector", ConnectorC).invoke(server, c); + } + } + + final Method shutdownMethod = ServerC.getMethod("stop"); + InvocationHandler proxy = new InvocationHandler() { + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable + { + String name = method.getName(); + if ( name.toLowerCase(Locale.ENGLISH).indexOf("started")>=0) + { + if ( shutdownShouldRun) + { + shutdownMethod.invoke( server); + } + else + { + started = true; + } + } + return null; + } + }; + Class[] interfaces = new Class[] {LifeCyleListenerC}; + Object proxyInstance = Proxy.newProxyInstance(loader, interfaces, proxy); + ServerC.getMethod("addLifeCycleListener", LifeCyleListenerC).invoke(server, proxyInstance); + Constructor newJndi = EnvEntryC.getConstructor(String.class,Object.class); + Method addBean = ServerC.getMethod("addBean", Object.class); + if ( !startupMode.equals("server")) + { + addBean.invoke(server, newJndi.newInstance("rapla_startup_user", startupUser)); + addBean.invoke(server, newJndi.newInstance("rapla_startup_mode", startupMode)); + addBean.invoke(server, newJndi.newInstance("rapla_download_url", downloadUrl)); + addBean.invoke(server, newJndi.newInstance("rapla_instance_counter", new ArrayList())); + if ( contextPath != null) + { + addBean.invoke(server, newJndi.newInstance("rapla_startup_context", contextPath)); + } + } + addBean.invoke(server, newJndi.newInstance("rapla_startup_port", port)); + { + Runnable shutdownCommand = new Runnable() { + + public void run() { + if ( started) + { + try { + shutdownMethod.invoke(server); + } catch (Exception ex) { + logger.log(Level.SEVERE,ex.getMessage(),ex); + } + } + else + { + shutdownShouldRun = true; + } + } + }; + addBean.invoke(server, newJndi.newInstance("rapla_shutdown_command", shutdownCommand)); + } + } + obj[i] = configuredObject; + last = configuration; + } + } + + // For all objects created by XmlConfigurations, start them if they are lifecycles. + for (int i = 0; i < obj.length; i++) + { + if (LifeCyleC.isInstance(obj[i])) + { + Object o =obj[i]; + if ( !(Boolean)LifeCyleC.getMethod("isStarted").invoke(o)) + { + LifeCyleC.getMethod("start").invoke(o); + } + } + } + } + catch (Exception e) + { + exception.set(e); + } + return null; + } + }); + if ( progressBar != null && LoadingProgressC != null) + { + LoadingProgressC.getMethod("close").invoke( progressBar); + } + Throwable th = exception.get(); + if (th != null) + { + if (th instanceof RuntimeException) + throw (RuntimeException)th; + else if (th instanceof Exception) + throw (Exception)th; + else if (th instanceof Error) + throw (Error)th; + throw new Error(th); + } + } + +// void doStart(final Object server, String passedContext) +// { +// try +// { +// Object bean = ServerC.getMethod("getBean", Class.class).invoke(server, DeploymentManagerC); +// Map raplaServletMap = new LinkedHashMap(); +// Collection apps = (Collection) DeploymentManagerC.getMethod("getApps").invoke(bean); +// for (Object handler:apps) +// { +// +// Object context_ = AppC.getMethod("getContextHandler").invoke(handler); +// String contextPath = (String) ContextHandlerC.getMethod("getContextPath").invoke(context_); +// Object[] servlets = (Object[]) ContextHandlerC.getMethod("getChildHandlersByClass", Class.class).invoke(context_, ServletHandlerC); +// for ( Object childHandler : servlets) +// { +// Object servlet = ServletHandlerC.getMethod("getServlet",String.class).invoke( childHandler,"RaplaServer"); +// if ( servlet != null) +// { +// raplaServletMap.put(contextPath, servlet); +// } +// } +// } +// +// Set keySet = raplaServletMap.keySet(); +// if ( keySet.size() == 0) +// { +// logger.log(Level.SEVERE,"No rapla context found in jetty container."); +// stopMethod.invoke(server); +// } +// else if ( keySet.size() > 1 && passedContext == null) +// { +// logger.log(Level.SEVERE,"Multiple context found in jetty container " + keySet +" Please specify one via -Dorg.rapla.context=REPLACE_WITH_CONTEXT"); +// stopMethod.invoke(server); +// } +// else +// { +// //Class MainServletC = loader.loadClass("org.rapla.MainServlet"); +// Object servletHolder = passedContext == null ? raplaServletMap.values().iterator().next(): raplaServletMap.get( passedContext); +// if ( servletHolder != null) +// { +// +// Object servlet = ServletHolderC.getMethod("getServlet").invoke( servletHolder); +// PropertyChangeListener castedHack = (PropertyChangeListener)servlet; +// castedHack.propertyChange( new PropertyChangeEvent(server, startupMode, null, shutdownCommand)); +// } +// else +// { +// logger.log(Level.SEVERE,"Rapla context ' " + passedContext +"' not found."); +// stopMethod.invoke(server); +// } +// } +// } +// catch (Exception ex) +// { +// logger.log(Level.SEVERE,ex.getMessage(),ex); +// try { +// stopMethod.invoke(server); +// } catch (Exception e) { +// logger.log(Level.SEVERE,e.getMessage(),e); +// } +// } +// } + +} diff --git a/rapla-source-1.8.2/src/org/rapla/bootstrap/LoadingProgress.java b/rapla-source-1.8.2/src/org/rapla/bootstrap/LoadingProgress.java new file mode 100644 index 0000000..48da992 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/bootstrap/LoadingProgress.java @@ -0,0 +1,173 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.bootstrap; +import java.awt.Color; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.MediaTracker; +import java.awt.Toolkit; +import java.awt.image.ImageObserver; +import java.net.URL; + +import javax.swing.JProgressBar; + +final public class LoadingProgress { + static LoadingProgress instance; + JProgressBar progressBar; + Frame frame; + ImageObserver observer; + Image image; + Component canvas; + + int maxValue; + + static public LoadingProgress getInstance() + { + if ( instance == null) + { + instance = new LoadingProgress(); + } + return instance; + } + + public boolean isStarted() + { + return frame != null; + } + + /** this method creates the progress bar */ + public void start(int startValue, int maxValue) + { + this.maxValue = maxValue; + frame = new Frame() + { + private static final long serialVersionUID = 1L; + + public void paint(Graphics g) + { + super.paint(g); + g.drawRect(0, 0, getWidth() - 1, getHeight() - 1); + } + }; + observer = new ImageObserver() + { + public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h) + { + if ((flags & ALLBITS) != 0) + { + canvas.repaint(); + } + return (flags & (ALLBITS | ABORT | ERROR)) == 0; + } + }; + frame.setBackground(new Color(255, 255, 204)); + canvas = new Component() + { + private static final long serialVersionUID = 1L; + + public void paint(Graphics g) + { + g.drawImage(image, 0, 0, observer); + } + }; + Toolkit toolkit = Toolkit.getDefaultToolkit(); + URL url = LoadingProgress.class.getResource("/org/rapla/bootstrap/tafel.png"); + + // Variables (integer pixels) for... + // ... the width of the border around the picture + int borderwidth = 4; + // ... the height of the border around the picture + int borderheight = 4; + // ... the width of the picture within the frame + int picturewidth = 356; + // ... the height of the picture within the frame + int pictureheight = 182; + // ... calculating the frame width + int framewidth = borderwidth + borderheight + picturewidth; + // ... calculating the frame height + int frameheight = borderwidth + borderheight + pictureheight; + // ... width of the loading progress bar + int progresswidth = 150; + // ... height of the loading progress bar + int progressheight = 15; + + image = toolkit.createImage(url); + frame.setResizable(false); + frame.setLayout(null); + + progressBar = new JProgressBar(0, maxValue); + progressBar.setValue(startValue); + // set the bounds to position the progressbar and set width and height + progressBar.setBounds(158, 130, progresswidth, progressheight); + progressBar.repaint(); + + // we have to add the progressbar first to get it infront of the picture + frame.add(progressBar); + frame.add(canvas); + + // width and height of the canvas equal to those of the picture inside + // but here we need the borderwidth as X and the borderheight as Y value + canvas.setBounds(borderwidth, borderheight, picturewidth, pictureheight); + try + { + // If run on jdk < 1.4 this will throw a MethodNotFoundException + // frame.setUndecorated(true); + Frame.class.getMethod("setUndecorated", new Class[] { boolean.class }).invoke(frame, new Object[] { new Boolean(true) }); + } + catch (Exception ex) + { + } + // we grab the actual size of the screen + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + // to make sure the starting dialog is positioned in the middle of + // the screen and has the width and height we specified for the frame + frame.setBounds((screenSize.width / 2) - (picturewidth / 2), (screenSize.height / 2) - (pictureheight / 2), framewidth, frameheight); + frame.validate(); + frame.setVisible(true); + frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + + MediaTracker mt = new MediaTracker(frame); + mt.addImage(image, 0); + try + { + mt.waitForID(0); + } + catch (InterruptedException e) + { + } + } + + public void advance() { + if ( frame == null) + { + return; + } + int oldValue = progressBar.getValue(); + if (oldValue < maxValue) + progressBar.setValue(oldValue + 1); + progressBar.repaint(); + } + + public void close() { + if ( frame != null) + { + frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + frame.dispose(); + frame = null; + } + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaClientLoader.java b/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaClientLoader.java new file mode 100644 index 0000000..3083407 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaClientLoader.java @@ -0,0 +1,12 @@ +package org.rapla.bootstrap; + +import java.io.IOException; + + +public class RaplaClientLoader +{ + public static void main(String[] args) throws IOException + { + RaplaJettyLoader.main(new String[] {"client"}); + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaJettyLoader.java b/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaJettyLoader.java new file mode 100644 index 0000000..4dfa271 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaJettyLoader.java @@ -0,0 +1,35 @@ +package org.rapla.bootstrap; + +import java.io.File; +import java.io.IOException; + + +public class RaplaJettyLoader +{ + public static void main(String[] args) throws IOException + { + String baseDir = System.getProperty("jetty.home"); + if ( baseDir == null) + { + baseDir = "."; + System.setProperty( "jetty.home", new File(baseDir ).getCanonicalPath() ); + } + for ( String arg:args) + { + if ( arg != null && arg.toLowerCase().equals("server")) + { + System.setProperty( "java.awt.headless", "true" ); + } + } + String dirList = "lib,lib/logging,lib/ext,resources"; + String classname = "org.rapla.bootstrap.CustomJettyStarter"; + String methodName = "main"; + //System.setProperty( "java.awt.headless", "true" ); + String test = "Starting rapla from " + System.getProperty("jetty.home"); + System.out.println(test ); + RaplaLoader.start( baseDir,dirList, classname,methodName, new Object[] {args }); + } + + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaLoader.java b/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaLoader.java new file mode 100644 index 0000000..72a2c52 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaLoader.java @@ -0,0 +1,180 @@ +package org.rapla.bootstrap; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.StringTokenizer; + +/** + Puts all jar-files from the libdirs into the classpath and start the mainClass. + Usage: + + Syntax: baseDir libdir1,libdir2,... mainClass arg1 arg2 ... + + Will put all jar-files from the libdirs into the classpath and start the mainClass + + baseDir: replace with the path, from wich you want the lib-dirs to resolve. + libdir[1-n]: Lib-Directories relativ to the base jars."); + mainClass: The Java-Class you want to start after loading the jars. + arg[1-n]: + + Example: ./lib common,client org.rapla.Main rapla + + loads the jars in lib/common and lib/client and + starts org.rapla.Main with the argument rapla + + */ +public class RaplaLoader { + /** returns all *.jar files in the directories passed in dirList relative to the baseDir */ + public static File[] getJarFilesAndClassesFolder(String baseDir,String dirList) throws IOException { + ArrayList completeList = new ArrayList(); + StringTokenizer tokenizer = new StringTokenizer(dirList,","); + while (tokenizer.hasMoreTokens()) + { + File jarDir = new File(baseDir,tokenizer.nextToken()); + if (jarDir.exists() && jarDir.isDirectory()) + { + File[] jarFiles = jarDir.listFiles(); + for (int i = 0; i < jarFiles.length; i++) { + if ( + jarFiles[i].getAbsolutePath().endsWith(".jar") + ) + { + completeList.add(jarFiles[i].getCanonicalFile()); + } + } + completeList.add( jarDir.getCanonicalFile() ); + } + } + return completeList.toArray(new File[] {}); + } + + + private static void printUsage() { + System.out.println("Syntax: baseDir libdir1,libdir2,... mainClass arg1 arg2 ..."); + System.out.println(); + System.out.println("Will put all jar-files from the libdirs into the classpath and start the mainClass"); + System.out.println(); + System.out.println(" baseDir: replace with the path, from wich you want the lib-dirs to resolve."); + System.out.println(" libdir[1-n]: Lib-Directories relativ to the base jars."); + System.out.println(" mainClass: The Java-Class you want to start after loading the jars."); + System.out.println(" arg[1-n]: "); + System.out.println(); + System.out.println(" Example: ./lib common,client org.rapla.Main rapla "); + System.out.println("loads the jars in lib/common and lib/client and "); + System.out.println(" starts org.rapla.Main with the argument rapla"); + } + + public static void main(String[] args) { + String baseDir; + String dirList; + String classname; + String[] applicationArgs; + + if (args.length <3) { + printUsage(); + System.exit(1); + } + baseDir=args[0]; + dirList=args[1]; + classname=args[2]; + + applicationArgs = new String[args.length-3]; + for (int i=0;i startClass = classLoader.loadClass(classname); + Class[] argTypes = new Class[args.length]; + for ( int i=0;i forName = loader.loadClass("org.slf4j.bridge.SLF4JBridgeHandler"); +// forName.getMethod("removeHandlersForRootLogger", new Class[] {}).invoke(null, new Object[] {}); +// forName.getMethod("install", new Class[] {}).invoke(null, new Object[] {}); +// loader.loadClass("org.rapla.bootstrap.JNDIInit").newInstance(); +// +// File file = new File(baseDir, warfile); +// ClassLoader classLoader; +// if (file.exists()) +// { +// Class webappContextClass = loader.loadClass("org.eclipse.jetty.webapp.WebAppContext"); +// //org.eclipse.jetty.webapp.WebAppContext context = new org.eclipse.jetty.webapp.WebAppContext("webapps/rapla.war","/"); +// Constructor const1 = webappContextClass.getConstructor(String.class, String.class); +// Object context = const1.newInstance(new Object[] {file.getPath(),"/"}); +// Class webappClassLoaderClass = loader.loadClass("org.eclipse.jetty.webapp.WebAppClassLoader"); +// Class contextClass = loader.loadClass("org.eclipse.jetty.webapp.WebAppClassLoader$Context"); +// //org.eclipse.jetty.webapp.WebAppClassLoader classLoader = new org.eclipse.jetty.webapp.WebAppClassLoader(parentClassLoader, context); +// Constructor const2 = webappClassLoaderClass.getConstructor(ClassLoader.class, contextClass); +// classLoader = (ClassLoader) const2.newInstance(loader, context); +// webappContextClass.getMethod("setClassLoader", ClassLoader.class).invoke( context,classLoader); +// Class configurationClass = loader.loadClass("org.eclipse.jetty.webapp.WebInfConfiguration"); +// Object config = configurationClass.newInstance(); +// configurationClass.getMethod("preConfigure", webappContextClass).invoke(config, context); +// configurationClass.getMethod("configure", webappContextClass).invoke(config, context); +// } +// else +// { +// classLoader = loader; +// System.err.println("War " + warfile + " not found. Using original classpath."); +// } +// startMain(classLoader,classname,methodName,applicationArgs); +// } catch (Exception ex) { +// ex.printStackTrace(); +// System.exit(1); +// } +// } + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaServerAsServiceLoader.java b/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaServerAsServiceLoader.java new file mode 100644 index 0000000..ea82f09 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaServerAsServiceLoader.java @@ -0,0 +1,20 @@ +package org.rapla.bootstrap; + +import java.io.File; +import java.io.IOException; + + +public class RaplaServerAsServiceLoader +{ + public static void main(String[] args) throws IOException + { + System.setProperty( "java.awt.headless", "true" ); + String baseDir = System.getProperty("jetty.home"); + if ( baseDir == null) + { + baseDir = "../.."; + System.setProperty( "jetty.home", new File(baseDir ).getCanonicalPath() ); + } + RaplaServerLoader.main( args); + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaServerLoader.java b/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaServerLoader.java new file mode 100644 index 0000000..9e6ae6b --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaServerLoader.java @@ -0,0 +1,13 @@ +package org.rapla.bootstrap; + +import java.io.IOException; + + +public class RaplaServerLoader +{ + public static void main(String[] args) throws IOException + { + System.setProperty( "java.awt.headless", "true" ); + RaplaJettyLoader.main(new String[] {"server"}); + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaStandaloneLoader.java b/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaStandaloneLoader.java new file mode 100644 index 0000000..5d12ffb --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/bootstrap/RaplaStandaloneLoader.java @@ -0,0 +1,20 @@ +package org.rapla.bootstrap; + +import java.io.IOException; + + +public class RaplaStandaloneLoader +{ + public static void main(String[] args) throws IOException + { + // This is for backwards compatibility + if ( args.length > 0 && args[0].equals( "client")) + { + RaplaJettyLoader.main(new String[] {"client"}); + } + else + { + RaplaJettyLoader.main(new String[] {"standalone"}); + } + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/bootstrap/tafel.png b/rapla-source-1.8.2/src/org/rapla/bootstrap/tafel.png new file mode 100644 index 0000000..48ee122 Binary files /dev/null and b/rapla-source-1.8.2/src/org/rapla/bootstrap/tafel.png differ diff --git a/rapla-source-1.8.2/src/org/rapla/client/ClientExtension.java b/rapla-source-1.8.2/src/org/rapla/client/ClientExtension.java new file mode 100644 index 0000000..a9ea52c --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/client/ClientExtension.java @@ -0,0 +1,8 @@ +package org.rapla.client; + +/** classes implementing ClientExtension are started automaticaly when a user has successfully login into the Rapla system. A class added as service doesn't need to implement a specific interface and is instanciated automaticaly after client login. You can add a RaplaContext parameter to your constructor to get access to the services of rapla. + * Generally you don't need to start a client service. It is better to provide functionality through the RaplaClientExtensionPoints + */ +public interface ClientExtension { + +} diff --git a/rapla-source-1.8.2/src/org/rapla/client/ClientService.java b/rapla-source-1.8.2/src/org/rapla/client/ClientService.java new file mode 100644 index 0000000..f38a5be --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/client/ClientService.java @@ -0,0 +1,57 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.client; + +import java.util.Map; + +import org.rapla.entities.User; +import org.rapla.facade.ClientFacade; +import org.rapla.framework.RaplaContext; +import org.rapla.framework.RaplaContextException; +import org.rapla.framework.RaplaException; +import org.rapla.framework.TypedComponentRole; +import org.rapla.gui.toolkit.RaplaFrame; +import org.rapla.gui.toolkit.RaplaWidget; + +/** This service starts and manages the rapla-gui-client. + */ +public interface ClientService +{ + public static TypedComponentRole> SESSION_MAP = new TypedComponentRole>("org.rapla.SessionMap"); + public static TypedComponentRole MAIN_COMPONENT = new TypedComponentRole("org.rapla.MainComponent"); + public static TypedComponentRole WELCOME_FIELD = new TypedComponentRole("org.rapla.gui.WelcomeField"); + + + void addRaplaClientListener(RaplaClientListener listener); + void removeRaplaClientListener(RaplaClientListener listener); + + ClientFacade getFacade() throws RaplaContextException; + /** setup a component with the services logger,context and servicemanager */ + boolean isRunning(); + + /** the admin can switch to another user! + * @throws RaplaContextException + * @throws RaplaException */ + void switchTo(User user) throws RaplaException; + /** returns true if the admin has switched to anoter user!*/ + boolean canSwitchBack(); + + /** restarts the complete Client and displays a new login*/ + void restart(); + /** returns true if an logout option is available. This is true when the user used an login dialog.*/ + boolean isLogoutAvailable(); + + RaplaContext getContext(); + + void logout(); +} diff --git a/rapla-source-1.8.2/src/org/rapla/client/ClientServiceContainer.java b/rapla-source-1.8.2/src/org/rapla/client/ClientServiceContainer.java new file mode 100644 index 0000000..7d1a62a --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/client/ClientServiceContainer.java @@ -0,0 +1,16 @@ +package org.rapla.client; + +import java.util.List; + +import org.rapla.ConnectInfo; +import org.rapla.framework.Container; +import org.rapla.framework.PluginDescriptor; +import org.rapla.framework.TypedComponentRole; + +public interface ClientServiceContainer extends Container +{ + TypedComponentRole>> CLIENT_PLUGIN_LIST = new TypedComponentRole>>("client-plugin-list"); + void start(ConnectInfo connectInfo) throws Exception; + //void addCompontentOnClientStart(Class componentToStart); + boolean isRunning(); +} diff --git a/rapla-source-1.8.2/src/org/rapla/client/MainApplet.java b/rapla-source-1.8.2/src/org/rapla/client/MainApplet.java new file mode 100644 index 0000000..09b0c32 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/client/MainApplet.java @@ -0,0 +1,136 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.client; + +import java.awt.Color; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.net.URL; + +import javax.swing.BorderFactory; +import javax.swing.JApplet; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import org.rapla.framework.StartupEnvironment; + +/** The applet-encapsulation of the Main.class reads the configuration + * from the document-base of the applet and displays + * an applet with a start button. + * @author Christopher Kohlhaas + * @see MainWebstart + */ +final public class MainApplet extends JApplet +{ + private static final long serialVersionUID = 1L; + + JPanel dlg = new JPanel(); + JButton button; + JLabel label; + + boolean startable = false; + + public MainApplet() + { + JPanel panel1 = new JPanel(); + panel1.setBackground( new Color( 255, 255, 204 ) ); + + GridLayout gridLayout1 = new GridLayout(); + gridLayout1.setColumns( 1 ); + gridLayout1.setRows( 3 ); + gridLayout1.setHgap( 10 ); + gridLayout1.setVgap( 10 ); + panel1.setLayout( gridLayout1 ); + + label = new JLabel( "Rapla-Applet loading" ); + panel1.add( label ); + + button = new JButton( "StartRapla" ); + button.addActionListener( new ActionListener() + { + + public void actionPerformed( ActionEvent e ) + { + startThread(); + } + + } ); + panel1.add( button ); + + dlg.setBackground( new Color( 255, 255, 204 ) ); + dlg.setBorder( BorderFactory.createMatteBorder( 1, 1, 2, 2, Color.black ) ); + dlg.add( panel1 ); + } + + public void start() + { + getRootPane().putClientProperty( "defeatSystemEventQueueCheck", Boolean.TRUE ); + try + { + setContentPane( dlg ); + button.setEnabled( startable ); + startable = true; + button.setEnabled( startable ); + } + catch ( Exception ex ) + { + ex.printStackTrace(); + } + } + + private void updateStartable() + { + javax.swing.SwingUtilities.invokeLater( new Runnable() + { + public void run() + { + button.setEnabled( startable ); + } + } ); + } + + private void startThread() + { + ( new Thread() + { + public void run() + { + try + { + startable = false; + updateStartable(); + MainWebclient main = new MainWebclient(); + String startupUser = getParameter("org.rapla.startupUser"); + main.setStartupUser( startupUser); + URL configURL = new URL( getDocumentBase(), MainWebclient.CLIENT_CONFIG_SERVLET_URL ); + main.init( configURL, StartupEnvironment.APPLET ); + main.env.setDownloadURL( getDocumentBase() ); + System.out.println( "Docbase " + getDocumentBase() ); + main.startRapla("client"); + } + catch ( Exception ex ) + { + ex.printStackTrace(); + } + finally + { + startable = true; + updateStartable(); + } + } + } ).start(); + } + +} diff --git a/rapla-source-1.8.2/src/org/rapla/client/MainWebclient.java b/rapla-source-1.8.2/src/org/rapla/client/MainWebclient.java new file mode 100644 index 0000000..0767e51 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/client/MainWebclient.java @@ -0,0 +1,141 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.client; +import java.net.URL; +import java.net.URLDecoder; + +import org.rapla.ConnectInfo; +import org.rapla.RaplaMainContainer; +import org.rapla.RaplaStartupEnvironment; +import org.rapla.framework.Container; +import org.rapla.framework.RaplaContextException; +import org.rapla.framework.StartupEnvironment; +import org.rapla.framework.logger.ConsoleLogger; +import org.rapla.framework.logger.Logger; + + +public class MainWebclient +{ + /** The default config filename for client-mode raplaclient.xconf*/ + public final static String CLIENT_CONFIG_SERVLET_URL = "rapla/raplaclient.xconf"; + + private Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_WARN).getChildLogger("init"); + RaplaStartupEnvironment env = new RaplaStartupEnvironment(); + Container raplaContainer; + + String startupUser; + + + + void init(URL configURL,int mode) throws Exception { + env.setStartupMode( mode ); + env.setConfigURL( configURL ); + env.setBootstrapLogger( getLogger() ); + } + + public String getStartupUser() + { + return startupUser; + } + + public void setStartupUser(String startupUser) + { + this.startupUser = startupUser; + } + + void startRapla(final String id) throws Exception { + ConnectInfo connectInfo = null; + + try + { + if ( startupUser != null) + { + String decoded = URLDecoder.decode( startupUser, "UTF-8"); + getLogger().warn("Starting rapla with username " + startupUser); + connectInfo = new ConnectInfo( decoded, "".toCharArray()); + } + else + { + getLogger().warn("Starting rapla with login screen."); + } + } catch (Throwable ex) + { + getLogger().error("Error reading system property " , ex); + } + startRapla(id, connectInfo); + } + + protected void startRapla(final String id, ConnectInfo connectInfo) throws Exception, RaplaContextException { + raplaContainer = new RaplaMainContainer( env); + ClientServiceContainer clientContainer = raplaContainer.lookup(ClientServiceContainer.class, id ); + ClientService client = clientContainer.getContext().lookup( ClientService.class); + client.addRaplaClientListener(new RaplaClientListenerAdapter() { + public void clientClosed(ConnectInfo reconnect) { + if ( reconnect != null) { + raplaContainer.dispose(); + try { + startRapla(id, reconnect); + } catch (Exception ex) { + getLogger().error("Error restarting client",ex); + exit(); + } + } else { + exit(); + } + } + public void clientAborted() + { + exit(); + } + }); + clientContainer.start(connectInfo); + } + + public static void main(String[] args) { + MainWebclient main = new MainWebclient(); + try { + + main.init( new URL("http://localhost:8051/rapla/raplaclient.xconf"),StartupEnvironment.CONSOLE); + main.startRapla("client"); + } catch (Throwable ex) { + main.getLogger().error("Couldn't start Rapla",ex); + main.raplaContainer.dispose(); + System.out.flush(); + try + { + Thread.sleep( 2000 ); + } + catch ( InterruptedException e ) + { + } + System.exit(1); + + } + } + + private void exit() { + if ( raplaContainer != null) + { + raplaContainer.dispose(); + } + if (env.getStartupMode() != StartupEnvironment.APPLET) + { + System.exit(0); + } + } + + Logger getLogger() { + return logger; + } + +} diff --git a/rapla-source-1.8.2/src/org/rapla/client/MainWebstart.java b/rapla-source-1.8.2/src/org/rapla/client/MainWebstart.java new file mode 100644 index 0000000..35b8519 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/client/MainWebstart.java @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.client; +import org.rapla.framework.StartupEnvironment; +import org.rapla.framework.internal.ConfigTools; + + +final public class MainWebstart +{ + public static void main(String[] args) { + MainWebclient main = new MainWebclient(); + try { + main.init( ConfigTools.webstartConfigToURL( MainWebclient.CLIENT_CONFIG_SERVLET_URL),StartupEnvironment.WEBSTART); + String startupUser = System.getProperty("jnlp.org.rapla.startupUser"); + main.setStartupUser( startupUser); + main.startRapla("client"); + } catch (Throwable ex) { + main.getLogger().error("Couldn't start Rapla",ex); + if (main.raplaContainer != null) + { + main.raplaContainer.dispose(); + } + System.out.flush(); + try + { + Thread.sleep( 2000 ); + } + catch ( InterruptedException e ) + { + } + System.exit(1); + + } + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/client/RaplaClientExtensionPoints.java b/rapla-source-1.8.2/src/org/rapla/client/RaplaClientExtensionPoints.java new file mode 100644 index 0000000..56d7b46 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/client/RaplaClientExtensionPoints.java @@ -0,0 +1,107 @@ +package org.rapla.client; + + +import org.rapla.facade.CalendarSelectionModel; +import org.rapla.framework.TypedComponentRole; +import org.rapla.gui.AppointmentStatusFactory; +import org.rapla.gui.EventCheck; +import org.rapla.gui.ObjectMenuFactory; +import org.rapla.gui.OptionPanel; +import org.rapla.gui.PluginOptionPanel; +import org.rapla.gui.PublishExtensionFactory; +import org.rapla.gui.ReservationCheck; +import org.rapla.gui.SwingViewFactory; +import org.rapla.gui.toolkit.IdentifiableMenuEntry; + + + + +/** Constant Pool of basic extension points of the Rapla client. + * You can add your extension in the provideService Method of your PluginDescriptor + *
+ * container.addContainerProvidedComponent( REPLACE_WITH_EXTENSION_POINT_NAME, REPLACE_WITH_CLASS_IMPLEMENTING_EXTENSION, config);
+ * 
+ * @see org.rapla.framework.PluginDescriptor +*/ + +public interface RaplaClientExtensionPoints +{ + /** add your own views to Rapla, by providing a org.rapla.gui.ViewFactory + * @see SwingViewFactory + * */ + Class CALENDAR_VIEW_EXTENSION = SwingViewFactory.class; + + /** A client extension is started automaticaly when a user has successfully login into the Rapla system. A class added as service doesn't need to implement a specific interface and is instanciated automaticaly after client login. You can add a RaplaContext parameter to your constructor to get access to the services of rapla. + */ + Class CLIENT_EXTENSION = ClientExtension.class; + /** You can add a specific configuration panel for your plugin. + * Note if you add a pluginOptionPanel you need to provide the PluginClass as hint. + * Example + * + * container.addContainerProvidedComponent( RaplaExtensionPoints.PLUGIN_OPTION_PANEL_EXTENSION, AutoExportPluginOption.class, getClass().getName()); + * + * @see org.rapla.entities.configuration.Preferences + * @see OptionPanel + * */ + TypedComponentRole PLUGIN_OPTION_PANEL_EXTENSION = new TypedComponentRole("org.rapla.plugin.Option"); + /** You can add additional option panels for editing the user preference. + * @see org.rapla.entities.configuration.Preferences + * @see OptionPanel + * */ + TypedComponentRole USER_OPTION_PANEL_EXTENSION = new TypedComponentRole("org.rapla.UserOptions"); + /** You can add additional option panels for the editing the system preferences + * @see org.rapla.entities.configuration.Preferences + * @see OptionPanel + * */ + TypedComponentRole SYSTEM_OPTION_PANEL_EXTENSION = new TypedComponentRole("org.rapla.SystemOptions"); + + /** add your own wizard menus to create events. Use the CalendarSelectionModel service to get access to the current calendar + * @see CalendarSelectionModel + **/ + TypedComponentRole RESERVATION_WIZARD_EXTENSION = new TypedComponentRole("org.rapla.gui.ReservationWizardExtension"); + + /** you can add an interactive check when the user stores a reservation + *@see ReservationCheck + **/ + Class RESERVATION_SAVE_CHECK = ReservationCheck.class; + + /** you can add an interactive check when the user stores a reservation + *@see ReservationCheck + **/ + Class EVENT_SAVE_CHECK = EventCheck.class; + + /** add your own menu entries in the context menu of an object. To do this provide + an ObjectMenuFactory under this entry. + @see ObjectMenuFactory + */ + Class OBJECT_MENU_EXTENSION = ObjectMenuFactory.class; + + /** add a footer for summary of appointments in edit window + * provide an AppointmentStatusFactory to add your own footer to the appointment edit + @see AppointmentStatusFactory + * */ + Class APPOINTMENT_STATUS = AppointmentStatusFactory.class; + + + /** add your own submenus to the admin menu. + */ + TypedComponentRole ADMIN_MENU_EXTENSION_POINT = new TypedComponentRole("org.rapla.gui.AdminMenuInsert"); + /** add your own import-menu submenus + */ + TypedComponentRole IMPORT_MENU_EXTENSION_POINT =new TypedComponentRole("org.rapla.gui.ImportMenuInsert"); + /** add your own export-menu submenus + */ + TypedComponentRole EXPORT_MENU_EXTENSION_POINT =new TypedComponentRole("org.rapla.gui.ExportMenuInsert"); + /** add your own view-menu submenus + */ + TypedComponentRole VIEW_MENU_EXTENSION_POINT =new TypedComponentRole("org.rapla.gui.ViewMenuInsert"); + /** add your own edit-menu submenus + */ + TypedComponentRole EDIT_MENU_EXTENSION_POINT = new TypedComponentRole("org.rapla.gui.EditMenuInsert"); + /** add your own help-menu submenus + */ + TypedComponentRole HELP_MENU_EXTENSION_POINT = new TypedComponentRole("org.rapla.gui.ExtraMenuInsert"); + + /** add your own publish options for the calendars*/ + Class PUBLISH_EXTENSION_OPTION = PublishExtensionFactory.class; +} diff --git a/rapla-source-1.8.2/src/org/rapla/client/RaplaClientListener.java b/rapla-source-1.8.2/src/org/rapla/client/RaplaClientListener.java new file mode 100644 index 0000000..934211a --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/client/RaplaClientListener.java @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.client; + +import org.rapla.ConnectInfo; + +public interface RaplaClientListener +{ + public void clientStarted(); + public void clientClosed(ConnectInfo reconnect); + public void clientAborted(); +} diff --git a/rapla-source-1.8.2/src/org/rapla/client/RaplaClientListenerAdapter.java b/rapla-source-1.8.2/src/org/rapla/client/RaplaClientListenerAdapter.java new file mode 100644 index 0000000..c003b23 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/client/RaplaClientListenerAdapter.java @@ -0,0 +1,27 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.client; + +import org.rapla.ConnectInfo; + +public class RaplaClientListenerAdapter implements RaplaClientListener +{ + public void clientStarted() { + } + public void clientClosed(ConnectInfo reconnect) { + } + public void clientAborted() + { + + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/client/internal/LanguageChooser.java b/rapla-source-1.8.2/src/org/rapla/client/internal/LanguageChooser.java new file mode 100644 index 0000000..ccc17b3 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/client/internal/LanguageChooser.java @@ -0,0 +1,114 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.client.internal; + +import java.awt.Component; +import java.util.Locale; + +import javax.swing.Action; +import javax.swing.DefaultListCellRenderer; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JList; + +import org.rapla.components.xmlbundle.I18nBundle; +import org.rapla.facade.RaplaComponent; +import org.rapla.framework.RaplaContext; +import org.rapla.framework.RaplaException; +import org.rapla.framework.RaplaLocale; +import org.rapla.framework.logger.Logger; +import org.rapla.gui.toolkit.RaplaWidget; + +final public class LanguageChooser implements RaplaWidget +{ + JComboBox jComboBox; + String country; + RaplaContext context; + Logger logger; + + public LanguageChooser(Logger logger,RaplaContext context) throws RaplaException { + this.logger = logger; + this.context = context; + final I18nBundle i18n = context.lookup( RaplaComponent.RAPLA_RESOURCES); + final RaplaLocale raplaLocale = context.lookup( RaplaLocale.class ); + country = raplaLocale.getLocale().getCountry(); + String[] languages = raplaLocale.getAvailableLanguages(); + + String[] entries = new String[languages.length + 1]; + System.arraycopy( languages, 0, entries, 1, languages.length); + @SuppressWarnings("unchecked") + JComboBox jComboBox2 = new JComboBox(entries); + jComboBox = jComboBox2; + DefaultListCellRenderer aRenderer = new DefaultListCellRenderer() { + private static final long serialVersionUID = 1L; + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) + { + if ( value != null) + { + value = new Locale( (String) value,country).getDisplayLanguage( raplaLocale.getLocale()); + } + else + { + value = i18n.getString("default") + " " + i18n.getString("preferences"); + } + return super.getListCellRendererComponent(list, + value, + index, + isSelected, + cellHasFocus); + } + }; + setRenderer(aRenderer); + //jComboBox.setSelectedItem( raplaLocale.getLocale().getLanguage()); + } + + @SuppressWarnings("unchecked") + private void setRenderer(DefaultListCellRenderer aRenderer) { + jComboBox.setRenderer(aRenderer); + } + + public JComponent getComponent() { + return jComboBox; + } + + public void setSelectedLanguage(String lang) { + jComboBox.setSelectedItem(lang); + } + + public String getSelectedLanguage() + { + return (String) jComboBox.getSelectedItem(); + } + + public void setChangeAction( Action languageChanged ) + { + jComboBox.setAction( languageChanged ); + } + +} + + + + + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/client/internal/LoginDialog.java b/rapla-source-1.8.2/src/org/rapla/client/internal/LoginDialog.java new file mode 100644 index 0000000..3c7dd6a --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/client/internal/LoginDialog.java @@ -0,0 +1,319 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas, Frithjof Kurtz | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.client.internal; + +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Graphics; +import java.awt.GridLayout; +import java.awt.Image; +import java.awt.MediaTracker; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.image.ImageObserver; +import java.beans.PropertyVetoException; +import java.net.URL; + +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JPasswordField; +import javax.swing.JTextField; + +import org.rapla.components.layout.TableLayout; +import org.rapla.components.xmlbundle.I18nBundle; +import org.rapla.components.xmlbundle.LocaleChangeEvent; +import org.rapla.components.xmlbundle.LocaleChangeListener; +import org.rapla.components.xmlbundle.LocaleSelector; +import org.rapla.facade.RaplaComponent; +import org.rapla.framework.RaplaContext; +import org.rapla.framework.RaplaException; +import org.rapla.framework.StartupEnvironment; +import org.rapla.gui.RaplaGUIComponent; +import org.rapla.gui.toolkit.RaplaFrame; + +public final class LoginDialog extends RaplaFrame implements LocaleChangeListener +{ + private static final long serialVersionUID = -1887723833652617352L; + + Container container; + JPanel upperpanel = new JPanel(); + JPanel lowerpanel = new JPanel(); + JLabel chooseLanguageLabel = new JLabel(); + JPanel userandpassword = new JPanel(); + JPanel buttonPanel = new JPanel(); + JTextField username = new JTextField(15); + JPasswordField password = new JPasswordField(15); + JLabel usernameLabel = new JLabel(); + JLabel passwordLabel = new JLabel(); + JButton loginBtn = new JButton(); + JButton exitBtn = new JButton(); + I18nBundle i18n; + ImageObserver observer; + Image image; + JPanel canvas; + protected LocaleSelector localeSelector; + StartupEnvironment env; + // we have to add an extra gui component here because LoginDialog extends RaplaFrame and therefore can't extent RaplaGUIComponent + RaplaGUIComponent guiComponent; + + public LoginDialog(RaplaContext context) throws RaplaException + { + super(context); + this.guiComponent = new RaplaGUIComponent(context); + env = context.lookup( StartupEnvironment.class ); + i18n = context.lookup(RaplaComponent.RAPLA_RESOURCES); + localeSelector = context.lookup(LocaleSelector.class); + localeSelector.addLocaleChangeListener(this); + } + + public static LoginDialog create(RaplaContext sm, JComponent languageSelector) throws RaplaException + { + LoginDialog dlg = new LoginDialog(sm); + dlg.init(languageSelector); + return dlg; + } + + Action exitAction; + + public void setLoginAction(Action action) + { + loginBtn.setAction(action); + } + + public void setExitAction(Action action) + { + exitAction = action; + exitBtn.setAction( action ); + } + + private void init(JComponent languageSelector) + { + container = getContentPane(); + container.setLayout(new BorderLayout()); + ((JComponent) container).setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + // ################## BEGIN LOGO ################### + + observer = new ImageObserver() + { + public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h) + { + if ((flags & ALLBITS) != 0) + { + canvas.repaint(); + } + return (flags & (ALLBITS | ABORT | ERROR)) == 0; + } + }; + + canvas = new JPanel() + { + private static final long serialVersionUID = 1L; + + public void paint(Graphics g) + { + g.drawImage(image, 0, 0, observer); + } + }; + + Toolkit toolkit = Toolkit.getDefaultToolkit(); + // creating an URL to the path of the picture + URL url = LoginDialog.class.getResource("/org/rapla/gui/images/tafel.png"); + // getting it as image object + image = toolkit.createImage(url); + + container.add(canvas, BorderLayout.CENTER); + + MediaTracker mt = new MediaTracker(container); + mt.addImage(image, 0); + try + { + mt.waitForID(0); + } + catch (InterruptedException e) + { + } + + // ################## END LOGO ################### + + // ################## BEGIN LABELS AND TEXTFIELDS ################### + + container.add(lowerpanel, BorderLayout.SOUTH); + lowerpanel.setLayout(new BorderLayout()); + lowerpanel.add(userandpassword, BorderLayout.NORTH); + double pre = TableLayout.PREFERRED; + double fill = TableLayout.FILL; + double[][] sizes = { { pre, 10, fill }, { pre, 5, pre, 5, pre, 5 } }; + TableLayout tableLayout = new TableLayout(sizes); + userandpassword.setLayout(tableLayout); + userandpassword.add(chooseLanguageLabel,"0,0"); + userandpassword.add(languageSelector, "2,0"); + userandpassword.add(usernameLabel, "0,2"); + userandpassword.add(passwordLabel, "0,4"); + userandpassword.add(username, "2,2"); + userandpassword.add(password, "2,4"); + username.setColumns(14); + password.setColumns(14); + Listener listener = new Listener(); + password.addActionListener(listener); + languageSelector.addFocusListener(listener); + guiComponent.addCopyPaste( username); + guiComponent.addCopyPaste( password ); + // ################## END LABELS AND TEXTFIELDS ################### + + // ################## BEGIN BUTTONS ################### + + // this is a separate JPanel for the buttons at the bottom + GridLayout gridLayout = new GridLayout(1, 2); + gridLayout.setHgap(20); + buttonPanel.setLayout(gridLayout); + buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + // adding a button for exiting + buttonPanel.add(exitBtn); + // and to login + buttonPanel.add(loginBtn); + setLocale(); + username.requestFocus(); + + int startupEnv = env.getStartupMode(); + if( startupEnv != StartupEnvironment.WEBSTART && startupEnv != StartupEnvironment.APPLET) { + try + { + String userName = System.getProperty("user.name"); + username.setText(userName); + username.selectAll(); + } + catch (SecurityException ex) + { + // Not sure if it is needed, to catch this. I don't know if a custom system property is by default protected in a sandbox environment + } + } + + lowerpanel.add(buttonPanel, BorderLayout.SOUTH); + + // ################## END BUTTONS ################### + + // ################## BEGIN FRAME ################### + + // these are the dimensions of the rapla picture + int picturewidth = 362; + int pictureheight = 182; + // and a border around it + int border = 10; + // canvas.setBounds(0, 0, picturewidth, pictureheight); + + this.getRootPane().setDefaultButton(loginBtn); + // with the picture dimensions as basis we determine the size + // of the frame, including some additional space below the picture + this.setSize(picturewidth + 2 * border, pictureheight + 210); + this.setResizable(false); + + // ################## END FRAME ################### + + } + + boolean closeCalledFromOutside = false; + + @Override + public void close() { + closeCalledFromOutside = true; + super.close(); + } + + protected void fireFrameClosing() throws PropertyVetoException { + super.fireFrameClosing(); + if ( !closeCalledFromOutside && exitAction != null) + { + exitAction.actionPerformed( new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "exit")); + } + } + + public String getUsername() + { + return username.getText(); + } + + public char[] getPassword() + { + return password.getPassword(); + } + + public void resetPassword() { + password.setText(""); + } + + /** overrides localeChanged from DialogUI */ + public void localeChanged(LocaleChangeEvent evt) + { + setLocale(); + } + + private I18nBundle getI18n() + { + return i18n; + } + + private void setLocale() + { + chooseLanguageLabel.setText(getI18n().getString("choose_language")); + exitBtn.setText(getI18n().getString("exit")); + loginBtn.setText(getI18n().getString("login")); + usernameLabel.setText(getI18n().getString("username") + ":"); + passwordLabel.setText(getI18n().getString("password") + ":"); + setTitle(getI18n().getString("logindialog.title")); + repaint(); + } + + public void dispose() + { + super.dispose(); + localeSelector.removeLocaleChangeListener(this); + } + + public void testEnter(String newUsername, String newPassword) + { + username.setText(newUsername); + password.setText(newPassword); + } + + class Listener extends FocusAdapter implements ActionListener + { + boolean bInit = false; + + public void focusGained(FocusEvent e) + { + if (!bInit) + { + username.requestFocus(); + bInit = true; + } + } + + public void actionPerformed(ActionEvent event) + { + if (event.getSource() == password) + { + loginBtn.doClick(); + return; + } + } + } + +} diff --git a/rapla-source-1.8.2/src/org/rapla/client/internal/RaplaClientServiceImpl.java b/rapla-source-1.8.2/src/org/rapla/client/internal/RaplaClientServiceImpl.java new file mode 100644 index 0000000..dd01535 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/client/internal/RaplaClientServiceImpl.java @@ -0,0 +1,893 @@ +/*--------------------------------------------------------------------------* +main.raplaContainer.dispose(); + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.client.internal; + +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Vector; +import java.util.concurrent.Semaphore; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; +import javax.swing.UIDefaults; +import javax.swing.UIManager; + +import org.rapla.ConnectInfo; +import org.rapla.RaplaMainContainer; +import org.rapla.client.ClientService; +import org.rapla.client.ClientServiceContainer; +import org.rapla.client.RaplaClientExtensionPoints; +import org.rapla.client.RaplaClientListener; +import org.rapla.components.calendar.DateRenderer; +import org.rapla.components.iolayer.DefaultIO; +import org.rapla.components.iolayer.IOInterface; +import org.rapla.components.iolayer.WebstartIO; +import org.rapla.components.util.Cancelable; +import org.rapla.components.util.Command; +import org.rapla.components.util.CommandScheduler; +import org.rapla.components.xmlbundle.I18nBundle; +import org.rapla.components.xmlbundle.LocaleSelector; +import org.rapla.entities.User; +import org.rapla.entities.configuration.Preferences; +import org.rapla.entities.configuration.RaplaConfiguration; +import org.rapla.entities.dynamictype.internal.AttributeImpl; +import org.rapla.facade.CalendarModel; +import org.rapla.facade.CalendarSelectionModel; +import org.rapla.facade.ClientFacade; +import org.rapla.facade.ModificationEvent; +import org.rapla.facade.ModificationListener; +import org.rapla.facade.RaplaComponent; +import org.rapla.facade.UpdateErrorListener; +import org.rapla.facade.UserModule; +import org.rapla.facade.internal.FacadeImpl; +import org.rapla.framework.Configuration; +import org.rapla.framework.DefaultConfiguration; +import org.rapla.framework.PluginDescriptor; +import org.rapla.framework.RaplaContext; +import org.rapla.framework.RaplaContextException; +import org.rapla.framework.RaplaException; +import org.rapla.framework.RaplaLocale; +import org.rapla.framework.StartupEnvironment; +import org.rapla.framework.internal.ComponentInfo; +import org.rapla.framework.internal.ContainerImpl; +import org.rapla.framework.internal.RaplaMetaConfigInfo; +import org.rapla.framework.logger.Logger; +import org.rapla.gui.AnnotationEditExtension; +import org.rapla.gui.EditController; +import org.rapla.gui.InfoFactory; +import org.rapla.gui.MenuFactory; +import org.rapla.gui.RaplaGUIComponent; +import org.rapla.gui.ReservationController; +import org.rapla.gui.TreeFactory; +import org.rapla.gui.images.Images; +import org.rapla.gui.internal.CalendarOption; +import org.rapla.gui.internal.MainFrame; +import org.rapla.gui.internal.MenuFactoryImpl; +import org.rapla.gui.internal.RaplaDateRenderer; +import org.rapla.gui.internal.RaplaStartOption; +import org.rapla.gui.internal.UserOption; +import org.rapla.gui.internal.WarningsOption; +import org.rapla.gui.internal.common.InternMenus; +import org.rapla.gui.internal.common.RaplaClipboard; +import org.rapla.gui.internal.edit.EditControllerImpl; +import org.rapla.gui.internal.edit.annotation.CategorizationAnnotationEdit; +import org.rapla.gui.internal.edit.annotation.ColorAnnotationEdit; +import org.rapla.gui.internal.edit.annotation.ConflictCreationAnnotationEdit; +import org.rapla.gui.internal.edit.annotation.EmailAnnotationEdit; +import org.rapla.gui.internal.edit.annotation.ExpectedColumnsAnnotationEdit; +import org.rapla.gui.internal.edit.annotation.ExpectedRowsAnnotationEdit; +import org.rapla.gui.internal.edit.annotation.ExportEventNameAnnotationEdit; +import org.rapla.gui.internal.edit.annotation.LocationAnnotationEdit; +import org.rapla.gui.internal.edit.annotation.ResourceTreeNameAnnotationEdit; +import org.rapla.gui.internal.edit.annotation.SortingAnnotationEdit; +import org.rapla.gui.internal.edit.reservation.ConflictReservationCheck; +import org.rapla.gui.internal.edit.reservation.DefaultReservationCheck; +import org.rapla.gui.internal.edit.reservation.ReservationControllerImpl; +import org.rapla.gui.internal.view.InfoFactoryImpl; +import org.rapla.gui.internal.view.LicenseInfoUI; +import org.rapla.gui.internal.view.TreeFactoryImpl; +import org.rapla.gui.toolkit.DialogUI; +import org.rapla.gui.toolkit.FrameControllerList; +import org.rapla.gui.toolkit.RaplaFrame; +import org.rapla.gui.toolkit.RaplaMenu; +import org.rapla.gui.toolkit.RaplaMenubar; +import org.rapla.gui.toolkit.RaplaSeparator; +import org.rapla.plugin.abstractcalendar.RaplaBuilder; +import org.rapla.storage.StorageOperator; +import org.rapla.storage.dbrm.RemoteConnectionInfo; +import org.rapla.storage.dbrm.RemoteOperator; +import org.rapla.storage.dbrm.RestartServer; +import org.rapla.storage.dbrm.StatusUpdater; + +/** Implementation of the ClientService. +*/ +public class RaplaClientServiceImpl extends ContainerImpl implements ClientServiceContainer,ClientService,UpdateErrorListener +{ + Vector listenerList = new Vector(); + I18nBundle i18n; + boolean started; + boolean restartingGUI; + String facadeName; + boolean defaultLanguageChoosen; + FrameControllerList frameControllerList; + Configuration config; + boolean logoutAvailable; + ConnectInfo reconnectInfo; + static boolean lookAndFeelSet; + CommandScheduler commandQueueWrapper; + + public RaplaClientServiceImpl(RaplaContext parentContext,Configuration config,Logger logger) throws RaplaException { + super(parentContext,config, logger); + this.config = config; + } + + @Override + protected Map getComponentInfos() { + return new RaplaMetaConfigInfo(); + } + + public static void setLookandFeel() { + if ( lookAndFeelSet ) + { + return; + } + UIDefaults defaults = UIManager.getDefaults(); + Font textFont = defaults.getFont("Label.font"); + if ( textFont == null) + { + textFont = new Font("SansSerif", Font.PLAIN, 12); + } + else + { + textFont = textFont.deriveFont( Font.PLAIN ); + } + defaults.put("Label.font", textFont); + defaults.put("Button.font", textFont); + defaults.put("Menu.font", textFont); + defaults.put("MenuItem.font", textFont); + defaults.put("RadioButton.font", textFont); + defaults.put("CheckBoxMenuItem.font", textFont); + defaults.put("CheckBox.font", textFont); + defaults.put("ComboBox.font", textFont); + defaults.put("Tree.expandedIcon",Images.getIcon("/org/rapla/gui/images/eclipse-icons/tree_minus.gif")); + defaults.put("Tree.collapsedIcon",Images.getIcon("/org/rapla/gui/images/eclipse-icons/tree_plus.gif")); + defaults.put("TitledBorder.font", textFont.deriveFont(Font.PLAIN,(float)10.)); + lookAndFeelSet = true; + } + + protected void init() throws RaplaException { + advanceLoading(false); + StartupEnvironment env = getContext().lookup(StartupEnvironment.class); + int startupMode = env.getStartupMode(); + final Logger logger = getLogger(); + if ( startupMode != StartupEnvironment.APPLET && startupMode != StartupEnvironment.WEBSTART) + { + try + { + Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + public void uncaughtException(Thread t, Throwable e) { + logger.error("uncaught exception", e); + } + }); + } + catch (Throwable ex) + { + logger.error("Can't set default exception handler-", ex); + } + } + + setLookandFeel(); + defaultLanguageChoosen = true; + getLogger().info("Starting gui "); + + super.init( ); + facadeName = m_config.getChild("facade").getValue("*"); + + addContainerProvidedComponent( WELCOME_FIELD, LicenseInfoUI.class ); + addContainerProvidedComponent( MAIN_COMPONENT, RaplaFrame.class); + + // overwrite commandqueue because we need to synchronize with swing + commandQueueWrapper = new AWTWrapper((DefaultScheduler)getContext().lookup(CommandScheduler.class)); + addContainerProvidedComponentInstance( CommandScheduler.class, commandQueueWrapper); + + addContainerProvidedComponent( RaplaClipboard.class, RaplaClipboard.class ); + addContainerProvidedComponent( TreeFactory.class, TreeFactoryImpl.class ); + addContainerProvidedComponent( MenuFactory.class, MenuFactoryImpl.class ); + addContainerProvidedComponent( InfoFactory.class, InfoFactoryImpl.class ); + addContainerProvidedComponent( EditController.class, EditControllerImpl.class ); + addContainerProvidedComponent( ReservationController.class, ReservationControllerImpl.class ); + addContainerProvidedComponent( RaplaClientExtensionPoints.USER_OPTION_PANEL_EXTENSION ,UserOption.class); + addContainerProvidedComponent( RaplaClientExtensionPoints.USER_OPTION_PANEL_EXTENSION , CalendarOption.class); + addContainerProvidedComponent( RaplaClientExtensionPoints.USER_OPTION_PANEL_EXTENSION , WarningsOption.class); + addContainerProvidedComponent( RaplaClientExtensionPoints.SYSTEM_OPTION_PANEL_EXTENSION, CalendarOption.class ); + addContainerProvidedComponent( RaplaClientExtensionPoints.SYSTEM_OPTION_PANEL_EXTENSION, RaplaStartOption.class ); + + addContainerProvidedComponent( AnnotationEditExtension.ATTRIBUTE_ANNOTATION_EDIT, ColorAnnotationEdit.class); + addContainerProvidedComponent( AnnotationEditExtension.ATTRIBUTE_ANNOTATION_EDIT, CategorizationAnnotationEdit.class); + addContainerProvidedComponent( AnnotationEditExtension.ATTRIBUTE_ANNOTATION_EDIT, ExpectedRowsAnnotationEdit.class); + addContainerProvidedComponent( AnnotationEditExtension.ATTRIBUTE_ANNOTATION_EDIT, ExpectedColumnsAnnotationEdit.class); + addContainerProvidedComponent( AnnotationEditExtension.ATTRIBUTE_ANNOTATION_EDIT, EmailAnnotationEdit.class); + addContainerProvidedComponent( AnnotationEditExtension.ATTRIBUTE_ANNOTATION_EDIT, SortingAnnotationEdit.class); + + addContainerProvidedComponent( AnnotationEditExtension.DYNAMICTYPE_ANNOTATION_EDIT, LocationAnnotationEdit.class); + addContainerProvidedComponent( AnnotationEditExtension.DYNAMICTYPE_ANNOTATION_EDIT, ConflictCreationAnnotationEdit.class); + addContainerProvidedComponent( AnnotationEditExtension.DYNAMICTYPE_ANNOTATION_EDIT, ResourceTreeNameAnnotationEdit.class); + addContainerProvidedComponent( AnnotationEditExtension.DYNAMICTYPE_ANNOTATION_EDIT, ExportEventNameAnnotationEdit.class); + + frameControllerList = new FrameControllerList(getLogger().getChildLogger("framelist")); + addContainerProvidedComponentInstance(FrameControllerList.class,frameControllerList); + + RaplaMenubar menuBar = new RaplaMenubar(); + + RaplaMenu systemMenu = new RaplaMenu( InternMenus.FILE_MENU_ROLE.getId() ); + RaplaMenu editMenu = new RaplaMenu( InternMenus.EDIT_MENU_ROLE.getId() ); + RaplaMenu viewMenu = new RaplaMenu( InternMenus.VIEW_MENU_ROLE.getId() ); + RaplaMenu helpMenu = new RaplaMenu( InternMenus.EXTRA_MENU_ROLE.getId() ); + + RaplaMenu newMenu = new RaplaMenu( InternMenus.NEW_MENU_ROLE.getId() ); + RaplaMenu settingsMenu = new RaplaMenu( InternMenus.CALENDAR_SETTINGS.getId()); + RaplaMenu adminMenu = new RaplaMenu( InternMenus.ADMIN_MENU_ROLE.getId() ); + RaplaMenu importMenu = new RaplaMenu( InternMenus.IMPORT_MENU_ROLE.getId()); + RaplaMenu exportMenu = new RaplaMenu( InternMenus.EXPORT_MENU_ROLE.getId()); + + menuBar.add( systemMenu ); + menuBar.add( editMenu ); + menuBar.add( viewMenu ); + menuBar.add( helpMenu ); + + addContainerProvidedComponentInstance( SESSION_MAP, new HashMap()); + + addContainerProvidedComponentInstance( InternMenus.MENU_BAR, menuBar); + addContainerProvidedComponentInstance( InternMenus.FILE_MENU_ROLE, systemMenu ); + addContainerProvidedComponentInstance( InternMenus.EDIT_MENU_ROLE, editMenu); + addContainerProvidedComponentInstance( InternMenus.VIEW_MENU_ROLE, viewMenu); + addContainerProvidedComponentInstance( InternMenus.ADMIN_MENU_ROLE, adminMenu); + addContainerProvidedComponentInstance( InternMenus.IMPORT_MENU_ROLE, importMenu ); + addContainerProvidedComponentInstance( InternMenus.EXPORT_MENU_ROLE, exportMenu ); + addContainerProvidedComponentInstance( InternMenus.NEW_MENU_ROLE, newMenu ); + addContainerProvidedComponentInstance( InternMenus.CALENDAR_SETTINGS, settingsMenu ); + addContainerProvidedComponentInstance( InternMenus.EXTRA_MENU_ROLE, helpMenu ); + + editMenu.add( new RaplaSeparator("EDIT_BEGIN")); + editMenu.add( new RaplaSeparator("EDIT_END")); + + addContainerProvidedComponent(RaplaClientExtensionPoints.EVENT_SAVE_CHECK, DefaultReservationCheck.class); + addContainerProvidedComponent(RaplaClientExtensionPoints.EVENT_SAVE_CHECK, ConflictReservationCheck.class); + + boolean webstartEnabled =getContext().lookup(StartupEnvironment.class).getStartupMode() == StartupEnvironment.WEBSTART; + + if (webstartEnabled) { + addContainerProvidedComponent( IOInterface.class,WebstartIO.class ); + } else { + addContainerProvidedComponent( IOInterface.class,DefaultIO.class ); + } + //Add this service to the container + addContainerProvidedComponentInstance(ClientService.class, this); + + } + + protected Runnable createTask(final Command command) { + Runnable timerTask = new Runnable() { + public void run() { + Runnable runnable = RaplaClientServiceImpl.super.createTask( command); + javax.swing.SwingUtilities.invokeLater(runnable); + } + public String toString() + { + return command.toString(); + } + }; + return timerTask; + } + + /** override to synchronize tasks with the swing event queue*/ + class AWTWrapper implements CommandScheduler + { + DefaultScheduler parent; + + public AWTWrapper(DefaultScheduler parent) { + this.parent = parent; + } + + @Override + public Cancelable schedule(Command command, long delay) { + Runnable task = createTask(command); + return parent.schedule(task, delay); + } + + @Override + public Cancelable schedule(Command command, long delay, long period) { + Runnable task = createTask(command); + return parent.schedule(task, delay, period); + } + + @Override + public Cancelable scheduleSynchronized(Object synchronizationObject, Command command, long delay) + { + Runnable task = createTask(command); + return parent.scheduleSynchronized(synchronizationObject, task, delay); + } + + public String toString() + { + return parent.toString(); + } + + } + + public ClientFacade getFacade() throws RaplaContextException { + return lookup(ClientFacade.class, facadeName); + } + + public void start(ConnectInfo connectInfo) throws Exception { + if (started) + return; + try { + getLogger().debug("RaplaClient started"); + i18n = getContext().lookup(RaplaComponent.RAPLA_RESOURCES ); + ClientFacade facade = getFacade(); + facade.addUpdateErrorListener(this); + StorageOperator operator = facade.getOperator(); + if ( operator instanceof RemoteOperator) + { + RemoteConnectionInfo remoteConnection = ((RemoteOperator) operator).getRemoteConnectionInfo(); + remoteConnection.setStatusUpdater( new StatusUpdater() + { + private Cursor waitCursor = new Cursor(Cursor.WAIT_CURSOR); + private Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR); + + public void setStatus(Status status) { + Cursor cursor =( status == Status.BUSY) ? waitCursor: defaultCursor; + frameControllerList.setCursor( cursor); + } + + } + ); + } + advanceLoading(true); + + logoutAvailable = true; + if ( connectInfo != null && connectInfo.getUsername() != null) + { + if (login( connectInfo)) + { + beginRaplaSession(); + return; + } + } + startLogin(); + } catch (Exception ex) { + throw ex; + } finally { + } + } + + protected void advanceLoading(boolean finish) { + try + { + Class LoadingProgressC= null; + Object progressBar = null; + if ( getContext().lookup(StartupEnvironment.class).getStartupMode() == StartupEnvironment.CONSOLE) + { + LoadingProgressC = getClass().getClassLoader().loadClass("org.rapla.bootstrap.LoadingProgress"); + progressBar = LoadingProgressC.getMethod("getInstance").invoke(null); + if ( finish) + { + LoadingProgressC.getMethod("close").invoke( progressBar); + } + else + { + LoadingProgressC.getMethod("advance").invoke( progressBar); + } + } + } + catch (Exception ex) + { + // Loading progress failure is not crucial to rapla excecution + } + } + + + /** + * @throws RaplaException + * + */ + private void beginRaplaSession() throws RaplaException { + initLanguage(); + ClientFacade facade = getFacade(); + addContainerProvidedComponentInstance( ClientFacade.class, facade); + + final CalendarSelectionModel model = createCalendarModel(); + addContainerProvidedComponentInstance( CalendarModel.class, model ); + addContainerProvidedComponentInstance( CalendarSelectionModel.class, model ); + StorageOperator operator = facade.getOperator(); + if ( operator instanceof RestartServer) + { + addContainerProvidedComponentInstance(RestartServer.class, (RestartServer)operator); + } + ((FacadeImpl)facade).addDirectModificationListener( new ModificationListener() { + + public void dataChanged(ModificationEvent evt) throws RaplaException { + model.dataChanged( evt ); + } + }); +// if ( facade.isClientForServer() ) +// { +// addContainerProvidedComponent (RaplaClientExtensionPoints.SYSTEM_OPTION_PANEL_EXTENSION , ConnectionOption.class); +// } + + Set pluginNames; + //List> pluginList; + try { + pluginNames = getContext().lookup( RaplaMainContainer.PLUGIN_LIST); + } catch (RaplaContextException ex) { + throw new RaplaException (ex ); + } + + List> pluginList = new ArrayList>( ); + Logger logger = getLogger().getChildLogger("plugin"); + for ( String plugin:pluginNames) + { + try { + boolean found = false; + try { + if ( plugin.toLowerCase().endsWith("serverplugin") || plugin.contains(".server.")) + { + continue; + } + Class componentClass = RaplaClientServiceImpl.class.getClassLoader().loadClass( plugin ); + Method[] methods = componentClass.getMethods(); + for ( Method method:methods) + { + if ( method.getName().equals("provideServices")) + { + Class type = method.getParameterTypes()[0]; + if (ClientServiceContainer.class.isAssignableFrom(type)) + { + found = true; + } + } + } + } catch (ClassNotFoundException ex) { + continue; + } catch (NoClassDefFoundError ex) { + getLogger().error("Error loading plugin " + plugin + " " +ex.getMessage()); + continue; + } catch (Exception e1) { + getLogger().error("Error loading plugin " + plugin + " " +e1.getMessage()); + continue; + } + if ( found ) + { + @SuppressWarnings("unchecked") + PluginDescriptor descriptor = (PluginDescriptor) instanciate(plugin, null, logger); + pluginList.add(descriptor); + logger.info("Installed plugin "+plugin); + } + } catch (RaplaContextException e) { + if (e.getCause() instanceof ClassNotFoundException) { + logger.error("Could not instanciate plugin "+ plugin, e); + } + } + } + addContainerProvidedComponentInstance(ClientServiceContainer.CLIENT_PLUGIN_LIST, pluginList); + initializePlugins( pluginList, facade.getSystemPreferences() ); + + // Add daterender if not provided by the plugins + if ( !getContext().has( DateRenderer.class)) + { + addContainerProvidedComponent( DateRenderer.class, RaplaDateRenderer.class ); + } + started = true; + User user = model.getUser(); + boolean showToolTips = facade.getPreferences( user ).getEntryAsBoolean( RaplaBuilder.SHOW_TOOLTIP_CONFIG_ENTRY, true); + javax.swing.ToolTipManager.sharedInstance().setEnabled(showToolTips); + //javax.swing.ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false); + javax.swing.ToolTipManager.sharedInstance().setInitialDelay( 1000 ); + javax.swing.ToolTipManager.sharedInstance().setDismissDelay( 10000 ); + javax.swing.ToolTipManager.sharedInstance().setReshowDelay( 0 ); + JPopupMenu.setDefaultLightWeightPopupEnabled(false); + + RaplaFrame mainComponent = getContext().lookup( MAIN_COMPONENT ); + mainComponent.addWindowListener(new WindowAdapter() { + public void windowClosed(WindowEvent e) { + try { + if ( !isRestartingGUI()) { + stop(); + } else { + restartingGUI = false; + } + } catch (Exception ex) { + getLogger().error(ex.getMessage(),ex); + } + } + + }); + MainFrame mainFrame = new MainFrame( getContext()); + fireClientStarted(); + mainFrame.show(); + + } + + private void initLanguage() throws RaplaException, RaplaContextException + { + ClientFacade facade = getFacade(); + if ( !defaultLanguageChoosen) + { + Preferences prefs = facade.edit(facade.getPreferences()); + RaplaLocale raplaLocale = getContext().lookup(RaplaLocale.class ); + String currentLanguage = raplaLocale.getLocale().getLanguage(); + prefs.putEntry( RaplaLocale.LANGUAGE_ENTRY, currentLanguage); + try + { + facade.store( prefs); + } + catch (Exception e) + { + getLogger().error("Can't store language change", e); + } + } + else + { + String language = facade.getPreferences().getEntryAsString( RaplaLocale.LANGUAGE_ENTRY, null); + if ( language != null) + { + LocaleSelector localeSelector = getContext().lookup(LocaleSelector.class); + localeSelector.setLanguage( language ); + } + } + AttributeImpl.TRUE_TRANSLATION.setName(i18n.getLang(), i18n.getString("yes")); + AttributeImpl.FALSE_TRANSLATION.setName(i18n.getLang(), i18n.getString("no")); + } + + protected void initializePlugins(List> pluginList, Preferences preferences) throws RaplaException { + RaplaConfiguration raplaConfig =preferences.getEntry(RaplaComponent.PLUGIN_CONFIG); + // Add plugin configs + for ( Iterator> it = pluginList.iterator(); it.hasNext(); ) { + PluginDescriptor pluginDescriptor = it.next(); + String pluginClassname = pluginDescriptor.getClass().getName(); + Configuration pluginConfig = null; + if ( raplaConfig != null) { + pluginConfig = raplaConfig.find("class", pluginClassname); + } + if ( pluginConfig == null) { + pluginConfig = new DefaultConfiguration("plugin"); + } + pluginDescriptor.provideServices( this, pluginConfig ); + } + + //Collection clientPlugins = getAllServicesForThisContainer(RaplaExtensionPoints.CLIENT_EXTENSION); + // start plugins + getAllServicesForThisContainer(RaplaClientExtensionPoints.CLIENT_EXTENSION); + // for (Iterator it = clientPlugins.iterator();it.hasNext();) { +// String hint = (String) it.next(); +// try { +// getContext().lookup( RaplaExtensionPoints.CLIENT_EXTENSION , hint); +// getLogger().info( "Initialize " + hint ); +// } catch (RaplaContextException ex ) { +// getLogger().error( "Can't initialize " + hint, ex ); +// } +// } + } + + public boolean isRestartingGUI() + { + return restartingGUI; + } + + public void addRaplaClientListener(RaplaClientListener listener) { + listenerList.add(listener); + } + + public void removeRaplaClientListener(RaplaClientListener listener) { + listenerList.remove(listener); + } + + public RaplaClientListener[] getRaplaClientListeners() { + return listenerList.toArray(new RaplaClientListener[]{}); + } + + protected void fireClientClosed(ConnectInfo reconnect) { + RaplaClientListener[] listeners = getRaplaClientListeners(); + for (int i=0;i +

+The client package is responsible for initialize the gui +and the client-plugins and providing the services for the +client application. +

+ + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendar/AbstractBlockField.java b/rapla-source-1.8.2/src/org/rapla/components/calendar/AbstractBlockField.java new file mode 100644 index 0000000..d48f15c --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendar/AbstractBlockField.java @@ -0,0 +1,457 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendar; + +import java.awt.Component; +import java.awt.MouseInfo; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.util.ArrayList; + +import javax.swing.InputVerifier; +import javax.swing.JComponent; +import javax.swing.JTextField; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import javax.swing.text.PlainDocument; + +/** The base class for TextFields that supports entering values in + blocks. Most notifiably the DateField and the TimeField.
You + can use the left/right arrow keys to switch the blocks. Use of the + top/down arrow keys will increase/decrease the values in the + selected block (page_up/page_down for major changes). You can + specify maximum length for each block. If a block reaches this + maximum value the focus will switch to the next block. + @see DateField + @see TimeField + */ +public abstract class AbstractBlockField extends JTextField { + private static final long serialVersionUID = 1L; + int m_markedBlock = 0; + char m_lastChar = 0; + boolean m_keyPressed = false; + protected String m_oldText; + + ArrayList m_listenerList = new ArrayList(); + + public AbstractBlockField() { + Listener listener = new Listener(); + addMouseListener(listener); + addActionListener(listener); + addFocusListener(listener); + addKeyListener(listener); + addMouseWheelListener( listener ); + setInputVerifier(new InputVerifier() { + public boolean verify(JComponent comp) { + boolean valid = blocksValid(); + if ( valid ) + { + fireValueChanged(); + } + return valid; + } + }); + } + + class Listener implements MouseListener,KeyListener,FocusListener,ActionListener, MouseWheelListener { + public void mouseReleased(MouseEvent evt) { + } + public void mousePressed(MouseEvent evt) { + if ( !isMouseOverComponent()) + { + blocksValid(); + fireValueChanged(); + } + if ( evt.getButton() != MouseEvent.BUTTON1) + { + return; + } + // We have to mark the block on mouse pressed and mouse clicked. + // Windows needs mouse clicked while Linux needs mouse pressed. + markCurrentBlock(); + } + public void mouseEntered(MouseEvent me) { + } + public void mouseExited(MouseEvent me) { + blocksValid(); + fireValueChanged(); + } + public void mouseClicked(MouseEvent evt) { + if ( evt.getButton() != MouseEvent.BUTTON1) + { + return; + } + // We have to mark the block on mouse pressed and mouse clicked. + markCurrentBlock(); + if (evt.getClickCount()>1) { + selectAll(); + return; + } + if (blocksValid()) { + fireValueChanged(); + } + } + + // Implementation of ActionListener + public void actionPerformed(ActionEvent e) { + blocksValid(); + fireValueChanged(); + } + + public void focusGained(FocusEvent evt) { + if (blocksValid()) { + //setBlock(0); + } + } + public void focusLost(FocusEvent evt) { + //select(-1,-1); + blocksValid(); + fireValueChanged(); + } + + public void keyPressed(KeyEvent evt) { + m_keyPressed = true; + m_lastChar=evt.getKeyChar(); + if (!blocksValid()) + return; + if (isSeparator(evt.getKeyChar())) { + evt.consume(); + return; + } + switch (evt.getKeyCode()) { + case KeyEvent.VK_LEFT: + case KeyEvent.VK_KP_LEFT: + if (blockCount() >1) { + setBlock(-1); + evt.consume(); + } + return; + case KeyEvent.VK_KP_RIGHT: + case KeyEvent.VK_RIGHT: + if (blockCount() >1) { + setBlock(1); + evt.consume(); + } + return; + case KeyEvent.VK_HOME: + setBlock(-1000); + evt.consume(); + return; + case KeyEvent.VK_END: + setBlock(1000); + evt.consume(); + return; + case KeyEvent.VK_KP_UP: + case KeyEvent.VK_UP: + changeSelectedBlock(1); + evt.consume(); + return; + case KeyEvent.VK_KP_DOWN: + case KeyEvent.VK_DOWN: + changeSelectedBlock(-1); + evt.consume(); + return; + case KeyEvent.VK_PAGE_UP: + changeSelectedBlock(10); + evt.consume(); + return; + case KeyEvent.VK_PAGE_DOWN: + changeSelectedBlock(-10); + evt.consume(); + return; + } + + } + + public void keyReleased(KeyEvent evt) { + m_lastChar=evt.getKeyChar(); + // Only change the block if the keyReleased + // event follows a keyPressed. + // If you type very quickly you could + // get two strunged keyReleased events + if (m_keyPressed == true) + m_keyPressed = false; + else + return; + if (!blocksValid()) + return; + if (isSeparator(m_lastChar) ) { + if ( isSeparator( getText().charAt(getCaretPosition()))) + nextBlock(); + evt.consume(); + } else if (isValidChar(m_lastChar)) { + advance(); + evt.consume(); + if (blocksValid() && !isMouseOverComponent()) + { +// fireValueChanged(); + } + } + } + + private boolean isMouseOverComponent() + { + Component comp = AbstractBlockField.this; + Point compLoc = comp.getLocationOnScreen(); + Point mouseLoc = MouseInfo.getPointerInfo().getLocation(); + boolean result = (mouseLoc.x >= compLoc.x && mouseLoc.x <= compLoc.x + comp.getWidth() + && mouseLoc.y >= compLoc.y && mouseLoc.y <= compLoc.y + comp.getHeight()); + return result; + } + + public void keyTyped(KeyEvent evt) { + } + + + public void mouseWheelMoved(MouseWheelEvent e) { + if (!hasFocus()) + { + return; + } + if (!blocksValid() || e == null) + return; + int count = e.getWheelRotation(); + changeSelectedBlock(-1 * count/(Math.abs(count))); + + } + } + + private void markCurrentBlock() { + if (!blocksValid()) { + return; + } + int blockstart[] = new int[blockCount()]; + int block = calcBlocks(blockstart); + markBlock(blockstart,block); + } + + public void addChangeListener(ChangeListener listener) { + m_listenerList.add(listener); + } + + /** removes a listener from this component.*/ + public void removeChangeListener(ChangeListener listener) { + m_listenerList.remove(listener); + } + + public ChangeListener[] getChangeListeners() { + return m_listenerList.toArray(new ChangeListener[]{}); + } + + /** A ChangeEvent will be fired to every registered ActionListener + * when the value has changed. + */ + protected void fireValueChanged() { + if (m_listenerList.size() == 0) + return; + + // Only fire, when text has changed. + if (m_oldText != null && m_oldText.equals(getText())) + return; + m_oldText = getText(); + + ChangeEvent evt = new ChangeEvent(this); + ChangeListener[] listeners = getChangeListeners(); + for (int i = 0; i= blockCount() -1) + return; + int selectedLen = (block ==0) ? blockstart[1] : (blockstart[block + 1] - blockstart[block] - 1); + if (selectedLen == maxBlockLength(block)) { + markBlock(blockstart,Math.min(block + 1,blockCount() -1)); + } + } + + /** changes the value of the selected Block. Adds the count value. */ + private void changeSelectedBlock(int count) { + int blockstart[] = new int[blockCount()]; + int block = calcBlocks(blockstart); + int start = (block == 0) ? 0 : blockstart[block] + 1; + int end = (block == blockCount() -1) ? getText().length() : blockstart[block+1]; + String selected = getText().substring(start,end); + markBlock(blockstart,block); + changeSelectedBlock(blockstart,block,selected,count); + } + + private void setBlock(int count) { + if (blockCount()<1) + return; + int blockstart[] = new int[blockCount()]; + int block = calcBlocks(blockstart); + if (count !=0) + markBlock(blockstart,Math.min(Math.max(0,block + count),blockCount()-1)); + else + markBlock(blockstart,m_markedBlock); + } + + + /** Select the specified block. */ + final protected void markBlock(int[] blockstart,int block) { + m_markedBlock = block; + if (m_markedBlock == 0) + mark(blockstart[0], (blockCount()>1) ? blockstart[1] : getText().length()); + else if (m_markedBlock==blockCount()-1) + mark(blockstart[m_markedBlock] + 1,getText().length()); + else + mark(blockstart[m_markedBlock] + 1,blockstart[m_markedBlock+1]); + } + + private boolean isPrevSeparator(int i,char[] source,String currentText,int offs) { + return (i>0 && isSeparator(source[i-1]) + || (offs > 0 && isSeparator(currentText.charAt(offs-1)))); + } + private boolean isNextSeparator(String currentText,int offs) { + return (offs < currentText.length()-1 && isSeparator(currentText.charAt(offs))); + } + + class DateDocument extends PlainDocument { + private static final long serialVersionUID = 1L; + + public void insertString(int offs, String str, AttributeSet a) + throws BadLocationException { + String currentText = getText(0, getLength()); + char[] source = str.toCharArray(); + char[] result = new char[source.length]; + int j = 0; + boolean bShouldBeep = false; + for (int i = 0; i < source.length; i++) { + boolean bValid = true; + if (!isValidChar(source[i])) { + bValid = false; + } else { + //if (offs < currentText.length()-1) + //System.out.println("offset-char: " + currentText.charAt(offs)); +// + if (isSeparator(source[i])) + if (isNextSeparator(currentText,offs) + || isPrevSeparator(i,source,currentText,offs) + || (i==0 && offs==0) + || (i==source.length && offs==currentText.length()) + ) + { + // beep(); + continue; + } + } + if (bValid) + result[j++] = source[i]; + else + bShouldBeep = true; + } + if (bShouldBeep) + beep(); + super.insertString(offs, new String(result, 0, j), a); + } + public void remove(int offs, int len) + throws BadLocationException { + if (m_lastChar == 0 + || (!isSeparator(m_lastChar) + && (isValidChar(m_lastChar) + || !Character.isLetter(m_lastChar)) + ) + ) + super.remove(offs, len); + } + } + + final protected Document createDefaultModel() { + return new DateDocument(); + } + + /** Calculate the blocks. The new blockstarts will be stored in + the int array. + @return the block that contains the caret. + */ + protected int calcBlocks(int[] blockstart) { + String text = getText(); + int dot = getCaretPosition(); + int block = 0; + blockstart[0] = 0; + char[] separators = getSeparators(); + for (int i=1;i=0 && pos < min) + min = pos; + } + blockstart[i] = min; + if (dot>blockstart[i]) + block = i; + } + return block; + } + + /** Select the text from dot to mark. */ + protected void mark(int dot,int mark) { + setCaretPosition(mark); + moveCaretPosition(dot); + } + + /** this method will be called when an non-valid character is entered. */ + protected void beep() { + Toolkit.getDefaultToolkit().beep(); + } + + /** returns true if the text can be split into blocks. */ + abstract public boolean blocksValid(); + /** The number of blocks for this Component. */ + abstract protected int blockCount(); + /** This method will be called, when the user has pressed the up/down + * arrows on a selected block. + * @param count Posible values are 1,-1,10,-10. + */ + abstract protected void changeSelectedBlock(int[] blocks,int block,String selected,int count); + /** returns the maximum length of the specified block. */ + abstract protected int maxBlockLength(int block); + /** returns true if the character should be accepted by the component. */ + abstract protected boolean isValidChar(char c); + /** returns true if the character is a block-separator. All block-separators must + be valid characters. + @see #isValidChar + */ + abstract protected boolean isSeparator(char c); + /** @return all seperators.*/ + abstract protected char[] getSeparators(); + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendar/ArrowPolygon.java b/rapla-source-1.8.2/src/org/rapla/components/calendar/ArrowPolygon.java new file mode 100644 index 0000000..34e630d --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendar/ArrowPolygon.java @@ -0,0 +1,78 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.calendar; +import java.awt.Polygon; + +/* + The following classes are only responsible to paint the Arrows for the NavButton. +*/ + +class ArrowPolygon extends Polygon { + private static final long serialVersionUID = 1L; + + public ArrowPolygon(char type,int width) { + this(type,width,true); + } + + public ArrowPolygon(char type,int width,boolean border) { + int polyWidth = ((width - 7) / 8); + polyWidth = (polyWidth + 1) * 8; + int dif = border ? (width - polyWidth) /2 : 0; + int half = polyWidth / 2 + dif; + int insets = (polyWidth == 8) ? 0 : polyWidth / 4; + int start = insets + dif; + int full = polyWidth - insets + dif; + int size = (polyWidth == 8) ? polyWidth / 4 : polyWidth / 8; + + if ( type == '>') { + addPoint(half - size,start); + addPoint(half + size,half); + addPoint(half - size,full); + } // end of if () + + if ( type == '<') { + addPoint(half + size,start); + addPoint(half - size,half); + addPoint(half + size,full); + } // end of if () + + if ( type == '^') { + addPoint(start,half + size); + addPoint(half,half - size); + addPoint(full,half + size); + } // end of if () + + if ( type == 'v') { + addPoint(start,half - size); + addPoint(half,half + size); + addPoint(full,half - size); + } // end of if () + + if ( type == '-') { + addPoint(start + 1,half - 1); + addPoint(full - 3,half - 1); + } // end of if () + + if ( type == '+') { + addPoint(start + 1,half - 1); + addPoint(full - 3,half - 1); + addPoint(half -1,half - 1); + addPoint(half- 1, half - (size + 1)); + addPoint(half -1,half + ( size -1)); + addPoint(half -1,half - 1); + } // end of if () + + } +} + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendar/CalendarMenu.java b/rapla-source-1.8.2/src/org/rapla/components/calendar/CalendarMenu.java new file mode 100644 index 0000000..35def5a --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendar/CalendarMenu.java @@ -0,0 +1,378 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.calendar; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Date; +import java.util.TimeZone; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.MenuElement; +import javax.swing.MenuSelectionManager; +import javax.swing.border.Border; +import javax.swing.border.EmptyBorder; +import javax.swing.border.LineBorder; +/** The graphical date-selection field with month and year incerement/decrement buttons. + * @author Christopher Kohlhaas + */ + + +public class CalendarMenu extends JPanel implements MenuElement { + private static final long serialVersionUID = 1L; + + static Color BACKGROUND_COLOR = Color.white; + static Border FOCUSBORDER = new LineBorder(DaySelection.FOCUSCOLOR,1); + static Border EMPTYBORDER = new EmptyBorder(1,1,1,1); + BorderLayout borderLayout1 = new BorderLayout(); + + JPanel topSelection = new JPanel(); + Border border1 = BorderFactory.createEtchedBorder(); + BorderLayout borderLayout2 = new BorderLayout(); + JPanel monthSelection = new JPanel(); + NavButton jPrevMonth = new NavButton('<'); + JLabel labelMonth = new JLabel(); + NavButton jNextMonth = new NavButton('>'); + JPanel yearSelection = new JPanel(); + NavButton jPrevYear = new NavButton('<'); + JLabel labelYear = new JLabel(); + NavButton jNextYear = new NavButton('>'); + + protected DaySelection daySelection; + JLabel labelCurrentDay = new JLabel(); + JButton focusButton = new JButton() { + private static final long serialVersionUID = 1L; + + public void paint(Graphics g) { + Dimension size = getSize(); + g.setColor(getBackground()); + g.fillRect(0,0,size.width,size.height); + } + }; + + + + DateModel m_model; + DateModel m_focusModel; + + String[] m_monthNames; + boolean m_focusable = true; + + public CalendarMenu(DateModel newModel) { + m_model = newModel; + + m_monthNames = createMonthNames(); + + m_focusModel = new DateModel(newModel.getLocale(),newModel.getTimeZone()); + daySelection = new DaySelection(newModel,m_focusModel); + + initGUI(); + Listener listener = new Listener(); + + jPrevMonth.addActionListener(listener); + jPrevMonth.setBorder( null ); + jNextMonth.addActionListener(listener); + jNextMonth.setBorder( null ); + jPrevYear.addActionListener(listener); + jPrevYear.setBorder( null ); + jNextYear.addActionListener(listener); + jNextYear.setBorder( null ); + + jPrevMonth.setFocusable( false ); + jNextMonth.setFocusable( false ); + jPrevYear.setFocusable( false ); + jNextYear.setFocusable( false ); + + this.addMouseListener(listener); + jPrevMonth.addMouseListener(listener); + jNextMonth.addMouseListener(listener); + jPrevYear.addMouseListener(listener); + jNextYear.addMouseListener(listener); + labelCurrentDay.addMouseListener(listener); + daySelection.addMouseListener(listener); + labelCurrentDay.addMouseListener(listener); + m_model.addDateChangeListener(listener); + m_focusModel.addDateChangeListener(listener); + focusButton.addKeyListener(listener); + + focusButton.addFocusListener(listener); + calculateSizes(); + m_focusModel.setDate(m_model.getDate()); + } + + class Listener implements ActionListener,MouseListener,FocusListener,DateChangeListener,KeyListener { + public void actionPerformed(ActionEvent evt) { + if ( evt.getSource() == jNextMonth) { + m_focusModel.addMonth(1); + } // end of if () + + if ( evt.getSource() == jPrevMonth) { + m_focusModel.addMonth(-1); + } // end of if () + + if ( evt.getSource() == jNextYear) { + m_focusModel.addYear(1); + } // end of if () + + if ( evt.getSource() == jPrevYear) { + m_focusModel.addYear(-1); + } // end of if () + } + + // Implementation of DateChangeListener + public void dateChanged(DateChangeEvent evt) { + if (evt.getSource() == m_model) { + m_focusModel.setDate(evt.getDate()); + } else { + updateFields(); + } + } + // Implementation of MouseListener + public void mousePressed(MouseEvent me) { + if (me.getSource() == labelCurrentDay) { + // Set the current day as sellected day + m_model.setDate(new Date()); + } else { + if (m_focusable && !focusButton.hasFocus()) + focusButton.requestFocus(); + } + } + public void mouseClicked(MouseEvent me) { + } + public void mouseReleased(MouseEvent me) { + } + public void mouseEntered(MouseEvent me) { + } + public void mouseExited(MouseEvent me) { + } + + // Implementation of KeyListener + public void keyPressed(KeyEvent e) { + processCalendarKey(e); + } + public void keyReleased(KeyEvent e) { + } + public void keyTyped(KeyEvent e) { + } + + // Implementation of FocusListener + public void focusGained(FocusEvent e) { + if (e.getSource() == focusButton) + setBorder(FOCUSBORDER); + else + transferFocus(); + } + public void focusLost(FocusEvent e) { + if (e.getSource() == focusButton) + setBorder(EMPTYBORDER); + } + } + + private void updateFields() { + labelCurrentDay.setText(m_focusModel.getCurrentDateString()); + labelMonth.setText(m_monthNames[m_focusModel.getMonth() -1]); + labelYear.setText(m_focusModel.getYearString()); + } + + public DateModel getModel() { + return m_model; + } + + public boolean hasFocus() { + return focusButton.hasFocus(); + } + + public boolean isFocusable() { + return m_focusable; + } + + public void setFocusable(boolean m_focusable) { + this.m_focusable = m_focusable; + } + + // #TODO Property change listener for TimeZone + public void setTimeZone(TimeZone timeZone) { + m_focusModel.setTimeZone(timeZone); + } + + public void setFont(Font font) { + super.setFont(font); + // Method called during constructor? + if (labelMonth == null || font == null) + return; + labelMonth.setFont(font); + labelYear.setFont(font); + daySelection.setFont(font); + labelCurrentDay.setFont(font); + calculateSizes(); + invalidate(); + } + + public void requestFocus() { + if (m_focusable) + focusButton.requestFocus(); + } + + public DaySelection getDaySelection() { + return daySelection; + } + + private void calculateSizes() { + // calculate max size of month names + int maxWidth =0; + FontMetrics fm = getFontMetrics(labelMonth.getFont()); + for (int i=0;i< m_monthNames.length;i++) { + int len = fm.stringWidth(m_monthNames[i]); + if (len>maxWidth) + maxWidth = len; + } + labelMonth.setPreferredSize(new Dimension(maxWidth,fm.getHeight())); + int h = fm.getHeight(); + jPrevMonth.setSize(h,h); + jNextMonth.setSize(h,h); + jPrevYear.setSize(h,h); + jNextYear.setSize(h,h); + // Workaraund for focus-bug in JDK 1.3.1 + Border dummyBorder = new EmptyBorder(fm.getHeight(),0,0,0); + focusButton.setBorder(dummyBorder); + } + + private void initGUI() { + setBorder(EMPTYBORDER); + topSelection.setLayout(borderLayout2); + topSelection.setBorder(border1); + daySelection.setBackground(BACKGROUND_COLOR); + + FlowLayout flowLayout = new FlowLayout(FlowLayout.LEFT,0,0); + monthSelection.setLayout(flowLayout); + monthSelection.add(focusButton); + monthSelection.add(jPrevMonth); + monthSelection.add(labelMonth); + monthSelection.add(jNextMonth); + + yearSelection.setLayout(flowLayout); + yearSelection.add(jPrevYear); + yearSelection.add(labelYear); + yearSelection.add(jNextYear); + + topSelection.add(monthSelection,BorderLayout.WEST); + topSelection.add(yearSelection,BorderLayout.EAST); + + setLayout(borderLayout1); + add(topSelection,BorderLayout.NORTH); + add(daySelection,BorderLayout.CENTER); + add(labelCurrentDay,BorderLayout.SOUTH); + } + + private String[] createMonthNames( ) { + Calendar calendar = Calendar.getInstance(m_model.getLocale()); + calendar.setLenient(true); + Collection monthNames = new ArrayList(); + SimpleDateFormat format = new SimpleDateFormat("MMM",m_model.getLocale()); + int firstMonth = 0; + int month = 0; + while (true) { + calendar.set(Calendar.DATE,1); + calendar.set(Calendar.MONTH,month); + if (month == 0) + firstMonth = calendar.get(Calendar.MONTH); + else + if (calendar.get(Calendar.MONTH) == firstMonth) + break; + monthNames.add(format.format(calendar.getTime())); + month ++; + } + return monthNames.toArray(new String[0]); + } + + private void processCalendarKey(KeyEvent e) { + switch (e.getKeyCode()) { + case (KeyEvent.VK_KP_UP): + case (KeyEvent.VK_UP): + m_focusModel.addDay(-7); + break; + case (KeyEvent.VK_KP_DOWN): + case (KeyEvent.VK_DOWN): + m_focusModel.addDay(7); + break; + case (KeyEvent.VK_KP_LEFT): + case (KeyEvent.VK_LEFT): + m_focusModel.addDay(-1); + break; + case (KeyEvent.VK_KP_RIGHT): + case (KeyEvent.VK_RIGHT): + m_focusModel.addDay(1); + break; + case (KeyEvent.VK_PAGE_DOWN): + m_focusModel.addMonth(1); + break; + case (KeyEvent.VK_PAGE_UP): + m_focusModel.addMonth(-1); + break; + case (KeyEvent.VK_ENTER): + m_model.setDate(m_focusModel.getDate()); + break; + case (KeyEvent.VK_SPACE): + m_model.setDate(m_focusModel.getDate()); + break; + } + } + + // Start of MenuElement implementation + public Component getComponent() { + return this; + } + public MenuElement[] getSubElements() { + return new MenuElement[0]; + } + + public void menuSelectionChanged(boolean isIncluded) { + } + + public void processKeyEvent(KeyEvent event, MenuElement[] path, MenuSelectionManager manager) { + if (event.getID() == KeyEvent.KEY_PRESSED) + processCalendarKey(event); + switch (event.getKeyCode()) { + case (KeyEvent.VK_ENTER): + case (KeyEvent.VK_ESCAPE): + manager.clearSelectedPath(); + } + event.consume(); + } + + public void processMouseEvent(MouseEvent event, MenuElement[] path, MenuSelectionManager manager) { + } + // End of MenuElement implementation +} + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendar/DEPENDENCIES b/rapla-source-1.8.2/src/org/rapla/components/calendar/DEPENDENCIES new file mode 100644 index 0000000..44dc11a --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendar/DEPENDENCIES @@ -0,0 +1,3 @@ +This component depends on the following packages (including subpackages): +java.* +javax.swing.* diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendar/DateChangeEvent.java b/rapla-source-1.8.2/src/org/rapla/components/calendar/DateChangeEvent.java new file mode 100644 index 0000000..b424b18 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendar/DateChangeEvent.java @@ -0,0 +1,28 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.calendar; +import java.util.Date; +import java.util.EventObject; +public class DateChangeEvent extends EventObject { + private static final long serialVersionUID = 1L; + + Date m_date; + public DateChangeEvent(Object source,Date date) { + super(source); + m_date = date; + } + public Date getDate() { + return m_date; + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendar/DateChangeListener.java b/rapla-source-1.8.2/src/org/rapla/components/calendar/DateChangeListener.java new file mode 100644 index 0000000..2f7831d --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendar/DateChangeListener.java @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.calendar; +/* The components that implement DateChangeListener + * get notified by the DateModel if the date has been changed + */ +public interface DateChangeListener extends java.util.EventListener { + public void dateChanged(DateChangeEvent evt); +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendar/DateField.java b/rapla-source-1.8.2/src/org/rapla/components/calendar/DateField.java new file mode 100644 index 0000000..3199930 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendar/DateField.java @@ -0,0 +1,348 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendar; + +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.event.MouseEvent; +import java.text.DateFormat; +import java.text.FieldPosition; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import org.rapla.components.calendar.DateRenderer.RenderingInfo; +/** The DateField only accepts characters that are part of + * DateFormat.getDateInstance(DateFormat.SHORT,locale). The + * inputblocks are [date,month,year]. The order of the input-blocks is + * determined by the locale. You can use the keyboard to navigate + * between the blocks or to increment/decrement the blocks. + * @see AbstractBlockField + */ + +final public class DateField extends AbstractBlockField { + private static final long serialVersionUID = 1L; + + private DateFormat m_outputFormat; + private DateFormat m_parsingFormat; + private Calendar m_calendar; + private int m_rank[] = null; + private char[] m_separators; + private SimpleDateFormat m_weekdayFormat; + private boolean m_weekdaysVisible = true; + private DateRenderer m_dateRenderer; + /** stores the y-coordinate of the weekdays display field*/ + private int m_weekdaysX; + private boolean nullValuePossible; + private boolean nullValue; + RenderingInfo renderingInfo; + + public boolean isNullValue() { + return nullValue; + } + + public void setNullValue(boolean nullValue) { + this.nullValue = nullValue; + } + + public boolean isNullValuePossible() + { + return nullValuePossible; + } + + public void setNullValuePossible(boolean nullValuePossible) + { + this.nullValuePossible = nullValuePossible; + } + + public DateField() { + this(Locale.getDefault(),TimeZone.getDefault()); + } + + public DateField(Locale locale,TimeZone timeZone) { + super(); + m_calendar = Calendar.getInstance(timeZone, locale); + super.setLocale(locale); + setFormat(); + setDate(new Date()); + } + + + /** you can choose, if weekdays should be displayed in the right corner of the DateField. + Default is true. + */ + public void setWeekdaysVisible(boolean m_weekdaysVisible) { + this.m_weekdaysVisible = m_weekdaysVisible; + } + + /** sets the DateRenderer for the calendar */ + public void setDateRenderer(DateRenderer dateRenderer) { + m_dateRenderer = dateRenderer; + } + + private void setFormat() { + m_parsingFormat = DateFormat.getDateInstance(DateFormat.SHORT, getLocale()); + m_weekdayFormat = new SimpleDateFormat("EE", getLocale()); + TimeZone timeZone = getTimeZone(); + m_parsingFormat.setTimeZone(timeZone); + m_weekdayFormat.setTimeZone(timeZone); + + String formatStr = m_parsingFormat.format(m_calendar.getTime()); + FieldPosition datePos = new FieldPosition(DateFormat.DATE_FIELD); + FieldPosition monthPos = new FieldPosition(DateFormat.MONTH_FIELD); + FieldPosition yearPos = new FieldPosition(DateFormat.YEAR_FIELD); + m_parsingFormat.format(m_calendar.getTime(), new StringBuffer(),datePos); + m_parsingFormat.format(m_calendar.getTime(), new StringBuffer(),monthPos); + m_parsingFormat.format(m_calendar.getTime(), new StringBuffer(),yearPos); + + int mp = monthPos.getBeginIndex(); + int dp = datePos.getBeginIndex(); + int yp = yearPos.getBeginIndex(); + int pos[] = null; + // System.out.println(formatStr + " day:"+dp+" month:"+mp+" year:"+yp); + if (mp<0 || dp<0 || yp<0) { + throw new IllegalArgumentException("Can't parse the date-format for this locale"); + } + // quick and diry sorting + if (dp= m_weekdaysX) + return super.getToolTipText(event); + return null; + } + + public boolean blocksValid() { + String dateTxt = null; + try { + dateTxt = getText(); + if ( isNullValuePossible() && dateTxt.length() == 0) + { + nullValue = true; + return true; + } + m_calendar.setTime(m_parsingFormat.parse(dateTxt)); + nullValue = false; + return true; + } catch (ParseException e) { + return false; + } + } + + static int[] BLOCKLENGTH = new int[] {2,2,5}; + + protected int blockCount() { + return BLOCKLENGTH.length; + } + + protected void mark(int dot,int mark) { + super.mark(dot,mark); + if (!m_weekdaysVisible) + repaint(); + } + + protected int maxBlockLength(int block) { + return BLOCKLENGTH[block]; + } + + protected boolean isValidChar(char c) { + return (Character.isDigit(c) || isSeparator(c) ); + } + + /** This method is necessary to shorten the names down to 2 characters. + Some date-formats ignore the setting. + */ + private String small(String string) { + return string.substring(0,Math.min(string.length(),2)); + } + + public void paint(Graphics g) { + super.paint(g); + if (!m_weekdaysVisible) + return; + Insets insets = getInsets(); + final String format = nullValue ? "" :m_weekdayFormat.format(m_calendar.getTime()); + String s = small(format); + FontMetrics fm = g.getFontMetrics(); + int width = fm.stringWidth(s); + int x = getWidth()-width-insets.right-3; + m_weekdaysX = x; + int y = insets.top + (getHeight() - (insets.bottom + insets.top))/2 + fm.getAscent()/3; + g.setColor(Color.gray); + if (renderingInfo != null) { + + Color color = renderingInfo.getBackgroundColor(); + if (color != null) { + g.setColor(color); + g.fillRect(x-1, insets.top, width + 3 , getHeight() - insets.bottom - insets.top - 1); + } + color = renderingInfo.getForegroundColor(); + if (color != null) { + g.setColor(color); + } + else + { + g.setColor(Color.GRAY); + } + } + g.drawString(s,x,y); + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendar/DateModel.java b/rapla-source-1.8.2/src/org/rapla/components/calendar/DateModel.java new file mode 100644 index 0000000..64e1c78 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendar/DateModel.java @@ -0,0 +1,210 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.calendar; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Locale; +import java.util.TimeZone; + +/** + * The model of the obligatory MVC approach is a wrapper arround an + * Calendar object. + */ +final class DateModel { + private Calendar m_calendar; + private int m_daysMonth; + private int m_daysLastMonth; + private int m_firstWeekday; + private Locale m_locale; + private DateFormat m_yearFormat; + private DateFormat m_currentDayFormat; + + ArrayList listenerList = new ArrayList(); + + public DateModel(Locale locale,TimeZone timeZone) { + m_locale = locale; + m_calendar = Calendar.getInstance(timeZone,m_locale); + trim(m_calendar); + m_yearFormat = new SimpleDateFormat("yyyy", m_locale); + m_yearFormat.setTimeZone(timeZone); + m_currentDayFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, m_locale); + m_currentDayFormat.setTimeZone(timeZone); + m_calendar.setLenient(true); + recalculate(); + } + + public boolean sameDate(Date date) { + Calendar calendar2 = Calendar.getInstance(m_locale); + TimeZone timeZone = getTimeZone(); + calendar2.setTimeZone(timeZone); + calendar2.setTime(date); + trim(calendar2); + Date trimedDate = getDate(); + Date date2 = calendar2.getTime(); + return date2.equals(trimedDate); + } + + public void addDateChangeListener(DateChangeListener listener) { + listenerList.add(listener); + } + + public void removeDateChangeListener(DateChangeListener listener) { + listenerList.remove(listener); + } + + public Locale getLocale() {return m_locale; } + public int getDay() { return m_calendar.get(Calendar.DATE); } + public int getMonth() { return m_calendar.get(Calendar.MONTH) + 1; } + public int getYear() { return m_calendar.get(Calendar.YEAR); } + + /** return the number of days of the selected month */ + public int daysMonth() { return m_daysMonth; } + /** return the number of days of the month before the selected month. */ + public int daysLastMonth() { return m_daysLastMonth; } + /** return the first weekday of the selected month (1 - 7). */ + public int firstWeekday() { return m_firstWeekday; } + + /** calculates the weekday from the passed day. */ + public int getWeekday(int day) { + // calculate the weekday, consider the index shift + return (((firstWeekday() - 1) + (day - 1)) % 7 ) + 1; + } + + public Date getDate() { + return m_calendar.getTime(); + } + + // #TODO Property change listener for TimeZone + public void setTimeZone(TimeZone timeZone) { + m_calendar.setTimeZone(timeZone); + m_yearFormat.setTimeZone(timeZone); + m_currentDayFormat.setTimeZone(timeZone); + recalculate(); + } + + public TimeZone getTimeZone() { + return m_calendar.getTimeZone(); + } + + public String getDateString() { + return m_currentDayFormat.format(getDate()); + } + + public String getCurrentDateString() { + return m_currentDayFormat.format(new Date()); + } + + public void addMonth(int count) { + m_calendar.add(Calendar.MONTH,count); + recalculate(); + } + + public void addYear(int count) { + m_calendar.add(Calendar.YEAR,count); + recalculate(); + } + + public void addDay(int count) { + m_calendar.add(Calendar.DATE,count); + recalculate(); + } + + public void setDay(int day) { + m_calendar.set(Calendar.DATE,day); + recalculate(); + } + + public void setMonth(int month) { + m_calendar.set(Calendar.MONTH,month); + recalculate(); + } + public String getYearString() { + DateFormat format; + if (m_calendar.get(Calendar.ERA)!=GregorianCalendar.AD) + format = new SimpleDateFormat("yyyy GG", getLocale()); + else + format = m_yearFormat; + return format.format(getDate()); + } + + public void setYear(int year) { + m_calendar.set(Calendar.YEAR,year); + recalculate(); + } + + public void setDate(int day,int month,int year) { + m_calendar.set(Calendar.DATE,day); + m_calendar.set(Calendar.MONTH,month -1); + m_calendar.set(Calendar.YEAR,year); + trim(m_calendar); + recalculate(); + } + + public void setDate(Date date) { + m_calendar.setTime(date); + trim(m_calendar); + recalculate(); + } + + private void trim(Calendar calendar) { + calendar.set(Calendar.HOUR_OF_DAY,0); + calendar.set(Calendar.MINUTE,0); + calendar.set(Calendar.SECOND,0); + calendar.set(Calendar.MILLISECOND,0); + } + + // 18.02.2004 CK: Workaround for bug in JDK 1.5.0 .Replace add with roll + private void recalculate() { + Calendar calendar = Calendar.getInstance(getTimeZone(), getLocale()); + Date date = getDate(); + calendar.setTime(date); + // calculate the number of days of the selected month + calendar.add(Calendar.MONTH,1); + calendar.set(Calendar.DATE,1); + calendar.add(Calendar.DAY_OF_YEAR,-1); + calendar.getTime(); + m_daysMonth = calendar.get(Calendar.DAY_OF_MONTH); + + // calculate the number of days of the month before the selected month + calendar.set(Calendar.DATE,1); + m_firstWeekday = calendar.get(Calendar.DAY_OF_WEEK); + calendar.add(Calendar.DAY_OF_YEAR,-1); + m_daysLastMonth = calendar.get(Calendar.DAY_OF_MONTH); + + // System.out.println("Calendar Recalculate: " + getDay() + "." + getMonth() + "." + getYear()); + fireDateChanged(); + } + + public DateChangeListener[] getDateChangeListeners() { + return listenerList.toArray(new DateChangeListener[]{}); + } + + protected void fireDateChanged() { + DateChangeListener[] listeners = getDateChangeListeners(); + Date date = getDate(); + DateChangeEvent evt = new DateChangeEvent(this,date); + for (int i = 0;imaximum days per month 40 + */ + private String[] days = new String[40]; + + + + private int selectedField = 10; + private int focusedField = 10; + private DateModel model; + private DateModel focusModel; + + private int lastFocusedMonth; // performance improvement + private int lastFocusedYear; // performance improvement + + + private PaintEnvironment e; + private DateRenderer dateRenderer = null; + + public DaySelection(DateModel model,DateModel focusModel) { + this.model = model; + this.focusModel = focusModel; + focusModel.addDateChangeListener(this); + addMouseListener(this); + createWeekdays(model.getLocale()); + createDays(model.getLocale()); + // setFont(DEFAULT_FONT); + } + + /** Implementation-specific. Should be private.*/ + public void mousePressed(MouseEvent me) { + me.consume(); + selectField(me.getX(),me.getY()); + } + /** Implementation-specific. Should be private.*/ + public void mouseReleased(MouseEvent me) { + me.consume(); + } + + /** Implementation-specific. Should be private.*/ + public void mouseClicked(MouseEvent me) { + me.consume(); + } + + /** Implementation-specific. Should be private.*/ + public void mouseEntered(MouseEvent me) { + } + + /** You must call javax.swing.ToolTipManager.sharedInstance().registerComponent(thisComponent) + to enable ToolTip text. + */ + public String getToolTipText(MouseEvent me) { + int day = calcDay(me.getX(),me.getY()); + if (day >=0 && dateRenderer != null) + return dateRenderer.getRenderingInfo(focusModel.getWeekday(day), day, focusModel.getMonth(), focusModel.getYear()).getTooltipText(); + else + return ""; + } + + /** Implementation-specific. Should be private.*/ + public void mouseExited(MouseEvent me) { + } + + + public void setDateRenderer(DateRenderer dateRenderer) { + this.dateRenderer = dateRenderer; + } + + // Recalculate the Components minimum and maximum sizes + private void calculateSizes() { + if (e == null) + e = new PaintEnvironment(); + int maxWidth =0; + FontMetrics fm = getFontMetrics(getFont()); + e.fontHeight = fm.getHeight(); + e.cellHeight = fm.getHeight() + VGAP *2; + + for (int i=0;imaxWidth) + maxWidth = len; + } + if (fm.stringWidth("33")> maxWidth) + maxWidth = fm.stringWidth("33"); + + e.fontWidth = maxWidth; + e.cellWidth = maxWidth + HGAP * 2 ; + int width = COLUMNS * e.cellWidth + HBORDER *2; + setPreferredSize(new Dimension( width,(ROWS) * e.cellHeight + 2*HBORDER)); + setMinimumSize(new Dimension( width,(ROWS) * e.cellHeight + 2*VBORDER)); + invalidate(); + } + + public void setFont(Font font) { + super.setFont(font); + if (font == null) + return; + else + // We need the font-size to calculate the component size + calculateSizes(); + } + + public Dimension getPreferredSize() { + if (getFont() != null && e==null) + // We need the font-size to calculate the component size + calculateSizes(); + return super.getPreferredSize(); + } + + public void dateChanged(DateChangeEvent evt) { + if (e==null) + // We need the font-size to calculate the component size + if (getFont() != null ) + calculateSizes(); + else + return; + + int lastSelectedField = selectedField; + if (model.getMonth() == focusModel.getMonth() && + model.getYear() == focusModel.getYear()) + // #BUGFIX consider index shift. + // weekdays 1..7 and days 1..31 but field 0..40 + selectedField = weekday2slot[model.firstWeekday()]+ (model.getDay() - 1) ; + else + selectedField = -1; + + int lastFocusedField = focusedField; + // #BUGFIX consider index shift. + // weekdays 1..7 and days 1..31 but field 0..40 + int newFocusedField = weekday2slot[focusModel.firstWeekday()] + (focusModel.getDay() - 1) ; + + if (lastSelectedField == selectedField + && lastFocusedMonth == focusModel.getMonth() + && lastFocusedYear == focusModel.getYear() + ) { + // Only repaint the focusedField (Performance improvement) + focusedField = -1; + calculateRectangle(lastFocusedField); + repaint(e.r); + focusedField = newFocusedField; + calculateRectangle(focusedField); + repaint(e.r); + } else { + // repaint everything + focusedField = newFocusedField; + repaint(); + } + lastFocusedMonth = focusModel.getMonth(); + lastFocusedYear = focusModel.getYear(); + } + + /** calculate the day of month from the specified field. 1..31 + */ + private int calcDay(int field) { + return (field + 1) - weekday2slot[focusModel.firstWeekday()] ; + } + + /** calculate the day of month from the x and y coordinates. + @return -1 if coordinates don't point to a day in the selected month + */ + private int calcDay(int x,int y) { + int col = (x - HBORDER) / e.cellWidth; + int row = (y - VBORDER) / e.cellHeight; + int field = 0; + // System.out.println(row + ":" + col); + if ( row > 0 && col < COLUMNS && row < ROWS) { + field =(row-1) * COLUMNS + col; + } + if (belongsToMonth(field)) { + return calcDay(field); + } else { + return -1; + } + } + + + private void createDays(Locale locale) { + NumberFormat format = NumberFormat.getInstance(locale); + // Try to simluate a right align of the numbers with a space + for ( int i=0; i <10; i++) + days[i] = " " + format.format(i); + for ( int i=10; i < 40; i++) + days[i] = format.format(i); + } + + /** This method is necessary to shorten the names down to 2 characters. + Some date-formats ignore the setting. + */ + private String small(String string) { + return string.substring(0,Math.min(string.length(),2)); + } + + private void createWeekdays(Locale locale ) { + Calendar calendar = Calendar.getInstance(locale); + SimpleDateFormat format = new SimpleDateFormat("EE",locale); + calendar.set(Calendar.DAY_OF_WEEK,calendar.getFirstDayOfWeek()); + for (int i=0;i<7;i++) { + weekday2slot[calendar.get(Calendar.DAY_OF_WEEK)] = i; + weekdayNames[i] = small(format.format(calendar.getTime())); + calendar.add(Calendar.DAY_OF_WEEK,1); + } + } + + // calculates the rectangle for a given field + private void calculateRectangle(int field) { + int row = (field / COLUMNS) + 1; + int col = (field % COLUMNS); + calculateRectangle(row,col); + } + + + // calculates the rectangle for a given row and col + private void calculateRectangle(int row,int col) { + Rectangle r = e.r; + r.x = e.cellWidth * col + HBORDER; + r.y = e.cellHeight * row + VBORDER; + r.width = e.cellWidth; + r.height = e.cellHeight; + } + + private void calculateTextPos(int field) { + int row = (field / COLUMNS) + 1; + int col = (field % COLUMNS); + calculateTextPos(row,col); + } + + // calculates the text-anchor for a giver field + private void calculateTextPos(int row,int col) { + Point p = e.p; + p.x = e.cellWidth * col + HBORDER + (e.cellWidth - e.fontWidth)/2; + p.y = e.cellHeight * row + VBORDER + e.fontHeight - 1; + } + + private boolean belongsToMonth(int field) { + return (calcDay(field) > 0 && calcDay(field) <= focusModel.daysMonth()); + } + + private void selectField(int x,int y) { + int day = calcDay(x,y); + + if ( day >=0 ) { + model.setDate(day, focusModel.getMonth(), focusModel.getYear()); + } // end of if () + } + + + private Color getBackgroundColor(RenderingInfo renderingInfo) { + Color color = null; + if ( renderingInfo != null) + { + color = renderingInfo.getBackgroundColor(); + } + if (color != null) + return color; + + return DEFAULT_CELL_BACKGROUND; + } + + protected RenderingInfo getRenderingInfo(int field) { + RenderingInfo renderingInfo = null; + int day = calcDay(field); + if (belongsToMonth(field) && dateRenderer != null) { + renderingInfo = dateRenderer.getRenderingInfo(focusModel.getWeekday(day), day, focusModel.getMonth(), focusModel.getYear()); + } + return renderingInfo; + } + + // return the Daytext, that should be displayed in the specified field + private String getText(int field) { + int index = 0; + + if ( calcDay(field) < 1) + index = focusModel.daysLastMonth() + calcDay(field) ; + + if (belongsToMonth(field)) + index = calcDay(field); + + if ( calcDay(field) > focusModel.daysMonth() ) + index = calcDay(field) - focusModel.daysMonth(); + + return days[index]; + } + + static char[] test = {'1'}; + private void drawField(int field,boolean highlight) { + if (field <0) + return; + Graphics g = e.g; + Rectangle r = e.r; + Point p = e.p; + + calculateRectangle(field); + RenderingInfo renderingInfo = getRenderingInfo( field); + if ( field == selectedField ) { + g.setColor(SELECTION_BACKGROUND); + g.fillRect(r.x +2 ,r.y +2 ,r.width-4,r.height-4); + g.setColor(SELECTION_BORDER); + //g.drawRect(r.x,r.y,r.width-1,r.height-1); + g.drawRect(r.x+1,r.y+1,r.width-3,r.height-3); + if ( field == focusedField ) + { + g.setColor(FOCUSCOLOR); + } + else + { + g.setColor(getBackgroundColor(renderingInfo)); + } + g.drawRect(r.x,r.y,r.width-1,r.height-1); + g.setColor(SELECTION); + } else if ( field == focusedField ) { + g.setColor(getBackgroundColor(renderingInfo)); + g.fillRect(r.x,r.y,r.width -1,r.height -1); + g.setColor(FOCUSCOLOR); + g.drawRect(r.x,r.y,r.width-1,r.height-1); + if ( highlight) { + g.setColor(SELECTABLE); + } else { + g.setColor(UNSELECTABLE); + } // end of else + } else { + g.setColor(getBackgroundColor(renderingInfo)); + g.fillRect(r.x ,r.y ,r.width ,r.height); + if ( highlight) { + g.setColor(SELECTABLE); + } else { + g.setColor(UNSELECTABLE); + } // end of else + } + calculateTextPos(field); + if ( field!= selectedField) + { + if ( renderingInfo != null) + { + Color foregroundColor = renderingInfo.getForegroundColor(); + if ( foregroundColor != null) + { + g.setColor( foregroundColor); + } + } + } + g.drawString(getText(field) + , p.x , p.y); + } + + private void drawHeader() { + Graphics g = e.g; + Point p = e.p; + + g.setColor(HEADER_BACKGROUND); + g.fillRect(HBORDER,VBORDER, getSize().width - 2 * HBORDER, e.cellHeight); + g.setColor(HEADER); + for ( int i=0; i < COLUMNS; i++) { + calculateTextPos(0,i); + g.drawString(weekdayNames[i], p.x,p.y); + } + } + + private void paintComplete() { + drawHeader(); + int field = 0; + int start = weekday2slot[focusModel.firstWeekday()]; + int end= start + focusModel.daysMonth() -1 ; + for ( int i=0; i< start; i++) { + drawField(field ++,false); + } + + for ( int i= start; i <= end ; i++) { + drawField(field ++,true); + } + + for ( int i= end + 1; i< FIELDS ; i++) { + drawField(field ++,false); + } + } + + private void updateEnvironment(Graphics g) { + e.cellWidth = (getSize().width - HBORDER * 2) / COLUMNS; + e.g = g; + } + + public void paint(Graphics g) { + super.paint(g); + if (e==null) + if (getFont() != null ) + // We need the font-size to calculate the component size + calculateSizes(); + else + return; + updateEnvironment(g); + paintComplete(); + drawField(selectedField,true); + drawField(focusedField,true); + } + +} + +// Environment stores the values that would normaly be stored on the stack. +// This is to speedup performance, e.g. new Point and new Rectangle are only called once. +class PaintEnvironment { + Graphics g; + int cellWidth; + int cellHeight; + int fontWidth; + int fontHeight; + Point p = new Point(); + Rectangle r = new Rectangle(); +} + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendar/NavButton.java b/rapla-source-1.8.2/src/org/rapla/components/calendar/NavButton.java new file mode 100644 index 0000000..916b817 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendar/NavButton.java @@ -0,0 +1,181 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.calendar; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Polygon; +import java.awt.event.ActionEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +import javax.swing.AbstractButton; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.plaf.ButtonUI; + +public class NavButton extends AbstractButton implements MouseListener { + private static final long serialVersionUID = 1L; + + Polygon m_poly; + char m_type; + boolean m_buttonDown = false; + Color m_disabledColor; + boolean m_enabled=true; + boolean m_border=true; + int m_delay = 0; + int leftPosition; + + ButtonStateChecker m_checker = new ButtonStateChecker(); + /** You can set the alignment of the arrow with one of these four characters: + '<', '^', '>', 'v' + */ + public NavButton(char type) { + this(type,18); + } + + public NavButton(char type,int size) { + this(type,size,true); + } + + public NavButton(char type,int size,boolean border) { + super(); + m_border = border; + m_type = type; + setSize(size,size); + addMouseListener(this); + m_disabledColor = UIManager.getColor("Button.disabledText"); + } + + /** Here you can set if the button should fire repeated clicks. If + set to 0 the button will fire only once when pressed. + */ + public void setClickRepeatDelay(int millis) { + m_delay = millis; + } + + public int getClickRepeatDelay() { + return m_delay; + } + + public void setUI(ButtonUI ui) { + super.setUI(ui); + m_disabledColor = UIManager.getColor("Button.disabledText"); + } + + void setLeftPosition(int position) { + leftPosition = position; + } + + /** Implementation-specific. Should be private.*/ + public void mouseEntered(MouseEvent me) { + } + /** Implementation-specific. Should be private.*/ + public void mouseExited(MouseEvent me) { + } + + /** Implementation-specific. Should be private.*/ + public void mousePressed(MouseEvent me) { + if (!isEnabled()) + return; + m_buttonDown = true; + repaint(); + m_checker.start(); + } + /** Implementation-specific. Should be private.*/ + public void mouseReleased(MouseEvent me) { + m_buttonDown = false; + repaint(); + } + + /** Implementation-specific. Should be private.*/ + public void mouseClicked(MouseEvent me) { + m_buttonDown = false; + repaint(); + } + + /** Set the size of the nav-button. A nav button is square. + The maximum of width and height will be used as new size. + */ + public void setSize(int width,int height) { + int size = Math.max(width,height); + m_poly = new ArrowPolygon(m_type,size,m_border); + super.setSize(size,size); + Dimension dim = new Dimension(size,size); + setPreferredSize(dim); + setMaximumSize(dim); + setMinimumSize(dim); + } + + public void setEnabled(boolean enabled) { + m_enabled = enabled; + repaint(); + } + public boolean isEnabled() { + return m_enabled; + } + public void paint(Graphics g) { + g.translate( leftPosition, 0); + if (m_buttonDown) { + //g.setColor( UIManager.getColor("Button.pressed")); + g.setColor( UIManager.getColor("Button.focus")); + g.fillPolygon(m_poly); + g.drawPolygon(m_poly); + } else { + if (isEnabled()) { + g.setColor( UIManager.getColor("Button.font") ); + g.fillPolygon(m_poly); + } else { + g.setColor(m_disabledColor); + } + g.drawPolygon(m_poly); + } + } + + + class ButtonStateChecker implements Runnable{ + long startMillis; + long startDelay; + public void start() { + startDelay = m_delay * 8; + fireAndReset(); + if (m_delay > 0) + SwingUtilities.invokeLater(this); + } + + private void fireAndReset() { + fireActionPerformed(new ActionEvent(this + ,ActionEvent.ACTION_PERFORMED + ,"")); + startMillis = System.currentTimeMillis(); + } + public void run() { + if (!m_buttonDown) + return; + if ((Math.abs(System.currentTimeMillis() - startMillis) > startDelay)) { + if (startDelay > m_delay) + startDelay = startDelay/2; + fireAndReset(); + } + try { + Thread.sleep(10); + } catch (Exception ex) { + return; + } + SwingUtilities.invokeLater(this); + } + } +} + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendar/NumberField.java b/rapla-source-1.8.2/src/org/rapla/components/calendar/NumberField.java new file mode 100644 index 0000000..a75b1f7 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendar/NumberField.java @@ -0,0 +1,220 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendar; + +import java.awt.ComponentOrientation; + +/** + * The NumberField only accepts integer values. + * Warning! Currently only Longs are supported. + */ + +public class NumberField extends AbstractBlockField { + private static final long serialVersionUID = 1L; + + static char[] m_separators = new char[0]; + Number m_number; + Number m_minimum; + Number m_maximum; + /** + * @return Returns the m_blockStepSize. + */ + public int getBlockStepSize() { + return m_blockStepSize; + } + /** + * @param stepSize The m_blockStepSize to set. + */ + public void setBlockStepSize(int stepSize) { + m_blockStepSize = stepSize; + } + /** + * @return Returns the m_stepSize. + */ + public int getStepSize() { + return m_stepSize; + } + /** + * @param size The m_stepSize to set. + */ + public void setStepSize(int size) { + m_stepSize = size; + } + int m_stepSize; + int m_blockStepSize; + int m_maxLength; + boolean m_isNullPermitted = true; + public NumberField() { + setComponentOrientation( ComponentOrientation.RIGHT_TO_LEFT); + updateColumns(); + } + + public NumberField(Number minimum,Number maximum,int stepSize,int blockStepSize) { + this(); + setStepSize(stepSize); + setBlockStepSize(blockStepSize); + setMinimum( minimum ); + setMaximum( maximum ); + } + + + public void setMinimum(Number minimum){ + m_minimum = minimum; + updateColumns(); + } + + public void setMaximum(Number maximum){ + m_maximum = maximum; + updateColumns(); + } + + public Number getMinimum() { + return m_minimum; + } + + public Number getMaximum() { + return m_maximum; + } + + private void updateColumns() { + if (m_maximum!= null && m_minimum != null) { + if ((Math.abs(m_maximum.longValue())) + > (Math.abs(m_minimum.longValue())) * 10) + m_maxLength = m_maximum.toString().length(); + else + m_maxLength = m_minimum.toString().length(); + setColumns(m_maxLength); + } else { + m_maxLength = 100; + setColumns(4); + } + } + + public boolean isNullPermitted() { + return m_isNullPermitted; + } + public void setNullPermitted(boolean isNullPermitted) { + m_isNullPermitted = isNullPermitted; + if (m_number == null && !isNullPermitted) + m_number = new Double(defaultValue()); + } + + private long defaultValue() { + if (m_minimum != null && m_minimum.longValue()>0) + return m_minimum.longValue(); + else if (m_maximum != null && m_maximum.longValue()<0) + return m_maximum.longValue(); + return 0; + } + + public void setNumber(Number number) { + updateNumber( number ); + m_oldText = getText(); + fireValueChanged(); + } + + private void updateNumber(Number number) { + m_number = number; + String text; + if (number != null) { + text = String.valueOf(number.longValue()); + } else { + text = ""; + } + String previous = getText(); + if ( previous != null && text.equals( previous)) + { + return; + } + setText( text ); + } + + public void increase() { + changeSelectedBlock(new int[1],0,"",1); + } + + public void decrease() { + changeSelectedBlock(new int[1],0,"",-1); + } + + public Number getNumber() { + return m_number; + } + + public boolean allowsNegative() { + return (m_minimum == null || m_minimum.longValue()<0); + } + + protected char[] getSeparators() { + return m_separators; + } + + protected boolean isSeparator(char c) { + return false; + } + + protected void changeSelectedBlock(int[] blocks,int block,String selected,int count) { + long longValue = ((m_number != null) ? m_number.longValue() : defaultValue()); + if (count == 1) + longValue = longValue + m_stepSize; + if (count == -1) + longValue = longValue - m_stepSize; + if (count == 10) + longValue = longValue + m_blockStepSize; + if (count == -10) + longValue = longValue - m_blockStepSize; + + if (m_minimum != null && longValuem_maximum.longValue()) + longValue = m_maximum.longValue(); + updateNumber(new Long(longValue)); + calcBlocks(blocks); + markBlock(blocks,block); + } + + public boolean blocksValid() { + try { + String text = getText(); + if (text.length() ==0) { + if (isNullPermitted()) + m_number = null; + return true; + } + + long newLong = Long.parseLong(text); + if ((m_minimum == null || newLong>=m_minimum.longValue()) + && (m_maximum == null || newLong<=m_maximum.longValue())) { + m_number = new Long(newLong); + return true; + } + } catch (NumberFormatException e) { + if (isNullPermitted()) + m_number = null; + } + return false; + } + + protected int blockCount() { + return 1; + } + + protected int maxBlockLength(int block) { + return m_maxLength; + } + + protected boolean isValidChar(char c) { + return (Character.isDigit(c) || (allowsNegative() && c=='-')); + } + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendar/RaplaArrowButton.java b/rapla-source-1.8.2/src/org/rapla/components/calendar/RaplaArrowButton.java new file mode 100644 index 0000000..f287160 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendar/RaplaArrowButton.java @@ -0,0 +1,156 @@ +/*--------------------------------------------------------------------------* +| Copyright (C) 2014 Christopher Kohlhaas | +| | +| This program is free software; you can redistribute it and/or modify | +| it under the terms of the GNU General Public License as published by the | +| Free Software Foundation. A copy of the license has been included with | +| these distribution in the COPYING file, if not go to www.fsf.org | +| | +| As a special exception, you are granted the permissions to link this | +| program with every library, which license fulfills the Open Source | +| Definition as published by the Open Source Initiative (OSI). | +*--------------------------------------------------------------------------*/ +package org.rapla.components.calendar; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; + +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.SwingUtilities; + +public class RaplaArrowButton extends JButton { + private static final long serialVersionUID = 1L; + + ButtonStateChecker m_checker = new ButtonStateChecker(); + + int m_delay = 0; + boolean m_buttonDown = false; + + ArrowPolygon poly; + char c; + + public RaplaArrowButton(char c) { + this(c,18); + + } + + public RaplaArrowButton(char c,int size) { + super(); + this.c = c; + setMargin(new Insets(0,0,0,0)); + setSize(size,size); + addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent me) { + if (!isEnabled()) + return; + m_buttonDown = true; + // repaint(); + m_checker.start(); + } + /** Implementation-specific. Should be private.*/ + public void mouseReleased(MouseEvent me) { + m_buttonDown = false; + // repaint(); + } + + /** Implementation-specific. Should be private.*/ + public void mouseClicked(MouseEvent me) { + m_buttonDown = false; + //repaint(); + } + }); + } + + /** Here you can set if the button should fire repeated clicks. If + set to 0 the button will fire only once when pressed. + */ + public void setClickRepeatDelay(int millis) { + m_delay = millis; + } + + public int getClickRepeatDelay() { + return m_delay; + } + + public boolean isOpen() + { + return c == '^'; + } + + public void setChar( char c) + { + this.c = c; + final Dimension size = getSize(); + final int width2 = (int)size.getWidth(); + final int height2 = (int)size.getHeight(); + setSize( width2,height2); + } + /** Set the size of the drop-down button. + The minimum of width and height will be used as new size of the arrow. + */ + public void setSize(int width,int height) { + int size = Math.min(width,height); + int imageSize = size - 8; + if (imageSize > 0) { + poly = new ArrowPolygon(c,imageSize); + BufferedImage image = new BufferedImage(imageSize,imageSize,BufferedImage.TYPE_INT_ARGB); + Graphics g = image.createGraphics(); + g.setColor(new Color(0, 0, 0, 0)); + g.fillRect( 0, 0, imageSize, imageSize ); + + g.setColor( Color.darkGray ); + g.fillPolygon( poly ); + g.setColor( Color.black ); + g.drawPolygon( poly ); + setIcon(new ImageIcon(image)); + } else { + setIcon(null); + } + super.setSize(width ,height); + Dimension dim = new Dimension(width ,height); + setPreferredSize(dim); + setMaximumSize(dim); + setMinimumSize(dim); + } + + class ButtonStateChecker implements Runnable{ + long startMillis; + long startDelay; + public void start() { + startDelay = m_delay * 10; + startMillis = System.currentTimeMillis(); + if (m_delay > 0) + SwingUtilities.invokeLater(this); + } + + private void fireAndReset() { + fireActionPerformed(new ActionEvent(this + ,ActionEvent.ACTION_PERFORMED + ,"")); + startMillis = System.currentTimeMillis(); + } + public void run() { + if (!m_buttonDown) + return; + if ((Math.abs(System.currentTimeMillis() - startMillis) > startDelay)) { + if (startDelay > m_delay) + startDelay = startDelay/2; + fireAndReset(); + } + try { + Thread.sleep(10); + } catch (Exception ex) { + return; + } + SwingUtilities.invokeLater(this); + } + } +} + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendar/RaplaCalendar.java b/rapla-source-1.8.2/src/org/rapla/components/calendar/RaplaCalendar.java new file mode 100644 index 0000000..a1029a4 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendar/RaplaCalendar.java @@ -0,0 +1,270 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.calendar; +import java.awt.Font; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import javax.swing.JComponent; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +/** This is another ComboBox-like calendar component. + * It is localizable and it uses swing-components. + *

The combobox editor is a {@link DateField}. If the ComboBox-Button + * is pressed, a CalendarMenu will drop down.

+ * @see CalendarMenu + * @see DateField + * @author Christopher Kohlhaas + */ +public final class RaplaCalendar extends RaplaComboBox { + private static final long serialVersionUID = 1L; + + protected DateField m_dateField; + protected CalendarMenu m_calendarMenu; + Collection m_listenerList = new ArrayList(); + protected DateModel m_model; + private Date m_lastDate; + DateRenderer m_dateRenderer; + + /** Create a new Calendar with the default locale. The calendarmenu + will be accessible via a drop-down-box */ + public RaplaCalendar() { + this(Locale.getDefault(),TimeZone.getDefault(),true); + } + + public DateField getDateField() + { + return m_dateField; + } + + /** Create a new Calendar with the specified locale and timezone. The calendarmenu + will be accessible via a drop-down-box */ + public RaplaCalendar(Locale locale,TimeZone timeZone) { + this(locale,timeZone,true); + } + + /** Create a new Calendar with the specified locale and timezone. The + isDropDown flag specifies if the calendarmenu should be + accessible via a drop-down-box. Alternatively you can get the + calendarmenu with getPopupComponent(). + */ + public RaplaCalendar(Locale locale,TimeZone timeZone,boolean isDropDown) { + super(isDropDown,new DateField(locale,timeZone)); + m_model = new DateModel(locale,timeZone); + m_dateField = (DateField) m_editorComponent; + Listener listener = new Listener(); + m_dateField.addChangeListener(listener); + m_model.addDateChangeListener(listener); + m_lastDate = m_model.getDate(); + setDateRenderer(new WeekendHighlightRenderer()); + } + + class Listener implements ChangeListener,DateChangeListener { + // Implementation of ChangeListener + public void stateChanged(ChangeEvent evt) { + validateEditor(); + } + + // Implementation of DateChangeListener + public void dateChanged(DateChangeEvent evt) { + closePopup(); + if (needSync()) + m_dateField.setDate(evt.getDate()); + if (m_lastDate == null || !m_lastDate.equals(evt.getDate())) + fireDateChange(evt.getDate()); + m_lastDate = evt.getDate(); + } + } + + public TimeZone getTimeZone() { + return m_model.getTimeZone(); + } + + + /* Use this to get the CalendarMenu Component. The calendar menu will be created lazily.*/ + public JComponent getPopupComponent() { + if (m_calendarMenu == null) { + m_calendarMenu = new CalendarMenu(m_model); + m_calendarMenu.setFont( getFont() ); + // #TODO Property change listener for TimeZone + m_calendarMenu.getDaySelection().setDateRenderer(m_dateRenderer); + javax.swing.ToolTipManager.sharedInstance().registerComponent(m_calendarMenu.getDaySelection()); + } + return m_calendarMenu; + } + + public void setFont(Font font) { + super.setFont(font); + // Method called during super-constructor? + if (m_calendarMenu == null || font == null) + return; + m_calendarMenu.setFont(font); + } + + /** Selects the date relative to the given timezone. + * The hour,minute,second and millisecond values will be ignored. + */ + public void setDate(Date date) + { + if ( date != null) + { + m_model.setDate(date); + } + else + { + boolean changed = m_dateField.getDate() != null; + m_dateField.setDate( null); + m_lastDate =null; + if ( changed ) + { + fireDateChange(null); + } + } + } + + /** Parse the returned date with a calendar-object set to the + * correct time-zone to get the date,month and year. The + * hour,minute,second and millisecond values should be ignored. + * @return the selected date + * @see #getYear + * @see #getMonth + * @see #getDay + */ + public Date getDate() { + if ( m_dateField.isNullValue()) + { + return null; + } + return m_model.getDate(); + } + + /** selects the specified day, month and year. + @see #setDate(Date date)*/ + public void select(int day,int month,int year) { + m_model.setDate(day,month,year); + } + + /** sets the DateRenderer for the calendar */ + public void setDateRenderer(DateRenderer dateRenderer) { + m_dateRenderer = dateRenderer; + if (m_calendarMenu != null) { + m_calendarMenu.getDaySelection().setDateRenderer(m_dateRenderer); + } + m_dateField.setDateRenderer(m_dateRenderer); + } + + /** you can choose, if weekdays should be displayed in the right corner of the DateField. + Default is true. This method simply calls setWeekdaysVisble on the DateField Component. + If a DateRender is installed the weekday will be rendered with the DateRenderer. + This includes a tooltip that shows up on the DateRenderer. + @see DateField + */ + public void setWeekdaysVisibleInDateField(boolean bVisible) { + m_dateField.setWeekdaysVisible(bVisible); + } + + /** @return the selected year (relative to the given TimeZone) + @see #getDate + @see #getMonth + @see #getDay + */ + public int getYear() {return m_model.getYear(); } + + /** @return the selected month (relative to the given TimeZone) + @see #getDate + @see #getYear + @see #getDay + */ + public int getMonth() {return m_model.getMonth(); } + + /** @return the selected day (relative to the given TimeZone) + @see #getDate + @see #getYear + @see #getMonth + */ + public int getDay() {return m_model.getDay(); } + + /** registers new DateChangeListener for this component. + * A DateChangeEvent will be fired to every registered DateChangeListener + * when the a different date is selected. + * @see DateChangeListener + * @see DateChangeEvent + */ + public void addDateChangeListener( DateChangeListener listener ) { + m_listenerList.add(listener); + } + + /** removes a listener from this component.*/ + public void removeDateChangeListener( DateChangeListener listener ) { + m_listenerList.remove(listener); + } + + public DateChangeListener[] getDateChangeListeners() { + return m_listenerList.toArray(new DateChangeListener[]{}); + } + + /** A DateChangeEvent will be fired to every registered DateChangeListener + * when the a different date is selected. + */ + protected void fireDateChange( Date date ) { + if (m_listenerList.size() == 0) + return; + DateChangeListener[] listeners = getDateChangeListeners(); + DateChangeEvent evt = new DateChangeEvent(this,date); + for (int i = 0;i +
  • No pluggable look and feel
  • +
  • drop-down button and editor in a separate component (each can get focus)
  • +
  • the popup-component can be an arbitrary JComponent.
  • + +*/ +public abstract class RaplaComboBox extends JPanel { + + private static final long serialVersionUID = 1L; + private JPopupMenu m_popup; + private boolean m_popupVisible = false; + private boolean m_isDropDown = true; + protected RaplaArrowButton m_popupButton; + protected JLabel jLabel; + protected JComponent m_editorComponent; + + // If you click on the popupButton while the PopupWindow is shown, + // the Window will be closed, because you clicked outside the Popup + // (not because you clicked that special button). + // The flag popupVisible is unset. + // After that the same click will trigger the actionPerfomed method + // on our button. And the window would popup again. + // Solution: We track down that one mouseclick that closes the popup + // with the following flags: + private boolean m_closing = false; + private boolean m_pressed = false; + private Listener m_listener = new Listener(); + + public RaplaComboBox(JComponent editorComponent) { + this(true,editorComponent); + } + + RaplaComboBox(boolean isDropDown,JComponent editorComponent) { + m_editorComponent = editorComponent; + m_isDropDown = isDropDown; + jLabel = new JLabel(); + setLayout(new BorderLayout()); + add(jLabel,BorderLayout.WEST); + add(m_editorComponent,BorderLayout.CENTER); + + if (m_isDropDown) { + installPopupButton(); + add(m_popupButton,BorderLayout.EAST); + m_popupButton.addActionListener(m_listener); + m_popupButton.addMouseListener(m_listener); + m_popupVisible = false; + } + } + + public JLabel getLabel() { + return jLabel; + } + + class Listener implements ActionListener,MouseListener,PopupMenuListener { + // Implementation of ActionListener + public void actionPerformed(ActionEvent e) { + // Ignore action, when Popup is closing + log("Action Performed"); + if (m_pressed && m_closing) { + m_closing = false; + return; + } + if ( !m_popupVisible && !m_closing) { + log("Open"); + showPopup(); + } else { + m_popupVisible = false; + closePopup(); + } // end of else + } + + private void log(@SuppressWarnings("unused") String string) { + // System.out.println(System.currentTimeMillis() / 1000 + "m_visible:" + m_popupVisible + " closing: " + m_closing + " [" + string + "]"); + } + // Implementation of MouseListener + public void mousePressed(MouseEvent evt) { + m_pressed = true; + m_closing = false; + log("Pressed"); + } + public void mouseClicked(MouseEvent evt) { + m_closing = false; + } + public void mouseReleased(MouseEvent evt) { + m_pressed = false; + m_closing = false; + log("Released"); + } + public void mouseEntered(MouseEvent me) { + } + public void mouseExited(MouseEvent me) { + } + + + // Implementation of PopupListener + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + m_popupVisible = true; + } + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + m_popupVisible = false; + m_closing = true; + m_popupButton.requestFocus(); + m_popupButton.setChar('v'); + log("Invisible"); + final boolean oldState = m_popupButton.isEnabled(); + m_popupButton.setEnabled( false); + final Timer timer = new Timer(true); + TimerTask task = new TimerTask() + { + public void run() + { + m_popupButton.setEnabled( oldState); + } + }; + timer.schedule(task, 100); + } + + public void popupMenuCanceled(PopupMenuEvent e) { + m_popupVisible = false; + m_closing = true; + m_popupButton.requestFocus(); + log("Cancel"); + } + + } + + private void installPopupButton() { + // Maybe we could use the combobox drop-down button here. + m_popupButton = new RaplaArrowButton('v'); + } + + public void setFont(Font font) { + super.setFont(font); + // Method called during constructor? + if (font == null) + return; + if (m_editorComponent != null) + m_editorComponent.setFont(font); + if (m_popupButton != null && m_isDropDown) { + int size = (int) getPreferredSize().getHeight(); + m_popupButton.setSize(size,size); + } + } + + public void setEnabled( boolean enabled ) { + super.setEnabled( enabled ); + if ( m_editorComponent != null ) { + m_editorComponent.setEnabled( enabled ); + } + if ( m_popupButton != null ) { + m_popupButton.setEnabled ( enabled ); + } + } + + protected void showPopup() { + if (m_popup == null) + createPopup(); + + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Dimension menuSize = m_popup.getPreferredSize(); + Dimension buttonSize = m_popupButton.getSize(); + Point location = m_popupButton.getLocationOnScreen(); + int diffx= buttonSize.width - menuSize.width; + if (location.x + diffx<0) + diffx = - location.x; + int diffy= buttonSize.height; + if (location.y + diffy + menuSize.height > screenSize.height) + diffy = screenSize.height - menuSize.height - location.y; + m_popup.show(m_popupButton,diffx,diffy); + m_popup.requestFocus(); + m_popupButton.setChar('^'); + } + + protected void closePopup() { + if (m_popup != null && m_popup.isVisible()) { + // #Workaround for JMenuPopup-Bug in JDK 1.4 + // intended behaviour: m_popup.setVisible(false); + + javax.swing.SwingUtilities.invokeLater(new Runnable() { + public void run() { + // Show JMenuItem and fire a mouse-click + cardLayout.last(m_popup); + menuItem.menuSelectionChanged(true); + menuItem.dispatchEvent(new MouseEvent(m_popup + ,MouseEvent.MOUSE_RELEASED + ,System.currentTimeMillis() + ,0 + ,0 + ,0 + ,1 + ,false)); + // show original popup again + cardLayout.first(m_popup); + m_popupButton.requestFocus(); + } + }); + } + m_popupVisible = false; + } + + private JMenuItem menuItem; + private CardLayout cardLayout; + + class MyPopup extends JPopupMenu { + private static final long serialVersionUID = 1L; + + MyPopup() { + super(); + } + public void menuSelectionChanged(boolean isIncluded) { + closePopup(); + } + } + + private void createPopup() { + m_popup = new JPopupMenu(); + /* try { + PopupMenu.class.getMethod("isPopupTrigger",new Object[]{}); + } catch (Exception ex) { + m_popup.setLightWeightPopupEnabled(true); + }*/ + m_popup.setBorder(null); + cardLayout = new CardLayout(); + m_popup.setLayout(cardLayout); + m_popup.setInvoker(this); + m_popup.add(getPopupComponent(),"0"); + menuItem = new JMenuItem(""); + m_popup.add(menuItem,"1"); + m_popup.setBorderPainted(true); + m_popup.addPopupMenuListener(m_listener); + } + + /** the component that should apear in the popup menu */ + protected abstract JComponent getPopupComponent(); +} + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendar/RaplaNumber.java b/rapla-source-1.8.2/src/org/rapla/components/calendar/RaplaNumber.java new file mode 100644 index 0000000..6fcbf8f --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendar/RaplaNumber.java @@ -0,0 +1,169 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2003 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendar; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.EventListenerList; +/** The RaplaNumber is an adapter for NumberField. + * Warning! Currently only Longs are supported. + * @see NumberField + */ +public final class RaplaNumber extends JPanel{ + private static final long serialVersionUID = 1L; + + NumberField m_numberField = null; + public static Number ZERO = new Long(0); + public static Number ONE = new Long(1); + public static Number DEFAULT_STEP_SIZE = new Long(1); + EventListenerList m_listenerList; + Listener m_listener = new Listener(); + Number m_emptyValue = ZERO; + JPanel m_buttonPanel = new JPanel(); + RaplaArrowButton m_upButton = new RaplaArrowButton('+', 15);//'^',10,false); + RaplaArrowButton m_downButton = new RaplaArrowButton('-', 15);//new NavButton('v',10,false); + + /** currently only Longs are supported */ + public RaplaNumber() { + this( null, null, null, false); + } + + public RaplaNumber(Number value,Number minimum,Number maximum,boolean isNullPermitted) { + m_numberField = new NumberField(minimum,maximum,DEFAULT_STEP_SIZE.intValue(),10); + m_numberField.setNumber(value); + m_numberField.setNullPermitted(isNullPermitted); + if (minimum != null && minimum.longValue()>0) + m_emptyValue = minimum; + else if (maximum != null && maximum.longValue()<0) + m_emptyValue = maximum; + m_buttonPanel.setLayout(new GridLayout(2,1)); + m_buttonPanel.add(m_upButton); + m_upButton.setBorder( null); + m_buttonPanel.add(m_downButton); + m_downButton.setBorder(null); + m_buttonPanel.setMinimumSize(new Dimension(18,20)); + m_buttonPanel.setPreferredSize(new Dimension(18,20)); + m_buttonPanel.setBorder(BorderFactory.createEtchedBorder()); + m_upButton.setClickRepeatDelay(50); + m_downButton.setClickRepeatDelay(50); + m_upButton.addActionListener(m_listener); + m_downButton.addActionListener(m_listener); + setLayout(new BorderLayout()); + add(m_numberField,BorderLayout.CENTER); + add(m_buttonPanel,BorderLayout.EAST); + + m_upButton.setFocusable( false); + m_downButton.setFocusable( false); + } + + public void setFont(Font font) { + super.setFont(font); + // Method called during constructor? + if (m_numberField == null || font == null) + return; + m_numberField.setFont(font); + } + + public void setColumns(int columns) { + m_numberField.setColumns(columns); + } + + public NumberField getNumberField() { + return m_numberField; + } + + public void setEnabled( boolean enabled ) { + super.setEnabled( enabled ); + if ( m_numberField != null ) { + m_numberField.setEnabled( enabled ); + } + if ( m_upButton != null ) { + m_upButton.setEnabled ( enabled ); + m_downButton.setEnabled ( enabled ); + } + } + + /** currently only Longs are supported */ + public void setNumber(Number newValue) { + m_numberField.setNumber(newValue); + } + + public Number getNumber() { + return m_numberField.getNumber(); + } + + public void addChangeListener(ChangeListener changeListener) { + if (m_listenerList == null) { + m_listenerList = new EventListenerList(); + m_numberField.addChangeListener(m_listener); + } + m_listenerList.add(ChangeListener.class,changeListener); + } + + public void removeChangeListener(ChangeListener changeListener) { + if (m_listenerList == null) { + return; + } + m_listenerList.remove(ChangeListener.class,changeListener); + } + + + class Listener implements ChangeListener,ActionListener { + public void actionPerformed(ActionEvent evt) { + m_numberField.requestFocus(); + if (evt.getSource() == m_upButton) { + m_numberField.increase(); + } + if (evt.getSource() == m_downButton) { + m_numberField.decrease(); + } + SwingUtilities.invokeLater( new Runnable() { + + public void run() { + stateChanged(null); + m_numberField.selectAll(); + } + } + + ); + } + + public void stateChanged(ChangeEvent originalEvent) { + if (m_listenerList == null) + return; + + + ChangeEvent evt = new ChangeEvent(RaplaNumber.this); + Object[] listeners = m_listenerList.getListenerList(); + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==ChangeListener.class) { + ((ChangeListener)listeners[i+1]).stateChanged(evt); + } + } + } + + } + + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendar/RaplaTime.java b/rapla-source-1.8.2/src/org/rapla/components/calendar/RaplaTime.java new file mode 100644 index 0000000..f06c8a6 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendar/RaplaTime.java @@ -0,0 +1,587 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.calendar; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.MediaTracker; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.image.BufferedImage; +import java.net.URL; +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import javax.swing.BorderFactory; +import javax.swing.DefaultListCellRenderer; +import javax.swing.DefaultListModel; +import javax.swing.ImageIcon; +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollBar; +import javax.swing.JScrollPane; +import javax.swing.ListSelectionModel; +import javax.swing.MenuElement; +import javax.swing.MenuSelectionManager; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +/** A ComboBox like time chooser. + * It is localizable and it uses swing-components. + *

    The combobox editor is a {@link TimeField}. If the ComboBox-Button + * is pressed a TimeSelectionList will drop down.

    + * @author Christopher Kohlhaas + */ +public final class RaplaTime extends RaplaComboBox { + private static final long serialVersionUID = 1L; + + protected TimeField m_timeField; + protected TimeList m_timeList; + protected TimeModel m_timeModel; + protected Collection m_listenerList = new ArrayList(); + private Date m_lastTime; + private int m_visibleRowCount = -1; + private int m_rowsPerHour = 4; + private TimeRenderer m_renderer; + private static Image clock; + boolean m_showClock; + + /** Create a new TimeBox with the default locale. */ + public RaplaTime() { + this(Locale.getDefault(),TimeZone.getDefault(),true, true); + } + + /** Create a new TimeBox with the specified locale and timeZone. */ + public RaplaTime(Locale locale,TimeZone timeZone) { + this(locale,timeZone,true, true); + } + + /** Create a new TimeBox with the specified locale and timeZone. The + isDropDown flag specifies if times could be selected + via a drop-down-box. + */ + public RaplaTime(Locale locale,TimeZone timeZone,boolean isDropDown, boolean showClock) { + super(isDropDown,new TimeField(locale,timeZone)); + m_showClock = showClock; + m_timeModel = new TimeModel(locale, timeZone); + m_timeField = (TimeField) m_editorComponent; + Listener listener = new Listener(); + m_timeField.addChangeListener(listener); + m_timeModel.addDateChangeListener(listener); + m_lastTime = m_timeModel.getTime(); + + if ( showClock ) + { + if ( clock == null ) + { + URL url = RaplaTime.class.getResource("clock.png"); + if ( url != null ) + { + clock =Toolkit.getDefaultToolkit().createImage(url ); + MediaTracker m = new MediaTracker(this); + m.addImage(clock, 0); + try { m.waitForID(0); } catch (InterruptedException ex) {} + } + } + + getLabel().setIcon( new ImageIcon( createClockImage())); + getLabel().setBorder( BorderFactory.createEmptyBorder(0,0,0,1)); + } + + } + + public TimeField getTimeField() + { + return m_timeField; + } + + static Color HOUR_POINTER = new Color( 40,40,100); + static Color MINUTE_POINTER = new Color( 100,100,180); + + protected Image createClockImage() { + BufferedImage image = new BufferedImage( 17, 17, BufferedImage.TYPE_INT_ARGB); + Calendar calendar = Calendar.getInstance(getTimeZone(),m_timeModel.getLocale()); + calendar.setTime( m_timeModel.getTime()); + int hourOfDay = calendar.get( Calendar.HOUR_OF_DAY) % 12; + int minute = calendar.get( Calendar.MINUTE); + + Graphics g = image.getGraphics(); + + double hourPos = (hourOfDay * 60 + minute - 180) / (60.0 * 12) * 2 * Math.PI ; + double minutePos = (minute -15) / 60.0 * 2 * Math.PI; + int xhour = (int) (Math.cos( hourPos) * 4.5); + int yhour = (int) (Math.sin( hourPos ) * 4.5 ); + int xminute = (int) (Math.cos( minutePos ) * 6.5 ); + int yminute = (int) (Math.sin( minutePos) * 6.5); + g.drawImage( clock,0,0,17,17, null); + g.setColor( HOUR_POINTER); + int centerx = 8; + int centery = 8; + g.drawLine( centerx, centery, centerx + xhour,centery + yhour); + g.setColor( MINUTE_POINTER); + g.drawLine( centerx, centery, centerx + xminute,centery +yminute); + return image; + } + /** The granularity of the selection rows: + *
      + *
    • 1: 1 rows per hour = 1 Hour
    • + *
    • 2: 2 rows per hour = 1/2 Hour
    • + *
    • 2: 3 rows per hour = 20 Minutes
    • + *
    • 4: 4 rows per hour = 15 Minutes
    • + *
    • 6: 6 rows per hour = 10 Minutes
    • + *
    • 12: 12 rows per hour = 5 Minutes
    • + *
    + */ + public void setRowsPerHour(int rowsPerHour) { + m_rowsPerHour = rowsPerHour; + if (m_timeList != null) { + throw new IllegalStateException("Property can only be set during initialization."); + } + } + + /** @see #setRowsPerHour */ + public int getRowsPerHour() { + return m_rowsPerHour; + } + + class Listener implements ChangeListener,DateChangeListener { + // Implementation of ChangeListener + public void stateChanged(ChangeEvent evt) { + validateEditor(); + } + + public void dateChanged(DateChangeEvent evt) { + closePopup(); + if (needSync()) + m_timeField.setTime(evt.getDate()); + if (m_lastTime == null || !m_lastTime.equals(evt.getDate())) + fireTimeChanged(evt.getDate()); + m_lastTime = evt.getDate(); + if ( clock != null && m_showClock) + { + getLabel().setIcon( new ImageIcon( createClockImage())); + } + } + } + + /** test if we need to synchronize the dateModel and the m_timeField*/ + private boolean needSync() { + return (m_timeField.getTime() != null && !m_timeModel.sameTime(m_timeField.getTime())); + } + + protected void validateEditor() { + if (needSync()) + m_timeModel.setTime(m_timeField.getTime()); + } + + /** the number of visble rows in the drop-down menu.*/ + public void setVisibleRowCount(int count) { + m_visibleRowCount = count; + if (m_timeList != null) + m_timeList.getList().setVisibleRowCount(count); + } + + public void setFont(Font font) { + super.setFont(font); + // Method called during constructor? + if (m_timeList == null || font == null) + return; + m_timeList.setFont(font); + } + + public TimeZone getTimeZone() { + return m_timeField.getTimeZone(); + } + + /** Set the time relative to the given timezone. + * The date,month and year values will be ignored. + */ + public void setTime(Date time) { + m_timeModel.setTime(time); + } + + public Date getDurationStart() + { + return m_timeModel.getDurationStart(); + } + + public void setDurationStart(Date durationStart) + { + m_timeModel.setDurationStart(durationStart); + if ( m_timeList != null) + { + m_timeList.setModel(m_timeModel,m_timeField.getOutputFormat()); + } + } + + /** Set the time relative to the given timezone. + */ + public void setTime(int hour, int minute) { + m_timeModel.setTime(hour,minute); + } + + /** Parse this date with a calendar-object set to the correct + time-zone to get the hour,minute and second. The + date,month and year values should be ignored. + */ + public Date getTime() { + return m_timeModel.getTime(); + } + + protected void showPopup() { + validateEditor(); + super.showPopup(); + m_timeList.selectTime(m_timeField.getTime()); + } + + /** registers new DateChangedListener for this component. + * An DateChangedEvent will be fired to every registered DateChangedListener + * when the a different time is selected. + * @see DateChangeListener + * @see DateChangeEvent + */ + public void addDateChangeListener(DateChangeListener listener) { + m_listenerList.add(listener); + } + + /** removes a listener from this component.*/ + public void removeDateChangeListener(DateChangeListener listener) { + m_listenerList.remove(listener); + } + + public DateChangeListener[] getDateChangeListeners() { + return m_listenerList.toArray(new DateChangeListener[]{}); + } + + protected void fireTimeChanged(Date date) { + DateChangeListener[] listeners = getDateChangeListeners(); + if (listeners.length == 0) + return; + DateChangeEvent evt = new DateChangeEvent(this,date); + for (int i = 0; i=0) + m_timeList.getList().setVisibleRowCount(m_visibleRowCount); + } + m_timeList.setTimeRenderer( m_renderer ); + m_timeList.setModel(m_timeModel,m_timeField.getOutputFormat()); + return m_timeList; + } + + public void setTimeRenderer(TimeRenderer renderer) { + m_renderer = renderer; + } + +} + + +class TimeList extends JPanel implements MenuElement,MouseListener,MouseMotionListener { + private static final long serialVersionUID = 1L; + + JScrollPane scrollPane = new JScrollPane(); + NavButton upButton = new NavButton('^',10); + NavButton downButton = new NavButton('v',10); + JList m_list; + DateFormat m_format; + TimeModel m_timeModel; + int m_rowsPerHour = 4; + int m_minutesPerRow = 60 / m_rowsPerHour; + TimeRenderer m_renderer; + + private double getRowHeight() { + return m_list.getVisibleRect().getHeight()/m_list.getVisibleRowCount(); + } + + public TimeList(int rowsPerHour) { + super(); + this.setLayout( new BorderLayout()); + JPanel upPane = new JPanel(); + upPane.setLayout( new BorderLayout()); + upPane.add( upButton, BorderLayout.CENTER ); + JPanel downPane = new JPanel(); + downPane.setLayout( new BorderLayout()); + downPane.add( downButton, BorderLayout.CENTER ); + upButton.addActionListener( new ActionListener() { + public void actionPerformed( ActionEvent e ) + { + int direction = (int)- getRowHeight() * (m_list.getVisibleRowCount() -1); + JScrollBar bar = scrollPane.getVerticalScrollBar(); + int value = Math.min( Math.max( 0, bar.getValue() + direction ), bar.getMaximum()); + scrollPane.getVerticalScrollBar().setValue( value ); + } + + }); + downButton.addActionListener( new ActionListener() { + public void actionPerformed( ActionEvent e ) + { + int direction = (int) getRowHeight() * (m_list.getVisibleRowCount() -1) ; + JScrollBar bar = scrollPane.getVerticalScrollBar(); + int value = Math.min( Math.max( 0, bar.getValue() + direction ), bar.getMaximum()); + scrollPane.getVerticalScrollBar().setValue( value ); + } + + }); + + /* + upPane.addMouseListener( new Mover( -1)); + upButton.addMouseListener( new Mover( -1)); + downPane.addMouseListener( new Mover( 1)); + downButton.addMouseListener( new Mover( 1)); + */ + //upPane.setPreferredSize( new Dimension(0,0)); + //downPane.setPreferredSize( new Dimension(0,0)); + this.add(upPane, BorderLayout.NORTH); + this.add( scrollPane, BorderLayout.CENTER); + this.add( downPane, BorderLayout.SOUTH); + scrollPane.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER ); + scrollPane.getVerticalScrollBar().setEnabled( false ); + scrollPane.getVerticalScrollBar().setSize( new Dimension(0,0)); + scrollPane.getVerticalScrollBar().setPreferredSize( new Dimension(0,0)); + scrollPane.getVerticalScrollBar().setMaximumSize( new Dimension(0,0)); + scrollPane.getVerticalScrollBar().setMinimumSize( new Dimension(0,0)); + m_rowsPerHour = rowsPerHour; + m_minutesPerRow = 60 / m_rowsPerHour; + //this.setLayout(new BorderLayout()); + m_list = new JList(); + scrollPane.setViewportView( m_list); + m_list.setBackground(this.getBackground()); + //JScrollPane scrollPane = new JScrollPane(m_list, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + m_list.setVisibleRowCount(8); + m_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + m_list.addMouseListener(this); + m_list.addMouseMotionListener(this); + DefaultListCellRenderer cellRenderer = new DefaultListCellRenderer() { + private static final long serialVersionUID = 1L; + + public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus ) + { + int hour = getHourForIndex( index ); + int minute = getMinuteForIndex( index ); + String string = (String) value; + + Component component = super.getListCellRendererComponent( list, string, index, isSelected,cellHasFocus ); + if ( m_renderer!= null && !isSelected && !cellHasFocus ) { + Color color = m_renderer.getBackgroundColor( hour, minute ); + if ( color != null ) { + component.setBackground( color ); + } + } + return component; + } + }; + setRenderer(cellRenderer); + } + + @SuppressWarnings("unchecked") + private void setRenderer(DefaultListCellRenderer cellRenderer) { + m_list.setCellRenderer( cellRenderer); + } + + @SuppressWarnings("unchecked") + public void setModel(TimeModel model,DateFormat format) { + m_timeModel = model; + m_format = (DateFormat) format.clone(); + Calendar calendar = Calendar.getInstance(m_format.getTimeZone(),model.getLocale()); + DefaultListModel listModel = new DefaultListModel(); + for (int i=0;i<24 * m_rowsPerHour;i++) { + int hour = i/m_rowsPerHour; + int minute = (i%m_rowsPerHour) * m_minutesPerRow; + calendar.setTimeInMillis(0); + calendar.set(Calendar.HOUR_OF_DAY,hour ); + calendar.set(Calendar.MINUTE,minute); + Date durationStart = m_timeModel.getDurationStart(); + String duration = ""; + if ( m_renderer != null && durationStart != null) + { + Date time = calendar.getTime(); + long millis = time.getTime() - durationStart.getTime(); + int durationInMinutes = (int) (millis / (1000 * 60)); + duration = m_renderer.getDurationString(durationInMinutes); + } + String timeWithoutDuration = m_format.format(calendar.getTime()); + String time = timeWithoutDuration; + if ( duration != null) + { + time += " " + duration; + } + listModel.addElement(" " + time + " "); + } + m_list.setModel(listModel); + int pos = (int)getPreferredSize().getWidth()/2 - 5; + upButton.setLeftPosition( pos); + downButton.setLeftPosition( pos ); + } + + public void setTimeRenderer(TimeRenderer renderer) { + m_renderer = renderer; + } + + public JList getList() { + return m_list; + } + + public void setFont(Font font) { + super.setFont(font); + if (m_list == null || font == null) + return; + m_list.setFont(font); + int pos = (int)getPreferredSize().getWidth()/2 - 5; + upButton.setLeftPosition( pos); + downButton.setLeftPosition( pos ); + } + + /** Implementation-specific. Should be private.*/ + public void mousePressed(MouseEvent e) { + ok(); + } + /** Implementation-specific. Should be private.*/ + public void mouseClicked(MouseEvent e) { + } + /** Implementation-specific. Should be private.*/ + public void mouseReleased(MouseEvent e) { + } + /** Implementation-specific. Should be private.*/ + public void mouseEntered(MouseEvent me) { + } + /** Implementation-specific. Should be private.*/ + public void mouseExited(MouseEvent me) { + } + + + private int lastIndex = -1; + private int lastY= -1; + public void mouseDragged(MouseEvent e) { + } + public void mouseMoved(MouseEvent e) { + if (e.getY() == lastY) + return; + lastY = e.getY(); + Point p = new Point(e.getX(),e.getY()); + int index = m_list.locationToIndex(p); + if (index == lastIndex) + return; + lastIndex = index; + m_list.setSelectedIndex(index); + } + + public void selectTime(Date time) { + Calendar calendar = Calendar.getInstance(m_timeModel.getTimeZone(),m_timeModel.getLocale()); + calendar.setTime(time); + int index = (calendar.get(Calendar.HOUR_OF_DAY)) * m_rowsPerHour + + (calendar.get(Calendar.MINUTE) / m_minutesPerRow); + select(index); + } + + + private void select(int index) { + m_list.setSelectedIndex(index); + m_list.ensureIndexIsVisible(Math.max(index -3,0)); + m_list.ensureIndexIsVisible(Math.min(index + 3,m_list.getModel().getSize() -1)); + } + + + // Start of MenuElement implementation + public Component getComponent() { + return this; + } + public MenuElement[] getSubElements() { + return new MenuElement[0]; + } + + public void menuSelectionChanged(boolean isIncluded) { + } + + public void processKeyEvent(KeyEvent event, MenuElement[] path, MenuSelectionManager manager) { + int index; + if (event.getID() == KeyEvent.KEY_PRESSED) { + switch (event.getKeyCode()) { + case (KeyEvent.VK_KP_UP): + case (KeyEvent.VK_UP): + index = m_list.getSelectedIndex(); + if (index > 0) + select(index - 1); + break; + case (KeyEvent.VK_KP_DOWN): + case (KeyEvent.VK_DOWN): + index = m_list.getSelectedIndex(); + if (index = 0) { + calendar.set(Calendar.HOUR_OF_DAY,hour ); + calendar.set(Calendar.MINUTE,minute); + calendar.set(Calendar.SECOND,0); + calendar.set(Calendar.MILLISECOND,0); + m_timeModel.setTime(calendar.getTime()); + } + } + + public void processMouseEvent(MouseEvent event, MenuElement[] path, MenuSelectionManager manager) { + } + // End of MenuElement implementation + +} + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendar/TimeField.java b/rapla-source-1.8.2/src/org/rapla/components/calendar/TimeField.java new file mode 100644 index 0000000..083cfb2 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendar/TimeField.java @@ -0,0 +1,307 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendar; + +import java.text.DateFormat; +import java.text.FieldPosition; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; +/** The TimeField only accepts characters that are part of DateFormat.getTimeInstance(DateFormat.SHORT,locale). + * The input blocks are [hour,minute,am_pm] or [hour_of_day,minute] + * depending on the selected locale. You can use the keyboard to + * navigate between the blocks or to increment/decrement the blocks. + * @see AbstractBlockField + */ + +final public class TimeField extends AbstractBlockField { + private static final long serialVersionUID = 1L; + + private DateFormat m_outputFormat; + private DateFormat m_parsingFormat; + private Calendar m_calendar; + private int m_rank[] = null; + private char[] m_separators; + private boolean m_useAM_PM = false; + private boolean americanAM_PM_character = false; + + public TimeField() { + this(Locale.getDefault()); + } + + public TimeField(Locale locale) { + this(locale, TimeZone.getDefault()); + } + + public TimeField(Locale locale,TimeZone timeZone) { + super(); + m_calendar = Calendar.getInstance(timeZone, locale); + super.setLocale(locale); + setFormat(); + setTime(new Date()); + } + + + public void setLocale(Locale locale) { + super.setLocale(locale); + if (locale != null && getTimeZone() != null) + setFormat(); + } + + private void setFormat() { + m_parsingFormat = DateFormat.getTimeInstance(DateFormat.SHORT, getLocale()); + m_parsingFormat.setTimeZone(getTimeZone()); + Date oldDate = m_calendar.getTime(); + m_calendar.set(Calendar.HOUR_OF_DAY,0); + m_calendar.set(Calendar.MINUTE,0); + String formatStr = m_parsingFormat.format(m_calendar.getTime()); + + FieldPosition minutePos = new FieldPosition(DateFormat.MINUTE_FIELD); + m_parsingFormat.format(m_calendar.getTime(), new StringBuffer(),minutePos); + + FieldPosition hourPos = new FieldPosition(DateFormat.HOUR0_FIELD); + StringBuffer hourBuf = new StringBuffer(); + m_parsingFormat.format(m_calendar.getTime(), hourBuf,hourPos); + + FieldPosition hourPos1 = new FieldPosition(DateFormat.HOUR1_FIELD); + StringBuffer hourBuf1 = new StringBuffer(); + m_parsingFormat.format(m_calendar.getTime(), hourBuf1,hourPos1); + + FieldPosition amPmPos = new FieldPosition(DateFormat.AM_PM_FIELD); + m_parsingFormat.format(m_calendar.getTime(), new StringBuffer(),amPmPos); + + String zeroDigit = m_parsingFormat.getNumberFormat().format(0); + int zeroPos = hourBuf.toString().indexOf(zeroDigit,hourPos.getBeginIndex()); + + // 0:30 or 12:30 + boolean zeroBased = (zeroPos == 0); + String testFormat = m_parsingFormat.format( m_calendar.getTime() ).toLowerCase(); + int mp = minutePos.getBeginIndex(); + int ap = amPmPos.getBeginIndex(); + int hp = Math.max( hourPos.getBeginIndex(), hourPos1.getBeginIndex() ); + + int pos[] = null; + + // Use am/pm + if (amPmPos.getEndIndex()>0) { + m_useAM_PM = true; + americanAM_PM_character = m_useAM_PM && (testFormat.indexOf( "am" )>=0 || testFormat.indexOf( "pm" )>=0); + // System.out.println(formatStr + " hour:"+hp+" minute:"+mp+" ampm:"+ap); + if (hp<0 || mp<0 || ap<0 || formatStr == null) { + throw new IllegalArgumentException("Can't parse the time-format for this locale: " + formatStr); + } + // quick and diry sorting + if (mp m_listenerList = new ArrayList(); + + public TimeModel(Locale locale,TimeZone timeZone) { + m_locale = locale; + m_calendar = Calendar.getInstance(timeZone, m_locale); + trim(m_calendar); + m_calendar.setLenient(true); + } + + public void addDateChangeListener(DateChangeListener listener) { + m_listenerList.add(listener); + } + + public void removeDateChangeListener(DateChangeListener listener) { + m_listenerList.remove(listener); + } + + public Locale getLocale() {return m_locale; } + public Date getTime() { + return m_calendar.getTime(); + } + + public Date getDurationStart() + { + return durationStart; + } + + public void setDurationStart(Date durationStart) + { + if ( durationStart == null) + { + this.durationStart = durationStart; + return; + } + Calendar clone = Calendar.getInstance(m_calendar.getTimeZone(), m_locale); + clone.setTime( durationStart); + trim(clone); + this.durationStart = clone.getTime(); + } + + // #TODO Property change listener for TimeZone + public void setTimeZone(TimeZone timeZone) { + m_calendar.setTimeZone(timeZone); + } + + public TimeZone getTimeZone() { + return m_calendar.getTimeZone(); + } + + public void setTime(int hours,int minutes) { + m_calendar.set(Calendar.HOUR_OF_DAY,hours); + m_calendar.set(Calendar.MINUTE,minutes); + trim(m_calendar); + fireDateChanged(); + } + + public void setTime(Date date) { + m_calendar.setTime(date); + trim(m_calendar); + fireDateChanged(); + } + + public boolean sameTime(Date date) { + Calendar calendar = Calendar.getInstance(getTimeZone(), getLocale()); + calendar.setTime(date); + trim(calendar); + return calendar.getTime().equals(getTime()); + } + + private void trim(Calendar calendar) { + int hours = calendar.get(Calendar.HOUR_OF_DAY); + int minutes = calendar.get(Calendar.MINUTE); + calendar.setTimeInMillis(0); + calendar.set(Calendar.HOUR_OF_DAY, hours); + calendar.set(Calendar.MINUTE, minutes); + } + + public DateChangeListener[] getDateChangeListeners() { + return m_listenerList.toArray(new DateChangeListener[]{}); + } + + protected void fireDateChanged() { + DateChangeListener[] listeners = getDateChangeListeners(); + DateChangeEvent evt = new DateChangeEvent(this,getTime()); + for (int i = 0;i +Contains widgets for date- and time- selection. +This package is independant from the rest of rapla. + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/AbstractCalendar.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/AbstractCalendar.java new file mode 100644 index 0000000..fdc66d6 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/AbstractCalendar.java @@ -0,0 +1,238 @@ +package org.rapla.components.calendarview; + +import java.text.DateFormat; +import java.text.FieldPosition; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.Iterator; +import java.util.Locale; +import java.util.TimeZone; + +import org.rapla.components.util.DateTools; + +public abstract class AbstractCalendar { + private int daysInView = 7; + private int firstWeekday = Calendar.getInstance().getFirstDayOfWeek(); + /** shared calendar instance. Only used for temporary stored values. */ + protected Calendar blockCalendar; + protected Collection excludeDays = Collections.emptySet(); + + private Date startDate; + private Date endDate; + protected Locale locale; + protected TimeZone timeZone; + protected int daysInMonth; + + protected Collection builders = new ArrayList(); + + public int getDaysInView() { + return daysInView; + } + + public void setDaysInView(int daysInView) + { + this.daysInView = daysInView; + } + + public int getFirstWeekday() + { + return firstWeekday; + } + + public void setFirstWeekday(int firstDayOfWeek) { + this.firstWeekday = firstDayOfWeek; + } + + public String getWeekdayName(int weekday) + { + SimpleDateFormat format = new SimpleDateFormat("EEEEEE",locale); + Calendar calendar = createCalendar(); + calendar.set(Calendar.DAY_OF_WEEK, weekday); + String weekdayName = format.format(calendar.getTime()); + return weekdayName; + } + + protected boolean isExcluded(int column) + { + if ( daysInView == 1) + { + return false; + } + blockCalendar.set(Calendar.DAY_OF_WEEK, getFirstWeekday()); + blockCalendar.add(Calendar.DATE, column); + int weekday = blockCalendar.get(Calendar.DAY_OF_WEEK); + if ( !excludeDays.contains(new Integer( weekday )) ) { + return false; + } + boolean empty = isEmpty(column); + return empty; + } + + abstract protected boolean isEmpty(int column); + + public void setTimeZone(TimeZone timeZone) { + this.timeZone = timeZone; + blockCalendar = createCalendar(); + } + + protected Calendar createCalendar() { + return Calendar.getInstance(getTimeZone(),locale); + } + + public TimeZone getTimeZone() { + return timeZone; + } + + public void setLocale(Locale locale) { + this.locale = locale; + // Constructor called? + if (timeZone != null) { + setTimeZone( timeZone ); + blockCalendar = createCalendar(); + } + } + + public void setToDate(Date date) + { + calcMinMaxDates( date ); + } + + public Date getStartDate() + { + return startDate; + } + + public Date getEndDate() + { + return endDate; + } + + protected void setStartDate(Date date) + { + this.startDate = date; + } + + protected void setEndDate(Date date) + { + this.endDate = date; + } + + public void setExcludeDays(Collection excludeDays) { + this.excludeDays = excludeDays; + if (getStartDate() != null) + calcMinMaxDates( getStartDate() ); + } + + public void rebuild(Builder builder) { + try { + addBuilder( builder); + rebuild(); + } finally { + removeBuilder( builder ); + } + } + + public void calcMinMaxDates(Date date) + { + Calendar blockCalendar = createCalendar(); + blockCalendar.setTime( date ); + blockCalendar.set(Calendar.HOUR_OF_DAY,0); + blockCalendar.set(Calendar.MINUTE,0); + blockCalendar.set(Calendar.SECOND,0); + blockCalendar.set(Calendar.MILLISECOND,0); + this.daysInMonth = blockCalendar.getActualMaximum( Calendar.DAY_OF_MONTH ) ; + if ( daysInView > 14) + { + blockCalendar.set(Calendar.DAY_OF_MONTH, 1); + this.startDate = blockCalendar.getTime(); + blockCalendar.set(Calendar.MILLISECOND,1); + + blockCalendar.set(Calendar.MILLISECOND,0); + blockCalendar.add(Calendar.DATE, this.daysInMonth); + this.endDate = blockCalendar.getTime(); + firstWeekday = blockCalendar.getFirstDayOfWeek(); + } + else + { + if ( daysInView >= 3) + { + int firstWeekday2 = getFirstWeekday(); + blockCalendar.set(Calendar.DAY_OF_WEEK, firstWeekday2); + if ( blockCalendar.getTime().after( date)) + { + blockCalendar.add(Calendar.DATE, -7); + } + } + else + { + firstWeekday = blockCalendar.get( Calendar.DAY_OF_WEEK); + } + startDate = blockCalendar.getTime(); + endDate =DateTools.addDays(startDate, daysInView); + } + } + + public abstract void rebuild(); + + public Iterator getBuilders() { + return builders.iterator(); + } + + public void addBuilder(Builder b) { + builders.add(b); + } + + public void removeBuilder(Builder b) { + builders.remove(b); + } + + /** formats the date and month in the selected locale and timeZone*/ + public static String formatDateMonth(Date date, Locale locale, TimeZone timeZone) { + FieldPosition fieldPosition = new FieldPosition( DateFormat.YEAR_FIELD ); + StringBuffer buf = new StringBuffer(); + DateFormat format = DateFormat.getDateInstance( DateFormat.SHORT, locale); + format.setTimeZone( timeZone ); + buf = format.format(date, + buf, + fieldPosition + ); + if ( fieldPosition.getEndIndex()=0) ) { + buf.delete( fieldPosition.getBeginIndex(), fieldPosition.getEndIndex() ); + } + char lastChar = buf.charAt(buf.length()-1); + if (lastChar == '/' || lastChar == '-' ) { + String result = buf.substring(0,buf.length()-1); + return result; + } else { + String result = buf.toString(); + return result; + } + } + + /** formats the day of week, date and month in the selected locale and timeZone*/ + public static String formatDayOfWeekDateMonth(Date date, Locale locale, TimeZone timeZone) { + SimpleDateFormat format = new SimpleDateFormat("EEE", locale); + format.setTimeZone(timeZone); + String datePart = format.format(date); + String dateOfMonthPart = AbstractCalendar.formatDateMonth( date,locale,timeZone ); + return datePart + " " + dateOfMonthPart ; + } + + public static boolean isAmPmFormat(Locale locale) { + // Determines if am-pm-format should be used. + DateFormat format= DateFormat.getTimeInstance(DateFormat.SHORT, locale); + FieldPosition amPmPos = new FieldPosition(DateFormat.AM_PM_FIELD); + format.format(new Date(), new StringBuffer(),amPmPos); + return (amPmPos.getEndIndex()>0); + } + + + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/AbstractGroupStrategy.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/AbstractGroupStrategy.java new file mode 100644 index 0000000..5cc9e4e --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/AbstractGroupStrategy.java @@ -0,0 +1,246 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender, Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendarview; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.rapla.components.util.DateTools; + +/** Arranges blocks into groups, and tries to place one group into one slot. + The subclass must overide the group method to perform the grouping on a given + list of blocks. +*/ +public abstract class AbstractGroupStrategy implements BuildStrategy { + boolean m_sortSlotsBySize; + public static long MILLISECONDS_PER_DAY = 24 * 3600 * 1000; + private boolean m_fixedSlots; + private boolean m_conflictResolving; + + protected Comparator blockComparator = new BlockComparator(); + + protected Comparator> slotComparator = new Comparator>() { + public int compare(List s1,List s2) { + if (s1.size() == 0 || s2.size() ==0) { + if (s1.size() == s2.size()) + return 0; + else + return s1.size() < s2.size() ? -1 : 1; + } + + Block b1 = s1.get(0); + Block b2 = s2.get(0); + return b1.getStart().compareTo(b2.getStart()); + } + }; + + + + public void build(CalendarView wv, List blocks) + { + LinkedHashMap> days = new LinkedHashMap>(); + Map blockMap = getBlockMap(wv, blocks); + for (Block b:blockMap.keySet()) { + Integer index = blockMap.get(b); + List list = days.get(index); + + if (list == null) + { + list = new ArrayList(); + days.put(index, list); + } + list.add(b); + } + + for (Integer day: days.keySet()) + { + List list = days.get(day); + Collections.sort(list, blockComparator); + if (list == null) + continue; + insertDay( wv, day,list ); + } + } + + protected Map getBlockMap(CalendarView wv, List blocks) { + Map map = new LinkedHashMap(); + Date startDate = wv.getStartDate(); + for (Block block:blocks) { + int days = (int)DateTools.countDays(startDate, block.getStart()); + map.put(block, days); + } + return map; + } + + protected void insertDay(CalendarView wv, int column,List blockList) { + Iterator> it = getSortedSlots(blockList).iterator(); + int slotCount= 0; + while (it.hasNext()) { + List slot = it.next(); + if (slot == null) { + continue; + } + for (Block bl:slot) { + wv.addBlock(bl,column,slotCount); + } + slotCount ++; + } + } + + /** You can split the blockList into different groups. + * This method returns a collection of lists. + * Each list represents a group + * of blocks. + * @return a collection of List-objects + * @see List + * @see Collection + */ + abstract protected Collection> group(List blockList); + + public boolean isSortSlotsBySize() { + return m_sortSlotsBySize; + } + + public void setSortSlotsBySize(boolean enable) { + m_sortSlotsBySize = enable; + } + + /** takes a block list and returns a sorted slotList */ + protected List> getSortedSlots(List blockList) { + Collection> group = group(blockList); + List> slots = new ArrayList>(group); + if ( isResolveConflictsEnabled()) { + resolveConflicts(slots); + } + if ( !isFixedSlotsEnabled() ) { + mergeSlots(slots); + } + if (isSortSlotsBySize()) + Collections.sort(slots, slotComparator); + return slots; + } + + protected boolean isCollision(Block b1, Block b2) { + final long start1 = b1.getStart().getTime(); + long minimumLength = DateTools.MILLISECONDS_PER_MINUTE * 5; + final long end1 = Math.max(start1+ minimumLength,b1.getEnd().getTime()); + + final long start2 = b2.getStart().getTime(); + final long end2 = Math.max(start2 + minimumLength,b2.getEnd().getTime()); + + boolean result = start1 < end2 && start2 > groups) { + int pos = 0; + while (pos < groups.size()) { + List group = groups.get(pos++ ); + List newSlot = null; + int i = 0; + while (i< group.size()) { + Block element1 = group.get( i++ ); + int j = i; + while (j< group.size()) { + Block element2 = group.get( j ++); + if ( isCollision( element1, element2 ) ) { + group.remove( element2 ); + j --; + if (newSlot == null) { + newSlot = new ArrayList(); + groups.add(pos, newSlot); + } + newSlot.add( element2); + } + } + } + } + } + + /** the lists must be sorted */ + private boolean canMerge(List slot1,List slot2) { + int size1 = slot1.size(); + int size2 = slot2.size(); + int i = 0; + int j = 0; + while (i> slots) { + // We use a (sub-optimal) greedy algorithm for merging slots + int pos = 0; + while (pos < slots.size()) { + List slot1 = slots.get(pos ++); + for (int i= pos; i slot2 = slots.get(i); + if (canMerge(slot1, slot2)) { + slot1.addAll(slot2); + Collections.sort(slot1, blockComparator); + slots.remove(slot2); + pos --; + break; + } + } + } + } + + public void setFixedSlotsEnabled( boolean enable) { + m_fixedSlots = enable; + } + + public boolean isFixedSlotsEnabled() { + return m_fixedSlots; + } + + + /** enables or disables conflict resolving. If turned on and 2 blocks ocupy the same slot, + * a new slot will be inserted dynamicly + * @param enable + */ + public void setResolveConflictsEnabled( boolean enable) { + m_conflictResolving = enable; + } + + public boolean isResolveConflictsEnabled() { + return m_conflictResolving; + } + + public Comparator getBlockComparator() { + return blockComparator; + } + + public void setBlockComparator(Comparator blockComparator) { + this.blockComparator = blockComparator; + } + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/BestFitStrategy.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/BestFitStrategy.java new file mode 100644 index 0000000..2eee840 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/BestFitStrategy.java @@ -0,0 +1,28 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender, Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.calendarview; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** This strategy groups all blocks in a single group */ +public class BestFitStrategy extends AbstractGroupStrategy { + protected Collection> group(List blockList) { + List> singleGroup = new ArrayList>(); + singleGroup.add(blockList); + return singleGroup; + } +} + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/Block.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/Block.java new file mode 100644 index 0000000..bfd845f --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/Block.java @@ -0,0 +1,35 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.calendarview; + +import java.util.Date; +/** +implementierung von block koennen in ein slot eingefuegt werden. +Sie dienen als modell fuer beliebige grafische komponenten. +mit getStart() und getEnd() wird anfangs- und endzeit des blocks definiert +(nur uhrzeit ist fuer positionierung in slots relevant). +*/ +public interface Block +{ + Date getStart(); + Date getEnd(); + String getName(); +} + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/BlockComparator.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/BlockComparator.java new file mode 100644 index 0000000..2c7b674 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/BlockComparator.java @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.calendarview; + +import java.util.Comparator; + +/** Compares to blocks by the starting time. block1 { + public static BlockComparator COMPARATOR = new BlockComparator(); + public int compare(Block b1,Block b2) { + int result = b1.getStart().compareTo(b2.getStart()); + if (result != 0) + return result; + else + return b1.getName().compareTo(b2.getName()); + + } +} + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/BuildStrategy.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/BuildStrategy.java new file mode 100644 index 0000000..318f05a --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/BuildStrategy.java @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender, Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.calendarview; + +import java.util.List; + +public interface BuildStrategy { + public void build(CalendarView wv,List blocks); +} + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/Builder.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/Builder.java new file mode 100644 index 0000000..f0e972e --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/Builder.java @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendarview; + +import java.util.Date; + +public interface Builder { + /** Calculate the blocks that should be displayed in the weekview. + * This method should not be called manually. + * It is called by the CalendarView during the build process. + * @see #build + * @param start + * @param end + */ + void prepareBuild(Date start, Date end); + + /** The maximal ending-time of all blocks that should be displayed. + Call prepareBuild first to calculate the blocks.*/ + int getMaxMinutes(); + + /** The minimal starting-time of all blocks that should be displayed. + Call prepareBuild first to calculate the blocks.*/ + int getMinMinutes(); + + /** Build the calculated blocks into the weekview. This method should not be called manually. + * It is called by the CalendarView during the build process. + * @see #prepareBuild */ + void build(CalendarView cv); + + void setEnabled(boolean enable); + boolean isEnabled(); +} + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/CalendarView.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/CalendarView.java new file mode 100644 index 0000000..93a0640 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/CalendarView.java @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender, Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendarview; +import java.util.Collection; +import java.util.Date; +import java.util.TimeZone; +public interface CalendarView +{ + public TimeZone getTimeZone(); + + /** returns the first Date that will be displayed in the calendar */ + public Date getStartDate(); + /** returns the last Date that will be displayed in the calendar */ + public Date getEndDate(); + + /** sets the calendarview to the selected date*/ + public void setToDate(Date weekDate); + + /** This method removes all existing blocks first. + * Then it calls the build method of all added builders, so that they can add blocks into the CalendarView again. + * After all blocks are added the Calendarthat repaints the screen. + */ + public void rebuild(); + + /** Adds a block. You can optionaly specify a slot, if the day-view supports multiple slots (like in the weekview). + * If the selected slot does not exist it will be created. This method is usually called by the builders. + */ + public void addBlock(Block bl, int column,int slot); + + /** returns a collection of all the added blocks + * @see #addBlock*/ + Collection getBlocks(); +} + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/DEPENDENCIES b/rapla-source-1.8.2/src/org/rapla/components/calendarview/DEPENDENCIES new file mode 100644 index 0000000..e91a426 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/DEPENDENCIES @@ -0,0 +1,4 @@ +This component depends on the following packages (including subpackages) +java.* +javax.swing.* +org.rapla.components.layout.* diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/GroupStartTimesStrategy.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/GroupStartTimesStrategy.java new file mode 100644 index 0000000..83bf9f8 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/GroupStartTimesStrategy.java @@ -0,0 +1,141 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender, Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendarview; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import org.rapla.components.util.DateTools; +import org.rapla.entities.domain.Allocatable; +import org.rapla.plugin.abstractcalendar.AbstractRaplaBlock; + +/** Tries to put reservations that allocate the same Ressources in the same column.*/ +public class GroupStartTimesStrategy extends AbstractGroupStrategy { + List allocatables; + + List startTimes = new ArrayList(); + + + { + for ( int i=0;i<=23;i++) + { + startTimes.add(i*60); + } + } + + @Override + protected Map getBlockMap(CalendarView wv, + List blocks) + { + if (allocatables != null) + { + Map map = new LinkedHashMap(); + for (Block block:blocks) + { + AbstractRaplaBlock b = (AbstractRaplaBlock)block; + for (Allocatable a:b.getReservation().getAllocatablesFor(b.getAppointment())) + { + int index = allocatables.indexOf( a ); + if ( index >= 0 ) + { + map.put( block, index ); + } + } + } + return map; + } + else + { + return super.getBlockMap(wv, blocks); + } + } + + @Override + protected List> getSortedSlots(List list) { + TreeMap> groups = new TreeMap>(); + for (Iterator it = list.iterator();it.hasNext();) { + Block block = it.next(); + long startTime = block.getStart().getTime(); + int minuteOfDay = DateTools.getMinuteOfDay(startTime); + int rowNumber = -1 ; + for ( Integer start: startTimes) + { + if ( start <= minuteOfDay) + { + rowNumber++; + } + else + { + break; + } + } + if ( rowNumber <0) + { + rowNumber = 0; + } + + List col = groups.get( rowNumber ); + if (col == null) { + col = new ArrayList(); + groups.put( rowNumber, col ); + } + col.add(block); + } + List> slots = new ArrayList>(); + for (int row =0 ;row oneRow = groups.get( row ); + if ( oneRow == null) + { + oneRow = new ArrayList(); + } + else + { + Collections.sort( oneRow, blockComparator); + } + slots.add(oneRow); + } + return slots; + } + + @Override + protected Collection> group(List blockList) { + List> singleGroup = new ArrayList>(); + singleGroup.add(blockList); + return singleGroup; + } + + public List getAllocatables() { + return allocatables; + } + + public void setAllocatables(List allocatables) { + this.allocatables = allocatables; + } + + public List getStartTimes() { + return startTimes; + } + + public void setStartTimes(List startTimes) { + this.startTimes = startTimes; + } + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/MonthMapper.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/MonthMapper.java new file mode 100644 index 0000000..64c4c34 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/MonthMapper.java @@ -0,0 +1,64 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas, Bettina Lademann | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendarview; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Locale; + + +/** maps weekday names to Calendar.DAY_OF_WEEK. + Example: +
    +       WeekdayMapper mapper = new WeekdayMapper();
    +       // print name of Sunday
    +       System.out.println(mapper.getName(Calendar.SUNDAY));
    +       // Create a weekday ComboBox
    +       JComboBox comboBox = new JComboBox();
    +       comboBox.setModel(new DefaultComboBoxModel(mapper.getNames()));
    +       // select sunday
    +       comboBox.setSelectedIndex(mapper.getIndexForDay(Calendar.SUNDAY));
    +       // weekday == Calendar.SUNDAY
    +       int weekday = mapper.getDayForIndex(comboBox.getSelectedIndex());
    +   
    + +*/ +public class MonthMapper { + String[] monthNames; + + public MonthMapper() { + this(Locale.getDefault()); + } + + public MonthMapper(Locale locale) { + monthNames = new String[12]; + SimpleDateFormat format = new SimpleDateFormat("MMMMMM",locale); + Calendar calendar = Calendar.getInstance(locale); + for (int i=0;i<12;i++) { + calendar.set(Calendar.MONTH,i); + monthNames[i] = format.format(calendar.getTime()); + } + } + + public String[] getNames() { + return monthNames; + } + + /** month are 0 based */ + public String getName(int month) { + return getNames()[month]; + } + + +} + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/WeekdayMapper.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/WeekdayMapper.java new file mode 100644 index 0000000..64bfb03 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/WeekdayMapper.java @@ -0,0 +1,86 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas, Bettina Lademann | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendarview; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; + + +/** maps weekday names to Calendar.DAY_OF_WEEK. + Example: +
    +       WeekdayMapper mapper = new WeekdayMapper();
    +       // print name of Sunday
    +       System.out.println(mapper.getName(Calendar.SUNDAY));
    +       // Create a weekday ComboBox
    +       JComboBox comboBox = new JComboBox();
    +       comboBox.setModel(new DefaultComboBoxModel(mapper.getNames()));
    +       // select sunday
    +       comboBox.setSelectedIndex(mapper.getIndexForDay(Calendar.SUNDAY));
    +       // weekday == Calendar.SUNDAY
    +       int weekday = mapper.getDayForIndex(comboBox.getSelectedIndex());
    +   
    + +*/ +public class WeekdayMapper { + String[] weekdayNames; + int[] weekday2index; + int[] index2weekday; + Map map = new LinkedHashMap(); + + public WeekdayMapper() { + this(Locale.getDefault()); + } + + public WeekdayMapper(Locale locale) + { + int days = 7; + weekdayNames = new String[days]; + weekday2index = new int[days+1]; + index2weekday = new int[days+1]; + SimpleDateFormat format = new SimpleDateFormat("EEEEEE",locale); + Calendar calendar = Calendar.getInstance(locale); + calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek()); + for (int i=0;i getBlocks(); + + void checkBlock( Block bl ) { + Date endDate = getEndDate(); + if ( !bl.getStart().before(endDate)) { + throw new IllegalStateException("Start-date " +bl.getStart() + " must be before calendar end at " +endDate); + } + } + + + public String getHtml() { + return m_html; + } + + + protected class HTMLSmallDaySlot extends ArrayList { + private static final long serialVersionUID = 1L; + + private String date; + private Date startTime; + public HTMLSmallDaySlot(String date) { + super(2); + this.date = date; + } + public void putBlock(Block block) { + add( block ); + } + public void sort() { + Collections.sort( this, BlockComparator.COMPARATOR); + } + + public void paint(StringBuffer out) { + out.append("
    "); + out.append( date ); + out.append("
    \n"); + for ( int i=0;i"); + out.append(block.toString()); + out.append("\n"); + } + } + + public void setStart(Date date) + { + startTime = date; + } + + public Date getStart() + { + return startTime; + } + } + + + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/html/HTMLBlock.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/html/HTMLBlock.java new file mode 100644 index 0000000..cbea980 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/html/HTMLBlock.java @@ -0,0 +1,8 @@ +package org.rapla.components.calendarview.html; + +import org.rapla.components.calendarview.Block; + +public interface HTMLBlock extends Block { + String getBackgroundColor(); + String toString(); +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/html/HTMLCompactWeekView.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/html/HTMLCompactWeekView.java new file mode 100644 index 0000000..d436816 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/html/HTMLCompactWeekView.java @@ -0,0 +1,210 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.calendarview.html; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.rapla.components.calendarview.AbstractCalendar; +import org.rapla.components.calendarview.Block; +import org.rapla.components.calendarview.Builder; +import org.rapla.components.util.DateTools; + +public class HTMLCompactWeekView extends AbstractHTMLView { + public final static int ROWS = 6; //without the header row + /** shared calendar instance. Only used for temporary stored values. */ + HTMLSmallDaySlot[] slots = {}; + String[] slotNames = {}; + private ArrayList> rows = new ArrayList>(); + Map columnMap = new HashMap(); + private double leftColumnSize = 0.1; + String weeknumber = ""; + + public String getWeeknumber() { + return weeknumber; + } + + public void setWeeknumber(String weeknumber) { + this.weeknumber = weeknumber; + } + + public void setLeftColumnSize(double leftColumnSize) { + this.leftColumnSize = leftColumnSize; + } + + public void setSlots( String[] slotNames ) { + this.slotNames = slotNames; + } + + public Collection getBlocks() { + ArrayList list = new ArrayList(); + for (int i=0;i headerNames; + int columns = getColumnCount(); + headerNames = getHeaderNames(); + columnMap.clear(); + rows.clear(); + for ( int i=0; i it= builders.iterator(); + while (it.hasNext()) { + Builder b= it.next(); + b.prepareBuild(getStartDate(),getEndDate()); + } + + // build Blocks + it= builders.iterator(); + while (it.hasNext()) { + Builder b= it.next(); + if (b.isEnabled()) { b.build(this); } + } + + Calendar calendar = createCalendar(); + calendar.setTime(getStartDate()); + calendar.set( Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek()); + + // resource header + + // add headers + StringBuffer result = new StringBuffer(); + result.append("\n"); + result.append("\n"); + + result.append(""); + String percentage = "" + Math.round(95.0 / (Math.max(0, columns))); + + int rowsize = rows.size(); + slots = new HTMLSmallDaySlot[rowsize * columns]; + for (int row=0;row blocks = rows.get( row ); + int fieldNumber = row * columns + column; + slots[fieldNumber] = createField( blocks, column ); + } + } + + for (int i=0;i"); + result.append(""); + result.append(headerNames.get(i)); + result.append(""); + result.append(""); + } + result.append("\n"); + + for (int row=0;row\n"); + result.append("\n"); + for (int column=0;column < columns; column++) { + int fieldNumber = row * columns + column; + if ( !isExcluded( column ) ) { + result.append("\n"); + } + } + result.append("\n"); + } + result.append("
    "); + result.append(weeknumber); + result.append("
    \n"); + if ( slotNames.length > row ) { + result.append( slotNames[ row ] ); + } + result.append("\n"); + slots[fieldNumber].paint( result ); + result.append("
    "); + m_html = result.toString(); + } + + protected List getHeaderNames() { + List headerNames = new ArrayList(); + blockCalendar.setTime(getStartDate()); + int columnCount = getColumnCount(); + for (int i=0;i blocks, int column) { + HTMLSmallDaySlot c = new HTMLSmallDaySlot(""); + c.setStart(DateTools.addDays( getStartDate(), column)); + if ( blocks != null) { + Iterator it = blocks.iterator(); + while (it.hasNext()){ + HTMLBlock block = (HTMLBlock)it.next(); + if (columnMap.get( block) == column) { + c.putBlock( block ); + } + } + } + c.sort(); + return c; + } + + + public void addBlock(Block block, int column,int slot) { + checkBlock( block ); + while ( rows.size() <= slot ) { + addRow(); + } + List blocks = rows.get( slot ); + blocks.add( block ); + columnMap.put(block, column); + } + + private void addRow() { + rows.add( rows.size(), new ArrayList()); + } + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/html/HTMLMonthView.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/html/HTMLMonthView.java new file mode 100644 index 0000000..8678336 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/html/HTMLMonthView.java @@ -0,0 +1,167 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.calendarview.html; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.Iterator; + +import org.rapla.components.calendarview.Block; +import org.rapla.components.calendarview.Builder; +import org.rapla.components.util.DateTools; + +public class HTMLMonthView extends AbstractHTMLView { + public final static int ROWS = 6; //without the header row + public final static int COLUMNS = 7; + HTMLSmallDaySlot[] slots; + + public Collection getBlocks() { + ArrayList list = new ArrayList(); + for (int i=0;i it= builders.iterator(); + final Date startDate = getStartDate(); + while (it.hasNext()) { + Builder b= it.next(); + b.prepareBuild(startDate,getEndDate()); + } + slots = new HTMLSmallDaySlot[ daysInMonth ]; + for (int i=0;i" + monthYearFormat.format(startDate) + "\n"); + + result.append("\n"); + result.append("\n"); + + counter.setTime( time ); + for (int i=0;i"); + result.append(""); + String name = getWeekdayName(weekday); + result.append(name); + result.append(""); + result.append(""); + counter.add(Calendar.DATE, 1); + } + result.append("\n"); + + for (int row=0; row<=lastRow; row++) { + boolean excludeRow = true; + // calculate if we can exclude the row + for (int column = 0; column\n"); + for (int column = 0; column\n"); + } else { + result.append("\n"); + } + } + result.append("\n"); + } + result.append("
    \n"); + slot.paint( result ); + result.append("
    "); + m_html = result.toString(); + } + + public void addBlock(Block block,int col,int slot) { + checkBlock( block ); + blockCalendar.setTime(block.getStart()); + int day = blockCalendar.get(Calendar.DATE); + slots[day-1].putBlock( block ); + } + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/html/HTMLWeekView.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/html/HTMLWeekView.java new file mode 100644 index 0000000..05be62a --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/html/HTMLWeekView.java @@ -0,0 +1,432 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.calendarview.html; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.rapla.components.calendarview.AbstractCalendar; +import org.rapla.components.calendarview.Block; +import org.rapla.components.calendarview.Builder; + +public class HTMLWeekView extends AbstractHTMLView { + private int endMinutes; + private int minMinute; + private int maxMinute; + private int startMinutes; + int m_rowsPerHour = 2; + HTMLDaySlot[] multSlots ; + ArrayList blocks = new ArrayList(); + //ArrayList blockStart = new ArrayList(); + //ArrayList blockSize = new ArrayList(); + + String weeknumber; + + /** The granularity of the selection rows. + *
      + *
    • 1: 1 rows per hour = 1 Hour
    • + *
    • 2: 2 rows per hour = 1/2 Hour
    • + *
    • 3: 3 rows per hour = 20 Minutes
    • + *
    • 4: 4 rows per hour = 15 Minutes
    • + *
    • 6: 6 rows per hour = 10 Minutes
    • + *
    • 12: 12 rows per hour = 5 Minutes
    • + *
    + * Default is 2. + */ + public void setRowsPerHour(int rows) { + m_rowsPerHour = rows; + } + + public int getRowsPerHour() { + return m_rowsPerHour; + } + + public void setWorktime(int startHour, int endHour) { + this.startMinutes = startHour * 60; + this.endMinutes = endHour * 60; + } + + public void setWorktimeMinutes(int startMinutes, int endMinutes) { + this.startMinutes = startMinutes; + this.endMinutes = endMinutes; + } + + public void setToDate(Date weekDate) { + calcMinMaxDates( weekDate ); + } + + public Collection getBlocks() { + return blocks; + } + + /** must be called after the slots are filled*/ + protected boolean isEmpty( int column) + { + return multSlots[column].isEmpty(); + } + + protected int getColumnCount() + { + return getDaysInView(); + } + + public void rebuild() { + int columns = getColumnCount(); + blocks.clear(); + multSlots = new HTMLDaySlot[columns]; + + String[] headerNames = new String[columns]; + + for (int i=0;i it= builders.iterator(); + while (it.hasNext()) { + Builder b= it.next(); + b.prepareBuild(getStartDate(),getEndDate()); + start = Math.min(b.getMinMinutes(),start); + end = Math.max(b.getMaxMinutes(),end); + if (start<0) + throw new IllegalStateException("builder.getMin() is smaller than 0"); + if (end>24*60) + throw new IllegalStateException("builder.getMax() is greater than 24"); + } + minMinute = start ; + maxMinute = end ; + for (int i=0;i\n"); + result.append(""); + + result.append("\n"); + result.append(""+weeknumber+""); + for (int i=0;i"); + result.append(""); + result.append(headerNames[i]); + result.append(""); + result.append(""); + } + result.append("\n"); + result.append(""); + boolean useAM_PM = org.rapla.components.calendarview.AbstractCalendar.isAmPmFormat( locale ); + int firstEventMarkerId = 7; + boolean firstEventMarkerSet = false; + + for (int minuteOfDay = minMinute;minuteOfDay\n"); + boolean fullHour = (minuteOfDay) % 60 == 0; + boolean isLine = (minuteOfDay ) % (60 / m_rowsPerHour) == 0; + if ( fullHour || minuteOfDay == minMinute) { + int rowspan = calcRowspan(minuteOfDay, ((minuteOfDay / 60) + 1) * 60); + String timeString = formatTime(minuteOfDay, useAM_PM); + result.append(""); + result.append(timeString); + result.append(""); + result.append("  \n"); + } + + + for (int day=0;day "); + result.append(" \n"); + } + else if (isLine) + { + result.append(" "); + result.append(" \n"); + } + else + { + result.append(" "); + result.append(" \n"); + } + } + else if ( firstEventMarkerSet) + { + firstEventMarkerId = day; + } + for (int slotnr = 0; slotnr < multSlots[day].size(); slotnr++) + { + // Rapla 1.4: Make line for full hours darker than others + if (fullHour) + { + result.append(" "); + } + else if (isLine) + { + result.append(" "); + } + else + { + result.append(""); + } + + Slot slot = multSlots[day].getSlotAt(slotnr); + Block block = slot.getBlock(minuteOfDay); + if ( block != null) + { + blockCalendar.setTime( block.getEnd()); + int endMinute = Math.min(maxMinute,blockCalendar.get(Calendar.HOUR_OF_DAY) * 60 + blockCalendar.get(Calendar.MINUTE)); + int rowspan = calcRowspan(minuteOfDay, endMinute); + result.append(""); + printBlock(result, firstEventMarkerId, block); + result.append(""); + slot.setLastEnd( endMinute); + } + else + { + // skip ? + if (slot.getLastEnd() > minuteOfDay) + { + // Do nothing + } + else + { + // Rapla 1.4: Make line for full hours darker than others + if (fullHour )//|| (!slot.isEmpty(row-1) && (row-minRow) > 0)) + { + result.append(" \n"); + } + else if (isLine) + { + result.append(" \n"); + } + else + { + result.append("\n"); + } + } + + } + } + + // Rapla 1.4: Make line for full hours darker than others + if (fullHour) + { + result.append(" "); + } + else if ( isLine) + { + result.append(" "); + } + else + { + result.append("\n"); + } + } + + result.append("\n\n"); + } + result.append(""); + result.append("\n"); + m_html = result.toString(); + } + + private int calcRowspan(int start, int end) + { + if ( start == end) + { + return 1; + } + SortedSet tailSet = minuteBlock.tailSet( start); + int row = 0; + for (Integer minute:tailSet) + { + if ( minute< end) + { + row++; + } + else + { + break; + } + } + return Math.max(1, row); + } + + public String getWeeknumber() { + return weeknumber; + } + + public void setWeeknumber(String weeknumber) { + this.weeknumber = weeknumber; + } + + protected void printBlock(StringBuffer result, @SuppressWarnings("unused") int firstEventMarkerId, Block block) { + String string = block.toString(); + result.append(string); + } + + + protected String createColumnHeader(int i) { + blockCalendar.setTime(getStartDate()); + blockCalendar.add(Calendar.DATE, i); + String headerName = AbstractCalendar.formatDayOfWeekDateMonth + (blockCalendar.getTime() + ,locale + ,timeZone + ); + return headerName; + } + + SortedSet minuteBlock = new TreeSet(); + + public void addBlock(Block block,int column,int slot) { + checkBlock ( block ); + HTMLDaySlot multiSlot =multSlots[column]; + blockCalendar.setTime( block.getStart()); + + int startMinute = Math.max(minMinute,( + blockCalendar.get(Calendar.HOUR_OF_DAY)* 60 + + blockCalendar.get(Calendar.MINUTE) + )); + blockCalendar.setTime(block.getEnd()); + int endMinute = (Math.min(maxMinute, + blockCalendar.get(Calendar.HOUR_OF_DAY)* 60 + + blockCalendar.get(Calendar.MINUTE) + )); + blocks.add(block); +// startBlock.add( startMinute); + // endBlock.add( endMinute); + minuteBlock.add( startMinute); + minuteBlock.add( endMinute); + multiSlot.putBlock( block, slot, startMinute); + + } + + private String formatTime(int minuteOfDay,boolean useAM_PM) { + blockCalendar.set(Calendar.MINUTE, minuteOfDay%60); + int hour = minuteOfDay/60; + blockCalendar.set(Calendar.HOUR_OF_DAY, hour); + SimpleDateFormat format = new SimpleDateFormat(useAM_PM ? "h:mm" : "H:mm", locale); + format.setTimeZone(blockCalendar.getTimeZone()); + if (useAM_PM && hour == 12 && minuteOfDay%60 == 0) { + return format.format(blockCalendar.getTime()) + " PM"; + } else { + return format.format(blockCalendar.getTime()); + } + } + + protected class HTMLDaySlot extends ArrayList { + private static final long serialVersionUID = 1L; + private boolean empty = true; + + public HTMLDaySlot(int size) { + super(size); + } + + public void putBlock(Block block,int slotnr, int startMinute) { + while (slotnr >= size()) { + addSlot(); + } + getSlotAt(slotnr).putBlock( block, startMinute); + empty = false; + } + + public int addSlot() { + Slot slot = new Slot(); + add(slot); + return size(); + } + public Slot getSlotAt(int index) { + return get(index); + } + + public boolean isEmpty() { + return empty; + } + } + + + + protected class Slot { +// int[] EMPTY = new int[]{-2}; + // int[] SKIP = new int[]{-1}; + int lastEnd = 0; + HashMap map = new HashMap(); + + public Slot() { + } + + public void putBlock( Block block, int startMinute) { + map.put( startMinute, block); + } + + Block getBlock(Integer startMinute) + { + return map.get( startMinute); + } + + public int getLastEnd() { + return lastEnd; + } + + public void setLastEnd(int lastEnd) { + this.lastEnd = lastEnd; + } + + + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/package.html b/rapla-source-1.8.2/src/org/rapla/components/calendarview/package.html new file mode 100644 index 0000000..4c28220 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/package.html @@ -0,0 +1,7 @@ + +Provides basic functionality for displaying and editing appointment blocks, +in table-like components. + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/AbstractDaySlot.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/AbstractDaySlot.java new file mode 100644 index 0000000..ad839d1 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/AbstractDaySlot.java @@ -0,0 +1,241 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender, Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendarview.swing; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.JPanel; +import javax.swing.UIManager; + +abstract class AbstractDaySlot extends JPanel implements DaySlot +{ + private static final long serialVersionUID = 1L; + private boolean bEditable = true; + boolean paintDraggingGrid; + int draggingSlot; + int draggingY; + SwingBlock draggingView; + int draggingHeight; + protected Map blockViewMapper = new HashMap(); +// BJO 00000076 +// protected Method getButtonMethod = null; +// BJO 00000076 + + AbstractDaySlot() { +/* +// BJO 00000076 + try { + //is only available sind 1.4 + getButtonMethod = MouseEvent.class.getMethod("getButton", new Class[] {}); + } catch (Exception ex) { + } +// BJO 00000076 +*/ + } + + public void setEditable(boolean b) { + bEditable = b; + } + + public boolean isEditable() { + return bEditable; + } + + SwingBlock getBlockFor(Object component) { + return blockViewMapper.get(component); + } + + protected void showPopup(MouseEvent evt) { + Point p = new Point(evt.getX(),evt.getY()); + SwingBlock block = getBlockFor(evt.getSource()); + if (block != null) + draggingHandler.blockPopup(block,p); + } + + protected Color getSelectionColor() { + return UIManager.getColor("Table.selectionBackground"); + } + + public void paintDraggingGrid(int slot,int y, int height,SwingBlock draggingView,int oldY,int oldHeight,boolean bPaint) { + this.paintDraggingGrid = bPaint; + this.draggingSlot = slot; + this.draggingY = y; + this.draggingHeight = height; + this.draggingView = draggingView; + this.invalidateDragging(); + } + + public int getX(Component component) { + return component.getParent().getLocation().x; + } + + void invalidateDragging() { + repaint(); + } + + void setDraggingHandler(DraggingHandler draggingHandler) { + this.draggingHandler = draggingHandler; + } + + private DraggingHandler draggingHandler; + /** BlockListener handles the dragging events and the Block + * Context Menu (right click). + */ + class BlockListener extends MouseAdapter { + boolean preventDragging = false; + + public void mouseClicked(MouseEvent evt) { + if (evt.isPopupTrigger()) { + showPopup(evt); + } else { + if (evt.getClickCount()>1) + blockEdit(evt); + } + //draggingPointOffset = evt.getY(); + } + + private int calcResizeDirection( MouseEvent evt ) { + if ( !draggingHandler.supportsResizing()) + return 0; + int height = ((Component)evt.getSource()).getHeight(); + int diff = height- evt.getY() ; + if ( diff <= 5 && diff >=0 ) + return 1; + if (evt.getY() >=0 && evt.getY() < 5) + return -1; + return 0; + } + + public void mousePressed(MouseEvent evt) { + if (evt.isPopupTrigger()) { + showPopup(evt); + } + + preventDragging = false; + /* +// BJO 00000076 + //System.out.println ("Button:" +evt.getButton() ); + if ( getButtonMethod != null) { + try { + Integer button = (Integer) getButtonMethod.invoke( evt, new Object [] {}); + preventDragging = button.intValue() != 1; + } catch (Exception ex) { + } + } + */ + preventDragging = evt.getButton() != 1; +// BJO 00000076 + if ( preventDragging ) + return; + SwingBlock block = getBlockFor(evt.getSource()); + int resizeDirection = calcResizeDirection( evt ); + if ( resizeDirection != 0) { + draggingHandler.blockBorderPressed( AbstractDaySlot.this,block, evt, resizeDirection ); + } + } + + public void mouseReleased(MouseEvent evt) { + if (evt.isPopupTrigger()) { + showPopup(evt); + } + preventDragging = false; + SwingBlock block = getBlockFor(evt.getSource()); + draggingHandler.mouseReleased( AbstractDaySlot.this, block, evt); + } + + public void mouseEntered(MouseEvent evt) { + } + + public void mouseExited(MouseEvent evt) { + if ( draggingHandler.isDragging()) + return; + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + + public void mouseMoved(MouseEvent evt) { + if ( draggingHandler.isDragging()) { + return; + } + SwingBlock block = getBlockFor(evt.getSource()); + // BJO 00000137 + if(!block.isMovable()) + return; + // BJO 00000137 + if ( calcResizeDirection( evt ) == 1 && block.isEndResizable()) { + setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR)); + } else if (calcResizeDirection( evt ) == -1 && block.isStartResizable()){ + setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR)); + } else { + setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + } + + public void mouseDragged(MouseEvent evt) { + if ( preventDragging || !isEditable()) + return; + + SwingBlock block = getBlockFor(evt.getSource()); + + draggingHandler.mouseDragged( AbstractDaySlot.this, block, evt); + } + + + private void blockEdit(MouseEvent evt) { + SwingBlock block = getBlockFor(evt.getSource()); + draggingHandler.blockEdit(block,new Point(evt.getX(),evt.getY())); + } + } + + protected void paintDraggingGrid(Graphics g, int x, int y, int width, int height) { + /* + Rectangle rect = g.getClipBounds(); + int startx = draggingView.getView().getX(); + int starty = draggingView.getView().getY(); + g.setColor(Color.gray); + for (int y1=10;y1= rect.x + && x2 <= rect.x + rect.width + && y2 >= rect.y + && y2 <= rect.y + rect.height + ) + g.drawRect(x2,y2,2,2); + } + */ + g.translate( x-1, y-1); + + if ( draggingView != null) { + draggingView.paintDragging( g, width , height +1 ); + } + g.translate( -(x-1), -(y-1)); + + + } + + static int count = 0; +} + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/AbstractSwingCalendar.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/AbstractSwingCalendar.java new file mode 100644 index 0000000..ab4b5d8 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/AbstractSwingCalendar.java @@ -0,0 +1,309 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender, Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendarview.swing; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.util.ArrayList; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import javax.swing.BoxLayout; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JScrollBar; +import javax.swing.JScrollPane; +import javax.swing.JViewport; +import javax.swing.ScrollPaneConstants; +import javax.swing.SwingUtilities; +import javax.swing.border.Border; +import javax.swing.border.EtchedBorder; + +import org.rapla.components.calendarview.AbstractCalendar; +import org.rapla.components.calendarview.Block; +import org.rapla.components.calendarview.CalendarView; +import org.rapla.components.layout.TableLayout; +import org.rapla.components.util.TimeInterval; + + +public abstract class AbstractSwingCalendar extends AbstractCalendar implements CalendarView { + + static Border SLOTHEADER_BORDER = new EtchedBorder(); + int slotSize = 100; + boolean bEditable = true; + protected int minBlockWidth = 3; + + + ArrayList listenerList = new ArrayList(); + + JScrollPane scrollPane = new JScrollPane(); + JPanel jHeader = new JPanel(); + BoxLayout boxLayout1 = new BoxLayout(jHeader, BoxLayout.X_AXIS); + JPanel jCenter = new JPanel(); + protected JPanel jTitlePanel = new JPanel(); + protected JPanel component = new JPanel(); + + AbstractSwingCalendar(boolean showScrollPane) { + jHeader.setLayout(boxLayout1); + jHeader.setOpaque( false ); + jCenter.setOpaque( false ); + jTitlePanel.setOpaque( false); + jTitlePanel.setLayout( new BorderLayout()); + jTitlePanel.add(jHeader,BorderLayout.CENTER); + if (showScrollPane) { + component.setLayout(new BorderLayout()); + component.add(scrollPane,BorderLayout.CENTER); + scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); + scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); + scrollPane.setViewportView(jCenter); + + + + scrollPane.setColumnHeaderView(jTitlePanel); + scrollPane.getVerticalScrollBar().setUnitIncrement(10); + scrollPane.getHorizontalScrollBar().setUnitIncrement(10); + scrollPane.setBorder(null); + } else { + component.setLayout(new TableLayout(new double[][] { + {TableLayout.PREFERRED,TableLayout.FILL} + ,{TableLayout.PREFERRED,TableLayout.FILL} + })); + component.add(jTitlePanel,"1,0"); + component.add(jCenter,"1,1"); + } + this.timeZone = TimeZone.getDefault(); + setLocale( Locale.getDefault() ); + + if ( showScrollPane) + { + component.addComponentListener( new ComponentListener() { + private boolean resizing = false; + + public void componentShown(ComponentEvent e) { + + } + + public void componentResized(ComponentEvent e) { + + if ( resizing) + { + return; + } + resizing = true; + if ( isEditable() ) + { + int width = component.getSize().width; + updateSize(width); + } + SwingUtilities.invokeLater(new Runnable() { + + public void run() { + resizing = false; + } + }); + + + } + + + + public void componentMoved(ComponentEvent e) { + } + + public void componentHidden(ComponentEvent e) { + } + }); + } + } + + abstract public void updateSize(int width); + + public JComponent getComponent() + { + return component; + } + + void checkBlock( Block bl ) { + if ( !bl.getStart().before(this.getEndDate())) { + throw new IllegalStateException("Start-date " +bl.getStart() + " must be before calendar end at " +this.getEndDate()); + } + } + + public boolean isEditable() { + return bEditable; + } + + public void setEditable( boolean editable ) { + bEditable = editable; + } + + + /** + Width of a single slot in pixel. + */ + public void setSlotSize(int slotSize) { + this.slotSize = slotSize; + } + + public int getSlotSize() { + return slotSize; + } + + /** the minimum width of a block in pixel */ + public int getMinBlockWidth() + { + return minBlockWidth; + } + + /** the minimum width of a block in pixel */ + public void setMinBlockWidth(int minBlockWidth) + { + this.minBlockWidth = Math.max(3,minBlockWidth); + } + + + public void setBackground(Color color) { + component.setBackground(color); + if (scrollPane != null) + scrollPane.setBackground(color); + if (jCenter != null) + jCenter.setBackground(color); + if (jHeader != null) + jHeader.setBackground(color); + } + + + + public void addCalendarViewListener(ViewListener listener) { + listenerList.add(listener); + } + + public void removeCalendarViewListener(ViewListener listener) { + listenerList.remove(listener); + } + + JScrollPane getScrollPane() { + return scrollPane; + } + + void scrollTo(int x, int y) { + JViewport viewport = scrollPane.getViewport(); + Rectangle rect = viewport.getViewRect(); + + int leftBound = rect.x; + int upperBound = rect.y; + int lowerBound = rect.y + rect.height; + int rightBound = rect.x + rect.width; + int maxX = viewport.getView().getWidth(); + int maxY = viewport.getView().getHeight(); + + + JScrollBar scrollBar = scrollPane.getVerticalScrollBar(); + if ( y > lowerBound && lowerBound < maxY) { + scrollBar.setValue(scrollBar.getValue() + 20); + } + if ( y < upperBound && upperBound >0) { + scrollBar.setValue(scrollBar.getValue() - 20); + } + + scrollBar = scrollPane.getHorizontalScrollBar(); + if ( x > rightBound && rightBound < maxX) { + scrollBar.setValue(scrollBar.getValue() + 20); + } + if ( x < leftBound && leftBound >0) { + scrollBar.setValue(scrollBar.getValue() - 20); + } + } + + + + public ViewListener[] getWeekViewListeners() { + return listenerList.toArray(new ViewListener[]{}); + } + + final void fireSelectionChanged(Date start, Date end) { + // Fire the popup event + ViewListener[] listeners = getWeekViewListeners(); + for (int i=0;i slots= new ArrayList(); + private int slotxsize; + + private int selectionStart = -1; + private int selectionEnd = -1; + private int oldSelectionStart = -1; + private int oldSelectionEnd = -1; + + BoxLayout boxLayout1 = new BoxLayout(this, BoxLayout.X_AXIS); + int right_gap = 8; + int left_gap = 5; + int slot_space = 3; + JComponent header; + IRowScale rowScale; + + private BlockListener blockListener = new BlockListener(); + /** + es muss auch noch setTimeIntervall() aufgerufen werden, um die initialisierung + fertig zu stellen (wie beim konstruktor von Slot). + slotxsize ist die breite der einzelnen slots. + "date" legt das Datum fest, fuer welches das Slot anzeigt (Uhrzeit bleibt unberuecksichtigt) + */ + public LargeDaySlot( + int slotxsize + ,IRowScale rowScale + ,JComponent header) { + this.slotxsize= slotxsize; + this.rowScale = rowScale; + this.header = header; + setLayout(boxLayout1); + this.add(Box.createHorizontalStrut(left_gap)); + addSlot(); + setBackground(getBackground()); + setAlignmentX(0); + setAlignmentY(TOP_ALIGNMENT); + this.setBackground(Color.white); + } + + public boolean isBorderVisible() { + return true; +// return getBackground() != Color.white; + } + + public int getSlotCount() + { + return slots.size(); + } + + public boolean isSelected() + { + return selectionStart >=0 ; + } + + public void setVisible(boolean b) { + super.setVisible(b); + header.setVisible(b); + } + + public JComponent getHeader() { + return header; + } + + public int calcSlot(int x) { + int slot = ((x - left_gap) / (slotxsize + slot_space)); + //System.out.println ( x + " slot " + slot); + if (slot<0) + slot = 0; + if (slot >= slots.size()) + slot = slots.size() -1; + return slot; + } + + public Collection getBlocks() { + ArrayList list = new ArrayList(); + for (int i=0;i it= slots.iterator(); + while (it.hasNext()) { + Slot slot = it.next(); + slot.setTimeIntervall(); + } + } + + private int addSlot() { + Slot slot= new Slot(); + slot.setTimeIntervall(); + slots.add(slot); + this.add(slot); + this.add(Box.createHorizontalStrut(slot_space)); + + updateHeaderSize(); + + return slots.size()-1; + } + + public void updateHeaderSize() { + Dimension size = header.getPreferredSize(); + Dimension newSize = new Dimension(slotxsize * slots.size() //Slotwidth and border + + slot_space * slots.size() //Space between Slots + + left_gap + right_gap // left and right gap + , (int)size.getHeight()); + header.setPreferredSize(newSize); + header.setMaximumSize(newSize); + header.invalidate(); + } + + /** + fuegt einen block im gewuenschten slot ein + (konflikte werden ignoriert). + */ + public void putBlock(SwingBlock bl, int slotnr) { + while (slotnr >= slots.size()) { + addSlot(); + } + slots.get(slotnr).putBlock(bl); + // The blockListener can be shared among all blocks, + // as long es we can only click on one block simultanously + bl.getView().addMouseListener(blockListener); + bl.getView().addMouseMotionListener(blockListener); + blockViewMapper.put(bl.getView(),bl); + } + + public Dimension getMinimumSize() { return getPreferredSize(); } + public Dimension getMaximumSize() { return getPreferredSize(); } + Insets insets = new Insets(0,0,0, right_gap); + Insets slotInsets = new Insets(0,0,0,0); + + public Insets getInsets() { + return insets; + } + + SwingBlock getBlockFor(Object component) { + return blockViewMapper.get(component); + } + + int getBlockCount() { + int count = 0; + Iterator it = slots.iterator(); + while (it.hasNext()) + count += it.next().getBlockCount(); + return count; + } + + boolean isEmpty() { + return getBlockCount() == 0; + } + + protected void invalidateDragging(Point oldPoint) { + int width = getSize().width; + int startRow = Math.min(calcRow(draggingY),calcRow(oldPoint.y )); + int endRow = Math.max(calcRow(draggingY),calcRow(oldPoint.y )) + 1; + repaint(0 + , rowScale.getYCoordForRow(startRow) -10 + , width + , rowScale.getSizeInPixelBetween(startRow, endRow) + draggingHeight + 20 + ); + } + + private void invalidateSelection() { + int width = getSize().width; + int startRow = Math.min(selectionStart,oldSelectionStart); + int endRow = Math.max(selectionEnd,oldSelectionEnd) + 1; + repaint(0,rowScale.getYCoordForRow(startRow ), width, rowScale.getSizeInPixelBetween(startRow, endRow )); + // Update the values after calling repaint, because paint needs the old values. + oldSelectionStart = selectionStart; + oldSelectionEnd = selectionEnd; + } + + public void paint(Graphics g) { + Dimension dim = getSize(); + Rectangle rect = g.getClipBounds(); + if (!isEditable()) { + g.setColor(Color.white); + g.fillRect(rect.x + ,rect.y + ,rect.width + ,rect.height); + } else { + int starty = rowScale.getStartWorktimePixel(); + int endy = rowScale.getEndWorktimePixel(); + int height = rowScale.getSizeInPixel(); + Color firstColor = NON_WORKTIME_BACKGROUND; + Color secondColor = WORKTIME_BACKGROUND; + + if ( starty >= endy) + { + int c = starty; + starty = endy; + endy = c; + secondColor = NON_WORKTIME_BACKGROUND; + firstColor = WORKTIME_BACKGROUND; + } + + if (rect.y - rect.height <= starty) { + g.setColor( firstColor ); + g.fillRect(rect.x + ,Math.max(rect.y,0) + ,rect.width + ,Math.min(rect.height,starty)); + } + if (rect.y + rect.height >= starty && rect.y <= endy ) { + g.setColor( secondColor ); + g.fillRect(rect.x + ,Math.max(rect.y,starty) + ,rect.width + ,Math.min(rect.height,endy - starty)); + } + if (rect.y + rect.height >= endy) { + g.setColor( firstColor ); + g.fillRect(rect.x + ,Math.max(rect.y,endy) + ,rect.width + ,Math.min(rect.height, height - endy)); + } + } + + if (isBorderVisible()) { + g.setColor(LINE_COLOR); + g.drawLine(0,rect.y,0,rect.y + rect.height); + g.drawLine(dim.width - 1,rect.y,dim.width - 1 ,rect.y + rect.height); + } + + int max = rowScale.getMaxRows() ; + // Paint selection + for (int i=0; i < max ; i++) { + int rowSize = rowScale.getRowSizeForRow( i); + int y = rowScale.getYCoordForRow( i); + if ((y + rowSize) >= rect.y && y < (rect.y + rect.height)) { + if (i>= selectionStart && i<=selectionEnd) { + g.setColor(getSelectionColor()); + g.fillRect(Math.max (rect.x,1) + , y + , Math.min (rect.width,dim.width - Math.max (rect.x,1) - 1) + , rowSize); + } + boolean bPaintRowThick = (rowScale.isPaintRowThick(i)); + g.setColor((bPaintRowThick) ? THICK_LINE_COLOR : LINE_COLOR); + if (isEditable() || (bPaintRowThick && (i blocks= new ArrayList(); + + public Slot() { + setLayout(null); + setBackground(Color.white); + setOpaque(false); + } + + /** legt fest, fuer welches zeitintervall das slot gelten soll. + (Beispiel 8:00 - 13:00) + min und max sind uhrzeiten in vollen stunden. + zur initialisierung der komponente muss diese methode mindestens einmal + aufgerufen werden. + */ + public void setTimeIntervall() { + int ysize= rowScale.getSizeInPixel() + 1; + setSize(slotxsize, ysize); + Dimension preferredSize = new Dimension(slotxsize, ysize ); + setPreferredSize(preferredSize ); + setMinimumSize(preferredSize ); + } + + + /** fuegt b in den Slot ein. */ + public void putBlock(SwingBlock b) { + blocks.add(b); + add(b.getView()); + updateBounds(b); + } + + public void updateBounds(SwingBlock b) { + //update bounds + int y1= rowScale.getYCoord(b.getStart()); + final int minimumSize = 15; + int y2= Math.max( y1+minimumSize,rowScale.getYCoord(b.getEnd())); + if ( y1 < 0) + y1 = 0; + if ( y2 > getMaximumSize().height) + y2 = getMaximumSize().height; + b.getView().setBounds(0, y1, slotxsize, y2 - y1 + 1); + } + + public int getBlockCount() { + return blocks.size(); + } + + public Dimension getMinimumSize() { return getPreferredSize(); } + public Dimension getMaximumSize() { return getPreferredSize(); } + + public Insets getInsets() { + return slotInsets; + } + + public Collection getBlocks() { + return blocks; + } + } + + + void updateSize(int slotsize) + { + this.slotxsize = slotsize; + for ( Slot slot:slots) + { + slot.setTimeIntervall(); + for (Block block:slot.getBlocks()) + { + slot.updateBounds((SwingBlock)block); + } + } + updateHeaderSize(); + } + + public int calcRow( int y ) + { + return rowScale.calcRow( y); + } +} + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/SelectionHandler.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/SelectionHandler.java new file mode 100644 index 0000000..f7d603a --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/SelectionHandler.java @@ -0,0 +1,301 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendarview.swing; + +import java.awt.Component; +import java.awt.Point; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Date; + +import javax.swing.SwingUtilities; + +/** SelectionHandler handles the selection events and the Slot + * Context Menu (right click). + * This is internally used by the weekview to communicate with its slots. + */ +public class SelectionHandler extends MouseAdapter { + Date start; + Date end; + boolean bPopupClicked = false; + boolean bSelecting = false; + public int selectionStart = -1; + public int selectionEnd = -1; + private int oldIndex = -1; + private int oldSlotNr = -1; + private int startSlot = -1; + private int endSlot = -1; + private int draggingSlot = -1; + private int draggingIndex = -1; + AbstractSwingCalendar m_wv; + public enum SelectionStrategy + { + FLOW,BLOCK; + } + SelectionStrategy selectionStrategy = SelectionStrategy.FLOW; + + public SelectionHandler(AbstractSwingCalendar wv) { + m_wv = wv; + } + + public void mouseClicked(MouseEvent evt) { + if (evt.isPopupTrigger()) { + bPopupClicked = true; + slotPopup(evt); + } else { + /* We don't check click here + if (SwingUtilities.isLeftMouseButton(evt)) + move(evt); + */ + } + } + public void mousePressed(MouseEvent evt) { + if (evt.isPopupTrigger()) { + bPopupClicked = true; + move(evt, true); + slotPopup(evt); + } else { + if (SwingUtilities.isLeftMouseButton(evt)) + move(evt,false); + } + } + + public void mouseReleased(MouseEvent evt) { + if (evt.isPopupTrigger()) { + bPopupClicked = true; + move(evt, true); + slotPopup(evt); + } + if (SwingUtilities.isLeftMouseButton(evt) && !bPopupClicked) + move(evt, false); + bPopupClicked = false; + bSelecting = false; + } + + public void mouseDragged(MouseEvent evt) { + if (SwingUtilities.isLeftMouseButton(evt) && !bPopupClicked) + move(evt, false); + } + public void mouseMoved(MouseEvent evt) { + } + + public void setSelectionStrategy(SelectionStrategy strategy) { + selectionStrategy = strategy; + } + + public void clearSelection() { + for (int i=0;i draggingIndex ) { + selectionStart = draggingIndex; + selectionEnd = selectedIndex; + } else if (selectedIndex < draggingIndex ){ + selectionStart = selectedIndex; + selectionEnd = draggingIndex; + } + } else if (slotNr > draggingSlot) { + startSlot = draggingSlot; + selectionStart = draggingIndex; + endSlot = slotNr; + selectionEnd = selectedIndex; + } else if (slotNr < draggingSlot) { + startSlot = slotNr; + selectionStart = selectedIndex; + endSlot = draggingSlot; + selectionEnd = draggingIndex; + } + if (selectedIndex == oldIndex && slotNr == oldSlotNr) + { + return; + } + int rowsPerDay = m_wv.getRowsPerDay(); + if (selectedIndex >= rowsPerDay-1) + { + selectedIndex = rowsPerDay-1; + } + } + oldSlotNr = slotNr; + oldIndex = selectedIndex; + switch ( selectionStrategy) + { + case BLOCK: setSelectionBlock();break; + case FLOW: setSelectionFlow();break; + } + { + Point location = m_wv.getSlot(slotNr).getLocation(); + m_wv.scrollTo( + location.x + evt.getX() + ,location.y + evt.getY() + ); + } + } + + private boolean inCurrentSelection(int slotNr, int selectedIndex) { + if ( slotNr < startSlot || slotNr > endSlot) + { + return false; + } + if (slotNr == startSlot && selectedIndex < selectionStart) { + return false; + } + if (slotNr == endSlot && selectedIndex > selectionEnd) { + return false; + } + return true; + } + + protected void setSelectionFlow() { + + int startRow = selectionStart; + int endRow = m_wv.getRowsPerDay() -1; + + + for (int i=0;i startSlot) + { + startRow = 0; + } + if (i == endSlot) + { + endRow = selectionEnd; + } + DaySlot slot = m_wv.getSlot(i); + if (slot != null) + { + slot.select(startRow,endRow); + } + } + startRow = selectionStart ; + endRow = selectionEnd ; + for (int i=endSlot+1;i= min_x && location.x <= max_x && location.y >= min_y && location.y <= max_y) + { + slot.select(startRow,endRow); + } + else + { + slot.unselectAll(); + } + } + } + start = m_wv.createDate(m_wv.getSlot(startSlot),startRow, true); + end = m_wv.createDate(m_wv.getSlot(endSlot),endRow, false); + m_wv.fireSelectionChanged(start,end); + } +} + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/SmallDaySlot.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/SmallDaySlot.java new file mode 100644 index 0000000..2cddeb9 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/SmallDaySlot.java @@ -0,0 +1,250 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender, Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendarview.swing; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.Rectangle; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +import org.rapla.components.calendarview.Block; + +public class SmallDaySlot extends AbstractDaySlot +{ + private static final long serialVersionUID = 1L; + + public static int BLOCK_HEIGHT = 32 +20; + public static int START_GAP = 10; + public static Color THICK_LINE_COLOR = Color.black; + public static Color LINE_COLOR = new Color(0xaa, 0xaa, 0xaa); + public static Color WORKTIME_BACKGROUND = Color.white; + + private List blocks = new LinkedList(); + private int slotxsize; + private Color headerColor; + private Color headerBackground; + private int rowSize = 15; + + private boolean selected; + + int slot_space = 3; + + private BlockListener blockListener = new BlockListener(); + private String headerText; + + public SmallDaySlot(String headerText,int slotxsize,Color headerColor, Color headerBackground + ) { + this.headerColor = headerColor; + this.headerBackground = headerBackground; + this.slotxsize= slotxsize; + this.headerText = headerText; + setLayout( null ); + setAlignmentX(0); + setAlignmentY(TOP_ALIGNMENT); + Dimension newSize = new Dimension(slotxsize, 10); + setPreferredSize(newSize); + this.setBackground(Color.white); + } + + public boolean isBorderVisible() { + return true; + } + + public Collection getBlocks() { + return blocks; + } + + public void select(int startRow, int endRow) { + boolean selected = (startRow >=0 || endRow>=0); + if (this.selected == selected) + return; + this.selected = selected; + invalidateSelection(); + } + + public void unselectAll() { + if (!selected ) + return; + selected = false; + invalidateSelection(); + } + + private void invalidateSelection() { + repaint(); + // Update the values after calling repaint, because paint needs the old values. + } + + + /** + fuegt einen block im gewuenschten slot ein + (konflikte werden ignoriert). + */ + public void putBlock(SwingBlock bl) { + add( bl.getView() ); + blocks.add( bl ); + // The blockListener can be shared among all blocks, + // as long as we can only click on one block simultaneously + bl.getView().addMouseListener( blockListener ); + bl.getView().addMouseMotionListener( blockListener ); + blockViewMapper.put( bl.getView(), bl ); + updateSize(); + } + + public void updateSize() { + int blockHeight = 0; + for ( Block b:blocks) + { + blockHeight += getHeight( b); + } + int height = Math.max( 25, blockHeight + START_GAP ); + Dimension newSize = new Dimension( slotxsize, height ); + setPreferredSize( newSize ); + updateBounds(); + } + + private void updateBounds() { + int y= START_GAP; + for (int i=0;i< blocks.size();i++) { + SwingBlock bl = (SwingBlock) blocks.get(i); + int blockHeight = getHeight(bl); + bl.getView().setBounds( 1 ,y, slotxsize -1, blockHeight-1); + y+= blockHeight; + } + } + + /** + * @param bl + */ + private int getHeight(Block bl) { + int blockHeight = BLOCK_HEIGHT; + // Special Solution for doubling the block height +// if (DateTools.countMinutes(bl.getStart(), bl.getEnd()) >= 60) +// { +// blockHeight*= 2; +// } + return blockHeight; + } + + public Dimension getMinimumSize() { return getPreferredSize(); } + public Dimension getMaximumSize() { return getPreferredSize(); } + Insets insets = new Insets(0,0,0, 0); + + public Insets getInsets() { + return insets; + } + + int getBlockCount() { + return blocks.size(); + } + + public boolean isEmpty() { + return getBlockCount() == 0; + } + + public int calcRow(int y) { + return 0; + } + + public int calcSlot(int x) { + return 0; + } + + public int getX(Component component) { + return component.getLocation().x; + } + + int max; + + public void paint(Graphics g) { + Dimension dim = getSize(); + Rectangle rect = g.getClipBounds(); + g.setColor(getForeground()); + + if (selected) { + g.setColor(getSelectionColor()); + } else { + g.setColor(getBackground()); + } + + g.fillRect(rect.x + , rect.y + , rect.x + rect.width + , rect.y + rect.height); + + if (isBorderVisible()) { + g.setColor(LINE_COLOR); + g.drawLine(0, rect.y, 0, rect.y + rect.height); + g.drawLine(dim.width - 1, rect.y, dim.width - 1, rect.y + rect.height); + g.drawLine(rect.x, 0, rect.x + rect.width, 0); + g.drawLine(rect.x, dim.height - 1, rect.x + rect.width, dim.height - 1); + } + + + + if ( headerText != null) + { + FontMetrics fontMetrics = g.getFontMetrics(); + int headerWidth = fontMetrics.stringWidth(headerText); + int headerHeight = 10;//fontMetrics.stringWidth(headerText); + int x = Math.max(10, dim.width - headerWidth - 3); + int y = Math.max(START_GAP, headerHeight); + if ( headerBackground != null) + { + g.setColor(headerBackground); + g.fillRect(1, y-headerHeight+1, dim.width -2, headerHeight); + } + g.setColor(headerColor); + g.drawString(headerText, x, y); + g.setColor(getForeground()); + } + + super.paintChildren(g); + if (paintDraggingGrid) { + int height = draggingView.getView().getHeight() - 1; + int x = 0; + int y = draggingView.getView().getBounds().y; + if (y + height + 2 > getHeight()) { + y = getHeight() - height - 2; + } + paintDraggingGrid(g, x, y, slotxsize - 1, height); + } + } + + public int getRowSize() + { + return rowSize; + } + + public boolean isSelected() + { + return selected ; + } + + public void updateSize(int newWidth) + { + this.slotxsize = newWidth; + updateSize(); + } + + + +} + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/SwingBlock.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/SwingBlock.java new file mode 100644 index 0000000..d9faeee --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/SwingBlock.java @@ -0,0 +1,26 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendarview.swing; + +import java.awt.Component; +import java.awt.Graphics; + +import org.rapla.components.calendarview.Block; + +public interface SwingBlock extends Block { + Component getView(); + public void paintDragging(Graphics g, int width, int height); + boolean isMovable(); + boolean isStartResizable(); + boolean isEndResizable(); +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/SwingCompactWeekView.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/SwingCompactWeekView.java new file mode 100644 index 0000000..76d8e0b --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/SwingCompactWeekView.java @@ -0,0 +1,405 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender, Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendarview.swing; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Point; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.SwingConstants; + +import org.rapla.components.calendarview.AbstractCalendar; +import org.rapla.components.calendarview.Block; +import org.rapla.components.calendarview.Builder; +import org.rapla.components.calendarview.swing.SelectionHandler.SelectionStrategy; +import org.rapla.components.layout.TableLayout; +import org.rapla.components.util.DateTools; + +/** Graphical component for displaying a calendar like weekview. + * This view doesn't show the times and arranges the different slots + * Vertically. +*/ +public class SwingCompactWeekView extends AbstractSwingCalendar +{ + private SmallDaySlot[] slots = new SmallDaySlot[0]; + private List> rows = new ArrayList>(); + DraggingHandler draggingHandler = new DraggingHandler(this, false); + SelectionHandler selectionHandler = new SelectionHandler(this); + String[] rowNames = new String[] {}; + int leftColumnSize = 100; + Map columnMap = new HashMap(); + + public SwingCompactWeekView() { + this(true); + } + + public SwingCompactWeekView(boolean showScrollPane) { + super( showScrollPane ); + selectionHandler.setSelectionStrategy(SelectionStrategy.BLOCK); + } + + public Collection getBlocks() { + ArrayList list = new ArrayList(); + for (int i=0;i it= builders.iterator(); + while (it.hasNext()) { + Builder b= it.next(); + b.prepareBuild(getStartDate(), getEndDate()); + } + + // clear everything + jHeader.removeAll(); + jCenter.removeAll(); + // build Blocks + it= builders.iterator(); + while (it.hasNext()) { + Builder b= it.next(); + if (b.isEnabled()) { b.build(this); } + } + tableLayout= new TableLayout(); + jCenter.setLayout(tableLayout); + + Calendar calendar = createCalendar(); + calendar.setTime(getStartDate()); + int firstDayOfWeek = getFirstWeekday(); + calendar.set( Calendar.DAY_OF_WEEK, firstDayOfWeek); + + if ( rowNames.length > 0) { + tableLayout.insertColumn(0, leftColumnSize); + jHeader.add( createColumnHeader( null ), "0,0,l,t" ); + } else { + tableLayout.insertColumn(0, 0); + } + + int columns = getColumnCount(); + + // add headers + for (int column=0;column getBlocksForColumn(List blocks,int column) + { + List result = new ArrayList(); + //Date startDate = getDateFromColumn(column); + if ( blocks != null) { + + Iterator it = blocks.iterator(); + while (it.hasNext()){ + Block block = it.next(); + if (columnMap.get( block) == column) { +// if ( DateTools.cutDate( block.getStart()).equals( startDate)) { + result.add( block); + } + } + } + return result; + } + + protected Date getDateFromColumn(int column) { + Date startDate = getStartDate(); + return DateTools.addDays( startDate, column); + } + + public void addBlock(Block block, int column,int slot) { + if ( rows.size() <= slot) + { + return; + } + checkBlock( block ); + List blocks = rows.get( slot ); + blocks.add( block ); + columnMap.put(block, column); + } + + private void addRow() { + rows.add( rows.size(), new ArrayList()); + } + + public int getSlotNr( DaySlot slot) { + for (int i=0;i=0 && nr< slots.length) + return slots[nr]; + else + return null; + } + + int getDayCount() { + return slots.length; + } + + int calcSlotNr(int x, int y) { + for (int i=0;i getBlocks(int dayOfMonth) { + int index = dayOfMonth-1; + return Collections.unmodifiableCollection(slots[ index ].getBlocks()); + } + + public Collection getBlocks() { + ArrayList list = new ArrayList(); + for (int i=0;i it= builders.iterator(); + Date startDate = getStartDate(); + while (it.hasNext()) { + Builder b= it.next(); + b.prepareBuild(startDate,getEndDate() ); + } + + // create fields + slots = new SmallDaySlot[daysInMonth]; + counter.setTime(startDate); + int year = counter.get(Calendar.YEAR); + SimpleDateFormat format = new SimpleDateFormat("MMMMMM",locale); + format.setTimeZone( getTimeZone() ); + String monthname = format.format(counter.getTime()); + // calculate the blocks + for (int i=0; i=0 && nr< slots.length) + return slots[nr]; + else + return null; + } + + int getDayCount() { + return slots.length; + } + + int calcSlotNr(int x, int y) { + for (int i=0;i=viewRect.x && + (slotRect.x + slotRect.width)< + (viewRect.x + viewRect.width ) + ) + { + return; + } + + scrollSlot.scrollRectToVisible(new Rectangle(0 + ,viewRect.y + ,scrollSlot.getWidth() + ,10)); + } + + public void scrollToStart() { + int y = rowScale.getStartWorktimePixel(); + int x = 0; + scrollPane.getViewport().setViewPosition(new Point(x,y)); + } + + public Collection getBlocks() { + ArrayList list = new ArrayList(); + for (int i=0;i + *
  • 1: 1 rows per hour = 1 Hour
  • + *
  • 2: 2 rows per hour = 1/2 Hour
  • + *
  • 3: 3 rows per hour = 20 Minutes
  • + *
  • 4: 4 rows per hour = 15 Minutes
  • + *
  • 6: 6 rows per hour = 10 Minutes
  • + *
  • 12: 12 rows per hour = 5 Minutes
  • + * + * Default is 4. + */ + public void setRowsPerHour(int rowsPerHour) { + if ( rowScale instanceof LinearRowScale) + ((LinearRowScale)rowScale).setRowsPerHour(rowsPerHour); + } + + /** @see #setRowsPerHour */ + public int getRowsPerHour() { + if ( rowScale instanceof LinearRowScale) + return ((LinearRowScale)rowScale).getRowsPerHour(); + return 0; + } + + /** The size of each row (in pixel). Default is 15.*/ + public void setRowSize(int rowSize) { + if ( rowScale instanceof LinearRowScale) + ((LinearRowScale)rowScale).setRowSize(rowSize); + } + + public int getRowSize() { + if ( rowScale instanceof LinearRowScale) + return ((LinearRowScale)rowScale).getRowSize(); + return 0; + } + + public void setBackground(Color color) { + super.setBackground(color); + if (timeScale != null) + timeScale.setBackground(color); + } + + public void setEditable(boolean b) { + super.setEditable( b ); + // Hide the rest + for (int i= 0;i it= builders.iterator(); + while (it.hasNext()) { + Builder b= it.next(); + b.prepareBuild(getStartDate(),getEndDate()); + if (! bEditable) { + start = Math.min(b.getMinMinutes(),start); + end = Math.max(b.getMaxMinutes(),end); + if (start<0) + throw new IllegalStateException("builder.getMin() is smaller than 0"); + if (end>24*60) + throw new IllegalStateException("builder.getMax() is greater than 24"); + } + } + + //rowScale = new VariableRowScale(); + if ( rowScale instanceof LinearRowScale) + { + LinearRowScale linearScale = (LinearRowScale) rowScale; + int pixelPerHour = linearScale.getRowsPerHour() * linearScale.getRowSize(); + + timeScale.setBackground(component.getBackground()); + + linearScale.setTimeZone( timeZone ); + if ( isEditable()) + { + timeScale.setTimeIntervall(0, 24, pixelPerHour); + linearScale.setTimeIntervall( 0, 24 * 60); + } + else + { + timeScale.setTimeIntervall(start / 60, Math.min( 24,(int)Math.ceil(end / 60.0)), pixelPerHour); + final int endMinute = Math.min( 24 * 60, ((end / 60) + ((end%60 != 0) ? 1 : 0)) * 60 ); + linearScale.setTimeIntervall( (start /60) * 60, endMinute); + } + linearScale.setWorktimeMinutes( this.startMinutes, this.endMinutes); + } + else + { + timeScale.setBackground(component.getBackground()); + timeScale.setTimeIntervall(0, 24, 60); + VariableRowScale periodScale = (VariableRowScale) rowScale; + periodScale.setTimeZone( timeZone ); + } + + // create Slots + DraggingHandler draggingHandler = new DraggingHandler(this, rowScale,true); + + for (int i=0; i=0 && nr< daySlots.length) + return daySlots[nr]; + else + return null; + } + + public boolean isSelected(int slotNr) + { + LargeDaySlot slot = getSlot(slotNr); + if ( slot == null) + { + return false; + } + return slot.isSelected(); + } + + int getDayCount() { + return daySlots.length; + } + + int calcSlotNr(int x, int y) { + for (int i=0;i= pad ) { + prefix = days[r].substring(i-mintime-pad,i-mintime+1-pad); + } else { + prefix = null; + } + + if (y >= rect.y && y <= (rect.y + rect.height)) { + g.drawLine(i == mintime ? 0:indent[0]+1,y,SCALE_WIDTH ,y); + } + + // Uncommenting this draws the last line +// if (y >= rect.y && y <= (rect.y + rect.height) && i == maxtime-1) { +// g.drawLine(0,y+pixelPerHour,SCALE_WIDTH ,y+pixelPerHour); +// } + if (y >= rect.y -heightHour && y <= (rect.y + rect.height) + heightHour ) { + if ( smallSize ) { + g.setFont(fontSmall); + } else { + g.setFont(fontLarge); + } + if ( prefix != null ) { + g.drawString(prefix, (indent[0]-fm.stringWidth(prefix)+1)/2,y + heightEnding); + } + g.drawString(hours[i],(hour < 10) ? indent[1]+2:indent[0]+2,y + ( smallSize ? heightEnding : heightHour)); + if ( !smallSize ) { + g.setFont(fontSmall); + } + g.drawString(ending, indent[2]+2,y + heightEnding); + } + } + } + } +} + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/ViewListener.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/ViewListener.java new file mode 100644 index 0000000..6b53807 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/ViewListener.java @@ -0,0 +1,46 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.calendarview.swing; + +import java.awt.Component; +import java.awt.Point; +import java.util.Date; + +import org.rapla.components.calendarview.Block; + +/** Listeners for user-changes in the weekview.*/ +public interface ViewListener { + /** Invoked when the user invokes the slot-contex (right-clicks on slot). + The selected area and suggested + coordinates at which the popup menu can be shown are passed.*/ + void selectionPopup(Component slotComponent,Point p,Date start,Date end, int slotNr); + /** Invoked when the selection has changed.*/ + void selectionChanged(Date start,Date end); + /** Invoked when the user invokes a block-context (right-clicks on a block). + The suggested coordinates at which the popup menu can be shown are passed.*/ + void blockPopup(Block block,Point p); + /** Invoked when the user invokes a block-edit (double-clicks on a block). + The suggested coordinates at which the popup menu can be shown are passed.*/ + void blockEdit(Block block,Point p); + /** Invoked when the user has dragged/moved a block */ + void moved(Block block,Point p,Date newStart, int slotNr); + /** Invoked when the user has resized a block */ + void resized(Block block,Point p,Date newStart, Date newEnd, int slotNr); +} + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/scaling/IRowScale.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/scaling/IRowScale.java new file mode 100644 index 0000000..8248731 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/scaling/IRowScale.java @@ -0,0 +1,20 @@ +package org.rapla.components.calendarview.swing.scaling; + +import java.util.Date; + + + +public interface IRowScale extends IRowScaleSmall +{ + int calcHour( int index ); + int calcMinute( int index ); + int getSizeInPixel(); + int getMaxRows(); + int getRowsPerDay(); + int getYCoord( Date time ); + int getStartWorktimePixel(); + int getEndWorktimePixel(); + int getSizeInPixelBetween( int startRow, int endRow ); + + boolean isPaintRowThick( int row ); +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/scaling/IRowScaleSmall.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/scaling/IRowScaleSmall.java new file mode 100644 index 0000000..d25db38 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/scaling/IRowScaleSmall.java @@ -0,0 +1,11 @@ +package org.rapla.components.calendarview.swing.scaling; + + +public interface IRowScaleSmall +{ + int getYCoordForRow( int row ); + int getRowSizeForRow( int row ); + int calcRow( int y ); + int trim( int y ); + int getDraggingCorrection(int y); +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/scaling/LinearRowScale.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/scaling/LinearRowScale.java new file mode 100644 index 0000000..4a8d916 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/scaling/LinearRowScale.java @@ -0,0 +1,162 @@ +package org.rapla.components.calendarview.swing.scaling; + +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + + + +public class LinearRowScale implements IRowScale +{ + private int rowSize = 15; + private int rowsPerHour = 4; + final private static int MINUTES_PER_HOUR= 60; + private TimeZone timeZone = TimeZone.getDefault(); + + private int mintime; + private int maxtime; + private int workstartMinutes; + private int workendMinutes; + + public LinearRowScale() + { + } + + public void setTimeZone( TimeZone timeZone) + { + this.timeZone = timeZone; + } + + public int getRowsPerDay() + { + return rowsPerHour * 24; + } + + public void setRowSize( int rowSize ) + { + this.rowSize = rowSize; + } + + public int getRowSize() + { + return rowSize; + } + + public int getRowsPerHour() + { + return rowsPerHour; + } + + public void setRowsPerHour( int rowsPerHour ) + { + this.rowsPerHour = rowsPerHour; + } + + public int calcHour(int index) { + return index / rowsPerHour; + } + + public int calcMinute(int index) { + double minutesPerRow = 60. / rowsPerHour; + long minute = Math.round((index % rowsPerHour) * (minutesPerRow)); + return (int)minute; + } + + public int getSizeInPixel() + { + return rowSize * getMaxRows(); + } + + public int getMaxRows() + { + int max; + max = (rowsPerHour * (maxtime - mintime)) / 60 ; + return max; + } + + private int getMinuteOfDay(Date time) { + Calendar cal = getCalendar(); + cal.setTime(time); + return (cal.get(Calendar.HOUR_OF_DAY )) * MINUTES_PER_HOUR + cal.get(Calendar.MINUTE); + } + + public int getYCoord(Date time) { + int diff = getMinuteOfDay(time) - mintime ; + int pixelPerHour= rowSize * rowsPerHour; + return (diff * pixelPerHour) / MINUTES_PER_HOUR; + } + + public int getStartWorktimePixel() + { + int pixelPerHour= rowSize * rowsPerHour; + int starty = (int) (pixelPerHour * workstartMinutes / 60.); + return starty; + } + + public int getEndWorktimePixel() + { + int pixelPerHour= rowSize * rowsPerHour; + int endy = (int) (pixelPerHour * workendMinutes / 60.); + return endy; + } + + + private Calendar calendar = null; + private Calendar getCalendar() { + // Lazy creation of the calendar + if (calendar == null) + calendar = Calendar.getInstance(timeZone); + return calendar; + } + + public boolean isPaintRowThick( int row ) + { + return row % rowsPerHour == 0; + } + + public void setTimeIntervall( int startMinutes, int endMinutes ) + { + mintime = startMinutes; + maxtime = endMinutes; + } + + public void setWorktimeMinutes( int workstartMinutes, int workendMinutes ) + { + this.workstartMinutes = workstartMinutes; + this.workendMinutes = workendMinutes; + } + + public int getYCoordForRow( int row ) + { + return row * rowSize; + } + + public int getSizeInPixelBetween( int startRow, int endRow ) + { + return (endRow - startRow) * rowSize; + } + + public int getRowSizeForRow( int row ) + { + return rowSize; + } + + public int calcRow(int y) { + int rowsPerDay = getRowsPerDay(); + int row = (y-3) / rowSize; + return Math.min(Math.max(0, row), rowsPerDay -1); + } + + public int trim(int y ) + { + return (y / rowSize) * rowSize; + } + + public int getDraggingCorrection( int y) + { + return rowSize / 2; + } + + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/scaling/OneRowScale.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/scaling/OneRowScale.java new file mode 100644 index 0000000..9287333 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/scaling/OneRowScale.java @@ -0,0 +1,32 @@ +package org.rapla.components.calendarview.swing.scaling; + + + +public class OneRowScale implements IRowScaleSmall +{ + public int getYCoordForRow( int row ) + { + return 0; + } + + public int getRowSizeForRow( int row ) + { + return 15; + } + + public int calcRow( int y ) + { + return 0; + } + + public int trim( int y ) + { + return 0; + } + + public int getDraggingCorrection( int y) + { + return 15 / 2; + } + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/scaling/VariableRowScale.java b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/scaling/VariableRowScale.java new file mode 100644 index 0000000..d6ba4a2 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/calendarview/swing/scaling/VariableRowScale.java @@ -0,0 +1,197 @@ +package org.rapla.components.calendarview.swing.scaling; + +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + + + +public class VariableRowScale implements IRowScale +{ + PeriodRow[] periodRows; + private int hourSize = 60; + final private static int MINUTES_PER_HOUR= 60; + private TimeZone timeZone = TimeZone.getDefault(); + + private int mintime =0 ; + /* + private int maxtime = 24; + private int workstart = 0; + private int workend = 24; + */ + class PeriodRow + { + int minutes; + int ypos; + int startMinute; + PeriodRow( int minutes ) + { + this.minutes = minutes; + } + + public int getRowSize() + { + return (minutes * hourSize) / 60; + } + + } + + public VariableRowScale() + { + periodRows = new PeriodRow[] { + new PeriodRow( 60 * 8 ), + new PeriodRow( 45 ), + new PeriodRow( 60 ), + new PeriodRow( 10 ), + new PeriodRow( 110 ), + new PeriodRow( 60 + 15), + new PeriodRow( 60 * 3 ), + new PeriodRow( 60 * 8 ) + }; + + for ( int i=0;i< periodRows.length-1;i++) + { + periodRows[i+1].ypos = periodRows[i].ypos + periodRows[i].getRowSize(); + periodRows[i+1].startMinute = periodRows[i].startMinute + periodRows[i].minutes; + } + } + + public void setTimeZone( TimeZone timeZone) + { + this.timeZone = timeZone; + } + + public int getRowsPerDay() + { + return periodRows.length; + } + + + + public int getSizeInPixel() + { + PeriodRow lastRow = getLastRow(); + return lastRow.ypos + lastRow.getRowSize(); + } + + public int getMaxRows() + { + return periodRows.length; + } + + private int getMinuteOfDay(Date time) { + Calendar cal = getCalendar(); + cal.setTime(time); + return (cal.get(Calendar.HOUR_OF_DAY )) * MINUTES_PER_HOUR + cal.get(Calendar.MINUTE); + } + + public int calcHour(int index) { + return periodRows[index].startMinute / MINUTES_PER_HOUR; + } + + public int calcMinute(int index) { + return periodRows[index].startMinute % MINUTES_PER_HOUR; + } + + public int getYCoord(Date time) { + int diff = getMinuteOfDay(time) - mintime * MINUTES_PER_HOUR ; + return (diff * hourSize) / MINUTES_PER_HOUR; + } + + public int getStartWorktimePixel() + { + return periodRows[0].getRowSize(); + } + + public int getEndWorktimePixel() + { + PeriodRow lastRow = getLastRow(); + return lastRow.ypos; + } + + private PeriodRow getLastRow() + { + PeriodRow lastRow = periodRows[periodRows.length-1]; + return lastRow; + } + + + private Calendar calendar = null; + private Calendar getCalendar() { + // Lazy creation of the calendar + if (calendar == null) + calendar = Calendar.getInstance(timeZone); + return calendar; + } + + public boolean isPaintRowThick( int row ) + { + return true; + } +/* + public void setTimeIntervall( int startHour, int endHour ) + { + mintime = startHour; + maxtime = endHour; + } + + public void setWorktime( int startHour, int endHour ) + { + workstart = startHour; + workend = endHour; + } +*/ + public int getYCoordForRow( int row ) + { + if ( row < 0 || row >= periodRows.length) + { + return row* 400; + } + return periodRows[row].ypos; + } + + public int getSizeInPixelBetween( int startRow, int endRow ) + { + if ( startRow < 0 || endRow < 0 || startRow >= periodRows.length || endRow >=periodRows.length) + { + return (endRow - startRow) * 400; + } + + return periodRows[endRow].ypos - periodRows[startRow].ypos; + } + + public int getRowSizeForRow( int row ) + { + /* if ( row < 0 || row >= periodRows.length) + { + return 60; + } + */ + return periodRows[row].getRowSize(); + } + + public int calcRow(int y) { + for ( int i=0;i< periodRows.length;i++) + { + PeriodRow row =periodRows[i]; + if (row.ypos + row.getRowSize() >=y) + return i; + } + return 0; + } + + public int trim(int y ) + { + int row = calcRow( y ); + int rowSize = getRowSizeForRow( row); + return (y / rowSize) * rowSize; + } + + public int getDraggingCorrection(int y) + { + return 0; + } + + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/iolayer/ComponentPrinter.java b/rapla-source-1.8.2/src/org/rapla/components/iolayer/ComponentPrinter.java new file mode 100644 index 0000000..d89b01d --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/iolayer/ComponentPrinter.java @@ -0,0 +1,83 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.iolayer; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; + +import javax.swing.RepaintManager; + +/** Use this to print an awt-Component on one page. + */ +public class ComponentPrinter implements Printable +{ + private Component component; + protected Dimension scaleToFit; + + public ComponentPrinter(Component c, Dimension scaleToFit) + { + component= c; + this.scaleToFit = scaleToFit; + } + + + protected boolean setPage( int pageNumber) + { + // default is one page + return pageNumber == 0; + } + + public int print(Graphics g, PageFormat format, int pagenumber) throws PrinterException + { + + if (!setPage( pagenumber)) { return Printable.NO_SUCH_PAGE; } + Graphics2D g2 = (Graphics2D) g; + if ( scaleToFit != null) { + scaleToFit(g2, format, scaleToFit); + } + RepaintManager rm = RepaintManager.currentManager(component); + boolean db= rm.isDoubleBufferingEnabled(); + try { + rm.setDoubleBufferingEnabled(false); + component.printAll(g2); + } finally { + rm.setDoubleBufferingEnabled(db); + } + return Printable.PAGE_EXISTS; + } + + private static void scaleToFit(Graphics2D g, PageFormat format, Dimension dim) + { + scaleToFit(g, format, dim.getWidth(),dim.getHeight()); + } + + public static void scaleToFit(Graphics2D g, PageFormat format, double width, double height) + { + g.translate(format.getImageableX(), format.getImageableY()); + double sx = format.getImageableWidth() / width; + double sy = format.getImageableHeight() / height; + if (sx < sy) { sy = sx; } else { sx = sy; } + g.scale(sx, sy); + } +} + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/iolayer/DEPENDECIES b/rapla-source-1.8.2/src/org/rapla/components/iolayer/DEPENDECIES new file mode 100644 index 0000000..e4ab5c8 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/iolayer/DEPENDECIES @@ -0,0 +1,5 @@ +This component depends on the following packages (including subpackages): +java.* +javax.jnlp.* (For the WebstartPrinter) +javax.print.* (For the saving in postscript-format) +org.apache.avalon.framework.* diff --git a/rapla-source-1.8.2/src/org/rapla/components/iolayer/DefaultIO.java b/rapla-source-1.8.2/src/org/rapla/components/iolayer/DefaultIO.java new file mode 100644 index 0000000..1218402 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/iolayer/DefaultIO.java @@ -0,0 +1,395 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.iolayer; + +import java.awt.Component; +import java.awt.FileDialog; +import java.awt.Frame; +import java.awt.Toolkit; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.Transferable; +import java.awt.print.PageFormat; +import java.awt.print.Paper; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; + +import javax.print.Doc; +import javax.print.DocFlavor; +import javax.print.PrintException; +import javax.print.SimpleDoc; +import javax.print.StreamPrintService; +import javax.print.StreamPrintServiceFactory; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.Size2DSyntax; +import javax.print.attribute.standard.MediaName; +import javax.print.attribute.standard.MediaPrintableArea; +import javax.print.attribute.standard.OrientationRequested; +import javax.swing.JFileChooser; +import javax.swing.filechooser.FileFilter; + +import org.rapla.framework.logger.Logger; + +public class DefaultIO implements IOInterface{ + static DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE; + /** + * Name of all Rapla printjobs (used in dialogs, printerqueue, etc). + */ + public final static String RAPLA_JOB= "Rapla Printjob"; + public PrinterJob job; + Logger logger; + + public DefaultIO(Logger logger) { + this.logger = logger; + } + + public Logger getLogger() { + return logger; + } + + private PrinterJob getJob() { + if (job == null) + job = PrinterJob.getPrinterJob(); + return job; + } + + public PageFormat defaultPage() throws UnsupportedOperationException { + try { + PageFormat format = getJob().defaultPage(); + return format; + } catch (SecurityException ex) { + return new PageFormat(); + } + } + + public PageFormat showFormatDialog(PageFormat format) throws UnsupportedOperationException { + logPaperSize (format.getPaper()); + format = getJob().pageDialog(format); + logPaperSize (format.getPaper()); + return format; + } + + public void setContents(Transferable transferable, ClipboardOwner owner) { + Toolkit.getDefaultToolkit().getSystemClipboard().setContents( transferable, owner ); + } + + public Transferable getContents( ClipboardOwner owner) { + return Toolkit.getDefaultToolkit().getSystemClipboard().getContents( owner); + } + + public boolean supportsPostscriptExport() { + if (!supportsPrintService()) + return false; + return getPSExportServiceFactory() != null; + } + + private boolean supportsPrintService() { + try { + getClass().getClassLoader().loadClass("javax.print.StreamPrintServiceFactory"); + return true; + } catch (ClassNotFoundException ex) { + getLogger().warn("No support for javax.print.StreamPrintServiceFactory"); + return false; + } + } + + protected void callExport(Printable printable, PageFormat format,OutputStream out, boolean pdf) throws UnsupportedOperationException,IOException { + if ( pdf) + { + ITextPrinter.createPdf(printable, out, format); + } + save(printable,format,out); + } + + private static StreamPrintServiceFactory getPSExportServiceFactory() { + StreamPrintServiceFactory []factories = + StreamPrintServiceFactory.lookupStreamPrintServiceFactories(flavor,"application/postscript"); + + if (factories.length == 0) { + return null; + } + /* + for (int i=0;i 0) + { + fd.setFilenameFilter( new FilenameFilter() { + + public boolean accept(File dir, String name) { + final String[] split = name.split("."); + if ( split.length > 1) + { + String extension = split[split.length -1].toLowerCase(); + for ( String ext: fileExtensions) + { + if ( ext.toLowerCase().equals(extension )) + { + return true; + } + } + } + return false; + } + }); + } + fd.setLocation(50, 50); + fd.setVisible( true); + final String savedFileName = fd.getFile(); + + if (savedFileName == null) { + return null; + } + + String path = createFullPath(fd); + final File savedFile = new File( path); + writeFile(savedFile, content); + return path; + } + + public FileContent openFile(Frame frame,String dir, String[] fileExtensions) throws IOException { + final FileDialog fd = new FileDialog(frame, "Open File", FileDialog.LOAD); + + if ( dir == null) + { + dir = getDirectory(); + } + fd.setDirectory(dir); + fd.setLocation(50, 50); + fd.setVisible( true); + final String openFileName = fd.getFile(); + + if (openFileName == null) { + return null; + } + String path = createFullPath(fd); + final FileInputStream openFile = new FileInputStream( path); + FileContent content = new FileContent(); + content.setName( openFileName); + content.setInputStream( openFile ); + return content; + } + + + private String getDirectory() { + final String userHome = System.getProperty("user.home"); + + if (userHome == null) { + final File execDir = new File(""); + return execDir.getAbsolutePath(); + } + + return userHome; + } + + private String createFullPath(final FileDialog fd) { + return fd.getDirectory() + + System.getProperty("file.separator").charAt(0) + fd.getFile(); + } + + private void writeFile(final File savedFile, byte[] content) throws IOException { + final FileOutputStream out; + out = new FileOutputStream(savedFile); + out.write( content); + out.flush(); + out.close(); + } + + public boolean openUrl(URL url) throws IOException { + try + { + java.awt.Desktop.getDesktop().browse(url.toURI()); + return true; + } + catch (Throwable ex) + { + getLogger().error(ex.getMessage(), ex); + return false; + + } + } + +} + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/iolayer/FileContent.java b/rapla-source-1.8.2/src/org/rapla/components/iolayer/FileContent.java new file mode 100644 index 0000000..3fab3f0 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/iolayer/FileContent.java @@ -0,0 +1,23 @@ +package org.rapla.components.iolayer; + +import java.io.InputStream; + +public class FileContent { + String name; + InputStream inputStream; + public InputStream getInputStream() { + return inputStream; + } + + void setInputStream(InputStream inputStream) { + this.inputStream = inputStream; + } + + public String getName() { + return name; + } + + void setName(String name) { + this.name = name; + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/iolayer/IOInterface.java b/rapla-source-1.8.2/src/org/rapla/components/iolayer/IOInterface.java new file mode 100644 index 0000000..46fe026 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/iolayer/IOInterface.java @@ -0,0 +1,76 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.iolayer; + +import java.awt.Frame; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.Transferable; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; + +/** The IO layer is an abstraction from the io differences in webstart or desktop mode */ +public interface IOInterface { + String saveAsFileShowDialog( + String toDir + ,Printable printable + ,PageFormat format + ,boolean askFormat + ,java.awt.Component owner + ,boolean pdf + ) + throws IOException,UnsupportedOperationException; + + void saveAsFile( + Printable printable + ,PageFormat format + ,OutputStream out + ,boolean pdf + ) + throws IOException,UnsupportedOperationException; + + boolean print( + Printable printable + ,PageFormat format + ,boolean askFormat + + ) + throws PrinterException,UnsupportedOperationException; + + PageFormat defaultPage() + throws UnsupportedOperationException; + + PageFormat showFormatDialog(PageFormat format) + throws UnsupportedOperationException; + + void setContents(Transferable transferable, ClipboardOwner owner); + Transferable getContents( ClipboardOwner owner); + public String saveFile(Frame frame,String dir, String[] fileExtensions,String path, byte[] content) throws IOException; + public FileContent openFile(Frame frame,String dir, String[] fileExtensions) throws IOException; + + public boolean openUrl(final URL url) throws IOException; + + boolean supportsPostscriptExport(); + + public double INCH_TO_MM = 25.40006; + public double MM_TO_INCH = 1.0 / INCH_TO_MM; +} + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/iolayer/ITextPrinter.java b/rapla-source-1.8.2/src/org/rapla/components/iolayer/ITextPrinter.java new file mode 100644 index 0000000..085731d --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/iolayer/ITextPrinter.java @@ -0,0 +1,52 @@ +package org.rapla.components.iolayer; + +import java.awt.Graphics2D; +import java.awt.print.PageFormat; +import java.awt.print.Printable; + +import com.itextpdf.text.Document; +import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.PdfContentByte; +import com.itextpdf.text.pdf.PdfTemplate; +import com.itextpdf.text.pdf.PdfWriter; + +public class ITextPrinter { + + static public void createPdf( Printable printable, java.io.OutputStream fileOutputStream, PageFormat format) { + float width = (float)format.getWidth(); + float height = (float)format.getHeight(); + Rectangle pageSize = new Rectangle(width, height); + Document document = new Document(pageSize); + + try { + PdfWriter writer = PdfWriter.getInstance(document, fileOutputStream); + document.open(); + PdfContentByte cb = writer.getDirectContent(); + + for (int page = 0;page<5000;page++) + { + Graphics2D g2; + PdfTemplate tp = cb.createTemplate(width, height); + g2 = tp.createGraphics(width, height); + int status = printable.print(g2, format, page); + g2.dispose(); + if ( status == Printable.NO_SUCH_PAGE) + { + break; + } + if ( status != Printable.PAGE_EXISTS) + { + break; + } + cb.addTemplate(tp, 0, 0); + document.newPage(); + + } + } catch (Exception e) { + System.err.println(e.getMessage()); + } + document.close(); + } + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/iolayer/WebstartIO.java b/rapla-source-1.8.2/src/org/rapla/components/iolayer/WebstartIO.java new file mode 100644 index 0000000..ff220dc --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/iolayer/WebstartIO.java @@ -0,0 +1,257 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.iolayer; + +import java.awt.Component; +import java.awt.Frame; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.Transferable; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; + +import org.rapla.framework.logger.Logger; + +final public class WebstartIO extends DefaultIO { + Method lookup; + Method getDefaultPage; + Method showPageFormatDialog; + Method print; + Method saveFileDialog; + Method openFileDialog; + Method getName; + Method getInputStream; + Method setContents; + Method getContents; + Method showDocument; + Class unavailableServiceException; + String basicService = "javax.jnlp.BasicService"; + String printService = "javax.jnlp.PrintService"; + String fileSaveService = "javax.jnlp.FileSaveService"; + String fileOpenService = "javax.jnlp.FileOpenService"; + String clipboardService = "javax.jnlp.ClipboardService"; + + public WebstartIO(Logger logger) throws UnsupportedOperationException { + super( logger); + try { + Class serviceManagerC = Class.forName("javax.jnlp.ServiceManager"); + Class printServiceC = Class.forName(printService); + Class fileSaveServiceC = Class.forName(fileSaveService); + Class fileOpenServiceC = Class.forName(fileOpenService); + Class clipboardServiceC = Class.forName(clipboardService); + Class basicServiceC = Class.forName(basicService); + Class fileContents = Class.forName("javax.jnlp.FileContents"); + unavailableServiceException = Class.forName("javax.jnlp.UnavailableServiceException"); + + getName = fileContents.getMethod("getName", new Class[] {} ); + getInputStream = fileContents.getMethod("getInputStream", new Class[] {} ); + lookup = serviceManagerC.getMethod("lookup", new Class[] {String.class}); + getDefaultPage = printServiceC.getMethod("getDefaultPage",new Class[] {}); + showPageFormatDialog = printServiceC.getMethod("showPageFormatDialog",new Class[] {PageFormat.class}); + print = printServiceC.getMethod("print",new Class[] {Printable.class}); + saveFileDialog = fileSaveServiceC.getMethod("saveFileDialog",new Class[] {String.class,String[].class,InputStream.class,String.class}); + openFileDialog = fileOpenServiceC.getMethod("openFileDialog",new Class[] {String.class,String[].class}); + setContents = clipboardServiceC.getMethod("setContents", new Class[] {Transferable.class}); + getContents = clipboardServiceC.getMethod("getContents", new Class[] {}); + showDocument = basicServiceC.getMethod("showDocument", new Class[] {URL.class}); + } catch (ClassNotFoundException ex) { + getLogger().error(ex.getMessage()); + throw new UnsupportedOperationException("Java Webstart not available due to " + ex.getMessage()); + } catch (Exception ex) { + getLogger().error(ex.getMessage()); + throw new UnsupportedOperationException(ex.getMessage()); + } + } + + private Object invoke(String serviceName, Method method, Object[] args) throws Exception { + Object service; + try { + service = lookup.invoke( null, new Object[] { serviceName }); + return method.invoke( service, args); + } catch (InvocationTargetException e) { + throw (Exception) e.getTargetException(); + } catch (Exception e) { + if ( unavailableServiceException.isInstance( e ) ) { + throw new UnsupportedOperationException("The java-webstart service " + serviceName + " is not available!"); + } + throw new UnsupportedOperationException(e.getMessage()); + } + } + + public PageFormat defaultPage() throws UnsupportedOperationException { + if ( isJDK1_5orHigher() ) + return super.defaultPage(); + PageFormat format = null; + try { + format = (PageFormat) invoke ( printService, getDefaultPage, new Object[] {} ) ; + } catch (Exception ex) { + getLogger().error("Can't get print service using default PageFormat." + ex.getMessage()); + } + if (format == null) + format = new PageFormat(); + logPaperSize (format.getPaper()); + return format; + } + + public void setContents(Transferable transferable, ClipboardOwner owner) { + try { + invoke( clipboardService, setContents, new Object[] {transferable}); + } catch (Exception ex) { + throw new UnsupportedOperationException(ex.getMessage()); + } + } + + public Transferable getContents( ClipboardOwner owner) { + try { + return (Transferable)invoke( clipboardService, getContents, new Object[] {}); + } catch (Exception ex) { + throw new UnsupportedOperationException(ex.getMessage()); + } + } + + public PageFormat showFormatDialog(PageFormat format) throws UnsupportedOperationException { + if ( isJDK1_5orHigher() ) + return super.showFormatDialog( format ); + logPaperSize (format.getPaper()); + try { + // format = getPrintService().showPageFormatDialog(format); + format = (PageFormat) invoke( printService, showPageFormatDialog, new Object[] {format}); + } catch (Exception ex) { + throw new UnsupportedOperationException(ex.getMessage()); + } + return format; + } + + /** in the new JDK we don't need the webstart print service */ + private boolean isJDK1_5orHigher() { + try { + String version = System.getProperty("java.version"); + boolean oldVersion = version.startsWith("1.4") || version.startsWith("1.3"); + //System.out.println( version + " new=" + !oldVersion); + return !oldVersion; + //return false; + } catch (SecurityException ex) { + return false; + } + } + + /** + Prints an printable object. The format parameter is ignored, if askFormat is not set. + Call showFormatDialog to set the PageFormat. + @param askFormat If true a dialog will show up to allow the user to edit printformat. + */ + public boolean print(Printable printable, PageFormat format, boolean askFormat) throws PrinterException,UnsupportedOperationException { + if ( isJDK1_5orHigher() ) { + return super.print( printable , format, askFormat ); + } + logPaperSize (format.getPaper()); + if ( askFormat ) { + format= showFormatDialog(format); + } + try { + Boolean result = (Boolean) invoke( printService , print, new Object[] { printable }); + return result.booleanValue(); + } catch (PrinterException ex) { + throw ex; + } catch (Exception ex) { + throw new UnsupportedOperationException(ex.getMessage()); + } + } + + public String saveAsFileShowDialog(String dir,Printable printable,PageFormat format,boolean askFormat,Component owner, boolean pdf) throws IOException,UnsupportedOperationException { + if (askFormat) { format= showFormatDialog(format); } + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + callExport(printable,format,out, pdf); + if (dir == null) + dir = ""; + if ( pdf){ + return saveFile( null, dir, new String[] {"pdf"},"RaplaOutput.pdf", out.toByteArray()); + } + else + { + return saveFile( null, dir, new String[] {"ps"},"RaplaOutput.ps", out.toByteArray()); + } + } + + public String saveFile(Frame frame,String dir, String[] fileExtensions, String filename, byte[] content) throws IOException { + try { + + InputStream in = new ByteArrayInputStream( content); + Object result = invoke( fileSaveService, saveFileDialog, new Object[] { + dir + ,fileExtensions + ,in + ,filename + }); + if (result != null) + return (String) getName.invoke( result, new Object[] {}); + else + return null; + } catch (IOException ex) { + throw ex; + } catch (Exception ex) { + throw new UnsupportedOperationException("Can't invoke save Method " + ex.getMessage() ); + } + + } + + public FileContent openFile(Frame frame,String dir, String[] fileExtensions) throws IOException { + try { + + Object result = invoke( fileOpenService, openFileDialog, new Object[] { + dir + ,fileExtensions + }); + + if (result != null) + { + String name = (String) getName.invoke( result, new Object[] {}); + InputStream in = (InputStream) getInputStream.invoke( result, new Object[] {}); + FileContent content = new FileContent(); + content.setName( name ); + content.setInputStream( in ); + return content; + } + + return null; + } catch (IOException ex) { + throw ex; + } catch (Exception ex) { + throw new UnsupportedOperationException("Can't invoke open Method " + ex.getMessage() ); + } + + } + + public boolean openUrl(URL url) throws IOException { + try { + // Lookup the javax.jnlp.BasicService object + invoke(basicService,showDocument, new Object[] {url}); + // Invoke the showDocument method + return true; + } catch(Exception ex) { + return false; + } + } + + +} + diff --git a/rapla-source-1.8.2/src/org/rapla/components/iolayer/package.html b/rapla-source-1.8.2/src/org/rapla/components/iolayer/package.html new file mode 100644 index 0000000..4feffae --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/iolayer/package.html @@ -0,0 +1,7 @@ + +The IO layer is an abstraction from the io differences in webstart or desktop mode. +With JDK 1.4 or higher PS export is supported. + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/layout/DEPENDENCIES b/rapla-source-1.8.2/src/org/rapla/components/layout/DEPENDENCIES new file mode 100644 index 0000000..02d1cf7 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/layout/DEPENDENCIES @@ -0,0 +1,3 @@ +This component depends on the following packages (including subpackages): +java.* + diff --git a/rapla-source-1.8.2/src/org/rapla/components/layout/TableLayout.java b/rapla-source-1.8.2/src/org/rapla/components/layout/TableLayout.java new file mode 100644 index 0000000..66db59f --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/layout/TableLayout.java @@ -0,0 +1,2137 @@ +package org.rapla.components.layout; + + + +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Insets; +import java.util.LinkedList; +import java.util.ListIterator; + + +/** + * TableLayout is a layout manager that arranges components in rows and columns + * like a spreadsheet. TableLayout allows each row or column to be a different + * size. A row or column can be given an absolute size in pixels, a percentage + * of the available space, or it can grow and shrink to fill the remaining space + * after other rows and columns have been resized. + * + *

    Using spreadsheet terminology, a cell is the intersection of a row and + * column. Cells have finite, non-negative sizes measured in pixels. The + * dimensions of a cell depend solely upon the dimensions of its row and column. + *

    + * + *

    A component occupies a rectangular group of one or more cells. If the + * component occupies more than one cell, the component is resized to fit + * perfectly in the rectangular region of cells. If the component occupies a + * single cell, it can be aligned in four ways within that cell.

    + * + *

    A single cell component can be stretched horizontally to fit the cell + * (full justification), or it can be placed in the center of the cell. The + * component could also be left justified or right justified. Similarly, the + * component can be full, center, top, or bottom justified in the vertical.

    + * + *
    + * public static void main (String args[])
    + * {
    + *     // Create a frame
    + *     Frame frame = new Frame("Example of TableLayout");
    + *     frame.setBounds (100, 100, 300, 300);
    + * 
    + *     // Create a TableLayout for the frame
    + *     double border = 10;
    + *     double size[][] =
    + *         {{border, 0.10, 20, TableLayout.FILL, 20, 0.20, border},  // Columns
    + *          {border, 0.20, 20, TableLayout.FILL, 20, 0.20, border}}; // Rows
    + * 
    + *     frame.setLayout (new TableLayout(size));
    + * 
    + *     // Create some buttons
    + *     String label[] = {"Top", "Bottom", "Left", "Right", "Center", "Overlap"};
    + *     Button button[] = new Button[label.length];
    + * 
    + *     for (int i = 0; i < label.length; i++)
    + *         button[i] = new Button(label[i]);
    + * 
    + *     // Add buttons
    + *     frame.add (button[0], "1, 1, 5, 1"); // Top
    + *     frame.add (button[1], "1, 5, 5, 5"); // Bottom
    + *     frame.add (button[2], "1, 3      "); // Left
    + *     frame.add (button[3], "5, 3      "); // Right
    + *     frame.add (button[4], "3, 3, c, c"); // Center
    + *     frame.add (button[5], "3, 3, 3, 5"); // Overlap
    + * 
    + *     // Allow user to close the window to terminate the program
    + *     frame.addWindowListener
    + *         (new WindowListener()
    + *             {
    + *                 public void windowClosing (WindowEvent e)
    + *                 {
    + *                     System.exit (0);
    + *                 }
    + * 
    + *                 public void windowOpened (WindowEvent e) {}
    + *                 public void windowClosed (WindowEvent e) {}
    + *                 public void windowIconified (WindowEvent e) {}
    + *                 public void windowDeiconified (WindowEvent e) {}
    + *                 public void windowActivated (WindowEvent e) {}
    + *                 public void windowDeactivated (WindowEvent e) {}
    + *             }
    + *         );
    + * 
    + *     // Show frame
    + *     frame.show();
    + * }
    + * 
    + * + * @author Daniel E. Barbalace + */ + +public class TableLayout implements + java.awt.LayoutManager2, + TableLayoutConstants +{ + + + +/** Default row/column size */ +protected static final double defaultSize[][] = {{}, {}}; + + + +/** Widths of columns expressed in absolute and relative terms */ +protected double columnSpec[]; + +/** Heights of rows expressed in absolute and relative terms */ +protected double rowSpec[]; + +/** Widths of columns in pixels */ +protected int columnSize[]; + +/** Heights of rows in pixels */ +protected int rowSize[]; + +/** Offsets of columns in pixels. The left boarder of column n is at + columnOffset[n] and the right boarder is at columnOffset[n + 1] for all + columns including the last one. columnOffset.length = columnSize.length + 1 */ +protected int columnOffset[]; + +/** Offsets of rows in pixels. The left boarder of row n is at + rowOffset[n] and the right boarder is at rowOffset[n + 1] for all + rows including the last one. rowOffset.length = rowSize.length + 1 */ +protected int rowOffset[]; + +/** List of components and their sizes */ +protected LinkedList list; + +/** Indicates whether or not the size of the cells are known for the last known + size of the container. If dirty is true or the container has been resized, + the cell sizes must be recalculated using calculateSize. */ +protected boolean dirty; + +/** Previous known width of the container */ +protected int oldWidth; + +/** Previous known height of the container */ +protected int oldHeight; + + + +//****************************************************************************** +//** Constructors *** +//****************************************************************************** + + + +/** + * Constructs an instance of TableLayout. This TableLayout will have one row + * and one column. + */ + +public TableLayout () +{ + this (defaultSize); +} + + + +/** + * Constructs an instance of TableLayout. + * + * @param size widths of columns and heights of rows in the format, + * {{col0, col1, col2, ..., colN}, {row0, row1, row2, ..., rowM}} + * If this parameter is invalid, the TableLayout will have + * exactly one row and one column. + */ + +public TableLayout (double size[][]) +{ + // Make sure rows and columns and nothing else is specified + if ((size != null) && (size.length == 2)) + { + // Get the rows and columns + double tempCol[] = size[0]; + double tempRow[] = size[1]; + + // Create new rows and columns + columnSpec = new double[tempCol.length]; + rowSpec = new double[tempRow.length]; + + // Copy rows and columns + System.arraycopy (tempCol, 0, columnSpec, 0, columnSpec.length); + System.arraycopy (tempRow, 0, rowSpec, 0, rowSpec.length); + + // Make sure rows and columns are valid + for (int counter = 0; counter < columnSpec.length; counter++) + if ((columnSpec[counter] < 0.0) && + (columnSpec[counter] != FILL) && + (columnSpec[counter] != PREFERRED) && + (columnSpec[counter] != MINIMUM)) + { + columnSpec[counter] = 0.0; + } + + for (int counter = 0; counter < rowSpec.length; counter++) + if ((rowSpec[counter] < 0.0) && + (rowSpec[counter] != FILL) && + (rowSpec[counter] != PREFERRED) && + (rowSpec[counter] != MINIMUM)) + { + rowSpec[counter] = 0.0; + } + } + else + { + double tempCol[] = {FILL}; + double tempRow[] = {FILL}; + + setColumn (tempCol); + setRow (tempRow); + } + + // Create an empty list of components + list = new LinkedList(); + + // Indicate that the cell sizes are not known + dirty = true; +} + + + +//****************************************************************************** +//** Get/Set methods *** +//****************************************************************************** + + + +/** + * Gets the constraints of a given component. + * + * @param component desired component + * + * @return If the given component is found, the constraints associated with + * that component. If the given component is null or is not found, + * null is returned. + */ + +public TableLayoutConstraints getConstraints (Component component) +{ + ListIterator iterator = list.listIterator(0); + + while (iterator.hasNext()) + { + Entry entry = iterator.next(); + + if (entry.component == component) + return new TableLayoutConstraints + (entry.col1, entry.row1, entry.col2, entry.row2, + entry.hAlign, entry.vAlign); + } + + return null; +} + + + +/** + * Sets the constraints of a given component. + * + * @param component desired component. This parameter cannot be null. + * @param constraint new set of constraints. This parameter cannot be null. + * + */ + +public void setConstraints + (Component component, TableLayoutConstraints constraint) +{ + // Check parameters + if (component == null) + throw new IllegalArgumentException + ("Parameter component cannot be null."); + else if (constraint == null) + throw new IllegalArgumentException + ("Parameter constraint cannot be null."); + + // Find and update constraints for the given component + ListIterator iterator = list.listIterator(0); + + while (iterator.hasNext()) + { + Entry entry = iterator.next(); + + if (entry.component == component) + iterator.set (new Entry(component, constraint)); + } +} + + + +/** + * Adjusts the number and sizes of rows in this layout. After calling this + * method, the caller should request this layout manager to perform the + * layout. This can be done with the following code: + * + *
    + *     layout.layoutContainer(container);
    + *     container.repaint();
    + * 
    + * + * or + * + *
    + *     window.pack()
    + * 
    + * + * If this is not done, the changes in the layout will not be seen until the + * container is resized. + * + * @param column heights of each of the columns + * + * @see #getColumn + */ + +public void setColumn (double column[]) +{ + // Copy columns + columnSpec = new double[column.length]; + System.arraycopy (column, 0, columnSpec, 0, columnSpec.length); + + // Make sure columns are valid + for (int counter = 0; counter < columnSpec.length; counter++) + if ((columnSpec[counter] < 0.0) && + (columnSpec[counter] != FILL) && + (columnSpec[counter] != PREFERRED) && + (columnSpec[counter] != MINIMUM)) + { + columnSpec[counter] = 0.0; + } + + // Indicate that the cell sizes are not known + dirty = true; +} + + + +/** + * Adjusts the number and sizes of rows in this layout. After calling this + * method, the caller should request this layout manager to perform the + * layout. This can be done with the following code: + * + * + * layout.layoutContainer(container); + * container.repaint(); + * + * + * or + * + *
    + *     window.pack()
    + * 
    + * + * If this is not done, the changes in the layout will not be seen until the + * container is resized. + * + * @param row widths of each of the rows. This parameter cannot be null. + * + * @see #getRow + */ + +public void setRow (double row[]) +{ + // Copy rows + rowSpec = new double[row.length]; + System.arraycopy (row, 0, rowSpec, 0, rowSpec.length); + + // Make sure rows are valid + for (int counter = 0; counter < rowSpec.length; counter++) + if ((rowSpec[counter] < 0.0) && + (rowSpec[counter] != FILL) && + (rowSpec[counter] != PREFERRED) && + (rowSpec[counter] != MINIMUM)) + { + rowSpec[counter] = 0.0; + } + + // Indicate that the cell sizes are not known + dirty = true; +} + + + +/** + * Adjusts the width of a single column in this layout. After calling this + * method, the caller should request this layout manager to perform the + * layout. This can be done with the following code: + * + * + * layout.layoutContainer(container); + * container.repaint(); + * + * + * or + * + *
    + *     window.pack()
    + * 
    + * + * If this is not done, the changes in the layout will not be seen until the + * container is resized. + * + * @param i zero-based index of column to set. If this parameter is not + * valid, an ArrayOutOfBoundsException will be thrown. + * @param size width of the column. This parameter cannot be null. + * + * @see #getColumn + */ + +public void setColumn (int i, double size) +{ + // Make sure size is valid + if ((size < 0.0) && + (size != FILL) && + (size != PREFERRED) && + (size != MINIMUM)) + { + size = 0.0; + } + + // Copy new size + columnSpec[i] = size; + + // Indicate that the cell sizes are not known + dirty = true; +} + + + +/** + * Adjusts the height of a single row in this layout. After calling this + * method, the caller should request this layout manager to perform the + * layout. This can be done with the following code: + * + * + * layout.layoutContainer(container); + * container.repaint(); + * + * + * or + * + *
    + *     window.pack()
    + * 
    + * + * If this is not done, the changes in the layout will not be seen until the + * container is resized. + * + * @param i zero-based index of row to set. If this parameter is not + * valid, an ArrayOutOfBoundsException will be thrown. + * @param size height of the row. This parameter cannot be null. + * + * @see #getRow + */ + +public void setRow (int i, double size) +{ + // Make sure size is valid + if ((size < 0.0) && + (size != FILL) && + (size != PREFERRED) && + (size != MINIMUM)) + { + size = 0.0; + } + + // Copy new size + rowSpec[i] = size; + + // Indicate that the cell sizes are not known + dirty = true; +} + + + +/** + * Gets the sizes of columns in this layout. + * + * @return widths of each of the columns + * + * @see #setColumn + */ + +public double [] getColumn () +{ + // Copy columns + double column[] = new double[columnSpec.length]; + System.arraycopy (columnSpec, 0, column, 0, column.length); + + return column; +} + + + +/** + * Gets the height of a single row in this layout. + * + * @return height of the requested row + * + * @see #setRow + */ + +public double [] getRow () +{ + // Copy rows + double row[] = new double[rowSpec.length]; + System.arraycopy (rowSpec, 0, row, 0, row.length); + + return row; +} + + + +/** + * Gets the width of a single column in this layout. + * + * @param i zero-based index of row to get. If this parameter is not valid, + * an ArrayOutOfBoundsException will be thrown. + * + * @return width of the requested column + * + * @see #setRow + */ + +public double getColumn (int i) +{ + return columnSpec[i]; +} + + + +/** + * Gets the sizes of a row in this layout. + * + * @param i zero-based index of row to get. If this parameter is not valid, + * an ArrayOutOfBoundsException will be thrown. + * + * @return height of each of the requested row + * + * @see #setRow + */ + +public double getRow (int i) +{ + return rowSpec[i]; +} + + + +/** + * Gets the number of columns in this layout. + * + * @return the number of columns + */ + +public int getNumColumn () +{ + return columnSpec.length; +} + + + +/** + * Gets the number of rows in this layout. + * + * @return the number of rows + */ + +public int getNumRow () +{ + return rowSpec.length; +} + + + +//****************************************************************************** +//** Insertion/Deletion methods *** +//****************************************************************************** + + + +/** + * Inserts a column in this layout. All components to the right of the + * insertion point are moved right one column. The container will need to + * be laid out after this method returns. See setColumn. + * + * @param i zero-based index at which to insert the column. + * @param size size of the column to be inserted + * + * @see #setColumn + * @see #deleteColumn + */ + +public void insertColumn (int i, double size) +{ + // Make sure position is valid + if ((i < 0) || (i > columnSpec.length)) + throw new IllegalArgumentException + ("Parameter i is invalid. i = " + i + ". Valid range is [0, " + + columnSpec.length + "]."); + + // Make sure column size is valid + if ((size < 0.0) && + (size != FILL) && + (size != PREFERRED) && + (size != MINIMUM)) + { + size = 0.0; + } + + // Copy columns + double column[] = new double[columnSpec.length + 1]; + System.arraycopy (columnSpec, 0, column, 0, i); + System.arraycopy (columnSpec, i, column, i + 1, columnSpec.length - i); + + // Insert column + column[i] = size; + columnSpec = column; + + // Move all components that are to the right of new row + ListIterator iterator = list.listIterator(0); + + while (iterator.hasNext()) + { + // Get next entry + Entry entry = iterator.next(); + + // Is the first column to the right of the new column + if (entry.col1 >= i) + // Move first column + entry.col1++; + + // Is the second column to the right of the new column + if (entry.col2 >= i) + // Move second column + entry.col2++; + } + + // Indicate that the cell sizes are not known + dirty = true; +} + + + +/** + * Inserts a row in this layout. All components below the insertion point + * are moved down one row. The container will need to be laid out after this + * method returns. See setRow. + * + * @param i zero-based index at which to insert the column. + * @param size size of the row to be inserted + * + * @see #setRow + * @see #deleteRow + */ + +public void insertRow (int i, double size) +{ + // Make sure position is valid + if ((i < 0) || (i > rowSpec.length)) + throw new IllegalArgumentException + ("Parameter i is invalid. i = " + i + ". Valid range is [0, " + + rowSpec.length + "]."); + + // Make sure row size is valid + if ((size < 0.0) && + (size != FILL) && + (size != PREFERRED) && + (size != MINIMUM)) + { + size = 0.0; + } + + // Copy rows + double row[] = new double[rowSpec.length + 1]; + System.arraycopy (rowSpec, 0, row, 0, i); + System.arraycopy (rowSpec, i, row, i + 1, rowSpec.length - i); + + // Insert row + row[i] = size; + rowSpec = row; + + // Move all components that are below the new row + ListIterator iterator = list.listIterator(0); + + while (iterator.hasNext()) + { + // Get next entry + Entry entry = iterator.next(); + + // Is the first row to the right of the new row + if (entry.row1 >= i) + // Move first row + entry.row1++; + + // Is the second row to the right of the new row + if (entry.row2 >= i) + // Move second row + entry.row2++; + } + + // Indicate that the cell sizes are not known + dirty = true; +} + + + +/** + * Deletes a column in this layout. All components to the right of the + * deletion point are moved left one column. The container will need to + * be laid out after this method returns. See setColumn. + * + * @param i zero-based index of column to delete + * + * @see #setColumn + * @see #deleteColumn + */ + +public void deleteColumn (int i) +{ + // Make sure position is valid + if ((i < 0) || (i >= columnSpec.length)) + throw new IllegalArgumentException + ("Parameter i is invalid. i = " + i + ". Valid range is [0, " + + (columnSpec.length - 1) + "]."); + + // Copy columns + double column[] = new double[columnSpec.length - 1]; + System.arraycopy (columnSpec, 0, column, 0, i); + System.arraycopy (columnSpec, i + 1, column, i, columnSpec.length - i - 1); + + // Delete column + columnSpec = column; + + // Move all components that are to the right of row deleted + ListIterator iterator = list.listIterator(0); + + while (iterator.hasNext()) + { + // Get next entry + Entry entry = iterator.next(); + + // Is the first column to the right of the new column + if (entry.col1 >= i) + // Move first column + entry.col1--; + + // Is the second column to the right of the new column + if (entry.col2 >= i) + // Move second column + entry.col2--; + } + + // Indicate that the cell sizes are not known + dirty = true; +} + + + +/** + * Deletes a row in this layout. All components below the deletion point are + * moved up one row. The container will need to be laid out after this method + * returns. See setRow. There must be at least two rows in order + * to delete a row. + * + * @param i zero-based index of column to delete + * + * @see #setRow + * @see #deleteRow + */ + +public void deleteRow (int i) +{ + // Make sure position is valid + if ((i < 0) || (i >= rowSpec.length)) + throw new IllegalArgumentException + ("Parameter i is invalid. i = " + i + ". Valid range is [0, " + + (rowSpec.length - 1) + "]."); + + // Copy rows + double row[] = new double[rowSpec.length - 1]; + System.arraycopy (rowSpec, 0, row, 0, i); + System.arraycopy (rowSpec, i + 1, row, i, rowSpec.length - i - 1); + + // Delete row + rowSpec = row; + + // Move all components that are to below the row deleted + ListIterator iterator = list.listIterator(0); + + while (iterator.hasNext()) + { + // Get next entry + Entry entry = iterator.next(); + + // Is the first row below the new row + if (entry.row1 >= i) + // Move first row + entry.row1--; + + // Is the second row below the new row + if (entry.row2 >= i) + // Move second row + entry.row2--; + } + + // Indicate that the cell sizes are not known + dirty = true; +} + + + +//****************************************************************************** +//** Misc methods *** +//****************************************************************************** + + + +/** + * Converts this TableLayout to a string. + * + * @return a string representing the columns and row sizes in the form + * "{{col0, col1, col2, ..., colN}, {row0, row1, row2, ..., rowM}}" + */ + +public String toString () +{ + int counter; + + String value = "TableLayout {{"; + + if (columnSpec.length > 0) + { + for (counter = 0; counter < columnSpec.length - 1; counter++) + value += columnSpec[counter] + ", "; + + value += columnSpec[columnSpec.length - 1] + "}, {"; + } + else + value += "}, {"; + + if (rowSpec.length > 0) + { + for (counter = 0; counter < rowSpec.length - 1; counter++) + value += rowSpec[counter] + ", "; + + value += rowSpec[rowSpec.length - 1] + "}}"; + } + else + value += "}}"; + + return value; +} + + + +/** + * Draws a grid on the given container. This is useful for seeing where the + * rows and columns go. In the container's paint method, call this method. + * + * @param container container using this TableLayout + * @param g graphics content of container (can be offscreen) + */ + +public void drawGrid (Container container, Graphics g) +{ + + // Calculate the sizes of the rows and columns + Dimension d = container.getSize(); + + if (dirty || (d.width != oldWidth) || (d.height != oldHeight)) + calculateSize (container); + + // Initialize y + int y = 0; + + for (int row = 0; row < rowSize.length; row++) + { + // Initialize x + int x = 0; + + for (int column = 0; column < columnSize.length; column++) + { + // Use a random color to make things easy to see + Color color = new Color((int) (Math.random() * 0xFFFFFFL)); + g.setColor (color); + + // Draw the cell as a solid rectangle + g.fillRect (x, y, columnSize[column], rowSize[row]); + + // Increment x + x += columnSize[column]; + } + + // Increment y + y += rowSize[row]; + } +} + + + +/** + * Determines whether or not there are any hidden components. A hidden + * component is one that will not be shown with this layout's current + * configuration. Such a component is, at least partly, in an invalid row + * or column. For example, on a table with five rows, row -1 and row 5 are both + * invalid. Valid rows are 0 through 4, inclusively. + * + * @return True, if there are any hidden components. False, otherwise. + * + * @see #overlapping + */ + +public boolean hidden () +{ + // Assume no components are hidden + boolean hidden = false; + + // Check all components + ListIterator iterator = list.listIterator(0); + + while (iterator.hasNext()) + { + // Get next entry + Entry entry = iterator.next(); + + // Is this component valid + if ((entry.row1 < 0) || (entry.col1 < 0) || + (entry.row2 > rowSpec.length) || + (entry.col2 > columnSpec.length)) + { + hidden = true; + break; + } + } + + return hidden; +} + + + +/** + * Determines whether or not there are any overlapping components. Two + * components overlap if they cover at least one common cell. + * + * @return True, if there are any overlapping components. False, otherwise. + * + * @see #hidden + */ + +public boolean overlapping () +{ + // Count contraints + int numEntry = list.size(); + + // If there are no components, they can't be overlapping + if (numEntry == 0) + return false; + + // Assume no components are overlapping + boolean overlapping = false; + + // Put entries in an array + Entry entry[] = list.toArray(new Entry[numEntry]); + + // Check all components + for (int knowUnique = 1; knowUnique < numEntry; knowUnique++) + for (int checking = knowUnique - 1; checking >= 0; checking--) + if + ( + ( + (entry[checking].col1 >= entry[knowUnique].col1) && + (entry[checking].col1 <= entry[knowUnique].col2) && + (entry[checking].row1 >= entry[knowUnique].row1) && + (entry[checking].row1 <= entry[knowUnique].row2) + ) + || + ( + (entry[checking].col2 >= entry[knowUnique].col1) && + (entry[checking].col2 <= entry[knowUnique].col2) && + (entry[checking].row2 >= entry[knowUnique].row1) && + (entry[checking].row2 <= entry[knowUnique].row2) + ) + ) + { + overlapping = true; + break; + } + + return overlapping; +} + + + +/** + * Calculates the sizes of the rows and columns based on the absolute and + * relative sizes specified in rowSpec and columnSpec + * and the size of the container. The result is stored in rowSize + * and columnSize. + * + * @param container container using this TableLayout + */ + +protected void calculateSize (Container container) +{ + int counter; // Counting variable; + + // Get number of rows and columns + int numColumn = columnSpec.length; + int numRow = rowSpec.length; + + // Create array to hold actual sizes in pixels + columnSize = new int[numColumn]; + rowSize = new int[numRow]; + + // Get the container's insets + Insets inset = container.getInsets(); + + // Get the size of the container's available space + Dimension d = container.getSize(); + int totalWidth = d.width - inset.left - inset.right; + int totalHeight = d.height - inset.top - inset.bottom; + + // Initially, the available space is the total space + int availableWidth = totalWidth; + int availableHeight = totalHeight; + + // Assign absolute widths; this reduces available width + for (counter = 0; counter < numColumn; counter++) + // Is the current column an absolue size + if ((columnSpec[counter] >= 1.0) || (columnSpec[counter] == 0.0)) + { + // Assign absolute width + columnSize[counter] = (int) (columnSpec[counter] + 0.5); + + // Reduce available width + availableWidth -= columnSize[counter]; + } + + // Assign absolute heights; this reduces available height + for (counter = 0; counter < numRow; counter++) + // Is the current column an absolue size + if ((rowSpec[counter] >= 1.0) || (rowSpec[counter] == 0.0)) + { + // Assign absolute width + rowSize[counter] = (int) (rowSpec[counter] + 0.5); + + // Reduce available width + availableHeight -= rowSize[counter]; + } + + // Assign preferred and minimum widths; this reduces available width. + // Assignment of preferred/minimum with is like assignment of absolute + // widths except that each column must determine the maximum + // preferred/minimum width of the components that are completely contained + // within the column. + for (counter = 0; counter < numColumn; counter++) + // Is the current column a preferred size + if ((columnSpec[counter] == PREFERRED) || + (columnSpec[counter] == MINIMUM)) + { + // Assume a maximum width of zero + int maxWidth = 0; + + // Find maximum preferred width of all components completely + // contained within this column + ListIterator iterator = list.listIterator(0); + + while (iterator.hasNext()) + { + Entry entry = iterator.next(); + + if ((entry.col1 == counter) && (entry.col2 == counter)) + { + Dimension p = (columnSpec[counter] == PREFERRED) ? + entry.component.getPreferredSize() : + entry.component.getMinimumSize(); + + int width = (p == null) ? 0 : p.width; + + if (maxWidth < width) + maxWidth = width; + } + } + + // Assign preferred width + columnSize[counter] = maxWidth; + + // Reduce available width + availableWidth -= maxWidth; + } + + // Assign preferred and minimum heights; this reduces available height. + // Assignment of preferred/minimum with is like assignment of absolute + // heights except that each row must determine the maximum + // preferred/minimum height of the components that are completely contained + // within the row. + for (counter = 0; counter < numRow; counter++) + // Is the current row a preferred size + if ((rowSpec[counter] == PREFERRED) || + (rowSpec[counter] == MINIMUM)) + { + // Assume a maximum height of zero + int maxHeight = 0; + + // Find maximum preferred height of all components completely + // contained within this row + ListIterator iterator = list.listIterator(0); + + while (iterator.hasNext()) + { + Entry entry = iterator.next(); + + if ((entry.row1 == counter) && (entry.row2 == counter)) + { + Dimension p = (rowSpec[counter] == PREFERRED) ? + entry.component.getPreferredSize() : + entry.component.getMinimumSize(); + + int height = (p == null) ? 0 : p.height; + + if (maxHeight < height) + maxHeight = height; + } + } + + // Assign preferred height + rowSize[counter] = maxHeight; + + // Reduce available height + availableHeight -= maxHeight; + } + + // Remember how much space is available for relatively sized cells + int relativeWidth = availableWidth; + int relativeHeight = availableHeight; + + // Make sure relativeWidth and relativeHeight are non-negative + if (relativeWidth < 0) + relativeWidth = 0; + + if (relativeHeight < 0) + relativeHeight = 0; + + // Assign relative widths + for (counter = 0; counter < numColumn; counter++) + // Is the current column an relative size + if ((columnSpec[counter] > 0.0) && (columnSpec[counter] < 1.0)) + { + // Assign relative width + columnSize[counter] = + (int) (columnSpec[counter] * relativeWidth + 0.5); + + // Reduce available width + availableWidth -= columnSize[counter]; + } + + // Assign relative widths + for (counter = 0; counter < numRow; counter++) + // Is the current column an relative size + if ((rowSpec[counter] > 0.0) && (rowSpec[counter] < 1.0)) + { + // Assign relative width + rowSize[counter] = (int) (rowSpec[counter] * relativeHeight + 0.5); + + // Reduce available width + availableHeight -= rowSize[counter]; + } + + // Make sure availableWidth and availableHeight are non-negative + if (availableWidth < 0) + availableWidth = 0; + + if (availableHeight < 0) + availableHeight = 0; + + // Count the number of "fill" cells + int numFillWidth = 0; + int numFillHeight = 0; + + for (counter = 0; counter < numColumn; counter++) + if (columnSpec[counter] == FILL) + numFillWidth++; + + for (counter = 0; counter < numRow; counter++) + if (rowSpec[counter] == FILL) + numFillHeight++; + + // If numFillWidth (numFillHeight) is zero, the cooresponding if statements + // will always evaluate to false and the division will not occur. + + // If there are more than one "fill" cell, slack may occur due to rounding + // errors + int slackWidth = availableWidth; + int slackHeight = availableHeight; + + // Assign "fill" cells equal amounts of the remaining space + for (counter = 0; counter < numColumn; counter++) + if (columnSpec[counter] == FILL) + { + columnSize[counter] = availableWidth / numFillWidth; + slackWidth -= columnSize[counter]; + } + + for (counter = 0; counter < numRow; counter++) + if (rowSpec[counter] == FILL) + { + rowSize[counter] = availableHeight / numFillHeight; + slackHeight -= rowSize[counter]; + } + + // Add slack to the last "fill" cell + for (counter = numColumn - 1; counter >= 0; counter--) + { + if (columnSpec[counter] == FILL) + { + columnSize[counter] += slackWidth; + break; + } + } + + for (counter = numRow - 1; counter >= 0; counter--) + { + if (rowSpec[counter] == FILL) + { + rowSize[counter] += slackHeight; + break; + } + } + + // Calculate offsets of each column (done for effeciency) + columnOffset = new int[numColumn + 1]; + columnOffset[0] = inset.left; + + for (counter = 0; counter < numColumn; counter++) + columnOffset[counter + 1] = + columnOffset[counter] + columnSize[counter]; + + // Calculate offsets of each row (done for effeciency) + rowOffset = new int[numRow + 1]; + rowOffset[0] = inset.top; + + for (counter = 0; counter < numRow; counter++) + rowOffset[counter + 1] = + rowOffset[counter] + rowSize[counter]; + + // Indicate that the size of the cells are known for the container's + // current size + dirty = false; + oldWidth = totalWidth; + oldHeight = totalHeight; +} + + + +//****************************************************************************** +//** java.awt.event.LayoutManager methods *** +//****************************************************************************** + + + +/** + * To lay out the specified container using this layout. This method reshapes + * the components in the specified target container in order to satisfy the + * constraints of all components. + * + *

    User code should not have to call this method directly.

    + * + * @param container container being served by this layout manager + */ + +public void layoutContainer (Container container) +{ + int x, y; // Coordinates of the currnet component in pixels + int w, h; // Width and height of the current component in pixels + + // Calculate sizes if container has changed size or components were added + Dimension d = container.getSize(); + + if (dirty || (d.width != oldWidth) || (d.height != oldHeight)) + calculateSize (container); + + // Get components + Component component[] = container.getComponents(); + + // Layout components + for (int counter = 0; counter < component.length; counter++) + { + try + { + // Get the entry entry for the next component + ListIterator iterator = list.listIterator(0); + Entry entry = null; + + while (iterator.hasNext()) + { + entry = iterator.next(); + + if (entry.component == component[counter]) + break; + else + entry = null; + } + + // Skip any components that have not been place in a specific cell + if (entry == null) + break; + + // Does the entry occupy a single cell + if (entry.singleCell) + { + // The following block of code has been optimized so that the + // preferred size of the component is only obtained if it is + // needed. There are components in which the getPreferredSize + // method is extremely expensive, such as data driven controls + // with a large amount of data. + + // Get the preferred size of the component + int preferredWidth = 0; + int preferredHeight = 0; + + if ((entry.hAlign != FULL) || (entry.vAlign != FULL)) + { + Dimension preferredSize = + component[counter].getPreferredSize(); + + preferredWidth = preferredSize.width; + preferredHeight = preferredSize.height; + } + + // Determine cell width and height + int cellWidth = columnSize[entry.col1]; + int cellHeight = rowSize[entry.row1]; + + // Determine the width of the component + if ((entry.hAlign == FULL) || + (cellWidth < preferredWidth)) + // Use the width of the cell + w = cellWidth; + else + // Use the prefered width of the component + w = preferredWidth; + + // Determine left and right boarders + switch (entry.hAlign) + { + case LEFT : + // Align left side along left edge of cell + x = columnOffset[entry.col1]; + break; + + case RIGHT : + // Align right side along right edge of cell + x = columnOffset[entry.col1 + 1] - w; + break; + + case CENTER : + // Center justify component + x = columnOffset[entry.col1] + ((cellWidth - w) >> 1); + break; + + case FULL : + // Align left side along left edge of cell + x = columnOffset[entry.col1]; + break; + + default : + // This is a never should happen case, but just in case + x = 0; + } + + // Determine the height of the component + if ((entry.vAlign == FULL) || + (cellHeight < preferredHeight)) + // Use the height of the cell + h = cellHeight; + else + // Use the prefered height of the component + h = preferredHeight; + + // Determine top and bottom boarders + switch (entry.vAlign) + { + case TOP : + // Align top side along top edge of cell + y = rowOffset[entry.row1]; + break; + + case BOTTOM : + // Align right side along right edge of cell + y = rowOffset[entry.row1 + 1] - h; + break; + + case CENTER : + // Center justify component + y = rowOffset[entry.row1] + ((cellHeight - h) >> 1); + break; + + case FULL : + // Align right side along right edge of cell + y = rowOffset[entry.row1]; + break; + + default : + // This is a never should happen case, but just in case + y = 0; + } + } + else + { + // Align left side with left boarder of first column + x = columnOffset[entry.col1]; + + // Align top side along top edge of first row + y = rowOffset[entry.row1]; + + // Align right side with right boarder of second column + w = columnOffset[entry.col2 + 1] - + columnOffset[entry.col1]; + + // Align bottom side with bottom boarder of second row + h = rowOffset[entry.row2 + 1] - rowOffset[entry.row1]; + } + + // Move and resize component + component[counter].setBounds (x, y, w, h); + } + catch (Exception error) + { + // If any error occurs, skip this component + continue; + } + } +} + + + +/** + * Determines the preferred size of the container argument using this layout. + * The preferred size is the smallest size that, if used for the container's + * size, will ensure that all components are at least as large as their + * preferred size. This method cannot guarantee that all components will be + * their preferred size. For example, if component A and component B are each + * allocate half of the container's width and component A wants to be 10 pixels + * wide while component B wants to be 100 pixels wide, they cannot both be + * accommodated. Since in general components rather be larger than their + * preferred size instead of smaller, component B's request will be fulfilled. + * The preferred size of the container would be 200 pixels. + * + * @param container container being served by this layout manager + * + * @return a dimension indicating the container's preferred size + */ + +public Dimension preferredLayoutSize (Container container) +{ + Dimension size; // Preferred size of current component + int scaledWidth = 0; // Preferred width of scalled components + int scaledHeight = 0; // Preferred height of scalled components + int temp; // Temporary variable used to compare sizes + int counter; // Counting variable + + // Determine percentage of space allocated to fill components. This is + // one minus the sum of all scalable components. + double fillWidthRatio = 1.0; + double fillHeightRatio = 1.0; + int numFillWidth = 0; + int numFillHeight = 0; + + for (counter = 0; counter < columnSpec.length; counter++) + if ((columnSpec[counter] > 0.0) && (columnSpec[counter] < 1.0)) + fillWidthRatio -= columnSpec[counter]; + else if (columnSpec[counter] == FILL) + numFillWidth++; + + for (counter = 0; counter < rowSpec.length; counter++) + if ((rowSpec[counter] > 0.0) && (rowSpec[counter] < 1.0)) + fillHeightRatio -= rowSpec[counter]; + else if (rowSpec[counter] == FILL) + numFillHeight++; + + // Adjust fill ratios to reflect number of fill rows/columns + if (numFillWidth > 1) + fillWidthRatio /= numFillWidth; + + if (numFillHeight > 1) + fillHeightRatio /= numFillHeight; + + // Cap fill ratio bottoms to 0.0 + if (fillWidthRatio < 0.0) + fillWidthRatio = 0.0; + + if (fillHeightRatio < 0.0) + fillHeightRatio = 0.0; + + // Calculate preferred/minimum column widths + int columnPrefMin[] = new int[columnSpec.length]; + + for (counter = 0; counter < columnSpec.length; counter++) + // Is the current column a preferred/minimum size + if ((columnSpec[counter] == PREFERRED) || + (columnSpec[counter] == MINIMUM)) + { + // Assume a maximum width of zero + int maxWidth = 0; + + // Find maximum preferred/minimum width of all components completely + // contained within this column + ListIterator iterator = list.listIterator(0); + + while (iterator.hasNext()) + { + Entry entry = iterator.next(); + + if ((entry.col1 == counter) && (entry.col2 == counter)) + { + Dimension p = (columnSpec[counter] == PREFERRED) ? + entry.component.getPreferredSize() : + entry.component.getMinimumSize(); + + int width = (p == null) ? 0 : p.width; + + if (maxWidth < width) + maxWidth = width; + } + } + + // Set column's preferred/minimum width + columnPrefMin[counter] = maxWidth; + } + + + // Calculate preferred/minimum row heights + int rowPrefMin[] = new int[rowSpec.length]; + + for (counter = 0; counter < rowSpec.length; counter++) + // Is the current row a preferred/minimum size + if ((rowSpec[counter] == PREFERRED) || + (rowSpec[counter] == MINIMUM)) + { + // Assume a maximum height of zero + int maxHeight = 0; + + // Find maximum preferred height of all components completely + // contained within this row + ListIterator iterator = list.listIterator(0); + + while (iterator.hasNext()) + { + Entry entry = iterator.next(); + + if ((entry.row1 == counter) && (entry.row1 == counter)) + { + Dimension p = (rowSpec[counter] == PREFERRED) ? + entry.component.getPreferredSize() : + entry.component.getMinimumSize(); + + int height = (p == null) ? 0 : p.height; + + if (maxHeight < height) + maxHeight = height; + } + } + + // Add preferred height + rowPrefMin[counter] += maxHeight; + } + + // Find maximum preferred size of all scaled components + ListIterator iterator = list.listIterator(0); + + while (iterator.hasNext()) + { + // Get next entry + Entry entry = iterator.next(); + + // Make sure entry is in valid rows and columns + if ((entry.col1 < 0) || (entry.col1 >= columnSpec.length) || + (entry.col2 >= columnSpec.length) || + (entry.row1 < 0) || (entry.row1 >= rowSpec.length) || + (entry.row2 >= rowSpec.length)) + { + // Skip the bad component + continue; + } + + // Get preferred size of current component + size = entry.component.getPreferredSize(); + + // Calculate portion of component that is not absolutely sized + int scalableWidth = size.width; + int scalableHeight = size.height; + + for (counter = entry.col1; counter <= entry.col2; counter++) + if (columnSpec[counter] >= 1.0) + scalableWidth -= columnSpec[counter]; + else if ((columnSpec[counter] == PREFERRED) || + (columnSpec[counter] == MINIMUM)) + { + scalableWidth -= columnPrefMin[counter]; + } + + for (counter = entry.row1; counter <= entry.row2; counter++) + if (rowSpec[counter] >= 1.0) + scalableHeight -= rowSpec[counter]; + else if ((rowSpec[counter] == PREFERRED) || + (rowSpec[counter] == MINIMUM)) + { + scalableHeight -= rowPrefMin[counter]; + } + + //---------------------------------------------------------------------- + + // Determine total percentage of scalable space that the component + // occupies by adding the relative columns and the fill columns + double relativeWidth = 0.0; + + for (counter = entry.col1; counter <= entry.col2; counter++) + { + // Column is scaled + if ((columnSpec[counter] > 0.0) && (columnSpec[counter] < 1.0)) + // Add scaled size to relativeWidth + relativeWidth += columnSpec[counter]; + // Column is fill + else if ((columnSpec[counter] == FILL) && (fillWidthRatio != 0.0)) + // Add fill size to relativeWidth + relativeWidth += fillWidthRatio; + } + + // Determine the total scaled width as estimated by this component + if (relativeWidth == 0) + temp = 0; + else + temp = (int) (scalableWidth / relativeWidth + 0.5); + + // If the container needs to be bigger, make it so + if (scaledWidth < temp) + scaledWidth = temp; + + //---------------------------------------------------------------------- + + // Determine total percentage of scalable space that the component + // occupies by adding the relative columns and the fill columns + double relativeHeight = 0.0; + + for (counter = entry.row1; counter <= entry.row2; counter++) + { + // Row is scaled + if ((rowSpec[counter] > 0.0) && (rowSpec[counter] < 1.0)) + // Add scaled size to relativeHeight + relativeHeight += rowSpec[counter]; + // Row is fill + else if ((rowSpec[counter] == FILL) && (fillHeightRatio != 0.0)) + // Add fill size to relativeHeight + relativeHeight += fillHeightRatio; + } + + // Determine the total scaled width as estimated by this component + if (relativeHeight == 0) + temp = 0; + else + temp = (int) (scalableHeight / relativeHeight + 0.5); + + // If the container needs to be bigger, make it so + if (scaledHeight < temp) + scaledHeight = temp; + } + + // totalWidth is the scaledWidth plus the sum of all absolute widths and all + // preferred widths + int totalWidth = scaledWidth; + + for (counter = 0; counter < columnSpec.length; counter++) + // Is the current column an absolute size + if (columnSpec[counter] >= 1.0) + totalWidth += (int) (columnSpec[counter] + 0.5); + // Is the current column a preferred/minimum size + else if ((columnSpec[counter] == PREFERRED) || + (columnSpec[counter] == MINIMUM)) + { + // Add preferred/minimum width + totalWidth += columnPrefMin[counter]; + } + + // totalHeight is the scaledHeight plus the sum of all absolute heights and + // all preferred widths + int totalHeight = scaledHeight; + + for (counter = 0; counter < rowSpec.length; counter++) + // Is the current row an absolute size + if (rowSpec[counter] >= 1.0) + totalHeight += (int) (rowSpec[counter] + 0.5); + // Is the current row a preferred size + else if ((rowSpec[counter] == PREFERRED) || + (rowSpec[counter] == MINIMUM)) + { + // Add preferred/minimum width + totalHeight += rowPrefMin[counter]; + } + + // Compensate for container's insets + Insets inset = container.getInsets(); + totalWidth += inset.left + inset.right; + totalHeight += inset.top + inset.bottom; + + return new Dimension(totalWidth, totalHeight); +} + + + +/** + * Determines the minimum size of the container argument using this layout. + * The minimum size is the smallest size that, if used for the container's + * size, will ensure that all components are at least as large as their + * minimum size. This method cannot guarantee that all components will be + * their minimum size. For example, if component A and component B are each + * allocate half of the container's width and component A wants to be 10 pixels + * wide while component B wants to be 100 pixels wide, they cannot both be + * accommodated. Since in general components rather be larger than their + * minimum size instead of smaller, component B's request will be fulfilled. + * The minimum size of the container would be 200 pixels. + * + * @param container container being served by this layout manager + * + * @return a dimension indicating the container's minimum size + */ + +public Dimension minimumLayoutSize (Container container) +{ + Dimension size; // Minimum size of current component + int scaledWidth = 0; // Minimum width of scalled components + int scaledHeight = 0; // Minimum height of scalled components + int temp; // Temporary variable used to compare sizes + int counter; // Counting variable + + // Determine percentage of space allocated to fill components. This is + // one minus the sum of all scalable components. + double fillWidthRatio = 1.0; + double fillHeightRatio = 1.0; + int numFillWidth = 0; + int numFillHeight = 0; + + for (counter = 0; counter < columnSpec.length; counter++) + if ((columnSpec[counter] > 0.0) && (columnSpec[counter] < 1.0)) + fillWidthRatio -= columnSpec[counter]; + else if (columnSpec[counter] == FILL) + numFillWidth++; + + for (counter = 0; counter < rowSpec.length; counter++) + if ((rowSpec[counter] > 0.0) && (rowSpec[counter] < 1.0)) + fillHeightRatio -= rowSpec[counter]; + else if (rowSpec[counter] == FILL) + numFillHeight++; + + // Adjust fill ratios to reflect number of fill rows/columns + if (numFillWidth > 1) + fillWidthRatio /= numFillWidth; + + if (numFillHeight > 1) + fillHeightRatio /= numFillHeight; + + // Cap fill ratio bottoms to 0.0 + if (fillWidthRatio < 0.0) + fillWidthRatio = 0.0; + + if (fillHeightRatio < 0.0) + fillHeightRatio = 0.0; + + // Find maximum minimum size of all scaled components + ListIterator iterator = list.listIterator(0); + + while (iterator.hasNext()) + { + // Get next entry + Entry entry = iterator.next(); + + // Make sure entry is in valid rows and columns + if ((entry.col1 < 0) || (entry.col1 >= columnSpec.length) || + (entry.col2 >= columnSpec.length) || + (entry.row1 < 0) || (entry.row1 >= rowSpec.length) || + (entry.row2 >= rowSpec.length)) + { + // Skip the bad component + continue; + } + + // Get minimum size of current component + size = entry.component.getMinimumSize(); + + // Calculate portion of component that is not absolutely sized + int scalableWidth = size.width; + int scalableHeight = size.height; + + for (counter = entry.col1; counter <= entry.col2; counter++) + if (columnSpec[counter] >= 1.0) + scalableWidth -= columnSpec[counter]; + + for (counter = entry.row1; counter <= entry.row2; counter++) + if (rowSpec[counter] >= 1.0) + scalableHeight -= rowSpec[counter]; + + //---------------------------------------------------------------------- + + // Determine total percentage of scalable space that the component + // occupies by adding the relative columns and the fill columns + double relativeWidth = 0.0; + + for (counter = entry.col1; counter <= entry.col2; counter++) + { + // Column is scaled + if ((columnSpec[counter] > 0.0) && (columnSpec[counter] < 1.0)) + // Add scaled size to relativeWidth + relativeWidth += columnSpec[counter]; + // Column is fill + else if ((columnSpec[counter] == FILL) && (fillWidthRatio != 0.0)) + // Add fill size to relativeWidth + relativeWidth += fillWidthRatio; + } + + // Determine the total scaled width as estimated by this component + if (relativeWidth == 0) + temp = 0; + else + temp = (int) (scalableWidth / relativeWidth + 0.5); + + // If the container needs to be bigger, make it so + if (scaledWidth < temp) + scaledWidth = temp; + + //---------------------------------------------------------------------- + + // Determine total percentage of scalable space that the component + // occupies by adding the relative columns and the fill columns + double relativeHeight = 0.0; + + for (counter = entry.row1; counter <= entry.row2; counter++) + { + // Row is scaled + if ((rowSpec[counter] > 0.0) && (rowSpec[counter] < 1.0)) + // Add scaled size to relativeHeight + relativeHeight += rowSpec[counter]; + // Row is fill + else if ((rowSpec[counter] == FILL) && (fillHeightRatio != 0.0)) + // Add fill size to relativeHeight + relativeHeight += fillHeightRatio; + } + + // Determine the total scaled width as estimated by this component + if (relativeHeight == 0) + temp = 0; + else + temp = (int) (scalableHeight / relativeHeight + 0.5); + + // If the container needs to be bigger, make it so + if (scaledHeight < temp) + scaledHeight = temp; + } + + // totalWidth is the scaledWidth plus the sum of all absolute widths and all + // preferred widths + int totalWidth = scaledWidth; + + for (counter = 0; counter < columnSpec.length; counter++) + // Is the current column an absolute size + if (columnSpec[counter] >= 1.0) + totalWidth += (int) (columnSpec[counter] + 0.5); + // Is the current column a preferred size + else if ((columnSpec[counter] == PREFERRED) || + (columnSpec[counter] == MINIMUM)) + { + // Assume a maximum width of zero + int maxWidth = 0; + + // Find maximum preferred width of all components completely + // contained within this column + iterator = list.listIterator(0); + + while (iterator.hasNext()) + { + Entry entry = iterator.next(); + + if ((entry.col1 == counter) && (entry.col2 == counter)) + { + Dimension p = (columnSpec[counter] == PREFERRED) ? + entry.component.getPreferredSize() : + entry.component.getMinimumSize(); + + int width = (p == null) ? 0 : p.width; + + if (maxWidth < width) + maxWidth = width; + } + } + + // Add preferred width + totalWidth += maxWidth; + } + + // totalHeight is the scaledHeight plus the sum of all absolute heights and + // all preferred widths + int totalHeight = scaledHeight; + + for (counter = 0; counter < rowSpec.length; counter++) + // Is the current row an absolute size + if (rowSpec[counter] >= 1.0) + totalHeight += (int) (rowSpec[counter] + 0.5); + // Is the current row a preferred size + else if ((rowSpec[counter] == PREFERRED) || + (rowSpec[counter] == MINIMUM)) + { + // Assume a maximum height of zero + int maxHeight = 0; + + // Find maximum preferred height of all components completely + // contained within this row + iterator = list.listIterator(0); + + while (iterator.hasNext()) + { + Entry entry = iterator.next(); + + if ((entry.row1 == counter) && (entry.row1 == counter)) + { + Dimension p = (rowSpec[counter] == PREFERRED) ? + entry.component.getPreferredSize() : + entry.component.getMinimumSize(); + + int height = (p == null) ? 0 : p.height; + + if (maxHeight < height) + maxHeight = height; + } + } + + // Add preferred height + totalHeight += maxHeight; + } + + // Compensate for container's insets + Insets inset = container.getInsets(); + totalWidth += inset.left + inset.right; + totalHeight += inset.top + inset.bottom; + + return new Dimension(totalWidth, totalHeight); +} + + + +/** + * Adds the specified component with the specified name to the layout. + * + * @param name indicates entry's position and anchor + * @param component component to add + */ + +public void addLayoutComponent (String name, Component component) +{ + addLayoutComponent (component, name); +} + + + +//****************************************************************************** +//** java.awt.event.LayoutManager2 methods *** +//****************************************************************************** + + + +/** + * Adds the specified component with the specified name to the layout. + * + * @param component component to add + * @param constraint indicates entry's position and alignment + */ + +public void addLayoutComponent (Component component, Object constraint) +{ + if (constraint instanceof String) + { + // Create an entry to associate component with its constraints + constraint = new TableLayoutConstraints((String) constraint); + + // Add component and constraints to the list + list.add (new Entry(component, (TableLayoutConstraints) constraint)); + } + else if (constraint instanceof TableLayoutConstraints) + { + // Add component and constraints to the list + list.add (new Entry(component, (TableLayoutConstraints) constraint)); + } + else if (constraint == null) + throw new IllegalArgumentException("No constraint for the component"); + else + throw new IllegalArgumentException + ("Cannot accept a constraint of class " + constraint.getClass()); +} + + + +/** + * Removes the specified component from the layout. + * + * @param component component being removed + */ + +public void removeLayoutComponent (Component component) +{ + list.remove (component); +} + + + +/** + * Returns the maximum dimensions for this layout given the components in the + * specified target container. + * + * @param target the component which needs to be laid out + * + * @return unconditionally, a Dimension of Integer.MAX_VALUE by + * Integer.MAX_VALUE since TableLayout does not limit the + * maximum size of a container + */ + +public Dimension maximumLayoutSize (Container target) +{ + return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); +} + + + +/** + * Returns the alignment along the x axis. This specifies how the component + * would like to be aligned relative to other components. The value should be + * a number between 0 and 1 where 0 represents alignment along the origin, 1 is + * aligned the furthest away from the origin, 0.5 is centered, etc. + * + * @return unconditionally, 0.5 + */ + +public float getLayoutAlignmentX (Container parent) +{ + return 0.5f; +} + + + +/** + * Returns the alignment along the y axis. This specifies how the component + * would like to be aligned relative to other components. The value should be + * a number between 0 and 1 where 0 represents alignment along the origin, 1 is + * aligned the furthest away from the origin, 0.5 is centered, etc. + * + * @return unconditionally, 0.5 + */ + +public float getLayoutAlignmentY (Container parent) +{ + return 0.5f; +} + + + +/** + * Invalidates the layout, indicating that if the layout manager has cached + * information it should be discarded. + */ + +public void invalidateLayout (Container target) +{ + dirty = true; +} + + + +//****************************************************************************** +//*** Inner Class *** +//****************************************************************************** + + + + // The following inner class is used to bind components to their constraints + protected class Entry extends TableLayoutConstraints + { + /** Component bound by the constraints */ + protected Component component; + + /** Does the component occupy a single cell */ + protected boolean singleCell; + + /** + * Constructs an Entry that binds a component to a set of constraints. + * + * @param component component being bound + * @param constraint constraints being applied + */ + + public Entry (Component component, TableLayoutConstraints constraint) + { + super (constraint.col1, constraint.row1, + constraint.col2, constraint.row2, + constraint.hAlign, constraint.vAlign); + + singleCell = ((row1 == row2) && (col1 == col2)); + this.component = component; + } + + /** + * Determines whether or not two entries are equal. + * + * @param object object being compared to; must be a Component if it + * is equal to this TableLayoutConstraints. + * + * @return True, if the entries refer to the same component object. + * False, otherwise. + */ + + public boolean equals (Object object) + { + boolean equal = false; + + if (object instanceof Component) + { + Component component = (Component) object; + equal = (this.component == component); + } + + return equal; + } + + public int hashCode() { + return component.hashCode(); + } + } + + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/layout/TableLayoutConstants.java b/rapla-source-1.8.2/src/org/rapla/components/layout/TableLayoutConstants.java new file mode 100644 index 0000000..f55c009 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/layout/TableLayoutConstants.java @@ -0,0 +1,55 @@ +package org.rapla.components.layout; + + + +/** + * Constants used by TableLayout. + * + * @author Daniel E. Barbalace + */ + +public interface TableLayoutConstants +{ + + + +/** Indicates that the component is left justified in its cell */ +public static final int LEFT = 0; + +/** Indicates that the component is top justified in its cell */ +public static final int TOP = 0; + +/** Indicates that the component is centered in its cell */ +public static final int CENTER = 1; + +/** Indicates that the component is full justified in its cell */ +public static final int FULL = 2; + +/** Indicates that the component is bottom justified in its cell */ +public static final int BOTTOM = 3; + +/** Indicates that the component is right justified in its cell */ +public static final int RIGHT = 3; + +/** Indicates that the row/column should fill the available space */ +public static final double FILL = -1.0; + +/** Indicates that the row/column should be allocated just enough space to + accomidate the preferred size of all components contained completely within + this row/column. */ +public static final double PREFERRED = -2.0; + +/** Indicates that the row/column should be allocated just enough space to + accomidate the minimum size of all components contained completely within + this row/column. */ +public static final double MINIMUM = -3.0; + +/** Minimum value for an alignment */ +public static final int MIN_ALIGN = 0; + +/** Maximum value for an alignment */ +public static final int MAX_ALIGN = 3; + + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/layout/TableLayoutConstraints.java b/rapla-source-1.8.2/src/org/rapla/components/layout/TableLayoutConstraints.java new file mode 100644 index 0000000..9fbc6ea --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/layout/TableLayoutConstraints.java @@ -0,0 +1,209 @@ +package org.rapla.components.layout; + + +import java.util.NoSuchElementException; +import java.util.StringTokenizer; + + +/** + * The following inner class is used to bind components to their + * constraints. + * + * @author Daniel E. Barbalace + */ + +public class TableLayoutConstraints implements TableLayoutConstants +{ + + + +/** Cell in which the upper left corner of the component lays */ +public int col1, row1; + +/** Cell in which the lower right corner of the component lays */ +public int col2, row2; + +/** Horizontal justification if component occupies just one cell */ +public int hAlign; + +/** Verical justification if component occupies just one cell */ +public int vAlign; + + + +/** + * Constructs an TableLayoutConstraints with the default settings. This + * constructor is equivalent to TableLayoutConstraints(0, 0, 0, 0, FULL, FULL). + */ + +public TableLayoutConstraints () +{ + col1 = row1 = col2 = row2 = 0; + hAlign = vAlign = FULL; +} + + + +/** + * Constructs an TableLayoutConstraints from a string. + * + * @param constraints indicates TableLayoutConstraints's position and justification + * as a string in the form "row, column" or + * "row, column, horizontal justification, vertical + * justification" or "row 1, column 1, row 2, column 2". + * It is also acceptable to delimit the paramters with + * spaces instead of commas. + */ + +public TableLayoutConstraints (String constraints) +{ + // Parse constraints using spaces or commas + StringTokenizer st = new StringTokenizer(constraints, ", "); + + // Use default values for any parameter not specified or specified + // incorrectly. The default parameters place the component in a single + // cell at column 0, row 0. The component is fully justified. + col1 = 0; + row1 = 0; + col2 = 0; + row2 = 0; + hAlign = FULL; + vAlign = FULL; + + String token = null; + + try + { + // Get the first column (assume component is in only one column) + token = st.nextToken(); + col1 = new Integer(token).intValue(); + col2 = col1; + + // Get the first row (assume component is in only one row) + token = st.nextToken(); + row1 = new Integer(token).intValue(); + row2 = row1; + + // Get the second column + token = st.nextToken(); + col2 = new Integer(token).intValue(); + + // Get the second row + token = st.nextToken(); + row2 = new Integer(token).intValue(); + } + catch (NoSuchElementException error) {} + catch (NumberFormatException error) + { + try + { + // Check if token means horizontally justification the component + @SuppressWarnings("null") // Can't be null because nextToken is called before the Integer parsing + String t = token.toString(); + if (t.equalsIgnoreCase("L")) + hAlign = LEFT; + else if (t.equalsIgnoreCase("C")) + hAlign = CENTER; + else if (t.equalsIgnoreCase("F")) + hAlign = FULL; + else if (t.equalsIgnoreCase("R")) + hAlign = RIGHT; + + // There can be one more token for the vertical justification even + // if the horizontal justification is invalid + token = st.nextToken(); + + // Check if token means horizontally justification the component + if (token.equalsIgnoreCase("T")) + vAlign = TOP; + else if (token.equalsIgnoreCase("C")) + vAlign = CENTER; + else if (token.equalsIgnoreCase("F")) + vAlign = FULL; + else if (token.equalsIgnoreCase("B")) + vAlign = BOTTOM; + } + catch (NoSuchElementException error2) {} + } + + // Make sure row2 >= row1 + if (row2 < row1) + row2 = row1; + + // Make sure col2 >= col1 + if (col2 < col1) + col2 = col1; +} + + + +/** + * Constructs an TableLayoutConstraints a set of constraints. + * + * @param col1 column where upper-left cornor of the component is placed + * @param row1 row where upper-left cornor of the component is placed + * @param col2 column where lower-right cornor of the component is placed + * @param row2 row where lower-right cornor of the component is placed + * @param hAlign horizontal justification of a component in a single cell + * @param vAlign vertical justification of a component in a single cell + */ + +public TableLayoutConstraints + (int col1, int row1, int col2, int row2, int hAlign, int vAlign) +{ + this.col1 = col1; + this.row1 = row1; + this.col2 = col2; + this.row2 = row2; + + if ((hAlign < MIN_ALIGN) || (hAlign > MAX_ALIGN)) + this.hAlign = FULL; + else + this.hAlign = hAlign; + + if ((vAlign < MIN_ALIGN) || (vAlign > MAX_ALIGN)) + this.vAlign = FULL; + else + this.vAlign = vAlign; +} + + + +/** + * Gets a string representation of this TableLayoutConstraints. + * + * @return a string in the form "row 1, column 1, row 2, column 2" or + * "row, column, horizontal justification, vertical justification" + */ + +public String toString () +{ + StringBuffer buffer = new StringBuffer(); + + buffer.append (row1); + buffer.append (", "); + buffer.append (col1); + buffer.append (", "); + + if ((row1 == row2) && (col1 == col2)) + { + final char h[] = {'L', 'C', 'F', 'R'}; + final char v[] = {'T', 'C', 'F', 'B'}; + + buffer.append (h[hAlign]); + buffer.append (", "); + buffer.append (v[vAlign]); + } + else + { + buffer.append (row2); + buffer.append (", "); + buffer.append (col2); + } + + return buffer.toString(); +} + + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/layout/package.html b/rapla-source-1.8.2/src/org/rapla/components/layout/package.html new file mode 100644 index 0000000..0fc5f41 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/layout/package.html @@ -0,0 +1,6 @@ + +This package contains additional LayoutManagers. + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/package.html b/rapla-source-1.8.2/src/org/rapla/components/package.html new file mode 100644 index 0000000..903f30d --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/package.html @@ -0,0 +1,8 @@ + +Contains all components and classes that are independant from the rest of rapla, +and can easily be reused in other projects. Dependencies with other components or +packages are explicitly stated in a file called DEPENDENCIES. + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/tablesorter/TableSorter.java b/rapla-source-1.8.2/src/org/rapla/components/tablesorter/TableSorter.java new file mode 100644 index 0000000..843612c --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/tablesorter/TableSorter.java @@ -0,0 +1,555 @@ +/* + * Sun Microsystems grants you ("Licensee") a non-exclusive, royalty + * free, license to use, modify and redistribute this software in + * source and binary code form, provided that i) this copyright notice + * and license appear on all copies of the software; and ii) Licensee + * does not utilize the software in a manner which is disparaging to + * Sun Microsystems. + * + * The software media is distributed on an "As Is" basis, without + * warranty. Neither the authors, the software developers nor Sun + * Microsystems make any representation, or warranty, either express + * or implied, with respect to the software programs, their quality, + * accuracy, or fitness for a specific purpose. Therefore, neither the + * authors, the software developers nor Sun Microsystems shall have + * any liability to you or any other person or entity with respect to + * any liability, loss, or damage caused or alleged to have been + * caused directly or indirectly by programs contained on the + * media. This includes, but is not limited to, interruption of + * service, loss of data, loss of classroom time, loss of consulting + * or anticipatory *profits, or consequential damages from the use of + * these programs. +*/ +package org.rapla.components.tablesorter; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.swing.Icon; +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.JTableHeader; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumnModel; +import javax.swing.table.TableModel; + +/** + *

    + * TableSorter is a decorator for TableModels; adding sorting + * functionality to a supplied TableModel. TableSorter does + * not store or copy the data in its TableModel; instead it maintains + * a map from the row indexes of the view to the row indexes of the + * model. As requests are made of the sorter (like getValueAt(row, col)) + * they are passed to the underlying model after the row numbers + * have been translated via the internal mapping array. This way, + * the TableSorter appears to hold another copy of the table + * with the rows in a different order. + *

    + *

    + * TableSorter registers itself as a listener to the underlying model, + * just as the JTable itself would. Events recieved from the model + * are examined, sometimes manipulated (typically widened), and then + * passed on to the TableSorter's listeners (typically the JTable). + * If a change to the model has invalidated the order of TableSorter's + * rows, a note of this is made and the sorter will resort the + * rows the next time a value is requested. + *

    + *

    + * When the tableHeader property is set, either by using the + * setTableHeader() method or the two argument constructor, the + * table header may be used as a complete UI for TableSorter. + * The default renderer of the tableHeader is decorated with a renderer + * that indicates the sorting status of each column. In addition, + * a mouse listener is installed with the following behavior: + *

    + *
      + *
    • + * Mouse-click: Clears the sorting status of all other columns + * and advances the sorting status of that column through three + * values: {NOT_SORTED, ASCENDING, DESCENDING} (then back to + * NOT_SORTED again). + *
    • + * SHIFT-mouse-click: Clears the sorting status of all other columns + * and cycles the sorting status of the column through the same + * three values, in the opposite order: {NOT_SORTED, DESCENDING, ASCENDING}. + *
    • + * CONTROL-mouse-click and CONTROL-SHIFT-mouse-click: as above except + * that the changes to the column do not cancel the statuses of columns + * that are already sorting - giving a way to initiate a compound + * sort. + *
    + * This is a long overdue rewrite of a class of the same name that + * first appeared in the swing table demos in 1997. + * + * @author Philip Milne + * @author Brendon McLean + * @author Dan van Enckevort + * @author Parwinder Sekhon + * @version 2.0 02/27/04 + */ + +public class TableSorter extends AbstractTableModel { + private static final long serialVersionUID = 1L; + + protected TableModel tableModel; + + public static final int DESCENDING = -1; + public static final int NOT_SORTED = 0; + public static final int ASCENDING = 1; + private Map enabled= new HashMap(); + + private static Directive EMPTY_DIRECTIVE = new Directive(-1, NOT_SORTED); + + @SuppressWarnings("rawtypes") + public static final Comparator COMPARABLE_COMAPRATOR = new Comparator() { + @SuppressWarnings("unchecked") + public int compare(Comparable o1, Comparable o2) { + return o1.compareTo(o2); + } + }; + + + private Row[] viewToModel; + private int[] modelToView; + + private JTableHeader tableHeader; + private MouseListener mouseListener; + private TableModelListener tableModelListener; + private Map> columnComparators = new HashMap>(); + private List sortingColumns = new ArrayList(); + + public TableSorter() { + this.mouseListener = new MouseHandler(); + this.tableModelListener = new TableModelHandler(); + } + + public TableSorter(TableModel tableModel) { + this(); + setTableModel(tableModel); + } + + public TableSorter(TableModel tableModel, JTableHeader tableHeader) { + this(); + setTableHeader(tableHeader); + setTableModel(tableModel); + } + + private void clearSortingState() { + viewToModel = null; + modelToView = null; + } + + public TableModel getTableModel() { + return tableModel; + } + + public void setTableModel(TableModel tableModel) { + if (this.tableModel != null) { + this.tableModel.removeTableModelListener(tableModelListener); + } + + this.tableModel = tableModel; + if (this.tableModel != null) { + this.tableModel.addTableModelListener(tableModelListener); + } + + clearSortingState(); + fireTableStructureChanged(); + } + + public JTableHeader getTableHeader() { + return tableHeader; + } + + public void setTableHeader(JTableHeader tableHeader) { + if (this.tableHeader != null) { + this.tableHeader.removeMouseListener(mouseListener); + TableCellRenderer defaultRenderer = this.tableHeader.getDefaultRenderer(); + if (defaultRenderer instanceof SortableHeaderRenderer) { + this.tableHeader.setDefaultRenderer(((SortableHeaderRenderer) defaultRenderer).tableCellRenderer); + } + } + this.tableHeader = tableHeader; + if (this.tableHeader != null) { + this.tableHeader.addMouseListener(mouseListener); + this.tableHeader.setDefaultRenderer( + new SortableHeaderRenderer(this.tableHeader.getDefaultRenderer())); + } + } + + public boolean isSorting() { + return sortingColumns.size() != 0; + } + + private Directive getDirective(int column) { + for (int i = 0; i < sortingColumns.size(); i++) { + Directive directive = sortingColumns.get(i); + if (directive.column == column) { + return directive; + } + } + return EMPTY_DIRECTIVE; + } + + public int getSortingStatus(int column) { + return getDirective(column).direction; + } + + private void sortingStatusChanged() { + clearSortingState(); + fireTableDataChanged(); + if (tableHeader != null) { + tableHeader.repaint(); + } + } + + public void setSortingStatus(int column, int status) { + Directive directive = getDirective(column); + if (directive != EMPTY_DIRECTIVE) { + sortingColumns.remove(directive); + } + if (status != NOT_SORTED) { + sortingColumns.add(new Directive(column, status)); + } + sortingStatusChanged(); + } + + protected Icon getHeaderRendererIcon(int column, int size) { + Directive directive = getDirective(column); + if (directive == EMPTY_DIRECTIVE) { + return null; + } + return new Arrow(directive.direction == DESCENDING, size, sortingColumns.indexOf(directive)); + } + + private void cancelSorting() { + sortingColumns.clear(); + sortingStatusChanged(); + } + + public void setColumnComparator(int column, Comparator comparator) { + if (comparator == null) { + columnComparators.remove(column); + } else { + columnComparators.put(column, comparator); + } + setSortingStatus(column, ASCENDING); + } + + @SuppressWarnings("rawtypes") + protected Comparator getComparator(int column) { + Comparator comparator = columnComparators.get(column); + if (comparator != null) { + return comparator; + } + Class columnType = tableModel.getColumnClass(column); + if ( columnType.isAssignableFrom( String.class)) + { + return String.CASE_INSENSITIVE_ORDER; + } + if (Comparable.class.isAssignableFrom(columnType)) { + return COMPARABLE_COMAPRATOR; + } + return String.CASE_INSENSITIVE_ORDER; + } + + private Row[] getViewToModel() { + if (viewToModel == null) { + int tableModelRowCount = tableModel.getRowCount(); + viewToModel = new Row[tableModelRowCount]; + for (int row = 0; row < tableModelRowCount; row++) { + viewToModel[row] = new Row(row); + } + + if (isSorting()) { + Arrays.sort(viewToModel); + } + } + return viewToModel; + } + + public int modelIndex(int viewIndex) { + return getViewToModel()[viewIndex].modelIndex; + } + + private int[] getModelToView() { + if (modelToView == null) { + int n = getViewToModel().length; + modelToView = new int[n]; + for (int i = 0; i < n; i++) { + modelToView[modelIndex(i)] = i; + } + } + return modelToView; + } + + // TableModel interface methods + + public int getRowCount() { + return (tableModel == null) ? 0 : tableModel.getRowCount(); + } + + public int getColumnCount() { + return (tableModel == null) ? 0 : tableModel.getColumnCount(); + } + + public String getColumnName(int column) { + return tableModel.getColumnName(column); + } + + public Class getColumnClass(int column) { + return tableModel.getColumnClass(column); + } + + public boolean isCellEditable(int row, int column) { + return tableModel.isCellEditable(modelIndex(row), column); + } + + public Object getValueAt(int row, int column) { + return tableModel.getValueAt(modelIndex(row), column); + } + + public void setValueAt(Object aValue, int row, int column) { + tableModel.setValueAt(aValue, modelIndex(row), column); + } + + // Helper classes + + private class Row implements Comparable { + private int modelIndex; + + public Row(int index) { + this.modelIndex = index; + } + + @SuppressWarnings("unchecked") + public int compareTo(Object o) { + int row1 = modelIndex; + int row2 = ((Row) o).modelIndex; + + for (Iterator it = sortingColumns.iterator(); it.hasNext();) { + Directive directive = it.next(); + int column = directive.column; + Object o1 = tableModel.getValueAt(row1, column); + Object o2 = tableModel.getValueAt(row2, column); + + int comparison = 0; + // Define null less than everything, except null. + if (o1 == null && o2 == null) { + comparison = 0; + } else if (o1 == null) { + comparison = -1; + } else if (o2 == null) { + comparison = 1; + } else { + if ( isSortabe(column) ) + { + comparison = getComparator(column).compare(o1, o2); + } + } + if (comparison != 0) { + return directive.direction == DESCENDING ? -comparison : comparison; + } + } + return 0; + } + } + + private class TableModelHandler implements TableModelListener { + public void tableChanged(TableModelEvent e) { + // If we're not sorting by anything, just pass the event along. + if (!isSorting()) { + clearSortingState(); + fireTableChanged(e); + return; + } + + // If the table structure has changed, cancel the sorting; the + // sorting columns may have been either moved or deleted from + // the model. + if (e.getFirstRow() == TableModelEvent.HEADER_ROW) { + cancelSorting(); + fireTableChanged(e); + return; + } + + // We can map a cell event through to the view without widening + // when the following conditions apply: + // + // a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and, + // b) all the changes are in one column (column != TableModelEvent.ALL_COLUMNS) and, + // c) we are not sorting on that column (getSortingStatus(column) == NOT_SORTED) and, + // d) a reverse lookup will not trigger a sort (modelToView != null) + // + // Note: INSERT and DELETE events fail this test as they have column == ALL_COLUMNS. + // + // The last check, for (modelToView != null) is to see if modelToView + // is already allocated. If we don't do this check; sorting can become + // a performance bottleneck for applications where cells + // change rapidly in different parts of the table. If cells + // change alternately in the sorting column and then outside of + // it this class can end up re-sorting on alternate cell updates - + // which can be a performance problem for large tables. The last + // clause avoids this problem. + int column = e.getColumn(); + if (e.getFirstRow() == e.getLastRow() + && column != TableModelEvent.ALL_COLUMNS + && getSortingStatus(column) == NOT_SORTED + && modelToView != null) { + int viewIndex = getModelToView()[e.getFirstRow()]; + fireTableChanged(new TableModelEvent(TableSorter.this, + viewIndex, viewIndex, + column, e.getType())); + return; + } + + // Something has happened to the data that may have invalidated the row order. + clearSortingState(); + fireTableDataChanged(); + return; + } + } + + private class MouseHandler extends MouseAdapter { + public void mouseClicked(MouseEvent e) { + JTableHeader h = (JTableHeader) e.getSource(); + TableColumnModel columnModel = h.getColumnModel(); + int viewColumn = columnModel.getColumnIndexAtX(e.getX()); + if ( viewColumn != -1) + { + int column = columnModel.getColumn(viewColumn).getModelIndex(); + if (column != -1) { + if ( !isSortabe( column)) + { + return; + } + int status = getSortingStatus(column); + if (!e.isControlDown()) { + cancelSorting(); + } + // Cycle the sorting states through {NOT_SORTED, ASCENDING, DESCENDING} or + // {NOT_SORTED, DESCENDING, ASCENDING} depending on whether shift is pressed. + status = status + (e.isShiftDown() ? -1 : 1); + status = (status + 4) % 3 - 1; // signed mod, returning {-1, 0, 1} + setSortingStatus(column, status); + } + } + } + } + + private static class Arrow implements Icon { + private boolean descending; + private int size; + private int priority; + + public Arrow(boolean descending, int size, int priority) { + this.descending = descending; + this.size = size; + this.priority = priority; + } + + public void paintIcon(Component c, Graphics g, int x, int y) { + Color color = c == null ? Color.gray : c.getBackground(); + // In a compound sort, make each succesive triangle 20% + // smaller than the previous one. + int dx = (int)(size/2*Math.pow(0.8, priority)); + int dy = descending ? dx : -dx; + // Align icon (roughly) with font baseline. + y = y + 5*size/6 + (descending ? -dy : 0); + int shift = descending ? 1 : -1; + g.translate(x, y); + + // Right diagonal. + g.setColor(color.darker()); + g.drawLine(dx / 2, dy, 0, 0); + g.drawLine(dx / 2, dy + shift, 0, shift); + + // Left diagonal. + g.setColor(color.brighter()); + g.drawLine(dx / 2, dy, dx, 0); + g.drawLine(dx / 2, dy + shift, dx, shift); + + // Horizontal line. + if (descending) { + g.setColor(color.darker().darker()); + } else { + g.setColor(color.brighter().brighter()); + } + g.drawLine(dx, 0, 0, 0); + + g.setColor(color); + g.translate(-x, -y); + } + + public int getIconWidth() { + return size; + } + + public int getIconHeight() { + return size; + } + } + + private class SortableHeaderRenderer implements TableCellRenderer { + private TableCellRenderer tableCellRenderer; + + public SortableHeaderRenderer(TableCellRenderer tableCellRenderer) { + this.tableCellRenderer = tableCellRenderer; + } + + public Component getTableCellRendererComponent(JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column) { + Component c = tableCellRenderer.getTableCellRendererComponent(table, + value, isSelected, hasFocus, row, column); + if (c instanceof JLabel) { + JLabel l = (JLabel) c; + l.setHorizontalTextPosition(JLabel.LEFT); + int modelColumn = table.convertColumnIndexToModel(column); + l.setIcon(getHeaderRendererIcon(modelColumn, l.getFont().getSize())); + } + return c; + } + } + + private static class Directive { + private int column; + private int direction; + + public Directive(int column, int direction) { + this.column = column; + this.direction = direction; + } + } + + public void setSortable(int column, boolean b) { + enabled.put( column,b); + } + + public boolean isSortabe( int column) + { + final Boolean sortable = enabled.get(column); + if ( sortable == null) + { + return true; + } + return sortable; + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/treetable/AbstractTreeTableModel.java b/rapla-source-1.8.2/src/org/rapla/components/treetable/AbstractTreeTableModel.java new file mode 100644 index 0000000..151fe76 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/treetable/AbstractTreeTableModel.java @@ -0,0 +1,212 @@ +/* + * AbstractTreeTableModel.java + * + * Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved. + * + * Sun Microsystems grants you ("Licensee") a non-exclusive, royalty + * free, license to use, modify and redistribute this software in + * source and binary code form, provided that i) this copyright notice + * and license appear on all copies of the software; and ii) Licensee + * does not utilize the software in a manner which is disparaging to + * Sun Microsystems. + * + * The software media is distributed on an "As Is" basis, without + * warranty. Neither the authors, the software developers nor Sun + * Microsystems make any representation, or warranty, either express + * or implied, with respect to the software programs, their quality, + * accuracy, or fitness for a specific purpose. Therefore, neither the + * authors, the software developers nor Sun Microsystems shall have + * any liability to you or any other person or entity with respect to + * any liability, loss, or damage caused or alleged to have been + * caused directly or indirectly by programs contained on the + * media. This includes, but is not limited to, interruption of + * service, loss of data, loss of classroom time, loss of consulting + * or anticipatory *profits, or consequential damages from the use of + * these programs. +*/ + +package org.rapla.components.treetable; + +import javax.swing.event.EventListenerList; +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; +import javax.swing.tree.TreePath; + +/** + * @version 1.2 10/27/98 + * An abstract implementation of the TreeTableModel interface, handling the list + * of listeners. + * @author Philip Milne + */ + +public abstract class AbstractTreeTableModel implements TreeTableModel { + protected Object root; + protected EventListenerList listenerList = new EventListenerList(); + + public AbstractTreeTableModel(Object root) { + this.root = root; + } + + // + // Default implementations for methods in the TreeModel interface. + // + + public Object getRoot() { + return root; + } + + public boolean isLeaf(Object node) { + return getChildCount(node) == 0; + } + + public void valueForPathChanged(TreePath path, Object newValue) {} + + // This is not called in the JTree's default mode: use a naive implementation. + public int getIndexOfChild(Object parent, Object child) { + for (int i = 0; i < getChildCount(parent); i++) { + if (getChild(parent, i).equals(child)) { + return i; + } + } + return -1; + } + + public void addTreeModelListener(TreeModelListener l) { + listenerList.add(TreeModelListener.class, l); + } + + public void removeTreeModelListener(TreeModelListener l) { + listenerList.remove(TreeModelListener.class, l); + } + + /* + * Notify all listeners that have registered interest for + * notification on this event type. The event instance + * is lazily created using the parameters passed into + * the fire method. + * @see EventListenerList + */ + protected void fireTreeNodesChanged(Object source, Object[] path, + int[] childIndices, + Object[] children) { + // Guaranteed to return a non-null array + Object[] listeners = listenerList.getListenerList(); + TreeModelEvent e = null; + // Process the listeners last to first, notifying + // those that are interested in this event + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeModelListener.class) { + // Lazily create the event: + if (e == null) + e = new TreeModelEvent(source, path, + childIndices, children); + ((TreeModelListener)listeners[i+1]).treeNodesChanged(e); + } + } + } + + /* + * Notify all listeners that have registered interest for + * notification on this event type. The event instance + * is lazily created using the parameters passed into + * the fire method. + * @see EventListenerList + */ + protected void fireTreeNodesInserted(Object source, Object[] path, + int[] childIndices, + Object[] children) { + // Guaranteed to return a non-null array + Object[] listeners = listenerList.getListenerList(); + TreeModelEvent e = null; + // Process the listeners last to first, notifying + // those that are interested in this event + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeModelListener.class) { + // Lazily create the event: + if (e == null) + e = new TreeModelEvent(source, path, + childIndices, children); + ((TreeModelListener)listeners[i+1]).treeNodesInserted(e); + } + } + } + + /* + * Notify all listeners that have registered interest for + * notification on this event type. The event instance + * is lazily created using the parameters passed into + * the fire method. + * @see EventListenerList + */ + protected void fireTreeNodesRemoved(Object source, Object[] path, + int[] childIndices, + Object[] children) { + // Guaranteed to return a non-null array + Object[] listeners = listenerList.getListenerList(); + TreeModelEvent e = null; + // Process the listeners last to first, notifying + // those that are interested in this event + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeModelListener.class) { + // Lazily create the event: + if (e == null) + e = new TreeModelEvent(source, path, + childIndices, children); + ((TreeModelListener)listeners[i+1]).treeNodesRemoved(e); + } + } + } + + /* + * Notify all listeners that have registered interest for + * notification on this event type. The event instance + * is lazily created using the parameters passed into + * the fire method. + * @see EventListenerList + */ + protected void fireTreeStructureChanged(Object source, Object[] path, + int[] childIndices, + Object[] children) { + // Guaranteed to return a non-null array + Object[] listeners = listenerList.getListenerList(); + TreeModelEvent e = null; + // Process the listeners last to first, notifying + // those that are interested in this event + for (int i = listeners.length-2; i>=0; i-=2) { + if (listeners[i]==TreeModelListener.class) { + // Lazily create the event: + if (e == null) + e = new TreeModelEvent(source, path, + childIndices, children); + ((TreeModelListener)listeners[i+1]).treeStructureChanged(e); + } + } + } + + // + // Default impelmentations for methods in the TreeTableModel interface. + // + + public Class getColumnClass(int column) { return Object.class; } + + /** By default, make the column with the Tree in it the only editable one. + * Making this column editable causes the JTable to forward mouse + * and keyboard events in the Tree column to the underlying JTree. + */ + public boolean isCellEditable(Object node, int column) { + return getColumnClass(column) == TreeTableModel.class; + } + + public void setValueAt(Object aValue, Object node, int column) {} + + + // Left to be implemented in the subclass: + + /* + * public Object getChild(Object parent, int index) + * public int getChildCount(Object parent) + * public int getColumnCount() + * public String getColumnName(Object node, int column) + * public Object getValueAt(Object node, int column) + */ +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/treetable/DEPENDENCIES b/rapla-source-1.8.2/src/org/rapla/components/treetable/DEPENDENCIES new file mode 100644 index 0000000..00a596d --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/treetable/DEPENDENCIES @@ -0,0 +1,4 @@ +This component depends on the following packages (including subpackages): + +java.* +javax.swing.* diff --git a/rapla-source-1.8.2/src/org/rapla/components/treetable/JTreeTable.java b/rapla-source-1.8.2/src/org/rapla/components/treetable/JTreeTable.java new file mode 100644 index 0000000..a5e605a --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/treetable/JTreeTable.java @@ -0,0 +1,916 @@ +/* + * Sun Microsystems grants you ("Licensee") a non-exclusive, royalty + * free, license to use, modify and redistribute this software in + * source and binary code form, provided that i) this copyright notice + * and license appear on all copies of the software; and ii) Licensee + * does not utilize the software in a manner which is disparaging to + * Sun Microsystems. + * + * The software media is distributed on an "As Is" basis, without + * warranty. Neither the authors, the software developers nor Sun + * Microsystems make any representation, or warranty, either express + * or implied, with respect to the software programs, their quality, + * accuracy, or fitness for a specific purpose. Therefore, neither the + * authors, the software developers nor Sun Microsystems shall have + * any liability to you or any other person or entity with respect to + * any liability, loss, or damage caused or alleged to have been + * caused directly or indirectly by programs contained on the + * media. This includes, but is not limited to, interruption of + * service, loss of data, loss of classroom time, loss of consulting + * or anticipatory *profits, or consequential damages from the use of + * these programs. +*/ + +package org.rapla.components.treetable; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.EventObject; +import java.util.List; + +import javax.swing.JComponent; +import javax.swing.JTable; +import javax.swing.JTree; +import javax.swing.KeyStroke; +import javax.swing.ListSelectionModel; +import javax.swing.LookAndFeel; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.border.Border; +import javax.swing.border.CompoundBorder; +import javax.swing.event.CellEditorListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.event.TreeExpansionEvent; +import javax.swing.event.TreeExpansionListener; +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.DefaultTreeSelectionModel; +import javax.swing.tree.TreeCellRenderer; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; + +/** + * Original version Philip Milne and Scott Violet + * Modified by Christopher Kohlhaas to support editing and keyboard handling. + */ + +public class JTreeTable extends JTable { + private static final long serialVersionUID = 1L; + + private RendererTree tree = new RendererTree(); + private TreeTableEditor treeCellEditor; + private TableToolTipRenderer toolTipRenderer = null; + private int focusedRow = -1; + private String cachedSearchKey = ""; + + public JTreeTable(TreeTableModel model) { + super(); + + setTreeTableModel( model ); + + // Force the JTable and JTree to share their row selection models. + ListToTreeSelectionModelWrapper selectionWrapper = new + ListToTreeSelectionModelWrapper(); + setSelectionModel(selectionWrapper.getListSelectionModel()); + setShowGrid( false); + // No intercell spacing + setIntercellSpacing(new Dimension(1, 0)); + setShowVerticalLines(true); + + tree.setEditable(false); + tree.setSelectionModel(selectionWrapper); + tree.setShowsRootHandles(true); + tree.setRootVisible(false); + setDefaultRenderer( TreeTableModel.class, tree ); + setTreeCellEditor(null); + + // And update the height of the trees row to match that of + // the table. + if (tree.getRowHeight() < 1) { + // Metal looks better like this. + setRowHeight(22); + } + } + + public void setToolTipRenderer(TableToolTipRenderer renderer) { + toolTipRenderer = renderer; + } + + public TableToolTipRenderer getToolTipRenderer() { + return toolTipRenderer; + } + + public String getToolTipText(MouseEvent evt) { + if (toolTipRenderer == null) + return super.getToolTipText(evt); + Point p = new Point(evt.getX(),evt.getY()); + int column = columnAtPoint(p); + int row = rowAtPoint(p); + if (row >=0 && column>=0) + return toolTipRenderer.getToolTipText(this,row,column); + else + return super.getToolTipText(evt); + } + + /** + * Overridden to message super and forward the method to the tree. + * Since the tree is not actually in the component hierarchy it will + * never receive this unless we forward it in this manner. + */ + public void updateUI() { + super.updateUI(); + if(tree != null) { + tree.updateUI(); + } + // Use the tree's default foreground and background colors in the + // table. + LookAndFeel.installColorsAndFont(this, "Tree.background", + "Tree.foreground", "Tree.font"); + } + + /** Set a custom TreeCellEditor. The default one is a TextField.*/ + public void setTreeCellEditor(TreeTableEditor editor) { + treeCellEditor = editor; + setDefaultEditor( TreeTableModel.class, new DelegationgTreeCellEditor(treeCellEditor) ); + } + + + /** Returns the tree that is being shared between the model. + If you set a different TreeCellRenderer for this tree it should + inherit from DefaultTreeCellRenderer. Otherwise the selection-color + and focus color will not be set correctly. + */ + public JTree getTree() { + return tree; + } + + /** + * search for given search term in child nodes of selected nodes + * @param search what to search for + * @param parentNode where to search fo + * @return first childnode where its tostring representation in tree starts with search term, null if no one found + */ + private TreeNode getNextTreeNodeMatching(String search, TreeNode parentNode) { + TreeNode result = null; + + Enumeration children = parentNode.children(); + while (children.hasMoreElements()) { + TreeNode treeNode = (TreeNode) children.nextElement(); + String compareS = treeNode.toString().toLowerCase(); + if (compareS.startsWith(search)) { + result = treeNode; + break; + } + } + return result; + } + + /** + * create treepath from treenode + * @param treeNode Treenode + * @return treepath object + */ + public static TreePath getPath(TreeNode treeNode) { + List nodes = new ArrayList(); + if (treeNode != null) { + + nodes.add(treeNode); + treeNode = treeNode.getParent(); + while (treeNode != null) { + nodes.add(0, treeNode); + treeNode = treeNode.getParent(); + } + } + + return nodes.isEmpty() ? null : new TreePath(nodes.toArray()); + } + + + /** overridden to support keyboard expand/collapse for the tree.*/ + protected boolean processKeyBinding(KeyStroke ks, + KeyEvent e, + int condition, + boolean pressed) + { + if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) + { + if (tree != null && !isEditing() && getSelectedColumn() == getTreeColumnNumber()) { + + if (e.getID() == KeyEvent.KEY_PRESSED) + { + if ( (e.getKeyCode() == KeyEvent.VK_ENTER || e.getKeyChar() =='+')) { + int row = getSelectedRow(); + if (row >= 0) { + if (tree.isExpanded(row)) { + tree.collapseRow(row); + } else { + tree.expandPath(tree.getPathForRow(row)); + } + } + return true; + } + + if (e.getKeyCode() == KeyEvent.VK_LEFT) { + int row = getSelectedRow(); + if (row >= 0) { + TreePath pathForRow = tree.getPathForRow(row); + // if selected node is expanded than collapse it + // else selected parents node + if (tree.isExpanded(pathForRow)) { + // only if root is visible we should collapse first level + final boolean canCollapse = pathForRow.getPathCount() > (tree.isRootVisible() ? 0 : 1); + if (canCollapse) + tree.collapsePath(pathForRow); + } else { + // only if root is visible we should collapse first level or select parent node + final boolean canCollapse = pathForRow.getPathCount() > (tree.isRootVisible() ? 1 : 2); + + if (canCollapse) { + pathForRow = pathForRow.getParentPath(); + final int parentRow = tree.getRowForPath(pathForRow ); + tree.setSelectionInterval(parentRow, parentRow); + } + } + + if (pathForRow != null) { + Rectangle rect = getCellRect(tree.getRowForPath(pathForRow), 0, false); + scrollRectToVisible(rect ); + } + + + + } + return true; + } + if (e.getKeyCode() == KeyEvent.VK_RIGHT) { + int row = getSelectedRow(); + if (row >= 0) { + final TreePath path = tree.getPathForRow(row); + if (tree.isCollapsed(path)) { + tree.expandPath(path); + } + } + return true; + } + + // live search in current parent node + if ((Character.isLetterOrDigit(e.getKeyChar()))) { + char keyChar = e.getKeyChar(); + + + // we are searching in the current parent node + // first we assume that we have selected a parent node + // so we should have children + TreePath selectedPath = tree.getSelectionModel().getLeadSelectionPath(); + TreeNode selectedNode = (TreeNode) selectedPath.getLastPathComponent(); + + + // if we don't have children we might have selected a leaf so choose its parent + if (selectedNode.getChildCount() == 0) { + // set new selectedNode + selectedPath = selectedPath.getParentPath(); + selectedNode = (TreeNode) selectedPath.getLastPathComponent(); + } + + // search term + String search = ("" + keyChar).toLowerCase(); + + // try to find node with matching searchterm plus the search before + TreeNode nextTreeNodeMatching = getNextTreeNodeMatching(cachedSearchKey + search, selectedNode); + + // if we did not find anything, try to find search term only: restart! + if (nextTreeNodeMatching == null) { + nextTreeNodeMatching = getNextTreeNodeMatching(search, selectedNode); + cachedSearchKey = ""; + } + // if we found a node, select it, make it visible and return true + if (nextTreeNodeMatching != null) { + TreePath foundPath = getPath(nextTreeNodeMatching); + + // select our found path + this.tree.getSelectionModel().setSelectionPath(foundPath); + + //make it visible + this.tree.expandPath(foundPath); + this.tree.makeVisible(foundPath); + // Scroll to the found row + int row = tree.getRowForPath( foundPath); + int col = 0; + Rectangle rect = getCellRect(row, col, false); + scrollRectToVisible(rect ); + + // store found treepath + cachedSearchKey = cachedSearchKey + search; + + return true; + } + } + cachedSearchKey = ""; + + /* Uncomment this if you don't want to start tree-cell-editing + on a non navigation key stroke. + + if (e.getKeyCode() != e.VK_TAB && e.getKeyCode() != e.VK_F2 + && e.getKeyCode() != e.VK_DOWN && e.getKeyCode() != e.VK_UP + && e.getKeyCode() != e.VK_LEFT && e.getKeyCode() != e.VK_RIGHT + && e.getKeyCode() != e.VK_PAGE_UP && e.getKeyCode() != e.VK_PAGE_DOWN + ) + return true; + */ + } + } + } + // reset cachedkey to null if we did not find anything + + return super.processKeyBinding(ks,e,condition,pressed); + } + + public void setTreeTableModel(TreeTableModel model) { + tree.setModel(model); + super.setModel(new TreeTableModelAdapter(model)); + } + + /** + * Workaround for BasicTableUI anomaly. Make sure the UI never tries to + * resize the editor. The UI currently uses different techniques to + * paint the renderers and editors; overriding setBounds() below + * is not the right thing to do for an editor. Returning -1 for the + * editing row in this case, ensures the editor is never painted. + */ + public int getEditingRow() { + int column = getEditingColumn(); + if( getColumnClass(column) == TreeTableModel.class ) + return -1; + return editingRow; + } + + /** + * Returns the actual row that is editing as getEditingRow + * will always return -1. + */ + private int realEditingRow() { + return editingRow; + } + + /** Overridden to pass the new rowHeight to the tree. */ + public void setRowHeight(int rowHeight) { + super.setRowHeight(rowHeight); + if (tree != null && tree.getRowHeight() != rowHeight) + tree.setRowHeight( rowHeight ); + } + + private int getTreeColumnNumber() { + for (int counter = getColumnCount() - 1; counter >= 0;counter--) + if (getColumnClass(counter) == TreeTableModel.class) + return counter; + return -1; + } + + /** isCellEditable returns true for the Tree-Column, even if it is not editable. + isCellRealEditable returns true only if the underlying TreeTableModel-Cell is + editable. + */ + private boolean isCellRealEditable(int row,int column) { + TreePath treePath = tree.getPathForRow(row); + if (treePath == null) + return false; + return (((TreeTableModel)tree.getModel()).isCellEditable(treePath.getLastPathComponent() + ,column)); + + } + + class RendererTree extends JTree implements TableCellRenderer { + private static final long serialVersionUID = 1L; + + protected int rowToPaint; + Color borderColor = Color.gray; + + /** Border to draw around the tree, if this is non-null, it will + * be painted. */ + protected Border highlightBorder; + + public RendererTree() { + super(); + } + + public void setRowHeight(int rowHeight) { + if (rowHeight > 0) { + super.setRowHeight(rowHeight); + if ( + JTreeTable.this.getRowHeight() != rowHeight) { + JTreeTable.this.setRowHeight(getRowHeight()); + } + } + } + + // Move and resize the tree to the table position + public void setBounds( int x, int y, int w, int h ) { + super.setBounds( x, 0, w, JTreeTable.this.getHeight() ); + } + + public void paintEditorBackground(Graphics g,int row) { + tree.rowToPaint = row; + g.translate( 0, -row * getRowHeight()); + Rectangle rect = g.getClipBounds(); + if (rect.width >0 && rect.height >0) + super.paintComponent(g); + g.translate( 0, row * getRowHeight()); + } + + // start painting at the rowToPaint + public void paint( Graphics g ) { + int row = rowToPaint; + + g.translate( 0, -rowToPaint * getRowHeight() ); + super.paint(g); + + int x = 0; + TreePath path = getPathForRow(row); + Object value = path.getLastPathComponent(); + boolean isSelected = tree.isRowSelected(row); + x = tree.getRowBounds(row).x; + if (treeCellEditor != null) { + x += treeCellEditor.getGap(tree,value,isSelected,row); + } else { + TreeCellRenderer tcr = getCellRenderer(); + if (tcr instanceof DefaultTreeCellRenderer) { + DefaultTreeCellRenderer dtcr = ((DefaultTreeCellRenderer)tcr); + // super.paint must have been called before + x += dtcr.getIconTextGap() + dtcr.getIcon().getIconWidth(); + } + } + + // Draw the Table border if we have focus. + if (highlightBorder != null) { + highlightBorder.paintBorder(this, g, x, rowToPaint * + getRowHeight(), getWidth() -x, + getRowHeight() ); + } // Paint the selection rectangle + } + + public Component getTableCellRendererComponent(JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, int column) { + Color background; + Color foreground; + if (hasFocus) + focusedRow = row; + + if(isSelected) { + background = table.getSelectionBackground(); + foreground = table.getSelectionForeground(); + } + else { + background = table.getBackground(); + foreground = table.getForeground(); + } + highlightBorder = null; + if (realEditingRow() == row && getEditingColumn() == column) { + background = UIManager.getColor("Table.focusCellBackground"); + foreground = UIManager.getColor("Table.focusCellForeground"); + } else if (hasFocus) { + highlightBorder = UIManager.getBorder + ("Table.focusCellHighlightBorder"); + if (isCellRealEditable(row,convertColumnIndexToModel(column))) { + background = UIManager.getColor + ("Table.focusCellBackground"); + foreground = UIManager.getColor + ("Table.focusCellForeground"); + } + } + + this.rowToPaint = row; + setBackground(background); + + TreeCellRenderer tcr = getCellRenderer(); + if (tcr instanceof DefaultTreeCellRenderer) { + DefaultTreeCellRenderer dtcr = ((DefaultTreeCellRenderer)tcr); + if (isSelected) { + dtcr.setTextSelectionColor(foreground); + dtcr.setBackgroundSelectionColor(background); + } + else { + dtcr.setTextNonSelectionColor(foreground); + dtcr.setBackgroundNonSelectionColor(background); + } + } + return this; + } + } + + class DelegationgTreeCellEditor implements TableCellEditor + { + TreeTableEditor delegate; + JComponent lastComp = null; + int textOffset = 0; + + MouseListener mouseListener = new MouseAdapter() { + public void mouseClicked(MouseEvent evt) + { + if (lastComp == null) + return; + if (delegate == null) + return; + if (evt.getY() < 0 || evt.getY()>lastComp.getHeight()) + delegate.stopCellEditing(); + // User clicked left from the text + if (textOffset > 0 && evt.getX()< textOffset ) + delegate.stopCellEditing(); + } + }; + + public DelegationgTreeCellEditor(TreeTableEditor delegate) { + this.delegate = delegate; + } + + public void addCellEditorListener(CellEditorListener listener) { + delegate.addCellEditorListener(listener); + } + + public void removeCellEditorListener(CellEditorListener listener) { + delegate.removeCellEditorListener(listener); + } + + public void cancelCellEditing() { + delegate.cancelCellEditing(); + } + + public Object getCellEditorValue() { + return delegate.getCellEditorValue(); + } + + public boolean stopCellEditing() { + return delegate.stopCellEditing(); + + } + + public boolean shouldSelectCell(EventObject anEvent) { + return true; + } + + private int getTextOffset(Object value,boolean isSelected,int row) { + int gap = delegate.getGap(tree,value,isSelected,row); + TreePath path = tree.getPathForRow(row); + return tree.getUI().getPathBounds(tree,path).x + gap; + } + + public boolean inHitRegion(int x,int y) { + int row = tree.getRowForLocation(x,y); + TreePath path = tree.getPathForRow(row); + if (path == null) + return false; + int gap = (delegate != null) ? + delegate.getGap(tree,null,false,row) + :16; + + return (x - gap >= tree.getUI().getPathBounds(tree,path).x || x<0); + } + + public Component getTableCellEditorComponent(JTable table, Object value, + boolean isSelected, + int row, + int column) + { + JTreeTable.this.tree.rowToPaint = row; + JComponent comp = delegate.getEditorComponent(tree,value,isSelected,row); + if (lastComp != comp) { + if (comp != null) + { + comp.removeMouseListener(mouseListener); + comp.addMouseListener(mouseListener); + } + } + lastComp = comp; + + textOffset = getTextOffset(value,isSelected,row); + Border outerBorder = new TreeBorder(0, textOffset , 0, 0,row); + Border editBorder = UIManager.getBorder("Tree.editorBorder"); + Border border = new CompoundBorder(outerBorder + ,editBorder + + ); + if ( comp != null) + { + comp.setBorder(border); + } + return comp; + } + + public boolean isCellEditable( EventObject evt ) { + int col = getTreeColumnNumber(); + if( evt instanceof MouseEvent ) { + MouseEvent me = (MouseEvent)evt; + if (col >= 0) { + int xPosRelativeToCell = me.getX() - getCellRect(0, col, true).x; + if (me.getClickCount() > 1 + && inHitRegion(xPosRelativeToCell,me.getY()) + && isCellRealEditable(tree.getRowForLocation(me.getX(),me.getY()) + ,convertColumnIndexToModel(col))) + return true; + MouseEvent newME = new MouseEvent(tree, me.getID(), + me.getWhen(), me.getModifiers(), + xPosRelativeToCell, + me.getY(), me.getClickCount(), + me.isPopupTrigger()); + if (! inHitRegion(xPosRelativeToCell,me.getY()) || me.getClickCount() > 1) + tree.dispatchEvent(newME); + } + return false; + } + + if (delegate != null && isCellRealEditable(focusedRow,convertColumnIndexToModel(col))) + return delegate.isCellEditable(evt); + else + return false; + } + } + + + class TreeBorder implements Border { + int row; + Insets insets; + + public TreeBorder(int top,int left,int bottom,int right,int row) { + this.row = row; + insets = new Insets(top,left,bottom,right); + } + + public Insets getBorderInsets(Component c) { + return insets; + } + + public void paintBorder(Component c,Graphics g,int x,int y,int width,int height) { + Shape originalClip = g.getClip(); + g.clipRect(0,0,insets.left -1 ,tree.getHeight()); + tree.paintEditorBackground(g,row); + g.setClip(originalClip); + } + + public boolean isBorderOpaque() { + return false; + } + + } + + + + /** + * ListToTreeSelectionModelWrapper extends DefaultTreeSelectionModel + * to listen for changes in the ListSelectionModel it maintains. Once + * a change in the ListSelectionModel happens, the paths are updated + * in the DefaultTreeSelectionModel. + */ + class ListToTreeSelectionModelWrapper extends DefaultTreeSelectionModel implements ListSelectionListener{ + private static final long serialVersionUID = 1L; + + /** Set to true when we are updating the ListSelectionModel. */ + protected boolean updatingListSelectionModel; + + public ListToTreeSelectionModelWrapper() { + super(); + getListSelectionModel().addListSelectionListener + (createListSelectionListener()); + } + + /** + * Returns the list selection model. ListToTreeSelectionModelWrapper + * listens for changes to this model and updates the selected paths + * accordingly. + */ + ListSelectionModel getListSelectionModel() { + return listSelectionModel; + } + + /** + * This is overridden to set updatingListSelectionModel + * and message super. This is the only place DefaultTreeSelectionModel + * alters the ListSelectionModel. + */ + public void resetRowSelection() { + if(!updatingListSelectionModel) { + updatingListSelectionModel = true; + try { + super.resetRowSelection(); + } + finally { + updatingListSelectionModel = false; + } + } + // Notice how we don't message super if + // updatingListSelectionModel is true. If + // updatingListSelectionModel is true, it implies the + // ListSelectionModel has already been updated and the + // paths are the only thing that needs to be updated. + } + + /** + * Creates and returns an instance of ListSelectionHandler. + */ + protected ListSelectionListener createListSelectionListener() { + return this; + } + + /** + * If updatingListSelectionModel is false, this will + * reset the selected paths from the selected rows in the list + * selection model. + */ + protected void updateSelectedPathsFromSelectedRows() { + if(!updatingListSelectionModel) { + updatingListSelectionModel = true; + try { + // This is way expensive, ListSelectionModel needs an + // enumerator for iterating. + int min = listSelectionModel.getMinSelectionIndex(); + int max = listSelectionModel.getMaxSelectionIndex(); + + clearSelection(); + if(min != -1 && max != -1) { + for(int counter = min; counter <= max; counter++) { + if(listSelectionModel.isSelectedIndex(counter)) { + TreePath selPath = tree.getPathForRow + (counter); + + if(selPath != null) { + addSelectionPath(selPath); + } + } + } + } + } finally { + updatingListSelectionModel = false; + } + } + } + /** Implemention of ListSelectionListener Interface: + * Class responsible for calling updateSelectedPathsFromSelectedRows + * when the selection of the list changse. + */ + public void valueChanged(ListSelectionEvent e) { + updateSelectedPathsFromSelectedRows(); + } + } + + class TreeTableModelAdapter extends AbstractTableModel implements TreeExpansionListener,TreeModelListener + { + private static final long serialVersionUID = 1L; + + TreeTableModel treeTableModel; + public TreeTableModelAdapter(TreeTableModel treeTableModel) { + this.treeTableModel = treeTableModel; + + tree.addTreeExpansionListener(this); + // Install a TreeModelListener that can update the table when + // tree changes. We use delayedFireTableDataChanged as we can + // not be guaranteed the tree will have finished processing + // the event before us. + treeTableModel.addTreeModelListener(this); + } + + + // Implementation of TreeExpansionListener + public void treeExpanded(TreeExpansionEvent event) { + int row = tree.getRowForPath(event.getPath()); + if (row + 1 < tree.getRowCount()) + fireTableRowsInserted(row + 1,row + 1); + } + public void treeCollapsed(TreeExpansionEvent event) { + int row = tree.getRowForPath(event.getPath()); + if (row < getRowCount()) + fireTableRowsDeleted(row + 1,row + 1); + } + + // Implementation of TreeModelLstener + public void treeNodesChanged(TreeModelEvent e) { + int firstRow = 0; + int lastRow = tree.getRowCount() -1; + delayedFireTableRowsUpdated(firstRow,lastRow); + } + + public void treeNodesInserted(TreeModelEvent e) { + delayedFireTableDataChanged(); + } + + public void treeNodesRemoved(TreeModelEvent e) { + delayedFireTableDataChanged(); + } + + public void treeStructureChanged(TreeModelEvent e) { + delayedFireTableDataChanged(); + } + + // Wrappers, implementing TableModel interface. + public int getColumnCount() { + return treeTableModel.getColumnCount(); + } + + public String getColumnName(int column) { + return treeTableModel.getColumnName(column); + } + + public Class getColumnClass(int column) { + return treeTableModel.getColumnClass(column); + } + + public int getRowCount() { + return tree.getRowCount(); + } + + private Object nodeForRow(int row) { + TreePath treePath = tree.getPathForRow(row); + if (treePath == null) + return null; + return treePath.getLastPathComponent(); + } + + public Object getValueAt(int row, int column) { + Object node = nodeForRow(row); + if (node == null) + return null; + return treeTableModel.getValueAt(node, column); + } + + public boolean isCellEditable(int row, int column) { + if (getColumnClass(column) == TreeTableModel.class) { + return true; + } else { + Object node = nodeForRow(row); + if (node == null) + return false; + return treeTableModel.isCellEditable(node, column); + } + } + + public void setValueAt(Object value, int row, int column) { + Object node = nodeForRow(row); + if (node == null) + return; + treeTableModel.setValueAt(value, node, column); + } + + /** + * Invokes fireTableDataChanged after all the pending events have been + * processed. SwingUtilities.invokeLater is used to handle this. + */ + protected void delayedFireTableRowsUpdated(int firstRow,int lastRow) { + SwingUtilities.invokeLater(new UpdateRunnable(firstRow,lastRow)); + } + + class UpdateRunnable implements Runnable { + int lastRow; + int firstRow; + UpdateRunnable(int firstRow,int lastRow) { + this.firstRow = firstRow; + this.lastRow = lastRow; + } + public void run() { + fireTableRowsUpdated(firstRow,lastRow); + } + } + /** + * Invokes fireTableDataChanged after all the pending events have been + * processed. SwingUtilities.invokeLater is used to handle this. + */ + protected void delayedFireTableDataChanged() { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + fireTableDataChanged(); + } + }); + + } + } + + + /* + public void paintComponent(Graphics g) { + super.paintComponent( g ); + Rectangle r = g.getClipBounds(); + g.setColor( Color.white); + g.fillRect(0,0, r.width, r.height ); + + } + */ + +} + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/treetable/TableToolTipRenderer.java b/rapla-source-1.8.2/src/org/rapla/components/treetable/TableToolTipRenderer.java new file mode 100644 index 0000000..273eb64 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/treetable/TableToolTipRenderer.java @@ -0,0 +1,17 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.treetable; +import javax.swing.JTable; +public interface TableToolTipRenderer { + public String getToolTipText(JTable table, int row, int column); +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/treetable/TreeTableEditor.java b/rapla-source-1.8.2/src/org/rapla/components/treetable/TreeTableEditor.java new file mode 100644 index 0000000..1f6540e --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/treetable/TreeTableEditor.java @@ -0,0 +1,23 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.treetable; + +import javax.swing.CellEditor; +import javax.swing.JComponent; +import javax.swing.JTree; + +public interface TreeTableEditor extends CellEditor { + JComponent getEditorComponent(JTree tree,Object value,boolean isSelected,int row); + int getGap(JTree tree, Object value, boolean isSelected, int row); +} + diff --git a/rapla-source-1.8.2/src/org/rapla/components/treetable/TreeTableModel.java b/rapla-source-1.8.2/src/org/rapla/components/treetable/TreeTableModel.java new file mode 100644 index 0000000..ebb5ad7 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/treetable/TreeTableModel.java @@ -0,0 +1,73 @@ +/* + * Sun Microsystems grants you ("Licensee") a non-exclusive, royalty + * free, license to use, modify and redistribute this software in + * source and binary code form, provided that i) this copyright notice + * and license appear on all copies of the software; and ii) Licensee + * does not utilize the software in a manner which is disparaging to + * Sun Microsystems. + * + * The software media is distributed on an "As Is" basis, without + * warranty. Neither the authors, the software developers nor Sun + * Microsystems make any representation, or warranty, either express + * or implied, with respect to the software programs, their quality, + * accuracy, or fitness for a specific purpose. Therefore, neither the + * authors, the software developers nor Sun Microsystems shall have + * any liability to you or any other person or entity with respect to + * any liability, loss, or damage caused or alleged to have been + * caused directly or indirectly by programs contained on the + * media. This includes, but is not limited to, interruption of + * service, loss of data, loss of classroom time, loss of consulting + * or anticipatory *profits, or consequential damages from the use of + * these programs. +*/ +package org.rapla.components.treetable; + +import javax.swing.tree.TreeModel; + +/** + * TreeTableModel is the model used by a JTreeTable. It extends TreeModel + * to add methods for getting inforamtion about the set of columns each + * node in the TreeTableModel may have. Each column, like a column in + * a TableModel, has a name and a type associated with it. Each node in + * the TreeTableModel can return a value for each of the columns and + * set that value if isCellEditable() returns true. + * + * @author Philip Milne + * @author Scott Violet + */ +public interface TreeTableModel extends TreeModel +{ + /** + * Returns the number ofs available columns. + */ + public int getColumnCount(); + + /** + * Returns the name for column number column. + */ + public String getColumnName(int column); + + /** + * Returns the type for column number column. + * Should return TreeTableModel.class for the tree-column. + */ + public Class getColumnClass(int column); + + /** + * Returns the value to be displayed for node node, + * at column number column. + */ + public Object getValueAt(Object node, int column); + + /** + * Indicates whether the the value for node node, + * at column number column is editable. + */ + public boolean isCellEditable(Object node, int column); + + /** + * Sets the value for node node, + * at column number column. + */ + public void setValueAt(Object aValue, Object node, int column); +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/treetable/package.html b/rapla-source-1.8.2/src/org/rapla/components/treetable/package.html new file mode 100644 index 0000000..58a7cba --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/treetable/package.html @@ -0,0 +1,6 @@ + +Contains all classes for the treetable widget. + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/Assert.java b/rapla-source-1.8.2/src/org/rapla/components/util/Assert.java new file mode 100644 index 0000000..e1999c8 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/Assert.java @@ -0,0 +1,76 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.util; + +/** Some of the assert functionality of 1.4 for 1.3 versions of Rapla*/ +public class Assert { + static String NOT_NULL_ASSERTION = "notNull-Assertion"; + static String IS_TRUE_ASSERTION = "isTrue-Assertion"; + static String ASSERTION_FAIL = "Assertion fail"; + static boolean _bActivate = true; + + public static void notNull(Object obj,String text) { + if ( obj == null && isActivated()) { + doAssert(getText(NOT_NULL_ASSERTION,text)); + } + } + + public static void notNull(Object obj) { + if ( obj == null && isActivated()) { + doAssert(getText(NOT_NULL_ASSERTION,"")); + } + } + + public static void isTrue(boolean condition,String text) { + if ( !condition && isActivated()) { + doAssert(getText(IS_TRUE_ASSERTION,text)); + } // end of if () + } + + public static void isTrue(boolean condition) { + if ( !condition && isActivated()) { + doAssert(getText(IS_TRUE_ASSERTION,"")); + } // end of if () + } + + public static void fail() throws AssertionError { + doAssert(getText(ASSERTION_FAIL,"")); + } + + public static void fail(String text) throws AssertionError { + doAssert(getText(ASSERTION_FAIL,text)); + } + + private static void doAssert(String text) throws AssertionError { + System.err.println(text); + throw new AssertionError(text); + } + + static boolean isActivated() { + return _bActivate; + } + + static void setActivated(boolean bActivate) { + _bActivate = bActivate; + } + + static String getText(String type, String text) { + return ( type + " failed '" + text + "'"); + } +} + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/AssertionError.java b/rapla-source-1.8.2/src/org/rapla/components/util/AssertionError.java new file mode 100644 index 0000000..cc51f25 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/AssertionError.java @@ -0,0 +1,33 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.util; + +public class AssertionError extends RuntimeException { + private static final long serialVersionUID = 1L; + + String text = ""; + + public AssertionError() { + } + public AssertionError(String text) { + this.text = text; + } + + public String toString() { + return text; + } +} + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/Cancelable.java b/rapla-source-1.8.2/src/org/rapla/components/util/Cancelable.java new file mode 100644 index 0000000..83004cc --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/Cancelable.java @@ -0,0 +1,5 @@ +package org.rapla.components.util; + +public interface Cancelable { + public void cancel(); +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/Command.java b/rapla-source-1.8.2/src/org/rapla/components/util/Command.java new file mode 100644 index 0000000..4227ace --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/Command.java @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------* +| Copyright (C) 2006 Christopher Kohlhaas | +| | +| This program is free software; you can redistribute it and/or modify | +| it under the terms of the GNU General Public License as published by the | +| Free Software Foundation. A copy of the license has been included with | +| these distribution in the COPYING file, if not go to www.fsf.org | +| | +| As a special exception, you are granted the permissions to link this | +| program with every library, which license fulfills the Open Source | +| Definition as published by the Open Source Initiative (OSI). | +*--------------------------------------------------------------------------*/ + +package org.rapla.components.util; + +public interface Command { + public void execute() throws Exception; +} + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/CommandQueue.java b/rapla-source-1.8.2/src/org/rapla/components/util/CommandQueue.java new file mode 100644 index 0000000..642e3b3 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/CommandQueue.java @@ -0,0 +1,85 @@ +/*--------------------------------------------------------------------------* +| Copyright (C) 2006 Christopher Kohlhaas | +| | +| This program is free software; you can redistribute it and/or modify | +| it under the terms of the GNU General Public License as published by the | +| Free Software Foundation. A copy of the license has been included with | +| these distribution in the COPYING file, if not go to www.fsf.org | +| | +| As a special exception, you are granted the permissions to link this | +| program with every library, which license fulfills the Open Source | +| Definition as published by the Open Source Initiative (OSI). | +*--------------------------------------------------------------------------*/ + +package org.rapla.components.util; + +import java.util.Vector; + +/** Creates a new thread that successively executes the queued command objects + * @see Command + * @deprecated use CommandScheduler instead + */ +@Deprecated +public class CommandQueue { + private Vector v = new Vector(); + public synchronized void enqueue(Command object) { + v.addElement( object ); + } + + public synchronized Command dequeue() { + if ( v.size() == 0) + return null; + Object firstElement =v.firstElement(); + if ( firstElement != null) { + v.removeElementAt( 0 ); + } + return (Command) firstElement; + } + + public void dequeueAll() { + while ( dequeue() != null){} + } + + /** Creates a new Queue for Command Object. + The commands will be executed in succession in a seperate Daemonthread. + @see Command + */ + public static CommandQueue createCommandQueue() { + CommandQueue commandQueue = new CommandQueue(); + Thread eventThread= new MyEventThread(commandQueue); + eventThread.setDaemon(true); + eventThread.start(); + return commandQueue; + } + + + static class MyEventThread extends Thread { + CommandQueue commandQueue; + MyEventThread(CommandQueue commandQueue) { + this.commandQueue = commandQueue; + } + public void run() { + try { + while (true) { + Command command = commandQueue.dequeue(); + if (command == null) { + sleep(100); + continue; + } + try { + command.execute(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } catch (InterruptedException ex) { + } + } + } + + + + +} + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/CommandScheduler.java b/rapla-source-1.8.2/src/org/rapla/components/util/CommandScheduler.java new file mode 100644 index 0000000..2ec9c73 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/CommandScheduler.java @@ -0,0 +1,29 @@ +/*--------------------------------------------------------------------------* +| Copyright (C) 2006 Christopher Kohlhaas | +| | +| This program is free software; you can redistribute it and/or modify | +| it under the terms of the GNU General Public License as published by the | +| Free Software Foundation. A copy of the license has been included with | +| these distribution in the COPYING file, if not go to www.fsf.org | +| | +| As a special exception, you are granted the permissions to link this | +| program with every library, which license fulfills the Open Source | +| Definition as published by the Open Source Initiative (OSI). | +*--------------------------------------------------------------------------*/ + +package org.rapla.components.util; + + + +/** Creates a new thread that successively executes the queued command objects + * @see Command + */ +public interface CommandScheduler +{ + public Cancelable schedule(Command command, long delay); + public Cancelable schedule(Command command, long delay, long period); + /** if two commands are scheduled for the same synchronisation object then they must be executed in the order in which they are scheduled*/ + public Cancelable scheduleSynchronized(Object synchronizationObject,Command command, long delay); +} + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/DEPENDENCIES b/rapla-source-1.8.2/src/org/rapla/components/util/DEPENDENCIES new file mode 100644 index 0000000..be45b1b --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/DEPENDENCIES @@ -0,0 +1,7 @@ +All classes except the XMLUtil depend on the java.* packages. + +The classes in the xml package depend on: + +java.* +javax.xml.* +org.xml.sax.* diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/DateTools.java b/rapla-source-1.8.2/src/org/rapla/components/util/DateTools.java new file mode 100644 index 0000000..db1110c --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/DateTools.java @@ -0,0 +1,475 @@ + /*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender, Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.util; + +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +/** Tools for manipulating dates. + * At the moment of writing rapla internaly stores all appointments + * in the GMT timezone. + */ +public abstract class DateTools +{ + + public static final int DAYS_PER_WEEK= 7; + public static final long MILLISECONDS_PER_MINUTE = 1000 * 60; + public static final long MILLISECONDS_PER_HOUR = MILLISECONDS_PER_MINUTE * 60; + public static final long MILLISECONDS_PER_DAY = 24 * MILLISECONDS_PER_HOUR; + public static final long MILLISECONDS_PER_WEEK = 7 * MILLISECONDS_PER_DAY; + public static final int SUNDAY = 1, MONDAY = 2, TUESDAY = 3, WEDNESDAY = 4, THURSDAY = 5, FRIDAY = 6, SATURDAY = 7; + + public static int getHourOfDay(long date) { + return (int) ((date % MILLISECONDS_PER_DAY)/ MILLISECONDS_PER_HOUR); + } + + public static int getMinuteOfHour(long date) { + return (int) ((date % MILLISECONDS_PER_HOUR)/ MILLISECONDS_PER_MINUTE); + } + + public static int getMinuteOfDay(long date) { + return (int) ((date % MILLISECONDS_PER_DAY)/ MILLISECONDS_PER_MINUTE); + } + + public static String formatDate(Date date) + { + SerializableDateTimeFormat format = new SerializableDateTimeFormat(); + String string = format.formatDate( date); + return string; + } + + public static String formatDate(Date date, @SuppressWarnings("unused") Locale locale) { + // FIXME has to be replaced with locale implementation +// DateFormat format = DateFormat.getDateInstance(DateFormat.SHORT,locale); +// format.setTimeZone(DateTools.getTimeZone()); +// String string = format.format( date); +// return string; + return formatDate(date); + } + + public static String formatTime(Date date) + { + SerializableDateTimeFormat format = new SerializableDateTimeFormat(); + String string = format.formatTime( date); + return string; + } + + public static String formatDateTime(Date date) + { + SerializableDateTimeFormat format = new SerializableDateTimeFormat(); + String dateString = format.formatDate( date); + String timeString = format.formatTime( date); + String string = dateString + " " + timeString; + return string; + } + + public static int getDaysInMonth(int year, int month) + { + int _month = month+1; + if ( _month == 2) + { + if ( isLeapYear(year)) + { + return 29; + } + return 28; + } + else if ( _month == 4 || _month == 6 || _month == 9 || _month == 11 ) + { + return 30; + } + else + { + return 31; + } + } + + public static boolean isLeapYear(int year) + { + return year % 4 == 0 && ((year % 100) != 0 || (year % 400) == 0); + } + + /** sets time of day to 0:00. + @see #cutDate(Date) + */ + public static long cutDate(long date) { + long dateModMillis = date % MILLISECONDS_PER_DAY; + if ( dateModMillis == 0) + { + return date; + } + if ( date >= 0) + { + return (date - dateModMillis); + } + else + { + return (date - (MILLISECONDS_PER_DAY + dateModMillis)); + + } + } + + public static boolean isMidnight(long date) { + return cutDate( date ) == date ; + } + + public static boolean isMidnight(Date date) { + return isMidnight( date.getTime()); + } + + /** sets time of day to 0:00. */ + public static Date cutDate(Date date) { + long time = date.getTime(); + if ( time %MILLISECONDS_PER_DAY == 0) + { + return date; + } + return new Date(cutDate(time)); + } + + private static TimeZone timeZone =TimeZone.getTimeZone("GMT"); + /** same as TimeZone.getTimeZone("GMT"). */ + public static TimeZone getTimeZone() { + return timeZone; + } + /** sets time of day to 0:00 and increases day. + @see #fillDate(Date) + */ + public static long fillDate(long date) { + // cut date + long cuttedDate = (date - (date % MILLISECONDS_PER_DAY)); + return cuttedDate + MILLISECONDS_PER_DAY; + } + + public static Date fillDate(Date date) { + return new Date(fillDate(date.getTime())); + } + + /** Monday 24:00 = tuesday 0:00. + But the first means end of monday and the second start of tuesday. + The default DateFormat always displays tuesday. + If you want to edit the first interpretation in calendar components. + call addDay() to add 1 day to the given date before displaying + and subDay() for mapping a day back after editing. + @see #subDay + @see #addDays + */ + public static Date addDay(Date date) { + return addDays( date, 1); + } + + public static Date addYear(Date date) { + return addYears(date, 1); + } + + public static Date addWeeks(Date date, int weeks) { + Date result = new Date(date.getTime() + MILLISECONDS_PER_WEEK * weeks); + return result; + } + + public static Date addYears(Date date, int yearModifier) { + + int monthModifier = 0; + return modifyDate(date, yearModifier, monthModifier); + } + + public static Date addMonth(Date startDate) { + return addMonths(startDate, 1); + } + + public static Date addMonths(Date startDate, int monthModifier) { + int yearModifier = 0; + return modifyDate(startDate, yearModifier, monthModifier); + } + + private static Date modifyDate(Date startDate, int yearModifier, + int monthModifier) { + long original = startDate.getTime(); + long millis = original - DateTools.cutDate( original ); + DateWithoutTimezone date = toDate( original); + int year = date.year + yearModifier; + int month = date.month + monthModifier; + if ( month < 1 ) + { + year += month/ 12 -1 ; + month = ((month +11) % 12) + 1; + + } + if ( month >12 ) + { + year += month/ 12; + month = ((month -1) % 12) + 1; + } + int day = date.day ; + long newDate = toDate(year, month, day); + Date result = new Date( newDate + millis); + return result; + } + + + /** see #addDay*/ + public static Date addDays(Date date,long days) { + return new Date(date.getTime() + MILLISECONDS_PER_DAY * days); + } + + /** + @see #addDay + @see #subDays + */ + public static Date subDay(Date date) { + return new Date(date.getTime() - MILLISECONDS_PER_DAY); + } + + /** + @see #addDay + */ + public static Date subDays(Date date,int days) { + return new Date(date.getTime() - MILLISECONDS_PER_DAY * days); + } + + /** returns if the two dates are one the same date. + * Dates must be in GMT */ + static public boolean isSameDay( Date d1, Date d2) { + return cutDate( d1 ).equals( cutDate ( d2 )); + } + + /** returns if the two dates are one the same date. + * Dates must be in GMT */ + static public boolean isSameDay( long d1, long d2) { + return cutDate( d1 ) == cutDate ( d2 ); + } + + /** returns the day of week SUNDAY = 1, MONDAY = 2, TUESDAY = 3, WEDNESDAY = 4, THURSDAY = 5, FRIDAY = 6, SATURDAY = 7 */ + public static int getWeekday(Date date) { + long days = countDays(0,date.getTime()); + int weekday_zero = THURSDAY; + int alt = (int) days%7; + int weekday = weekday_zero + alt; + if ( weekday > 7) + { + weekday -=7; + } + else if ( weekday <=0 ) + { + weekday += 7 ; + } + return weekday; + } + + public static int getDayOfWeekInMonth(Date date) + { + DateWithoutTimezone date2 = toDate( date.getTime()); + int day = date2.day; + int occurances = (day-1) / 7 + 1; + return occurances; + } + +// public static int getWeekOfYear(Date date) +// { +// // 1970/1/1 is a thursday +// long millis = date.getTime(); +// long daysSince1970 = millis >= 0 ? millis/ MILLISECONDS_PER_DAY : ((millis + MILLISECONDS_PER_DAY - 1)/ MILLISECONDS_PER_DAY + 1) ; +// int weekday = daysSince1970 + 4; +// +// } + + + public static int getDayOfMonth(Date date) { + DateWithoutTimezone date2 = toDate( date.getTime()); + int result = date2.day; + return result; + } + +// /** uses the calendar-object for date comparison. +// * Use this for non GMT Dates*/ +// static public boolean isSameDay( Calendar calendar, Date d1, Date d2 ) { +// calendar.setTime( d1 ); +// int era1 = calendar.get( Calendar.ERA ); +// int year1 = calendar.get( Calendar.YEAR ); +// int day_of_year1 = calendar.get( Calendar.DAY_OF_YEAR ); +// calendar.setTime( d2 ); +// int era2 = calendar.get( Calendar.ERA ); +// int year2 = calendar.get( Calendar.YEAR ); +// int day_of_year2 = calendar.get( Calendar.DAY_OF_YEAR ); +// return ( era1 == era2 && year1 == year2 && day_of_year1 == day_of_year2 ); +// } + + static public long countDays(Date start,Date end) { + return countDays(start.getTime(), end.getTime()); + } + + static public long countDays(long start,long end) { + return (cutDate(end) - cutDate(start)) / MILLISECONDS_PER_DAY; + } + + static public long countMinutes(Date start, Date end) { + return (end.getTime()- start.getTime())/ MILLISECONDS_PER_MINUTE; + } + + static public long countMinutes(long start, long end){ + return (end-start)/ MILLISECONDS_PER_MINUTE; + } +// static public Calendar createGMTCalendar() +// { +// return Calendar.getInstance( GMT); +// } + + static int date_1970_1_1 = calculateJulianDayNumberAtNoon(1970, 1, 1); + /** + Return a the whole number, with no fraction. + The JD at noon is 1 more than the JD at midnight. + */ + private static int calculateJulianDayNumberAtNoon(int y, int m, int d) { + //http://www.hermetic.ch/cal_stud/jdn.htm + int result = (1461 * (y + 4800 + (m - 14) / 12)) / 4 + (367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 - (3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 + d - 32075; + return result; + } + + /** + * + * @param year + * @param month ranges from 1-12 + * @param day + * @return + */ + public static long toDate(int year, int month, int day ) + { + int days = calculateJulianDayNumberAtNoon(year, month, day); + int diff = days - date_1970_1_1; + long millis = diff * MILLISECONDS_PER_DAY; + return millis; + } + + public static Date toDateTime(Date date, Date time ) + { + long millisTime = time.getTime() - DateTools.cutDate( time.getTime()); + Date result = new Date( DateTools.cutDate(date.getTime()) + millisTime); + return result; + } + + public static class DateWithoutTimezone + { + public int year; + public int month; + public int day; + public String toString() + { + return year+"-" +month + "-" + day; + } + } + + public static class TimeWithoutTimezone + { + public int hour; + public int minute; + public int second; + public int milliseconds; + public String toString() + { + return hour+":" +minute + ":" + second + "." + milliseconds; + } + } + + public static TimeWithoutTimezone toTime(long millis) + { + long millisInDay = millis - DateTools.cutDate( millis); + TimeWithoutTimezone result = new TimeWithoutTimezone(); + result.hour = (int) (millisInDay / MILLISECONDS_PER_HOUR); + result.minute = (int) ((millisInDay % MILLISECONDS_PER_HOUR) / MILLISECONDS_PER_MINUTE); + result.second = (int) ((millisInDay % MILLISECONDS_PER_MINUTE) / 1000); + result.milliseconds = (int) (millisInDay % 1000 ); + return result; + } + + public static long toTime(int hour, int minute, int second) { + return toTime(hour, minute, second, 0); + } + + public static long toTime(int hour, int minute, int second, int millisecond) { + long millis = hour * MILLISECONDS_PER_HOUR; + millis += minute * MILLISECONDS_PER_MINUTE; + millis += second * 1000; + millis += millisecond; + return millis; + } + + public static int toHour(long millisecond) { + long result = (millisecond % MILLISECONDS_PER_DAY - millisecond % MILLISECONDS_PER_HOUR)/MILLISECONDS_PER_HOUR; + return (int) result; + } + + + public static DateWithoutTimezone toDate(long millis) + { + // special case for negative milliseconds as day rounding needs to get the lower day + int day = millis >= 0 ? (int) (millis/ MILLISECONDS_PER_DAY) : (int) (( millis + MILLISECONDS_PER_DAY -1) / MILLISECONDS_PER_DAY); + int julianDateAtNoon = day + date_1970_1_1; + DateWithoutTimezone result = fromJulianDayNumberAtNoon( julianDateAtNoon); + return result; + } + + private static DateWithoutTimezone fromJulianDayNumberAtNoon(int julianDateAtNoon) + { + //http://www.hermetic.ch/cal_stud/jdn.htm + int l = julianDateAtNoon + 68569; + int n = (4 * l) / 146097; + l = l - (146097 * n + 3) / 4; + int i = (4000 * (l + 1)) / 1461001; + l = l - (1461 * i) / 4 + 31; + int j = (80 * l) / 2447; + int d = l - (2447 * j) / 80; + l = j / 11; + int m = j + 2 - (12 * l); + int y = 100 * (n - 49) + i + l; + DateWithoutTimezone dt = new DateWithoutTimezone(); + dt.year = y; + dt.month = m; + dt.day = d; + return dt; + } + + /** returns the largest date null dates count as postive infinity*/ + public static Date max(Date... param) { + Date max = null; + boolean set = false; + for (Date d:param) + { + if ( !set) + { + max = d; + set = true; + } + else if ( max != null ) + { + if ( d == null || max.before( d)) + { + max = d; + } + } + + } + return max; + } + + + + +} + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/IOUtil.java b/rapla-source-1.8.2/src/org/rapla/components/util/IOUtil.java new file mode 100644 index 0000000..7921dbe --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/IOUtil.java @@ -0,0 +1,309 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.util; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.StringTokenizer; + +/** Some IOHelper methods. */ +abstract public class IOUtil { + + /** returns the path of the url without the last path component */ + public static URL getBase(URL url) { + try { + String file = url.getPath(); + String separator = "/"; + if (url.getProtocol().equals("file") && file.indexOf(File.separator)>0) { + separator = File.separator; + } + int index = file.lastIndexOf(separator); + String dir = (index<0) ? file: file.substring(0,index + 1); + return new URL(url.getProtocol() + ,url.getHost() + ,url.getPort() + ,dir); + } catch ( MalformedURLException e) { + // This should not happen + e.printStackTrace(); + throw new RuntimeException("Unknown error while getting the base of the url!"); + } // end of try-catch + } + + /** reads the content form an url into a ByteArray*/ + public static byte[] readBytes(URL url) throws IOException { + InputStream in = null; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + in = url.openStream(); + byte[] buffer = new byte[1024]; + int count = 0; + do { + out.write(buffer, 0, count); + count = in.read(buffer, 0, buffer.length); + } while (count != -1); + return out.toByteArray(); + } finally { + if ( in != null) { + in.close(); + } // end of if () + } + } + + + + /** same as {@link URLDecoder#decode}. + * But calls the deprecated method under 1.3. + */ + public static String decode(String s,String enc) throws UnsupportedEncodingException { + return callEncodeDecode(URLDecoder.class,"decode",s,enc); + } + + /** same as {@link URLEncoder#encode}. + * But calls the deprecated method under 1.3. + */ + public static String encode(String s,String enc) throws UnsupportedEncodingException { + return callEncodeDecode(URLEncoder.class,"encode",s,enc); + } + + private static String callEncodeDecode(Class clazz,String methodName,String s,String enc) throws UnsupportedEncodingException { + Assert.notNull(s); + Assert.notNull(enc); + try { + Method method = + clazz.getMethod(methodName + ,new Class[] { + String.class + ,String.class + } + ); + return (String) method.invoke(null,new Object[] {s,enc}); + } catch (NoSuchMethodException ex) { + try { + Method method = + URLDecoder.class.getMethod(methodName + ,new Class[] {String.class} + ); + return (String) method.invoke(null,new Object[] {s}); + } catch (Exception ex2) { + ex2.printStackTrace(); + throw new IllegalStateException("Should not happen" + ex2.getMessage()); + } + } catch (InvocationTargetException ex) { + throw (UnsupportedEncodingException) ex.getTargetException(); + } catch (IllegalAccessException ex) { + ex.printStackTrace(); + throw new IllegalStateException("Should not happen" + ex.getMessage()); + } + } + + + /** returns a BufferedInputStream from the url. + If the url-protocol is "file" no url connection will + be opened. + */ + public static InputStream getInputStream(URL url) throws IOException { + if (url.getProtocol().equals("file")) { + String path = decode(url.getPath(),"UTF-8"); + return new BufferedInputStream(new FileInputStream(path)); + } else { + return new BufferedInputStream(url.openStream()); + } // end of else + } + + public static File getFileFrom(URL url) throws IOException { + String path = decode(url.getPath(),"UTF-8"); + return new File( path ); + } + + + /** copies a file. + * @param srcPath the source-path. Thats the path of the file that should be copied. + * @param destPath the destination-path + */ + + public static void copy( String srcPath, String destPath) throws IOException{ + copy( srcPath, destPath, false); + } + + /** copies a file. + * @param srcPath the source-path. Thats the path of the file that should be copied. + * @param destPath the destination-path + */ + public static void copy( String srcPath, String destPath,boolean onlyOverwriteIfNewer ) throws IOException{ + copy ( new File( srcPath ) , new File( destPath ), onlyOverwriteIfNewer ); + } + + /** copies a file. + */ + public static void copy(File srcFile, File destFile, boolean onlyOverwriteIfNewer) throws IOException { + if ( ! srcFile.exists() ) { + throw new IOException( srcFile.getPath() + " doesn't exist!!"); + } + if ( destFile.exists() && destFile.lastModified() >= srcFile.lastModified() && onlyOverwriteIfNewer) + { + return; + } + FileInputStream in = null; + FileOutputStream out = null; + try { + in = new FileInputStream( srcFile ); + out = new FileOutputStream( destFile); + copyStreams ( in, out ); + } finally { + if ( in != null ) + in.close(); + + if ( out != null ) + out.close(); + } + } + + /** copies the contents of the input stream to the output stream. + * @param in + * @param out + * @throws IOException + */ + public static void copyStreams( InputStream in, OutputStream out ) throws IOException { + byte[] buf = new byte[ 32000 ]; + int n = 0; + while ( n != -1 ) { + out.write( buf, 0, n ); + n = in.read(buf, 0, buf.length ); + } + return; + } + + public static void deleteAll(File f) + { + if (f.isDirectory()) { + File[] files = f.listFiles(); + for (File file:files) { + deleteAll(file); + } + } + f.delete(); + } + /** returns the relative path of file to base. + * @throws IOException if position of file is not relative to base + */ + public static String getRelativePath(File base,File file) throws IOException { + String filePath = file.getAbsoluteFile().getCanonicalPath(); + String basePath = base.getAbsoluteFile().getCanonicalPath(); + int start = filePath.indexOf(basePath); + if (start != 0) + throw new IOException(basePath + " not ancestor of " + filePath); + return filePath.substring(basePath.length()); + } + + /** returns the relative path of file to base. + * same as {@link #getRelativePath(File, File)} but replaces windows-plattform-specific + * file separator \ with / + * @throws IOException if position of file is not relative to base + */ + public static String getRelativeURL(File base,File file) throws IOException { + StringBuffer result= new StringBuffer(getRelativePath(base,file)); + for (int i=0;i completeList = new ArrayList(); + StringTokenizer tokenizer = new StringTokenizer(dirList,","); + while (tokenizer.hasMoreTokens()) + { + File jarDir = new File(baseDir,tokenizer.nextToken()); + if (jarDir.exists() && jarDir.isDirectory()) + { + File[] jarFiles = jarDir.listFiles(); + for (int i = 0; i < jarFiles.length; i++) { + if (jarFiles[i].getAbsolutePath().endsWith(".jar")) { + completeList.add(jarFiles[i].getCanonicalFile()); + } + } + } + } + return completeList.toArray(new File[] {}); + } + + public static String getStackTraceAsString(Throwable ex) { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + PrintWriter writer = new PrintWriter(bytes,true); + writer.println("

    " + ex.getMessage() +"


    "); + ex.printStackTrace(writer); + while (true) { + ex = ex.getCause(); + if (ex != null) { + writer.println("

    Caused by: "+ ex.getMessage() + "


    "); + ex.printStackTrace(writer); + } else { + break; + } + } + return bytes.toString(); + } + + public static boolean isSigned() { + try + { + final ClassLoader classLoader = IOUtil.class.getClassLoader(); + { + final Enumeration resources = classLoader.getResources("META-INF/RAPLA.SF"); + if (resources.hasMoreElements() ) + return true; + } + { + final Enumeration resources = classLoader.getResources("META-INF/RAPLA.DSA"); + if (resources.hasMoreElements() ) + return true; + } + } + catch ( IOException ex) + { + + } + return false; + } + + +} + + + + + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/InverseComparator.java b/rapla-source-1.8.2/src/org/rapla/components/util/InverseComparator.java new file mode 100644 index 0000000..cc92c2b --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/InverseComparator.java @@ -0,0 +1,36 @@ +/*--------------------------------------------------------------------------* +| Copyright (C) 2006 Christopher Kohlhaas | +| | +| This program is free software; you can redistribute it and/or modify | +| it under the terms of the GNU General Public License as published by the | +| Free Software Foundation. A copy of the license has been included with | +| these distribution in the COPYING file, if not go to www.fsf.org | +| | +| As a special exception, you are granted the permissions to link this | +| program with every library, which license fulfills the Open Source | +| Definition as published by the Open Source Initiative (OSI). | +*--------------------------------------------------------------------------*/ + +package org.rapla.components.util; + +import java.util.Comparator; + +/** + * + * Reverts the Original Comparator + * -1 -> 1 + * 1 -> -1 + * 0 -> 0 + */ +public class InverseComparator implements Comparator { + Comparator original; + public InverseComparator( Comparator original) { + this.original = original; + } + public int compare( T arg0, T arg1 ) + { + return -1 * original.compare( arg0, arg1); + } +} + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/JNLPUtil.java b/rapla-source-1.8.2/src/org/rapla/components/util/JNLPUtil.java new file mode 100644 index 0000000..86c501c --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/JNLPUtil.java @@ -0,0 +1,35 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.util; + +import java.lang.reflect.Method; +import java.net.URL; +/** returns the codebase in an webstart application */ +abstract public class JNLPUtil { + final static String basicService = "javax.jnlp.BasicService"; + final public static URL getCodeBase() throws Exception { + try { + Class serviceManagerC = Class.forName("javax.jnlp.ServiceManager"); + Class basicServiceC = Class.forName( basicService ); + //Class unavailableServiceException = Class.forName("javax.jnlp.UnavailableServiceException"); + + Method lookup = serviceManagerC.getMethod("lookup", new Class[] {String.class}); + Method getCodeBase = basicServiceC.getMethod("getCodeBase", new Class[] {}); + Object service = lookup.invoke( null, new Object[] { basicService }); + return (URL) getCodeBase.invoke( service, new Object[] {}); + } catch (ClassNotFoundException ex ) { + throw new Exception( "Webstart not available :" + ex.getMessage()); + } + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/ParseDateException.java b/rapla-source-1.8.2/src/org/rapla/components/util/ParseDateException.java new file mode 100644 index 0000000..2cf114a --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/ParseDateException.java @@ -0,0 +1,9 @@ +package org.rapla.components.util; + +public class ParseDateException extends Exception { + + private static final long serialVersionUID = 1L; + public ParseDateException(String message) { + super(message); + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/Predicate.java b/rapla-source-1.8.2/src/org/rapla/components/util/Predicate.java new file mode 100644 index 0000000..f60218b --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/Predicate.java @@ -0,0 +1,6 @@ +package org.rapla.components.util; + +public interface Predicate +{ + boolean apply(T t); +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/SerializableDateTimeFormat.java b/rapla-source-1.8.2/src/org/rapla/components/util/SerializableDateTimeFormat.java new file mode 100644 index 0000000..69353e9 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/SerializableDateTimeFormat.java @@ -0,0 +1,241 @@ +package org.rapla.components.util; + +import java.util.Date; + +import org.rapla.components.util.DateTools.TimeWithoutTimezone; +import org.rapla.components.util.iterator.IntIterator; + + +/** +Provides methods for parsing and formating dates +and times in the following format:
    +2002-25-05 for dates and 13:00:00 for times. +This is according to the xschema specification for dates and time and +ISO8601 +*/ +public class SerializableDateTimeFormat +{ + public static SerializableDateTimeFormat INSTANCE = new SerializableDateTimeFormat(); + // we ommit T + private final static char DATE_TIME_SEPERATOR = 'T'; + //private final static char DATE_TIME_SEPERATOR = ' '; + + + private Date parseDate( String date, String time, boolean fillDate ) throws ParseDateException { + if( date == null || date.length()==0 ) + throwParseDateException("empty" ); + + long millis = parseDate_(date, fillDate); + if ( time != null ) { + long timeMillis = parseTime_(time); + millis+= timeMillis; + } + // logger.log( "parsed to " + calendar.getTime() ); + return new Date( millis); + } + + private long parseTime_(String time) throws ParseDateException { + int length = time.length(); + if ( length <1) + { + throwParseTimeException( time ); + } + if ( time.charAt( length-1) == 'Z') + { + time = time.substring(0,length-1); + } + IntIterator it = new IntIterator( time, new char[]{':','.',','} ); + if ( !it.hasNext() ) + throwParseTimeException( time ); + int hour = it.next(); + if ( !it.hasNext() ) + throwParseTimeException( time ); + int minute = it.next(); + int second; + if ( it.hasNext() ) + { + second = it.next(); + } + else + { + second = 0; + } + int millisecond; + if ( it.hasNext() ) + { + millisecond = it.next(); + } + else + { + millisecond = 0; + } + long result = DateTools.toTime( hour, minute,second, millisecond); + return result; + } + + private long parseDate_(String date, boolean fillDate) + throws ParseDateException { + int indexOfSeperator = indexOfSeperator(date); + if ( indexOfSeperator > 0) + { + date = date.substring(0, indexOfSeperator); + } + IntIterator it = new IntIterator(date,'-'); + if ( !it.hasNext() ) + throwParseDateException( date ); + int year = it.next(); + if ( !it.hasNext() ) + throwParseDateException( date); + int month = it.next(); + if ( !it.hasNext() ) + throwParseDateException( date); + int day = it.next(); + if (fillDate ) + { + day+=1; + } + return DateTools.toDate( year, month, day); + } + + private int indexOfSeperator(String date) { + // First try the new ISO8601 + int indexOfSeperator = date.indexOf( 'T' ); + if ( indexOfSeperator<0) + { + //then search for a space + indexOfSeperator = date.indexOf( ' ' ); + } + return indexOfSeperator; + } + + private void throwParseDateException( String date) throws ParseDateException { + throw new ParseDateException( "No valid date format: " + date); + } + + private void throwParseTimeException( String time) throws ParseDateException { + throw new ParseDateException( "No valid time format: " + time); + } + + /** The date-string must be in the following format 2001-10-21. + The format of the time-string is 18:00:00. + @return The parsed date + @throws ParseDateException when the date cannot be parsed. + */ + public Date parseDateTime( String date, String time) throws ParseDateException { + return parseDate( date, time, false); + } + + /** + The format of the time-string is 18:00:00. + @return The parsed time + @throws ParseDateException when the date cannot be parsed. + */ + public Date parseTime( String time) throws ParseDateException { + if( time == null || time.length()==0 ) + throwParseDateException("empty"); + long millis = parseTime_( time); + Date result = new Date( millis); + return result; + } + + /** The date-string must be in the following format 2001-10-21. + * @param fillDate if this flag is set the time will be 24:00 instead of 0:00 + When this flag is set the time parameter should be null + @return The parsed date + @throws ParseDateException when the date cannot be parsed. + */ + public Date parseDate( String date, boolean fillDate ) throws ParseDateException { + return parseDate( date, null, fillDate); + } + + public Date parseTimestamp(String timestamp) throws ParseDateException + { + boolean fillDate = false; + timestamp = timestamp.trim(); + long millisDate = parseDate_(timestamp, fillDate); + int indexOfSeperator = indexOfSeperator(timestamp); + if ( timestamp.indexOf(':') >= indexOfSeperator && indexOfSeperator > 0) + { + String timeString = timestamp.substring( indexOfSeperator + 1); + if ( timeString.length() > 0) + { + long time = parseTime_( timeString); + millisDate+= time; + } + } + Date result = new Date( millisDate); + return result; + } + + + /** returns the time object in the following format: 13:00:00.
    */ + public String formatTime( Date date ) { + return formatTime(date, false); + } + + private String formatTime(Date date, boolean includeMilliseconds) { + StringBuilder buf = new StringBuilder(); + if ( date == null) + { + date = new Date(); + } + TimeWithoutTimezone time = DateTools.toTime( date.getTime()); + append( buf, time.hour, 2 ); + buf.append( ':' ); + append( buf, time.minute, 2 ); + buf.append( ':' ); + append( buf, time.second, 2 ); + if ( includeMilliseconds) + { + buf.append('.'); + append( buf, time.milliseconds, 4 ); + } + //buf.append( 'Z'); + return buf.toString(); + } + + /** returns the date object in the following format: 2001-10-21.
    + @param adaptDay if the flag is set 2001-10-21 will be stored as 2001-10-20. + This is usefull for end-dates: 2001-10-21 00:00 is then interpreted as + 2001-10-20 24:00. + */ + public String formatDate( Date date, boolean adaptDay ) { + StringBuilder buf = new StringBuilder(); + DateTools.DateWithoutTimezone splitDate; + splitDate = DateTools.toDate( date.getTime() - (adaptDay ? DateTools.MILLISECONDS_PER_DAY : 0)); + append( buf, splitDate.year, 4 ); + buf.append( '-' ); + append( buf, splitDate.month, 2 ); + buf.append( '-' ); + append( buf, splitDate.day, 2 ); + return buf.toString(); + } + + public String formatTimestamp( Date date ) { + StringBuilder builder = new StringBuilder(); + builder.append(formatDate( date, false)); + builder.append( DATE_TIME_SEPERATOR); + builder.append( formatTime( date , true)); + builder.append( 'Z'); + String timestamp = builder.toString();; + return timestamp; + } + + /** same as formatDate(date, false). + @see #formatDate(Date,boolean) + */ + public String formatDate( Date date ) { + return formatDate( date, false ); + } + + private void append( StringBuilder buf, int number, int minLength ) { + int limit = 1; + for ( int i=0;i[] EMPTY_CLASS_ARRAY = new Class[0]; + public static final String[] EMPTY_STRING_ARRAY = new String[0]; + + /** test if 2 char arrays match. */ + public static boolean match(char[] p1, char[] p2) { + boolean bMatch = true; + if (p1.length == p2.length) { + for (int i = 0; iArrayIndexOutOfBoundsException if string.length()<width. + */ + public static String left(String string,int width) { + return string.substring(0, Math.min(string.length(), width -1)); + } + + /** Convert a byte array into a printable format containing aString of hexadecimal digit characters (two per byte). + * This method is taken form the apache jakarata + * tomcat project. + */ + public static String convert(byte bytes[]) { + StringBuffer sb = new StringBuffer(bytes.length * 2); + for (int i = 0; i < bytes.length; i++) { + sb.append(convertDigit(bytes[i] >> 4)); + sb.append(convertDigit(bytes[i] & 0x0f)); + } + return (sb.toString()); + } + + /** Convert the specified value (0-15) to the corresponding hexadecimal digit. + * This method is taken form the apache jakarata tomcat project. + */ + public static char convertDigit(int value) { + value &= 0x0f; + if (value >= 10) + return ((char) (value - 10 + 'a')); + else + return ((char) (value + '0')); + } + + public static boolean equalsOrBothNull(Object o1, Object o2) { + if (o1 == null) { + if (o2 != null) { + return false; + } + } else if ( o2 == null) { + return false; + } else if (!o1.equals( o2 ) ) { + return false; + } + return true; + } + + /** 1.3 compatibility method */ + public static String[] split(String stringToSplit, char delimiter) { + List keys = new ArrayList(); + int lastIndex = 0; + while( true ) { + int index = stringToSplit.indexOf( delimiter,lastIndex); + if ( index < 0) + { + String token = stringToSplit.substring( lastIndex ); + if ( token.length() >= 0) + { + keys.add( token ); + } + break; + } + String token = stringToSplit.substring( lastIndex , index ); + keys.add( token ); + lastIndex = index + 1; + } + return keys.toArray( new String[] {}); + + } + +// /** 1.3 compatibility method */ +// public static String replaceAll( String string, String stringToReplace, String newString ) { +// if ( stringToReplace.equals( newString)) +// return string; +// int length = stringToReplace.length(); +// int oldPos = 0; +// while ( true ) { +// int pos = string.indexOf( stringToReplace,oldPos); +// if ( pos < 0 ) +// return string; +// +// string = string.substring(0, pos) + newString + string.substring( pos + length); +// oldPos = pos + 1; +// if ( oldPos >= string.length() ) +// return string; +// +// } +// } + + /** reads a table from a csv file. You can specify a minimum number of columns */ + @GwtIncompatible + public static String[][] csvRead(Reader reader, int expectedColumns) throws IOException { + return csvRead(reader, ';', expectedColumns); + } + /** reads a table from a csv file. You can specify the seperator and a minimum number of columns */ + @GwtIncompatible + public static String[][] csvRead(Reader reader, char seperator,int expectedColumns) throws IOException { + //System.out.println( "Using Encoding " + reader.getEncoding() ); + StringBuffer buf = new StringBuffer(); + while (true) { + int c = reader.read(); + if ( c == -1 ) + break; + buf.append( (char) c ); + } + String[] lines = buf.toString().split(System.getProperty("line.separator")); //BJO + //String[] lines = split( buf.toString(),'\n'); + String[][] lineEntries = new String[ lines.length ][]; + for ( int i=0;i implements Iterable { + Iterable iterable; + public FilterIterable( Iterable iterable) { + this.iterable = iterable; + } + + class FilterIterator implements Iterator + { + Iterator it; + Object obj; + FilterIterator( Iterable iterable) + { + this.it = iterable.iterator(); + obj = getNextObject(); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + private Object getNextObject() { + Object o; + do { + if ( !it.hasNext() ) { + return null; + } + o = it.next(); + } while (!isInIterator( o)); + return o; + } + + @SuppressWarnings("unchecked") + public T next() { + if ( obj == null) + throw new NoSuchElementException(); + + Object result = obj; + obj = getNextObject(); + return (T)result; + } + + public boolean hasNext() { + return obj != null; + } + + } + + + protected abstract boolean isInIterator(Object obj); + + @Override + public Iterator iterator() { + Iterator iterator = new FilterIterator(iterable); + return iterator; + } +} + diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/iterator/IntIterator.java b/rapla-source-1.8.2/src/org/rapla/components/util/iterator/IntIterator.java new file mode 100644 index 0000000..531dd60 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/iterator/IntIterator.java @@ -0,0 +1,114 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.util.iterator; + +import java.util.NoSuchElementException; + +/** This class can iterate over a string containing a list of integers. + Its tuned for performance, so it will return int instead of Integer +*/ +public class IntIterator { + int parsePosition = 0; + String text; + char[] delimiter; + int len; + int next; + boolean hasNext=false; + char endingDelimiter; + + public IntIterator(String text,char delimiter) { + this(text,new char[] {delimiter}); + } + + public IntIterator(String text,char[] delimiter) { + this.text = text; + len = text.length(); + this.delimiter = delimiter; + parsePosition = 0; + parseNext(); + } + + public boolean hasNext() { + return hasNext; + } + + public int next() { + if (!hasNext()) + throw new NoSuchElementException(); + int result = next; + parseNext(); + return result; + } + + private void parseNext() { + boolean isNegative = false; + int relativePos = 0; + + next = 0; + + if (parsePosition == len) { + hasNext = false; + return; + } + + while (parsePosition< len) { + char c = text.charAt(parsePosition ); + if (relativePos == 0 && c=='-') { + isNegative = true; + parsePosition++; + continue; + } + + boolean delimiterFound = false; + for ( char d:delimiter) + { + if (c == d ) { + parsePosition++; + delimiterFound = true; + break; + } + } + + if (delimiterFound || c == endingDelimiter ) { + break; + } + + int digit = c-'0'; + if (digit<0 || digit>9) { + hasNext = false; + return; + } + + next *= 10; + next += digit; + parsePosition++; + relativePos++; + } + + if (isNegative) + next *= -1; + + hasNext = parsePosition > 0; + } + public int getPos() { + return parsePosition; + } +} + + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/iterator/IterableChain.java b/rapla-source-1.8.2/src/org/rapla/components/util/iterator/IterableChain.java new file mode 100644 index 0000000..4b12a68 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/iterator/IterableChain.java @@ -0,0 +1,44 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.util.iterator; + +import java.util.Iterator; + +/** concatenates two Iterators */ +public class IterableChain implements Iterable { + protected Iterable firstIt; + protected Iterable secondIt; + protected Iterable thirdIt; + + public IterableChain(Iterable firstIt, Iterable secondIt, Iterable thirdIt) + { + this.firstIt = firstIt; + this.secondIt = secondIt; + this.thirdIt = thirdIt; + } + + public IterableChain(Iterable firstIt, Iterable secondIt) + { + this.firstIt = firstIt; + this.secondIt = secondIt; + } + + + @Override + public Iterator iterator() + { + return new IteratorChain(firstIt != null ? firstIt.iterator(): null, secondIt != null ? secondIt.iterator(): null , thirdIt != null ? thirdIt.iterator() :null); + } + +} + diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/iterator/IteratorChain.java b/rapla-source-1.8.2/src/org/rapla/components/util/iterator/IteratorChain.java new file mode 100644 index 0000000..bdd0112 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/iterator/IteratorChain.java @@ -0,0 +1,69 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.util.iterator; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** concatenates two Iterators */ +public class IteratorChain implements Iterator { + protected Iterator firstIt; + protected Iterator secondIt; + protected Iterator thirdIt; + + public IteratorChain(Iterator firstIt, Iterator secondIt) { + this.firstIt = firstIt; + this.secondIt = secondIt; + } + + public IteratorChain(Iterator firstIt, Iterator secondIt, Iterator thirdIt) { + this.firstIt = firstIt; + this.secondIt = secondIt; + this.thirdIt = thirdIt; + } + + public boolean hasNext() { + return (firstIt!=null && firstIt.hasNext()) || (secondIt != null && secondIt.hasNext()) || (thirdIt != null && thirdIt.hasNext()); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + public T next() { + if (firstIt!=null && !firstIt.hasNext()) + { + firstIt = null; + } + if (secondIt!=null && !secondIt.hasNext()) + { + secondIt = null; + } +// else if (thirdIt!=null && !thirdIt.hasNext()) +// { +// thirdIt = null; +// } + + if ( firstIt != null ) + return firstIt.next(); + else if ( secondIt != null) + return secondIt.next(); + else if (thirdIt != null) + return thirdIt.next(); + else + throw new NoSuchElementException(); + } + + +} + diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/iterator/NestedIterable.java b/rapla-source-1.8.2/src/org/rapla/components/util/iterator/NestedIterable.java new file mode 100644 index 0000000..b9843ec --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/iterator/NestedIterable.java @@ -0,0 +1,87 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.util.iterator; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +/**Successivly iterates over the elements specified in the nested Iterators. +Example of an recursive traversal of an Entity Tree: +
    +class RecursiveEntityIterator extends NestedIterator {
    +    public RecursiveEntityIterator(Iterator it) {
    +        super(it);
    +    }
    +    public Iterator getNestedIterator(Object obj) {
    +        return new RecursiveEntityIterator(((Entity)obj).getSubEntities());
    +    }
    +}
    +
    +*/ + +public abstract class NestedIterable implements Iterable { + Iterable outerIterable; + class NestedIterator implements Iterator + { + protected Iterator outerIt; + protected Iterator innerIt; + T nextElement; + boolean isInitialized; + + public NestedIterator(Iterator outerIt) { + this.outerIt = outerIt; + } + + private T nextElement() { + while (outerIt.hasNext() || (innerIt != null && innerIt.hasNext())) { + if (innerIt != null && innerIt.hasNext()) + return innerIt.next(); + innerIt = getNestedIterable(outerIt.next()).iterator(); + } + return null; + } + + public boolean hasNext() { + if (!isInitialized) + { + nextElement = nextElement(); + isInitialized = true; + } + return nextElement != null; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + public T next() { + if (!hasNext()) + throw new NoSuchElementException(); + T result = nextElement; + nextElement = nextElement(); + return result; + } + } + + public NestedIterable(Iterable outerIterable) { + this.outerIterable = outerIterable; + } + + public abstract Iterable getNestedIterable(S obj); + + public Iterator iterator() { + Iterator iterator = outerIterable.iterator(); + return new NestedIterator(iterator); + } +} + diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/iterator/package.html b/rapla-source-1.8.2/src/org/rapla/components/util/iterator/package.html new file mode 100644 index 0000000..7b426d4 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/iterator/package.html @@ -0,0 +1,4 @@ + +

    Iterators used by Rapla.

    + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/package.html b/rapla-source-1.8.2/src/org/rapla/components/util/package.html new file mode 100644 index 0000000..b806f9f --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/package.html @@ -0,0 +1,4 @@ + +

    Some more helpful tools.

    + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/undo/CommandHistory.java b/rapla-source-1.8.2/src/org/rapla/components/util/undo/CommandHistory.java new file mode 100644 index 0000000..c56a28f --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/undo/CommandHistory.java @@ -0,0 +1,168 @@ +package org.rapla.components.util.undo; + +import java.util.ArrayList; +import java.util.List; +import java.util.Vector; + + +/** + * This is where all the committed actions are saved. + * A list will be initialized, every action is an item of this list. + * There is a list for the calendar view, and one for the edit view. + * @author Jens Fritz + * + */ + +//Erstellt von Dominick Krickl-Vorreiter +public class CommandHistory { + private List> history = new ArrayList>(); + private int current = -1; + private int maxSize = 100; + + private Vector listenerList = new Vector(); + + private void fireChangeEvent() { + for (CommandHistoryChangedListener listener: listenerList.toArray(new CommandHistoryChangedListener[] {})) + { + listener.historyChanged(); + } + } + + public boolean storeAndExecute(CommandUndo cmd) throws T { + while (!history.isEmpty() && (current < history.size() - 1)) { + history.remove(history.size() - 1); + } + + while (history.size() >= maxSize) { + history.remove(0); + current--; + } + + if (cmd.execute()) { + history.add(cmd); + current++; + fireChangeEvent(); + return true; + } + else + { + return false; + } + + } + + public void undo() throws Exception { + if (!history.isEmpty() && (current >= 0)) { + if (history.get(current).undo()) + { + current--; + } + fireChangeEvent(); + } + } + + public void redo() throws Exception { + if (!history.isEmpty() && (current < history.size() - 1)) { + if (history.get(current + 1).execute()) + { + current++; + } + fireChangeEvent(); + } + } + + public void clear() { + history.clear(); + current = -1; + + fireChangeEvent(); + } + + public int size() { + return history.size(); + } + + public int getCurrent() { + return current; + } + + public int getMaxSize() { + return maxSize; + } + + public void setMaxSize(int maxSize) { + if (maxSize > 0) { + this.maxSize = maxSize; + } + } + + public boolean canUndo() { + return current >= 0; + } + + public boolean canRedo() { + return current < history.size() - 1; + } + + public String getRedoText() + { + if ( !canRedo()) + { + return ""; + } + else + { + return history.get(current + 1).getCommandoName(); + } + } + + public String getUndoText() + { + if ( !canUndo()) + { + return ""; + } + else + { + return history.get(current ).getCommandoName(); + } + } + + + public void addCommandHistoryChangedListener(CommandHistoryChangedListener actionListener) { + this.listenerList.add( actionListener); + } + + + public void removeCommandHistoryChangedListener(CommandHistoryChangedListener actionListener) { + this.listenerList.remove( actionListener); + } + + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Undo=["); + for (int i=current;i>0;i--) + { + CommandUndo command = history.get(i); + builder.append(command.getCommandoName()); + if ( i > 0) + { + builder.append(", "); + } + } + builder.append("]"); + builder.append(", "); + builder.append("Redo=["); + for (int i=current+1;i command = history.get(i); + builder.append(command.getCommandoName()); + if ( i < history.size() -1) + { + builder.append(", "); + } + } + builder.append("]"); + return builder.toString(); + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/undo/CommandHistoryChangedListener.java b/rapla-source-1.8.2/src/org/rapla/components/util/undo/CommandHistoryChangedListener.java new file mode 100644 index 0000000..a8cb391 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/undo/CommandHistoryChangedListener.java @@ -0,0 +1,10 @@ +package org.rapla.components.util.undo; + +import java.util.EventListener; + + + +public interface CommandHistoryChangedListener extends EventListener +{ + public void historyChanged(); +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/undo/CommandUndo.java b/rapla-source-1.8.2/src/org/rapla/components/util/undo/CommandUndo.java new file mode 100644 index 0000000..66ee017 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/undo/CommandUndo.java @@ -0,0 +1,10 @@ +package org.rapla.components.util.undo; + + +//Erstellt von Dominick Krickl-Vorreiter +public interface CommandUndo { + // Der Rückgabewert signalisiert, ob alles korrekt ausgeführt wurde + public boolean execute() throws T; + public boolean undo() throws T; + public String getCommandoName(); +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/xml/RaplaContentHandler.java b/rapla-source-1.8.2/src/org/rapla/components/util/xml/RaplaContentHandler.java new file mode 100644 index 0000000..2d3a2fa --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/xml/RaplaContentHandler.java @@ -0,0 +1,110 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org . | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.util.xml; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.xml.sax.Attributes; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.DefaultHandler; + +public class RaplaContentHandler extends DefaultHandler +{ + Locator locator; + RaplaSAXHandler handler; + public RaplaContentHandler(RaplaSAXHandler handler) { + this.handler = handler; + } + + public void setDocumentLocator( Locator locator ) + { + this.locator = locator; + } + + final public void startElement( + String namespaceURI, + String localName, + String qName, + Attributes atts ) throws SAXException + { + try + { + Map attributeMap; + if ( atts != null) { + int length = atts.getLength(); + if ( length == 0) + { + attributeMap = Collections.emptyMap(); + } + else if ( length == 1) + { + String key = atts.getLocalName( 0); + String value = atts.getValue( 0); + attributeMap = Collections.singletonMap(key, value); + } + else + { + attributeMap = new LinkedHashMap(); + for ( int i=0;i attributeMap; + public RaplaSAXAttributes(Map map) + { + this.attributeMap = map; + } + + public String getValue(@SuppressWarnings("unused") String uri,String key) + { + return getValue( key); + } + + public String getValue(String key) + { + return attributeMap.get( key); + } + + public Map getMap() + { + return Collections.unmodifiableMap( attributeMap); + } + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/xml/RaplaSAXHandler.java b/rapla-source-1.8.2/src/org/rapla/components/util/xml/RaplaSAXHandler.java new file mode 100644 index 0000000..638d3dd --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/xml/RaplaSAXHandler.java @@ -0,0 +1,14 @@ +package org.rapla.components.util.xml; + + +public interface RaplaSAXHandler { + public void startElement(String namespaceURI, String localName, + RaplaSAXAttributes atts) throws RaplaSAXParseException; + + public void endElement( + String namespaceURI, + String localName + ) throws RaplaSAXParseException; + + public void characters( char[] ch, int start, int length ); +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/xml/RaplaSAXParseException.java b/rapla-source-1.8.2/src/org/rapla/components/util/xml/RaplaSAXParseException.java new file mode 100644 index 0000000..6c35cc8 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/xml/RaplaSAXParseException.java @@ -0,0 +1,16 @@ +package org.rapla.components.util.xml; + +import org.rapla.framework.RaplaException; + +public class RaplaSAXParseException extends RaplaException{ + + public RaplaSAXParseException(String text, Throwable cause) { + super(text, cause); + } + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/xml/XMLReaderAdapter.java b/rapla-source-1.8.2/src/org/rapla/components/util/xml/XMLReaderAdapter.java new file mode 100644 index 0000000..1ba99cf --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/xml/XMLReaderAdapter.java @@ -0,0 +1,57 @@ +/*---------------------------------------------------------------------------* + | (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org . | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.util.xml; + +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +final public class XMLReaderAdapter { + + static SAXParserFactory spfvalidating; + static SAXParserFactory spfnonvalidating; + + static private SAXParserFactory getFactory( boolean validating) + { + if ( validating && spfvalidating != null) + { + return spfvalidating; + } + if ( !validating && spfnonvalidating != null) + { + return spfnonvalidating; + } + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + spf.setValidating(validating); + if ( validating) + { + spfvalidating = spf; + } + else + { + spfnonvalidating = spf; + } + return spf; + } + + public static XMLReader createXMLReader(boolean validating) throws SAXException { + try { + SAXParserFactory spf = getFactory(validating); + return spf.newSAXParser().getXMLReader(); + } catch (Exception ex2) { + throw new SAXException("Couldn't create XMLReader " + ex2.getMessage(), ex2); + } + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/util/xml/XMLWriter.java b/rapla-source-1.8.2/src/org/rapla/components/util/xml/XMLWriter.java new file mode 100644 index 0000000..a693463 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/util/xml/XMLWriter.java @@ -0,0 +1,205 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.util.xml; + +import java.io.IOException; +import java.util.Map; + +/** Provides some basic functionality for xml-file creation. This + * is the SAX like alternative to the creation of a DOM Tree.*/ +public class XMLWriter { + Appendable appendable; + //BufferedWriter writer; + boolean xmlSQL = false; + + public void setWriter(Appendable writer) { + this.appendable = writer; + } + + public Appendable getWriter() { + return this.appendable; + } + + int level = 0; + private void indent() throws IOException { + if( !xmlSQL) //BJO do not indent for sql db, XML_VALUE column will be too small + for (int i = 0; i < level * 3; i++) write(' '); + } + + protected void increaseIndentLevel() { + level ++; + } + + protected void decreaseIndentLevel() { + if (level > 0) + level --; + } + + public int getIndentLevel() { + return level; + } + + public void setIndentLevel(int level) { + this.level = level; + } + + public static String encode(String text) { + boolean needsEncoding = false; + int size = text.length(); + for ( int i= 0; i': + case '&': + case '"': + needsEncoding = true; + break; + } + } + if ( !needsEncoding ) + return text; + StringBuilder buf = new StringBuilder(); + for ( int i= 0; i': + buf.append(">"); + break; + case '&': + buf.append("&"); + break; + case '"': + buf.append("""); + break; + default: + buf.append(c); + break; + } // end of switch () + } // end of for () + return buf.toString(); + } + + protected void printEncode(String text) throws IOException { + if (text == null) + return; + write( encode(text) ); + } + + protected void openTag(String start) throws IOException { + indent(); + write('<'); + write(start); + level++; + } + + protected void openElement(String start) throws IOException { + indent(); + write('<'); + write(start); + write('>');newLine(); + level++; + } + + protected void openElementOnLine(String start) throws IOException { + indent(); + write('<'); + write(start); + write('>'); + level++; + } + + protected void att(Map attributes) throws IOException{ + for (Map.Entry entry: attributes.entrySet()) + { + + att(entry.getKey(),entry.getValue()); + } + } + + protected void att(String attribute,String value) throws IOException { + write(' '); + write(attribute); + write('='); + write('"'); + printEncode(value); + write('"'); + } + + protected void closeTag() throws IOException { + write('>');newLine(); + } + + protected void closeTagOnLine() throws IOException{ + write('>'); + } + + protected void closeElementOnLine(String element) throws IOException { + level--; + write('<'); + write('/'); + write(element); + write('>'); + } + + protected void closeElement(String element) throws IOException { + level--; + indent(); + write('<'); + write('/'); + write(element); + write('>');newLine(); + } + + + protected void closeElementTag() throws IOException { + level--; + write('/'); + write('>');newLine(); + } + + /** writes the line to the specified PrintWriter */ + public void println(String text) throws IOException { + indent(); + write(text);newLine(); + } + + protected void newLine() throws IOException { + appendable.append("\n"); + } + + protected void write(String text) throws IOException { + appendable.append( text); + } + + protected void write(char c) throws IOException { + appendable.append( c ); + } + + /** writes the text to the specified PrintWriter */ + public void print(String text) throws IOException { + write(text); + } + + /** writes the line to the specified PrintWriter */ + public void println() throws IOException { + newLine(); + } + + public void setSQL(boolean sql) { + this.xmlSQL = sql; + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/CompoundI18n.java b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/CompoundI18n.java new file mode 100644 index 0000000..d28f091 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/CompoundI18n.java @@ -0,0 +1,85 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.xmlbundle; + +import java.util.Locale; +import java.util.MissingResourceException; + +import javax.swing.ImageIcon; +/** Allows the combination of two resource-bundles. + First the inner bundle will be searched. + If the requested resource was not found the + outer bundle will be searched. + */ +public class CompoundI18n implements I18nBundle { + I18nBundle inner; + I18nBundle outer; + public CompoundI18n(I18nBundle inner,I18nBundle outer) { + this.inner = inner; + this.outer = outer; + } + + public String format(String key,Object obj1) { + Object[] array1 = new Object[1]; + array1[0] = obj1; + return format(key,array1); + } + + public String format(String key,Object obj1,Object obj2) { + Object[] array2 = new Object[2]; + array2[0] = obj1; + array2[1] = obj2; + return format(key,array2); + } + + @Override + public String format(String key,Object[] obj) { + try { + return inner.format(key, obj); + } catch (MissingResourceException ex) { + return outer.format( key, obj); + } + } + + public ImageIcon getIcon(String key) { + try { + return inner.getIcon(key); + } catch (MissingResourceException ex) { + return outer.getIcon(key); + } + } + + public String getString(String key) { + try { + return inner.getString(key); + } catch (MissingResourceException ex) { + return outer.getString(key); + } + } + + public String getLang() { + return inner.getLang(); + } + + public Locale getLocale() { + return inner.getLocale(); + } + + public String getString(String key, Locale locale) { + try { + return inner.getString(key,locale); + } catch (MissingResourceException ex) { + return outer.getString(key, locale); + } + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/DEPENDENCIES b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/DEPENDENCIES new file mode 100644 index 0000000..051531a --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/DEPENDENCIES @@ -0,0 +1,7 @@ +This component depends on the following packages (including subpackages): +java.* +javax.xml.* +javax.swing.Icon +org.xml.sax.* +org.rapla.components.util.* +org.apache.avalon.framework.* diff --git a/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/I18nBundle.java b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/I18nBundle.java new file mode 100644 index 0000000..de25eb2 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/I18nBundle.java @@ -0,0 +1,67 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.xmlbundle; + +import java.util.Locale; +import java.util.MissingResourceException; + +import javax.swing.ImageIcon; + +/**The interface provides access to a resourcebundle that + can be defined in XML or as an java-object. +Example Usage: +
    +   I18nBundle i18n = serviceManager.lookup(I18nBundle.class);
    +   i18n.getString("yes"); // will get the translation for yes.
    +
    +*/ + +public interface I18nBundle { + /** same as format(key,new Object[] {obj1}); + @see #format(String,Object[]) + */ + String format(String key,Object obj1) throws MissingResourceException; + /** same as format(key,new Object[] {obj1, obj2}); + @see #format(String,Object[]) + */ + String format(String key,Object obj1,Object obj2) throws MissingResourceException; + /** same as + + (new MessageFormat(getString(key))).format(obj); + + @see java.text.MessageFormat + */ + String format(String key,Object... obj) throws MissingResourceException; + + /** returns the specified icon from the image-resource-file. + @throws MissingResourceException if not found or can't be loaded. + */ + ImageIcon getIcon(String key) throws MissingResourceException; + + /** returns the specified string from the selected resource-file. + * Same as getString(key,getLocale()) + * @throws MissingResourceException if not found or can't be loaded. + */ + String getString(String key) throws MissingResourceException; + + /** returns the specified string from the selected resource-file for the specified locale + @throws MissingResourceException if not found or can't be loaded. + */ + String getString( String key, Locale locale); + + /** @return the selected language. */ + String getLang(); + + /** @return the selected Locale. */ + Locale getLocale(); +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/LocaleChangeEvent.java b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/LocaleChangeEvent.java new file mode 100644 index 0000000..5d00aea --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/LocaleChangeEvent.java @@ -0,0 +1,27 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.xmlbundle; +import java.util.EventObject; +import java.util.Locale; +public class LocaleChangeEvent extends EventObject{ + private static final long serialVersionUID = 1L; + + Locale locale; + public LocaleChangeEvent(Object source,Locale locale) { + super(source); + this.locale = locale; + } + public Locale getLocale() { + return locale; + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/LocaleChangeListener.java b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/LocaleChangeListener.java new file mode 100644 index 0000000..3bf470e --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/LocaleChangeListener.java @@ -0,0 +1,17 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.xmlbundle; +import java.util.EventListener; +public interface LocaleChangeListener extends EventListener{ + void localeChanged(LocaleChangeEvent evt); +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/LocaleSelector.java b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/LocaleSelector.java new file mode 100644 index 0000000..d506879 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/LocaleSelector.java @@ -0,0 +1,39 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.xmlbundle; + +import java.util.Locale; + + +/** If you want to change the locales during runtime put a LocaleSelector + in the base-context. Instances of I18nBundle will then register them-self + as {@link LocaleChangeListener LocaleChangeListeners}. Change the locale + with {@link #setLocale} and all bundles will try to load the appropriate resources. + */ +public interface LocaleSelector { + + void addLocaleChangeListener(LocaleChangeListener listener); + + void removeLocaleChangeListener(LocaleChangeListener listener); + + void setLocale(Locale locale); + + Locale getLocale(); + + void setLanguage(String language); + + void setCountry(String country); + + String getLanguage(); + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/DictionaryEntry.java b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/DictionaryEntry.java new file mode 100644 index 0000000..16d9ea6 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/DictionaryEntry.java @@ -0,0 +1,64 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.xmlbundle.impl; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + +class DictionaryEntry { + String key; + Map translations = Collections.synchronizedMap(new TreeMap()); + + public DictionaryEntry(String key) { + this.key = key; + } + public void add(String lang,String value) { + translations.put(lang,value); + } + + public String getKey() { + return key; + } + + public String get(String lang) { + return translations.get(lang); + } + + public String get(String lang,String defaultLang) { + String content = translations.get(lang); + if ( content == null) { + content = translations.get(defaultLang); + } // end of if () + + if ( content == null) { + Iterator it = translations.values().iterator(); + content = it.next(); + } + return content; + } + + public String[] availableLanguages() { + String[] result = new String[translations.keySet().size()]; + Iterator it = translations.keySet().iterator(); + int i = 0; + while ( it.hasNext()) { + result[i++] = it.next(); + } + return result; + } + +} + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/I18nBundleImpl.java b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/I18nBundleImpl.java new file mode 100644 index 0000000..e75b5a1 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/I18nBundleImpl.java @@ -0,0 +1,612 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.xmlbundle.impl; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.net.URL; +import java.text.MessageFormat; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.TreeMap; + +import javax.swing.Icon; +import javax.swing.ImageIcon; + +import org.rapla.components.util.IOUtil; +import org.rapla.components.xmlbundle.I18nBundle; +import org.rapla.components.xmlbundle.LocaleChangeEvent; +import org.rapla.components.xmlbundle.LocaleChangeListener; +import org.rapla.components.xmlbundle.LocaleSelector; +import org.rapla.framework.Configuration; +import org.rapla.framework.DefaultConfiguration; +import org.rapla.framework.Disposable; +import org.rapla.framework.RaplaContext; +import org.rapla.framework.RaplaException; +import org.rapla.framework.logger.Logger; + +/** The default implementation of the xmlbundle component allows reading from + a compiled ResourceBundle as well as directly from the source-xml-file. +

    + Sample Configuration 1: (Resources are loaded from the compiled ResourceBundles) +

    + <resource-bundle id="org.rapla.RaplaResources"/>
    + 
    +

    +

    + Sample Configuration 2: (Resources will be loaded directly from the resource-file) +

    + <resource-bundle id="org.rapla.plugin.periodwizard.WizardResources">
    + <file>/home/christopher/Rapla/src/org/rapla/periodwizard/WizardResources.xml</file>
    + </resource-bundle>
    + 
    +

    +

    + This class looks for a LocaleSelector on the context and registers itself as + a LocaleChangeListener and switches to the new Locale on a LocaleChangeEvent. +

    + @see TranslationParser + @see LocaleSelector + */ + +public class I18nBundleImpl implements I18nBundle, LocaleChangeListener, Disposable +{ + String className; + Locale locale; + Logger logger = null; + LocaleSelectorImpl m_localeSelector; + + final String dictionaryFile; + final RaplaDictionary dict; + + LinkedHashMap packMap = new LinkedHashMap(); + String parentId = null; + class LanguagePack + { + Locale locale; + Map iconCache = Collections.synchronizedMap( new TreeMap() ); + ResourceBundle resourceBundle; + public String getString( String key ) throws MissingResourceException + { + String lang = locale.getLanguage(); + if ( dictionaryFile != null ) + { + String lookup = dict.lookup(key, lang); + if ( lookup == null) + { + throw new MissingResourceException("Entry not found for "+ key, dictionaryFile, key); + } + return lookup; + } + DictionaryEntry entry = dict.getEntry(key); + String string; + if ( entry != null) + { + string = entry.get( lang ); + if ( string == null ) + { + string = resourceBundle.getString( key ); + entry.add(lang, key); + } + } + else + { + string = resourceBundle.getString( key ); + entry = new DictionaryEntry( key); + entry.add(lang, string); + try { + dict.addEntry( entry); + } catch (UniqueKeyException e) { + // we can ignore it here + } + } + return string; + } + + public ImageIcon getIcon( String key ) throws MissingResourceException + { + String iconfile; + try + { + iconfile = getString( key ); + } + catch ( MissingResourceException ex ) + { + getLogger().debug( ex.getMessage() ); //BJO + throw ex; + } + try + { + ImageIcon icon = (ImageIcon) iconCache.get( iconfile ); + if ( icon == null ) + { + icon = new ImageIcon( loadResource( iconfile ), key ); + iconCache.put( iconfile, icon ); + } // end of if () + return icon; + } + catch ( Exception ex ) + { + String message = "Icon " + iconfile + " can't be created: " + ex.getMessage(); + getLogger().error( message ); + throw new MissingResourceException( message, className, key ); + } + } + + private final byte[] loadResource( String fileName ) throws IOException + { + return IOUtil.readBytes( getResourceFromFile( fileName ) ); + } + + private URL getResourceFromFile( String fileName ) throws IOException + { + URL resource = null; + String base; + if ( dictionaryFile == null ) + { + if ( resourceBundle == null) + { + throw new IOException("Resource Bundle for locale " + locale + " is missing while looking up " + fileName); + } + if ( resourceBundle instanceof PropertyResourceBundleWrapper) + { + base = ((PropertyResourceBundleWrapper) resourceBundle).getName(); + } + else + { + base = resourceBundle.getClass().getName(); + } + base = base.substring(0,base.lastIndexOf(".")); + base = base.replaceAll("\\.", "/"); + String file = "/" + base + "/" + fileName; + resource = I18nBundleImpl.class.getResource( file ); + + } + else + { + if ( getLogger().isDebugEnabled() ) + getLogger().debug( "Looking for resourcefile " + fileName + " in classpath "); + + URL resourceBundleURL = getClass().getClassLoader().getResource(dictionaryFile); + if (resourceBundleURL != null) + { + resource = new URL( resourceBundleURL, fileName); + base = resource.getPath(); + } + else + { + base = ( new File( dictionaryFile ) ).getParent(); + if ( base != null) + { + if ( getLogger().isDebugEnabled() ) + getLogger().debug( "Looking for resourcefile " + fileName + " in directory " + base ); + File resourceFile = new File( base, fileName ); + if ( resourceFile.exists() ) + resource = resourceFile.toURI().toURL(); + } + } + } + if ( resource == null ) + throw new IOException( "File '" + + fileName + + "' not found. " + + " in bundle " + + className + + " It must be in the same location as '" + + base + + "'" ); + return resource; + } + } + + /** + * @throws RaplaException when the resource-file is missing or can't be accessed + or can't be parsed + */ + public I18nBundleImpl( RaplaContext context, Configuration config, Logger logger ) throws RaplaException + { + enableLogging( logger ); + Locale locale; + m_localeSelector = (LocaleSelectorImpl) context.lookup( LocaleSelector.class ) ; + if ( m_localeSelector != null ) + { + m_localeSelector.addLocaleChangeListenerFirst( this ); + locale = m_localeSelector.getLocale(); + + } + else + { + locale = Locale.getDefault(); + } + String filePath = config.getChild( "file" ).getValue( null ); + try + { + InputStream resource; + if ( filePath == null ) + { + className = config.getChild( "classname" ).getValue( null ); + if ( className == null ) + { + className = config.getAttribute( "id" ); + } + else + { + className = className.trim(); + } + String resourceFile = "" + className.replaceAll("\\.", "/") + ".xml"; + resource = getClass().getClassLoader().getResourceAsStream(resourceFile); + dictionaryFile = resource != null ? resourceFile : null; + } + else + { + File file = new File( filePath); + getLogger().info( "getting lanaguageResources from " + file.getCanonicalPath() ); + resource = new FileInputStream( file ); + dictionaryFile = filePath; + } + if ( resource != null) + { + dict = new TranslationParser().parse( resource ); + resource.close(); + } + else + { + dict = new RaplaDictionary(locale.getLanguage()); + } + } + catch ( Exception ex ) + { + throw new RaplaException( ex ); + } + setLocale( locale ); + try + { + parentId = getPack(locale).getString( TranslationParser.PARENT_BUNDLE_IDENTIFIER ); + } + catch ( MissingResourceException ex ) + { + } + } + + public String getParentId() + { + return parentId; + } + + public static Configuration createConfig( String resourceFile ) + { + DefaultConfiguration config = new DefaultConfiguration( "component"); + config.setAttribute( "id", resourceFile.toString() ); + return config; + } + + public void dispose() + { + if ( m_localeSelector != null ) + m_localeSelector.removeLocaleChangeListener( this ); + } + + public void localeChanged( LocaleChangeEvent evt ) + { + try + { + setLocale( evt.getLocale() ); + } + catch ( Exception ex ) + { + getLogger().error( "Can't set new locale " + evt.getLocale(), ex ); + } + } + + public void enableLogging( Logger logger ) + { + this.logger = logger; + } + + protected Logger getLogger() + { + return logger; + } + + public String format( String key, Object obj1 ) + { + Object[] array1 = new Object[1]; + array1[0] = obj1; + return format( key, array1 ); + } + + public String format( String key, Object obj1, Object obj2 ) + { + Object[] array2 = new Object[2]; + array2[0] = obj1; + array2[1] = obj2; + return format( key, array2 ); + } + + public String format( String key, Object... obj ) + { + MessageFormat msg = new MessageFormat( getString( key ) ); + return msg.format( obj ); + } + + public ImageIcon getIcon( String key ) throws MissingResourceException + { + ImageIcon icon = getPack(getLocale()).getIcon( key); + return icon; + } + + public Locale getLocale() + { + if ( locale == null ) + throw new IllegalStateException( "Call setLocale first!" ); + return locale; + } + + public String getLang() + { + if ( locale == null ) + throw new IllegalStateException( "Call setLocale first!" ); + return locale.getLanguage(); + } + + public String getString( String key ) throws MissingResourceException + { + if ( locale == null ) + throw new IllegalStateException( "Call setLocale first!" ); + return getString(key, locale); + } + + public String getString( String key, Locale locale) throws MissingResourceException + { + LanguagePack pack = getPack(locale); + return pack.getString(key); + } + + +// /* replaces XHTML with HTML because swing can't display proper XHTML*/ +// String filterXHTML( String text ) +// { +// if ( text.indexOf( "
    " ) >= 0 ) +// { +// return applyXHTMLFilter( text ); +// } +// else +// { +// return text; +// } // end of else +// } + +// public static String replaceAll( String text, String token, String with ) +// { +// StringBuffer buf = new StringBuffer(); +// int i = 0; +// int lastpos = 0; +// while ( ( i = text.indexOf( token, lastpos ) ) >= 0 ) +// { +// if ( i > 0 ) +// buf.append( text.substring( lastpos, i ) ); +// buf.append( with ); +// i = ( lastpos = i + token.length() ); +// } // end of if () +// buf.append( text.substring( lastpos, text.length() ) ); +// return buf.toString(); +// } +// +// private String applyXHTMLFilter( String text ) +// { +// return replaceAll( text, "
    ", "

    " ); +// } + + public void setLocale( Locale locale ) + { + this.locale = locale; + getLogger().debug( "Locale changed to " + locale ); + try + { + getPack(locale); + } + catch (MissingResourceException ex) + { + getLogger().error(ex.getMessage(), ex); + } + } + + private LanguagePack getPack(Locale locale) throws MissingResourceException { + LanguagePack pack = packMap.get(locale); + if (pack != null) + { + return pack; + } + synchronized ( packMap ) + { + // again, now with synchronization + pack = packMap.get(locale); + if (pack != null) + { + return pack; + } + pack = new LanguagePack(); + pack.locale = locale; + if ( dictionaryFile == null ) + { + pack.resourceBundle = new ResourceBundleLoader().loadResourceBundle( className, locale ); + } + packMap.put( locale, pack); + return pack; + } + } + +} + +class ResourceBundleLoader +{ + + /** this method imitates the orginal + * ResourceBundle.getBundle(String className,Locale + * locale) which causes problems when the locale is changed + * to the base locale (english). For a full description see + * ResourceBundle.getBundle(String className) in the java-api.*/ + public ResourceBundle loadResourceBundle( String className, Locale locale ) throws MissingResourceException + { + String tries[] = new String[7]; + StringBuffer buf = new StringBuffer(); + tries[6] = className; + buf.append( className ); + if ( locale.getLanguage().length() > 0 ) + { + buf.append( '_' ); + buf.append( locale.getLanguage() ); + tries[2] = buf.toString(); + } + if ( locale.getCountry().length() > 0 ) + { + buf.append( '_' ); + buf.append( locale.getCountry() ); + tries[1] = buf.toString(); + } + if ( locale.getVariant().length() > 0 ) + { + buf.append( '_' ); + buf.append( locale.getVariant() ); + tries[0] = buf.toString(); + } + buf.delete( className.length(), buf.length() - 1 ); + Locale defaultLocale = Locale.getDefault(); + if ( defaultLocale.getLanguage().length() > 0 ) + { + buf.append( defaultLocale.getLanguage() ); + tries[5] = buf.toString(); + } + if ( defaultLocale.getCountry().length() > 0 ) + { + buf.append( '_' ); + buf.append( defaultLocale.getCountry() ); + tries[4] = buf.toString(); + } + if ( defaultLocale.getVariant().length() > 0 ) + { + buf.append( '_' ); + buf.append( defaultLocale.getVariant() ); + tries[3] = buf.toString(); + } + + ResourceBundle bundle = null; + for ( int i = 0; i < tries.length; i++ ) + { + if ( tries[i] == null ) + continue; + bundle = loadBundle( tries[i] ); + if ( bundle != null ) + { + loadParent( tries, i, bundle ); + return bundle; + } + } + throw new MissingResourceException( "'" + className + "' not found. The resource-file is missing.", className, + "" ); + } + + private ResourceBundle loadBundle( String name ) + { + InputStream io = null; + try + { + String pathName = getPropertyFileNameFromClassName( name ); + io = this.getClass().getResourceAsStream( pathName ); + if ( io != null ) + { + return new PropertyResourceBundleWrapper(io , name); + } + ResourceBundle bundle = (ResourceBundle) this.getClass().getClassLoader().loadClass( name ).newInstance(); + return bundle; + } + catch ( Exception ex ) + { + return null; + } + catch ( ClassFormatError ex ) + { + return null; + } + finally + { + if ( io != null) + { + try { + io.close(); + } catch (IOException e) { + return null; + } + } + } + } + + private void loadParent( String[] tries, int i, ResourceBundle bundle ) + { + ResourceBundle parent = null; + if ( i == 0 || i == 3 ) + { + parent = loadBundle( tries[i++] ); + if ( parent != null ) + setParent( bundle, parent ); + bundle = parent; + } + if ( i == 1 || i == 4 ) + { + parent = loadBundle( tries[i++] ); + if ( parent != null ) + setParent( bundle, parent ); + bundle = parent; + } + if ( i == 2 || i == 5 ) + { + parent = loadBundle( tries[6] ); + if ( parent != null ) + setParent( bundle, parent ); + } + } + + private void setParent( ResourceBundle bundle, ResourceBundle parent ) + { + try + { + Method method = bundle.getClass().getMethod( "setParent", new Class[] + { ResourceBundle.class } ); + method.invoke( bundle, new Object[] + { parent } ); + } + catch ( Exception ex ) + { + } + } + + private String getPropertyFileNameFromClassName( String classname ) + { + StringBuffer result = new StringBuffer( classname ); + for ( int i = 0; i < result.length(); i++ ) + { + if ( result.charAt( i ) == '.' ) + result.setCharAt( i, '/' ); + } + result.insert( 0, '/' ); + result.append( ".properties" ); + return result.toString(); + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/LocaleSelectorImpl.java b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/LocaleSelectorImpl.java new file mode 100644 index 0000000..0e0d2fa --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/LocaleSelectorImpl.java @@ -0,0 +1,85 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.components.xmlbundle.impl; + +import java.util.Locale; +import java.util.Vector; + +import org.rapla.components.xmlbundle.LocaleChangeEvent; +import org.rapla.components.xmlbundle.LocaleChangeListener; +import org.rapla.components.xmlbundle.LocaleSelector; + + +/** If you want to change the locales during runtime put a LocaleSelector + in the base-context. Instances of {@link I18nBundleImpl} will then register them-self + as {@link LocaleChangeListener LocaleChangeListeners}. Change the locale + with {@link #setLocale} and all bundles will try to load the appropriate resources. + */ +public class LocaleSelectorImpl implements LocaleSelector { + Locale locale; + Vector localeChangeListeners = new Vector(); + + public LocaleSelectorImpl() { + locale = Locale.getDefault(); + } + + public void addLocaleChangeListener(LocaleChangeListener listener) { + localeChangeListeners.add(listener); + } + public void removeLocaleChangeListener(LocaleChangeListener listener) { + localeChangeListeners.remove(listener); + } + + public void setLocale(Locale locale) { + this.locale = locale; + fireLocaleChanged(); + } + + public Locale getLocale() { + return this.locale; + } + + public LocaleChangeListener[] getLocaleChangeListeners() { + return localeChangeListeners.toArray(new LocaleChangeListener[]{}); + } + + public void setLanguage(String language) { + setLocale(new Locale(language,locale.getCountry())); + } + + public void setCountry(String country) { + setLocale(new Locale(locale.getLanguage(),country)); + } + + public String getLanguage() { + return locale.getLanguage(); + } + + protected void fireLocaleChanged() { + if (localeChangeListeners.size() == 0) + return; + LocaleChangeListener[] listeners = getLocaleChangeListeners(); + LocaleChangeEvent evt = new LocaleChangeEvent(this,getLocale()); + for (int i=0;i lookup; + String name; + + static Charset charset = Charset.forName("UTF-8"); + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public PropertyResourceBundleWrapper(InputStream stream,String name) throws IOException { + Properties properties = new Properties(); + properties.load(new InputStreamReader(stream, charset)); + lookup = new LinkedHashMap(properties); + this.name = name; + } + + public String getName() + { + return name; + } + + // We make the setParent method public, so that we can use it in I18nImpl + public void setParent(ResourceBundle parent) { + super.setParent(parent); + } + + // Implements java.util.ResourceBundle.handleGetObject; inherits javadoc specification. + public Object handleGetObject(String key) { + if (key == null) { + throw new NullPointerException(); + } + return lookup.get(key); + } + + /** + * Returns an Enumeration of the keys contained in + * this ResourceBundle and its parent bundles. + * + * @return an Enumeration of the keys contained in + * this ResourceBundle and its parent bundles. + * @see #keySet() + */ + public Enumeration getKeys() { + ResourceBundle parent = this.parent; + Set set = new LinkedHashSet(lookup.keySet()); + if ( parent != null) + { + set.addAll( parent.keySet()); + } + Vector vector = new Vector(set); + Enumeration enum1 = vector.elements(); + return enum1; + } + + /** + * Returns a Set of the keys contained + * only in this ResourceBundle. + * + * @return a Set of the keys contained only in this + * ResourceBundle + * @since 1.6 + * @see #keySet() + */ + protected Set handleKeySet() { + return lookup.keySet(); + } + + // ==================privates==================== + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/RaplaDictionary.java b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/RaplaDictionary.java new file mode 100644 index 0000000..0d2b885 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/RaplaDictionary.java @@ -0,0 +1,72 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.xmlbundle.impl; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; +import java.util.TreeMap; + + + +class RaplaDictionary { + Map entries = new TreeMap(); + Collection availableLang = new ArrayList(); + String defaultLang; + + public RaplaDictionary(String defaultLang) { + this.defaultLang = defaultLang; + } + + public void addEntry(DictionaryEntry entry) throws UniqueKeyException { + if ( entries.get(entry.getKey()) != null) { + throw new UniqueKeyException("Key '" + entry.getKey() + "' already in map."); + } // end of if () + + String[] lang = entry.availableLanguages(); + for ( int i = 0; i getEntries() { + return entries.values(); + } + + public String getDefaultLang() { + return defaultLang; + } + + public String[] getAvailableLanguages() { + return availableLang.toArray(new String[0]); + } + + public String lookup(String key,String lang) { + DictionaryEntry entry = getEntry(key); + if ( entry != null) { + return entry.get(lang,defaultLang); + } else { + return null; + } // end of else + } + + public DictionaryEntry getEntry(String key) { + return entries.get(key); + } + +} + + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/ResourceFileGenerator.java b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/ResourceFileGenerator.java new file mode 100644 index 0000000..6f072dc --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/ResourceFileGenerator.java @@ -0,0 +1,293 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.xmlbundle.impl; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Properties; +import java.util.Set; +import java.util.Stack; +import java.util.Vector; + +import org.rapla.framework.ConfigurationException; +import org.rapla.framework.logger.ConsoleLogger; +import org.rapla.framework.logger.Logger; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + + + + +class ResourceFileGenerator { + public static final String encoding = "UTF-8"; + + static Logger log = new ConsoleLogger( ConsoleLogger.LEVEL_INFO ); + boolean writeProperties = true; + + public void transform(RaplaDictionary dict + ,String packageName + ,String classPrefix + ,File destDir + ) + throws IOException + { + String[] languages = dict.getAvailableLanguages(); + for (String lang:languages) { + String className = classPrefix; + if (!lang.equals(dict.getDefaultLang())) + { + className += "_" + lang; + } + String ending = writeProperties ? ".properties" : ".java"; + File file = new File(destDir, className + ending); + + PrintWriter w = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),encoding))); + if ( writeProperties) + { + + Properties properties = new Properties(); + Iterator it = dict.getEntries().iterator(); + while ( it.hasNext()) { + DictionaryEntry entry = it.next(); + String key = entry.getKey(); + String value = entry.get(lang); + if ( value != null) + { + properties.put(key, value); + } + } + @SuppressWarnings("serial") + Properties temp = new Properties() + { + @SuppressWarnings({ "rawtypes", "unchecked" }) + public synchronized Enumeration keys() { + Enumeration keysEnum = super.keys(); + Vector keyList = new Vector(); + while(keysEnum.hasMoreElements()){ + keyList.add(keysEnum.nextElement()); + } + Collections.sort(keyList); + return keyList.elements(); + } + }; + temp.putAll( properties); + String comment = packageName + "." + className + "_" + lang; + temp.store(w, comment); + } + else + { + generateJavaHeader(w,packageName); + generateJavaContent(w,dict, className, lang); + } + w.flush(); + w.close(); + + + } + } + + +// public void transformSingleLanguage(RaplaDictionary dict +// ,String packageName +// ,String classPrefix +// ,String lang +// ) { +// String className = classPrefix + "_" + lang; +// w = new PrintWriter(System.out); +// generateHeader(packageName); +// generateContent(dict,className, lang); +// w.flush(); +// } + + public static String toPackageName(String pathName) { + StringBuffer buf = new StringBuffer(); + char[] c =pathName.toCharArray(); + for (int i=0;i0 && i it = dict.getEntries().iterator(); + while ( it.hasNext()) { + DictionaryEntry entry = it.next(); + String value = entry.get(lang); + if (value != null) { + String content = convertToJava(value); + w.println(" , { \"" + entry.getKey() + "\",\"" + content + "\"}"); + } + } + + w.println(" };"); + w.println("}"); + } + + static public String byteToHex(byte b) { + // Returns hex String representation of byte b + char hexDigit[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + char[] array = { hexDigit[(b >> 4) & 0x0f], hexDigit[b & 0x0f] }; + return new String(array); + } + + static public String charToHex(char c) { + // Returns hex String representation of char c + byte hi = (byte) (c >>> 8); + byte lo = (byte) (c & 0xff); + return byteToHex(hi) + byteToHex(lo); + } + + private String convertToJava(String text) { + StringBuffer result = new StringBuffer(); + for ( int i = 0;i< text.length();i++) { + char c = text.charAt(i); + + switch ( c) { + case '\n': // LineBreaks + result.append("\" \n + \""); + break; + case '\\': // \ + result.append("\\\\"); + break; + case '\"': // " + result.append("\\\""); + break; + default: + if ( c > 127) { + result.append("\\u" + charToHex(c)); + } else { + result.append(c); + } // end of else + break; + } // end of switch () + } // end of for () + return result.toString(); + } + + public static final String USAGE = new String( "Usage : \n" + + "PATH_TO_SOURCES [DESTINATION_PATH]\n" + + "Example usage under windows:\n" + + "java -classpath build\\classes " + + "org.rapla.components.xmlbundle.ResourceFileGenerator " + + "src \n" ); + + public static void processDir( String srcDir, String destDir ) throws IOException, SAXException, + ConfigurationException + { + TranslationParser parser = new TranslationParser(); + ResourceFileGenerator generator = new ResourceFileGenerator(); + Set languages = new HashSet(); + Stack stack = new Stack(); + File topDir = new File( srcDir ); + stack.push( topDir ); + while ( !stack.empty() ) + { + File file = stack.pop(); + if ( file.isDirectory() ) + { + // System.out.println("Checking Dir: " + file.getName()); + File[] files = file.listFiles(); + for ( int i = 0; i < files.length; i++ ) + stack.push( files[i] ); + } + else + { + // System.out.println("Checking File: " + file.getName()); + if ( file.getName().endsWith( "Resources.xml" ) ) + { + String absolut = file.getAbsolutePath(); + System.out.println( "Transforming source:" + file ); + String relativePath = absolut.substring( topDir.getAbsolutePath().length() ); + String prefix = file.getName().substring( 0, file.getName().length() - "Resources.xml".length() ); + String pathName = relativePath.substring( 0, relativePath.indexOf( file.getName() ) ); + RaplaDictionary dict = parser.parse( file.toURI().toURL().toExternalForm() ); + + File dir = new File( destDir, pathName ); + System.out.println( "destination:" + dir ); + dir.mkdirs(); + + String packageName = ResourceFileGenerator.toPackageName( pathName ); + generator.transform( dict, packageName, prefix + "Resources", dir ); + String[] langs = dict.getAvailableLanguages(); + for ( int i = 0; i < langs.length; i++ ) + languages.add( langs[i] ); + } + } + } + } + + public static void main( String[] args ) + { + try + { + if ( args.length < 1 ) + { + System.out.println( USAGE ); + return; + } // end of if () + + String sourceDir = args[0]; + String destDir = ( args.length > 1 ) ? args[1] : sourceDir; + processDir( sourceDir, destDir ); + + } + catch ( SAXParseException ex ) + { + log.error( "Line:" + ex.getLineNumber() + " Column:" + ex.getColumnNumber() + " " + ex.getMessage(), ex ); + System.exit( 1 ); + } + catch ( Throwable e ) + { + log.error( e.getMessage(), e ); + System.exit( 1 ); + } + } // end of main () + +} + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/TranslationParser.java b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/TranslationParser.java new file mode 100644 index 0000000..eaf5239 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/TranslationParser.java @@ -0,0 +1,312 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.xmlbundle.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import org.rapla.components.util.Assert; +import org.rapla.components.util.IOUtil; +import org.rapla.components.util.xml.XMLReaderAdapter; +import org.rapla.framework.ConfigurationException; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.DefaultHandler; + +/** This class reads *Resources.xml files and generates + the appropriate ResourceBundle java-files. +
    + Usage :
    + org.rapla.components.xmlbundle.TranslationParser PATH_TO_SOURCES [DESTINATION_PATH]
    +
    + Note: a xml-parser must be on your classpath.
    +
    + Example usage under windows:
    + java -classpath lib\saxon.jar;lib\fortress.jar;build\classes org.rapla.components.xmlbundle.TranslationParser src
    + 
    + + */ +public class TranslationParser extends DefaultHandler +{ + RaplaDictionary dict; + DictionaryEntry currentEntry = null; + String currentLang = null; + String defaultLang = null; + String currentIconSrc = null; + + int level = 0; + + // used to store the nested content in the translation element + StringBuffer charBuffer; + XMLReader xmlReader; + /** The translation parser will add an extra identifer {$i18nbundle_parent$} to + the translation table if a parentbundle is specified. + */ + public final static String PARENT_BUNDLE_IDENTIFIER = "{$i18nbundle_parent$}"; + DefaultHandler handler = new DefaultHandler() + { + public InputSource resolveEntity( String publicId, String systemId ) throws SAXException + { + if ( systemId.endsWith( "resources.dtd" ) ) + { + try + { + URL resource = getClass().getResource( "/org/rapla/components/xmlbundle/resources.dtd" ); + Assert.notNull( resource, "resources.dtd not found on classpath" ); + return new InputSource( IOUtil.getInputStream( resource ) ); + } + catch ( IOException ex ) + { + throw new SAXException( ex ); + } + } + else + { + // use the default behaviour + try + { + return super.resolveEntity( publicId, systemId ); + } + catch ( SAXException ex ) + { + throw ex; + } + catch ( Exception ex ) + { + throw new SAXException( ex ); + } + } + } + + public void startElement( String uri, String name, String qName, Attributes atts ) throws SAXException + { +// if ( log.isDebugEnabled() ) +// log.debug( indent() + "Start element: " + qName + "(" + name + ")" ); + + level: + { + if ( name.equals( "resources" ) ) + { + String defaultLang = atts.getValue( "", "default" ); + String parentDict = atts.getValue( "", "parent" ); + dict = new RaplaDictionary( defaultLang ); + if ( parentDict != null && parentDict.trim().length() > 0 ) + { + DictionaryEntry entry = new DictionaryEntry( PARENT_BUNDLE_IDENTIFIER ); + entry.add( "en", parentDict.trim() ); + try + { + dict.addEntry( entry ); + } + catch ( UniqueKeyException ex ) + { + //first entry must be unique + } + } + break level; + } + + if ( name.equals( "entry" ) ) + { + String key = atts.getValue( "", "key" ); + currentEntry = new DictionaryEntry( key ); + break level; + } + + if ( name.equals( "text" ) ) + { + currentLang = atts.getValue( "", "lang" ); + if ( currentLang == null ) + currentLang = dict.getDefaultLang(); + charBuffer = new StringBuffer(); + break level; + } + + if ( name.equals( "icon" ) ) + { + currentLang = atts.getValue( "", "lang" ); + if ( currentLang == null ) + currentLang = dict.getDefaultLang(); + currentIconSrc = atts.getValue( "", "src" ); + charBuffer = new StringBuffer(); + break level; + } + + // copy startag + if ( charBuffer != null ) + { + copyStartTag( name, atts ); + } + } + level++; + } + + public void endElement( String uri, String name, String qName ) throws SAXException + { + level--; +// if ( log.isDebugEnabled() ) +// log.debug( indent() + "End element: " + qName + "(" + name + ")" ); + + level: + { + if ( name.equals( "icon" ) ) + { + if ( currentIconSrc != null ) + currentEntry.add( currentLang, currentIconSrc ); + break level; + } + + if ( name.equals( "text" ) ) + { + removeWhiteSpaces( charBuffer ); + currentEntry.add( currentLang, charBuffer.toString() ); + break level; + } + + if ( name.equals( "entry" ) ) + { + try + { + dict.addEntry( currentEntry ); + } + catch ( UniqueKeyException e ) + { + throw new SAXException( e.getMessage() ); + } // end of try-catch + currentEntry = null; + break level; + } + + // copy endtag + if ( charBuffer != null ) + { + copyEndTag( name ); + } // end of if () + } + } + + public void characters( char ch[], int start, int length ) + { + // copy nested content + if ( charBuffer != null ) + { + charBuffer.append( ch, start, length ); + } // end of if () + } + }; + + TranslationParser() throws ConfigurationException + { + super(); + try + { + xmlReader = XMLReaderAdapter.createXMLReader( false ); + xmlReader.setContentHandler( handler ); + xmlReader.setErrorHandler( handler ); + xmlReader.setDTDHandler( handler ); + xmlReader.setEntityResolver( handler ); + } + catch ( SAXException ex ) + { + if ( ex.getException() != null ) + { + throw new ConfigurationException( "", ex.getException() ); + } + else + { + throw new ConfigurationException( "", ex ); + } // end of else + } + } + + RaplaDictionary parse( InputStream in ) throws IOException, SAXException + { + dict = null; + xmlReader.parse( new InputSource( in ) ); + checkDict(); + return dict; + } + + RaplaDictionary parse( String systemID ) throws IOException, SAXException + { + dict = null; + xmlReader.parse( systemID ); + checkDict(); + return dict; + } + + private void checkDict() throws IOException + { + if ( dict == null ) + { + throw new IOException( "Dictionary file empty " ); + } + } + + private void copyStartTag( String name, Attributes atts ) + { + charBuffer.append( '<' ); + charBuffer.append( name ); + for ( int i = 0; i < atts.getLength(); i++ ) + { + charBuffer.append( ' ' ); + charBuffer.append( atts.getLocalName( i ) ); + charBuffer.append( '=' ); + charBuffer.append( '\"' ); + charBuffer.append( atts.getValue( i ) ); + charBuffer.append( '\"' ); + } + charBuffer.append( '>' ); + } + + private void copyEndTag( String name ) + { + if ( ( charBuffer != null ) + && ( charBuffer.length() > 0 ) + && ( charBuffer.charAt( charBuffer.length() - 1 ) == '>' ) ) + { + // --> + charBuffer.insert( charBuffer.length() - 1, "/" ); + } + else + { + // + charBuffer.append( "" ); + } // end of else + + } + + private void removeWhiteSpaces( StringBuffer buf ) + { + for ( int i = 1; i < buf.length(); i++ ) + { + if ( ( buf.charAt( i ) == ' ' ) && ( buf.charAt( i - 1 ) == ' ' ) ) + buf.deleteCharAt( --i ); + } // end of for () + } + + /** @deprecated moved to {@link ResourceFileGenerator}*/ + @Deprecated + public static void main( String[] args ) + { + ResourceFileGenerator.main(args); + } + + + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/UniqueKeyException.java b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/UniqueKeyException.java new file mode 100644 index 0000000..71f61bc --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/impl/UniqueKeyException.java @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.components.xmlbundle.impl; + +/** thrown by the RaplaDictionary when a duplicated entry is found */ +class UniqueKeyException extends Exception { + private static final long serialVersionUID = 1L; + + public UniqueKeyException(String text) { + super(text); + } +} + diff --git a/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/package.html b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/package.html new file mode 100644 index 0000000..9a7f540 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/package.html @@ -0,0 +1,10 @@ + +

    Components for storing locale-specific resources in xml-files. +Java Resource-Bundles can be created automatically. +

    +

    +For adding a new language to Rapla take a look at resources.xml. +

    +@see rapla.sourceforge.net + + diff --git a/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/resources.dtd b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/resources.dtd new file mode 100644 index 0000000..60a5155 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/components/xmlbundle/resources.dtd @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/rapla-source-1.8.2/src/org/rapla/entities/Annotatable.java b/rapla-source-1.8.2/src/org/rapla/entities/Annotatable.java new file mode 100644 index 0000000..0fae151 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/Annotatable.java @@ -0,0 +1,28 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities; + + + +public interface Annotatable { + void setAnnotation(String key, String annotation) throws IllegalAnnotationException; + // String getAnnotation(Class annotation); + // String getAnnotation(Class annotation, T defaultValue); + String getAnnotation(String key); + String getAnnotation(String key, String defaultValue); + String[] getAnnotationKeys(); +} + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/Category.java b/rapla-source-1.8.2/src/org/rapla/entities/Category.java new file mode 100644 index 0000000..e6b4f85 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/Category.java @@ -0,0 +1,65 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities; +import java.util.Locale; + +/** Hierarchical categorization of information. + * Categories can be used as attribute values. + * @see org.rapla.entities.dynamictype.Attribute + */ +public interface Category extends MultiLanguageNamed,Entity,Timestamp, Annotatable, Comparable +{ + final RaplaType TYPE = new RaplaType(Category.class, "category"); + final String SUPER_CATEGORY_ID = TYPE.getLocalName() + "_0"; + /** add a sub-category. + * This category is set as parent of the passed category.*/ + void addCategory(Category category); + /** remove a sub-category */ + void removeCategory(Category category); + /** returns all subcategories */ + Category[] getCategories(); + /** returns the subcategory with the specified key. + * null if subcategory was not found. */ + Category getCategory(String key); + /** find a sub-category in that equals the specified category. */ + Category findCategory(Category copy); + /** Returns the parent of this category or null if the category has no parent.*/ + Category getParent(); + /** returns true if the passed category is a direct child of this category */ + boolean hasCategory(Category category); + /** set the key of the category. The can be used in the getCategory() method for lookup. */ + void setKey(String key); + /** returns the key of the category */ + String getKey(); + /** returns true this category is an ancestor + * (parent or parent of parent, ...) of the specified + * category */ + boolean isAncestorOf(Category category); + /** returns the path form the rootCategory to this category. + * Path elements are the category-names in the selected locale separated + * with the / operator. If the rootCategory is null the path will be calculated + * to the top-most parent. + * Example: area51/aliencell + */ + String getPath(Category rootCategory,Locale locale); + + /** returns the max depth of the cildrens */ + int getDepth(); + + /** returns the number of ancestors. + * (How many Time you must call getParent() until you receive null) */ + int getRootPathLength(); + + Category[] CATEGORY_ARRAY = new Category[0]; + +} diff --git a/rapla-source-1.8.2/src/org/rapla/entities/CategoryAnnotations.java b/rapla-source-1.8.2/src/org/rapla/entities/CategoryAnnotations.java new file mode 100644 index 0000000..83332b7 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/CategoryAnnotations.java @@ -0,0 +1,29 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities; + +public interface CategoryAnnotations{ + String KEY_NAME_COLOR="color"; +} + + + + + + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/DependencyException.java b/rapla-source-1.8.2/src/org/rapla/entities/DependencyException.java new file mode 100644 index 0000000..4b57aee --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/DependencyException.java @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities; +import java.util.Arrays; +import java.util.Collection; + +import org.rapla.framework.RaplaException; + +public class DependencyException extends RaplaException { + private static final long serialVersionUID = 1L; + + Collection dependentObjects; + public DependencyException(String message,String[] dependentObjectsNames) { + this(message, Arrays.asList(dependentObjectsNames)); + } + + public DependencyException(String message,Collection dependentObjectsNames) { + super(message); + this.dependentObjects = dependentObjectsNames ; + } + + + public Collection getDependencies() { + return dependentObjects; + } +} + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/Entity.java b/rapla-source-1.8.2/src/org/rapla/entities/Entity.java new file mode 100644 index 0000000..0d55540 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/Entity.java @@ -0,0 +1,48 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities; + + +public interface Entity extends RaplaObject { + /** returns true, if the passed object is an instance of Entity + * and has the same id as the object. If both Entities have + * no ids, the == operator will be applied. + */ + + String getId(); + + boolean isIdentical(Entity id2); + + /** @deprecated as of rapla 1.8 there can be multiple persistant versions of an object. You can still use isReadOnly to test if the object is editable + * returns if the instance of the entity is persisant and the cache or just a local copy. + * Persistant objects are usably not editable and are updated in a multiuser system. + * Persistant instances with the same id should therefore have the same content and + * persistant1.isIdentical(persistant2) implies persistant1 == persistant2. + * A non persistant instance has never the same reference as the persistant entity with the same id. + * persistant1.isIdentical(nonPersitant1) implies persistant1 != nonPersistant2. + * As + */ + @Deprecated + boolean isPersistant(); + + boolean isReadOnly(); + + public static Entity[] ENTITY_ARRAY = new Entity[0]; +} + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/EntityNotFoundException.java b/rapla-source-1.8.2/src/org/rapla/entities/EntityNotFoundException.java new file mode 100644 index 0000000..5596970 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/EntityNotFoundException.java @@ -0,0 +1,41 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities; +import org.rapla.framework.RaplaException; +public class EntityNotFoundException extends RaplaException { + private static final long serialVersionUID = 1L; + Comparable id; + + public EntityNotFoundException(String text) + { + this(text, null); + } + + public EntityNotFoundException(String text, Comparable id) + { + super(text); + this.id = id; + } + + public Comparable getId() + { + return id; + } +} + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/IllegalAnnotationException.java b/rapla-source-1.8.2/src/org/rapla/entities/IllegalAnnotationException.java new file mode 100644 index 0000000..33687bf --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/IllegalAnnotationException.java @@ -0,0 +1,33 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities; +import org.rapla.framework.RaplaException; + +public class IllegalAnnotationException extends RaplaException { + private static final long serialVersionUID = 1L; + public IllegalAnnotationException(String text) + { + super(text); + } + public IllegalAnnotationException(String text, Exception ex) + { + super(text, ex); + } +} + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/LastChangedTimestamp.java b/rapla-source-1.8.2/src/org/rapla/entities/LastChangedTimestamp.java new file mode 100644 index 0000000..3112e18 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/LastChangedTimestamp.java @@ -0,0 +1,10 @@ +package org.rapla.entities; + +import java.util.Date; + +public interface LastChangedTimestamp { + + /** returns the date of last change of the object. */ + public abstract Date getLastChanged(); + +} diff --git a/rapla-source-1.8.2/src/org/rapla/entities/MultiLanguageName.java b/rapla-source-1.8.2/src/org/rapla/entities/MultiLanguageName.java new file mode 100644 index 0000000..a0f73ff --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/MultiLanguageName.java @@ -0,0 +1,116 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + + + + + +/** Some entities (especially dynamic-types and attributes) + can have multiple names to allow easier reuse of created schemas or + support for multi-language-environments. + @see MultiLanguageNamed +*/ +public class MultiLanguageName implements java.io.Serializable { + // Don't forget to increase the serialVersionUID when you change the fields + private static final long serialVersionUID = 1; + Map mapLocales = new TreeMap(); + transient private boolean readOnly; + + public MultiLanguageName(String language,String translation) { + setName(language,translation); + } + + public MultiLanguageName(String[][] data) { + for (int i=0;i it = mapLocales.values().iterator(); + if (it.hasNext()) + result = it.next(); + } + if (result == null) { + result = ""; + } + return result; + } + + public void setName(String language,String translation) { + checkWritable(); + setNameWithoutReadCheck(language, translation); + } + + private void checkWritable() { + if ( isReadOnly() ) + throw new ReadOnlyException("Can't modify this multilanguage name."); + } + + public void setTo(MultiLanguageName newName) { + checkWritable(); + mapLocales = new TreeMap(newName.mapLocales); + } + + public Collection getAvailableLanguages() { + return mapLocales.keySet(); + } + + public Object clone() { + MultiLanguageName newName= new MultiLanguageName(); + newName.mapLocales.putAll(mapLocales); + return newName; + } + + public String toString() { + return getName("en"); + } + + @Deprecated + public void setNameWithoutReadCheck(String language, String translation) { + if (translation != null && !translation.trim().equals("")) { + mapLocales.put(language,translation.trim()); + } else { + mapLocales.remove(language); + } + } +} + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/MultiLanguageNamed.java b/rapla-source-1.8.2/src/org/rapla/entities/MultiLanguageNamed.java new file mode 100644 index 0000000..8c9f5d9 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/MultiLanguageNamed.java @@ -0,0 +1,25 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities; + + + + +/* @see MultiLanguageName */ +public interface MultiLanguageNamed extends Named { + MultiLanguageName getName(); +} + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/Named.java b/rapla-source-1.8.2/src/org/rapla/entities/Named.java new file mode 100644 index 0000000..ae32ac6 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/Named.java @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities; +import java.util.Locale; + +public interface Named { + String getName(Locale locale); +} + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/NamedComparator.java b/rapla-source-1.8.2/src/org/rapla/entities/NamedComparator.java new file mode 100644 index 0000000..62dd1f9 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/NamedComparator.java @@ -0,0 +1,42 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities; +import java.text.Collator; +import java.util.Comparator; +import java.util.Locale; + +import org.rapla.components.util.Assert; + +public class NamedComparator implements Comparator { + Locale locale; + Collator collator; + public NamedComparator(Locale locale) { + this.locale = locale; + Assert.notNull( locale ); + collator = Collator.getInstance(locale); + } + public int compare(Named o1,Named o2) { + if ( o1.equals(o2)) return 0; + + Named r1 = o1; + Named r2 = o2; + int result = collator.compare( + r1.getName(locale) + ,r2.getName(locale) + ); + if ( result !=0 ) + return result; + else + return (o1.hashCode() < o2.hashCode()) ? -1 : 1; + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/entities/Ownable.java b/rapla-source-1.8.2/src/org/rapla/entities/Ownable.java new file mode 100644 index 0000000..e73d6a1 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/Ownable.java @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities; + + +/**Should be implemented by objects which can be uniquely associated with a User. */ +public interface Ownable { + void setOwner(User owner); + User getOwner(); + String getOwnerId(); +} + + + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/RaplaObject.java b/rapla-source-1.8.2/src/org/rapla/entities/RaplaObject.java new file mode 100644 index 0000000..fc106d4 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/RaplaObject.java @@ -0,0 +1,35 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities; + + +/**This interface is a marker to distinct the different rapla classes + * like Reservation, Allocatable and Category. + * It is something like the java instanceof keyword. But it must be unique for each + * class. This type-information is for examle used for mapping the correct storage-, + * editing- mechanism to the class. + */ +public interface RaplaObject extends Cloneable { + public static final String[] EMPTY_STRING_ARRAY = new String[0]; + + RaplaType getRaplaType(); + + T clone(); +} + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/RaplaType.java b/rapla-source-1.8.2/src/org/rapla/entities/RaplaType.java new file mode 100644 index 0000000..9d120c3 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/RaplaType.java @@ -0,0 +1,135 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.rapla.framework.RaplaException; + +/** + * Enumeration Pattern for all Rapla objects. You should not instanciate Objects of this type, + * there is only one instance of RaplaType for each class of objects. You can get it via + * the object interface. E.g. Reservation.TYPE or Allocatable.TYPE + */ +public class RaplaType { + + private Class type; + private String localname; + private Character firstLetter; + private static Map,RaplaType> registeredTypes = new HashMap,RaplaType>(); + private static Map registeredTypeNames = new HashMap(); + + public RaplaType(Class clazz, String localname) { +// @SuppressWarnings("unchecked") +// Class clazz2 = clazz; + this.type = clazz; + this.localname = localname; + firstLetter = localname.charAt( 0); + if ( registeredTypes == null) + { + registeredTypes = new HashMap,RaplaType>(); + registeredTypeNames = new HashMap(); + } + if ( registeredTypes.get( clazz ) != null) { + throw new IllegalStateException( "Type already registered"); + } + @SuppressWarnings("unchecked") + Class casted = (Class) type; + registeredTypes.put( casted, this); + registeredTypeNames.put( localname, this); + } + + public RaplaType(Class clazz, String localname, Character firstLetter) { + this(clazz, localname); + this.firstLetter = firstLetter; + } + + static public RaplaType find( String typeName) throws RaplaException + { + RaplaType raplaType = registeredTypeNames.get( typeName); + if (raplaType != null) + { + return raplaType; + } + throw new RaplaException("Cant find Raplatype for name" + typeName); + } + + static public RaplaType get(Class clazz) + { + @SuppressWarnings("unchecked") + RaplaType result = registeredTypes.get( clazz); + return result; + } + + public boolean is(RaplaType other) { + if ( other == null) + return false; + return type.equals( other.type); + } + + public String getLocalName() { + return localname; + } + + public String toString() { + return type.getName(); + } + + public boolean equals( Object other) { + if ( !(other instanceof RaplaType)) + return false; + return is( (RaplaType)other); + } + + public int hashCode() { + return type.hashCode(); + } + + public Class getTypeClass() + { + return type; + } + + public Character getFirstLetter() + { + return firstLetter; + } + + @SuppressWarnings("unchecked") + public static Set retainObjects(Collection set,Collection col) { + HashSet tempSet = new HashSet(set.size()); + tempSet.addAll(set); + tempSet.retainAll(col); + if (tempSet.size() >0) + { + HashSet result = new HashSet(); + for ( RaplaObject t : tempSet) + { + result.add( (T)t); + } + return result; + } + else + { + return Collections.emptySet(); + } + } + + +} + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/ReadOnlyException.java b/rapla-source-1.8.2/src/org/rapla/entities/ReadOnlyException.java new file mode 100644 index 0000000..4e7d756 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/ReadOnlyException.java @@ -0,0 +1,25 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities; + +/** This Exception is thrown when the application + wants to write to a read-only entity. You should use + the edit method to get a writable version of the entity. + */ +public class ReadOnlyException extends RuntimeException { + private static final long serialVersionUID = 1L; + + public ReadOnlyException(Object object) { + super("Can't modify entity [" + object + "]. Use the edit-method to get a writable version!"); + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/entities/Timestamp.java b/rapla-source-1.8.2/src/org/rapla/entities/Timestamp.java new file mode 100644 index 0000000..814daf3 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/Timestamp.java @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org . | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.entities; +import java.util.Date; + +public interface Timestamp extends LastChangedTimestamp { + /** returns the creation date of the object. */ + Date getCreateTime(); + /**@deprecated use getLastChanged instead */ + Date getLastChangeTime(); + User getLastChangedBy(); + //String getId(); +} diff --git a/rapla-source-1.8.2/src/org/rapla/entities/UniqueKeyException.java b/rapla-source-1.8.2/src/org/rapla/entities/UniqueKeyException.java new file mode 100644 index 0000000..23259de --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/UniqueKeyException.java @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities; + +import org.rapla.framework.RaplaException; + +/** Thrown if the same key is used by another object. */ +public class UniqueKeyException extends RaplaException { + private static final long serialVersionUID = 1L; + + public UniqueKeyException(String text) + { + super(text); + } +} + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/User.java b/rapla-source-1.8.2/src/org/rapla/entities/User.java new file mode 100644 index 0000000..c7ad981 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/User.java @@ -0,0 +1,86 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities; + +import java.util.Collection; +import java.util.Comparator; + +import org.rapla.entities.domain.Allocatable; +import org.rapla.framework.RaplaException; + + +/** +The User-Class is mainly for authentication-purpose +*/ +public interface User extends Entity, Named, Comparable, Timestamp +{ + final RaplaType TYPE = new RaplaType(User.class,"user"); + + /** returns the loginname */ + String getUsername(); + /** returns the complete name of user */ + String getName(); + /** returns the email of the user */ + String getEmail(); + /** returns if the user has admin-privilige */ + boolean isAdmin(); + + void setPerson(Allocatable person) throws RaplaException; + Allocatable getPerson(); + + void setUsername(String username); + void setName(String name); + void setEmail(String email); + void setAdmin(boolean isAdmin); + + void addGroup(Category group); + boolean removeGroup(Category group); + + @Deprecated + Category[] getGroups(); + + Collection getGroupList(); + + boolean belongsTo( Category group ); + + + public static User[] USER_ARRAY = new User[0]; + + Comparator USER_COMPARATOR= new Comparator() + { + @SuppressWarnings("unchecked") + @Override + public int compare(User u1, User u2) { + if ( u2 == null) + { + return 1; + } + if ( u1==u2 || u1.equals(u2)) return 0; + int result = String.CASE_INSENSITIVE_ORDER.compare( + u1.getUsername() + ,u2.getUsername() + ); + if ( result !=0 ) + return result; + + result = u1.compareTo( u2 ); + return result; + } + }; + +} + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/configuration/CalendarModelConfiguration.java b/rapla-source-1.8.2/src/org/rapla/entities/configuration/CalendarModelConfiguration.java new file mode 100644 index 0000000..a41be40 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/configuration/CalendarModelConfiguration.java @@ -0,0 +1,53 @@ +/*--------------------------------------------------------------------------* +| Copyright (C) 2014 Christopher Kohlhaas | +| | +| This program is free software; you can redistribute it and/or modify | +| it under the terms of the GNU General Public License as published by the | +| Free Software Foundation. A copy of the license has been included with | +| these distribution in the COPYING file, if not go to www.fsf.org | +| | +| As a special exception, you are granted the permissions to link this | +| program with every library, which license fulfills the Open Source | +| Definition as published by the Open Source Initiative (OSI). | +*--------------------------------------------------------------------------*/ +package org.rapla.entities.configuration; + +import java.util.Collection; +import java.util.Date; +import java.util.Map; + +import org.rapla.entities.Entity; +import org.rapla.entities.RaplaObject; +import org.rapla.entities.RaplaType; +import org.rapla.entities.dynamictype.ClassificationFilter; +import org.rapla.framework.TypedComponentRole; + +/** + * + * @author ckohlhaas + * @version 1.00.00 + * @since 2.03.00 + */ +public interface CalendarModelConfiguration extends RaplaObject +{ + + public static final RaplaType TYPE = new RaplaType(CalendarModelConfiguration.class, "calendar"); + public static final TypedComponentRole CONFIG_ENTRY = new TypedComponentRole("org.rapla.DefaultSelection"); + public static final TypedComponentRole> EXPORT_ENTRY = new TypedComponentRole>("org.rapla.plugin.autoexport"); + public Date getStartDate(); + public Date getEndDate(); + public Date getSelectedDate(); + public String getTitle(); + public String getView(); + public Collection getSelected(); + public Map getOptionMap(); + //public Configuration get + public ClassificationFilter[] getFilter(); + + public boolean isDefaultEventTypes(); + public boolean isDefaultResourceTypes(); + + public boolean isResourceRootSelected(); + + public CalendarModelConfiguration cloneWithNewOptions(Map newMap); +} diff --git a/rapla-source-1.8.2/src/org/rapla/entities/configuration/Preferences.java b/rapla-source-1.8.2/src/org/rapla/entities/configuration/Preferences.java new file mode 100644 index 0000000..a23cfe8 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/configuration/Preferences.java @@ -0,0 +1,63 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities.configuration; + +import org.rapla.entities.Entity; +import org.rapla.entities.Named; +import org.rapla.entities.Ownable; +import org.rapla.entities.RaplaObject; +import org.rapla.entities.RaplaType; +import org.rapla.entities.Timestamp; +import org.rapla.framework.TypedComponentRole; + +/** Preferences store user-specific Information. + You can store arbitrary configuration objects under unique role names. + Each role can contain 1-n configuration entries. + @see org.rapla.entities.User + */ +public interface Preferences extends Entity,Ownable,Timestamp, Named { + final RaplaType TYPE = new RaplaType(Preferences.class, "preferences"); + final String ID_PREFIX = TYPE.getLocalName() + "_"; + final String SYSTEM_PREFERENCES_ID = ID_PREFIX + "0"; + /** returns if there are any preference-entries */ + boolean isEmpty(); + boolean hasEntry(TypedComponentRole role); + + T getEntry(TypedComponentRole role); + T getEntry(TypedComponentRole role, T defaultEntry); + String getEntryAsString(TypedComponentRole role, String defaultValue); + Boolean getEntryAsBoolean(TypedComponentRole role, boolean defaultValue); + Integer getEntryAsInteger(TypedComponentRole role, int defaultValue); + + /** puts a new configuration entry to the role.*/ + void putEntry(TypedComponentRole role,Boolean entry); + void putEntry(TypedComponentRole role,Integer entry); + void putEntry(TypedComponentRole role,String entry); + void putEntry(TypedComponentRole role,CalendarModelConfiguration entry); + void putEntry(TypedComponentRole> role,RaplaMap entry); + void putEntry(TypedComponentRole role,RaplaConfiguration entry); + void removeEntry(String role); + +} + + + + + + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/configuration/RaplaConfiguration.java b/rapla-source-1.8.2/src/org/rapla/entities/configuration/RaplaConfiguration.java new file mode 100644 index 0000000..3a847dd --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/configuration/RaplaConfiguration.java @@ -0,0 +1,102 @@ +/*--------------------------------------------------------------------------* +| Copyright (C) 2014 Christopher Kohlhaas | +| | +| This program is free software; you can redistribute it and/or modify | +| it under the terms of the GNU General Public License as published by the | +| Free Software Foundation. A copy of the license has been included with | +| these distribution in the COPYING file, if not go to www.fsf.org | +| | +| As a special exception, you are granted the permissions to link this | +| program with every library, which license fulfills the Open Source | +| Definition as published by the Open Source Initiative (OSI). | +*--------------------------------------------------------------------------*/ +package org.rapla.entities.configuration; + +import java.io.Serializable; + +import org.rapla.entities.RaplaObject; +import org.rapla.entities.RaplaType; +import org.rapla.framework.Configuration; +import org.rapla.framework.DefaultConfiguration; +import org.rapla.framework.TypedComponentRole; + +/** + * This class adds just the get Type method to the DefaultConfiguration so that the config can be stored in a preference object + * @author ckohlhaas + * @version 1.00.00 + * @since 2.03.00 + */ +public class RaplaConfiguration extends DefaultConfiguration implements RaplaObject, Serializable{ + // Don't forget to increase the serialVersionUID when you change the fields + private static final long serialVersionUID = 1; + + public static final RaplaType TYPE = new RaplaType(RaplaConfiguration.class, "config"); + + public RaplaConfiguration() + { + super(); + } + + /** Creates a RaplaConfinguration with one element of the specified name +* @param name the element name +* @param content The content of the element. Can be null. +*/ + public RaplaConfiguration( String name, String content) { + super(name, content); + } + + public RaplaConfiguration(String localName) { + super(localName); + } + + public RaplaConfiguration(Configuration configuration) { + super( configuration); + } + + public RaplaType getRaplaType() { + return TYPE; + } + + public RaplaConfiguration replace( Configuration oldChild, Configuration newChild) + { + return (RaplaConfiguration) super.replace( oldChild, newChild); + } + + public String getChildValue(TypedComponentRole key, String defaultValue ) + { + String id = key.getId(); + Configuration child = getChild( id); + String result = child.getValue(defaultValue); + return result; + } + + public Integer getChildValue(TypedComponentRole key, Integer defaultValue ) + { + String id = key.getId(); + Configuration child = getChild( id); + Integer result = child.getValueAsInteger(defaultValue); + return result; + } + + public Boolean getChildValue(TypedComponentRole key, Boolean defaultValue ) + { + String id = key.getId(); + Configuration child = getChild( id); + Boolean result = child.getValueAsBoolean(defaultValue); + return result; + } + + @Override + protected RaplaConfiguration newConfiguration(String localName) { + return new RaplaConfiguration( localName); + } + + + public RaplaConfiguration clone() + { + return new RaplaConfiguration( this); + } + + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/entities/configuration/RaplaMap.java b/rapla-source-1.8.2/src/org/rapla/entities/configuration/RaplaMap.java new file mode 100644 index 0000000..d73eafb --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/configuration/RaplaMap.java @@ -0,0 +1,27 @@ +/*--------------------------------------------------------------------------* +| Copyright (C) 2014 Christopher Kohlhaas | +| | +| This program is free software; you can redistribute it and/or modify | +| it under the terms of the GNU General Public License as published by the | +| Free Software Foundation. A copy of the license has been included with | +| these distribution in the COPYING file, if not go to www.fsf.org | +| | +| As a special exception, you are granted the permissions to link this | +| program with every library, which license fulfills the Open Source | +| Definition as published by the Open Source Initiative (OSI). | +*--------------------------------------------------------------------------*/ +package org.rapla.entities.configuration; + +import java.util.Map; + +import org.rapla.entities.RaplaObject; +import org.rapla.entities.RaplaType; + +/** + * This Map can hold only Objects of type RaplaObject and String + * (It cannot hold references to appointments or attributes) + * @see RaplaObject + */ +public interface RaplaMap extends RaplaObject, Map { + public static final RaplaType TYPE = new RaplaType(RaplaMap.class, "map"); +} diff --git a/rapla-source-1.8.2/src/org/rapla/entities/configuration/internal/AbstractClassifiableFilter.java b/rapla-source-1.8.2/src/org/rapla/entities/configuration/internal/AbstractClassifiableFilter.java new file mode 100644 index 0000000..aed0110 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/configuration/internal/AbstractClassifiableFilter.java @@ -0,0 +1,116 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas, Frithjof Kurtz | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities.configuration.internal; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import org.rapla.components.util.iterator.NestedIterable; +import org.rapla.entities.dynamictype.ClassificationFilter; +import org.rapla.entities.dynamictype.DynamicType; +import org.rapla.entities.dynamictype.internal.ClassificationFilterImpl; +import org.rapla.entities.storage.CannotExistWithoutTypeException; +import org.rapla.entities.storage.DynamicTypeDependant; +import org.rapla.entities.storage.EntityReferencer; +import org.rapla.entities.storage.EntityResolver; + +public abstract class AbstractClassifiableFilter implements EntityReferencer, DynamicTypeDependant, Serializable +{ + private static final long serialVersionUID = 1L; + List classificationFilters; + protected transient EntityResolver resolver; + + AbstractClassifiableFilter() { + classificationFilters = new ArrayList(); + } + + public void setResolver( EntityResolver resolver) { + this.resolver = resolver; + for (ClassificationFilterImpl filter:classificationFilters) { + filter.setResolver( resolver ); + } + } + + @Override + public Iterable getReferenceInfo() { + Iterable classificatonFilterIterator = classificationFilters; + return new NestedIterable(classificatonFilterIterator) { + public Iterable getNestedIterable(ClassificationFilterImpl obj) { + return obj.getReferenceInfo(); + } + }; + } + + public void setClassificationFilter(List classificationFilters) { + if ( classificationFilters != null) + this.classificationFilters = classificationFilters; + else + this.classificationFilters = Collections.emptyList(); + } + + public boolean needsChange(DynamicType type) { + for (ClassificationFilterImpl filter:classificationFilters) + { + if (filter.needsChange(type)) + return true; + } + return false; + } + + public void commitChange(DynamicType type) { + for (ClassificationFilterImpl filter:classificationFilters) + { + if (filter.getType().equals(type)) + filter.commitChange(type); + } + } + + public void commitRemove(DynamicType type) throws CannotExistWithoutTypeException + { + boolean removed = false; + List newFilter = new ArrayList( classificationFilters); + for (Iterator f=newFilter.iterator();f.hasNext();) { + ClassificationFilterImpl filter = f.next(); + if (filter.getType().equals(type)) + { + removed = true; + f.remove(); + } + } + if ( removed) + { + classificationFilters = newFilter; + } + } + + public ClassificationFilter[] getFilter() { + return classificationFilters.toArray( ClassificationFilter.CLASSIFICATIONFILTER_ARRAY); + } + + public String toString() + { + return classificationFilters.toString(); + + } + +} + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/configuration/internal/CalendarModelConfigurationImpl.java b/rapla-source-1.8.2/src/org/rapla/entities/configuration/internal/CalendarModelConfigurationImpl.java new file mode 100644 index 0000000..0abcf38 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/configuration/internal/CalendarModelConfigurationImpl.java @@ -0,0 +1,260 @@ +/*--------------------------------------------------------------------------* +| Copyright (C) 2014 Christopher Kohlhaas | +| | +| This program is free software; you can redistribute it and/or modify | +| it under the terms of the GNU General Public License as published by the | +| Free Software Foundation. A copy of the license has been included with | +| these distribution in the COPYING file, if not go to www.fsf.org | +| | +| As a special exception, you are granted the permissions to link this | +| program with every library, which license fulfills the Open Source | +| Definition as published by the Open Source Initiative (OSI). | +*--------------------------------------------------------------------------*/ +package org.rapla.entities.configuration.internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.rapla.components.util.iterator.IterableChain; +import org.rapla.entities.Entity; +import org.rapla.entities.RaplaType; +import org.rapla.entities.User; +import org.rapla.entities.configuration.CalendarModelConfiguration; +import org.rapla.entities.domain.Allocatable; +import org.rapla.entities.dynamictype.ClassificationFilter; +import org.rapla.entities.dynamictype.DynamicType; +import org.rapla.entities.dynamictype.internal.ClassificationFilterImpl; +import org.rapla.entities.storage.EntityResolver; +import org.rapla.framework.RaplaException; + + +public class CalendarModelConfigurationImpl extends AbstractClassifiableFilter implements CalendarModelConfiguration +{ + // Don't forget to increase the serialVersionUID when you change the fields + private static final long serialVersionUID = 1; + List selected; + List typeList; + String title; + Date startDate; + Date endDate; + Date selectedDate; + String view; + Map optionMap; + boolean defaultEventTypes; + boolean defaultResourceTypes; + boolean resourceRootSelected; + + public CalendarModelConfigurationImpl( Collection selected,Collection idTypeList,boolean resourceRootSelected, ClassificationFilter[] filter, boolean defaultResourceTypes, boolean defaultEventTypes,String title, Date startDate, Date endDate, Date selectedDate,String view,Map extensionMap) { + if (selected != null) + { + this.selected = Collections.unmodifiableList(new ArrayList(selected)); + typeList = new ArrayList(); + for ( RaplaType type:idTypeList) + { + typeList.add(type.getLocalName()); + } + } + else + { + this.selected = Collections.emptyList(); + typeList = Collections.emptyList(); + } + + this.view = view; + this.resourceRootSelected = resourceRootSelected; + this.defaultEventTypes = defaultEventTypes; + this.defaultResourceTypes = defaultResourceTypes; + this.title = title; + this.startDate = startDate; + this.endDate = endDate; + this.selectedDate = selectedDate; + List filterList = new ArrayList(); + if ( filter != null) + { + for ( ClassificationFilter f:filter) + { + filterList.add((ClassificationFilterImpl)f); + } + } + super.setClassificationFilter( filterList ); + Map map= new LinkedHashMap(); + if ( extensionMap != null) + { + map.putAll(extensionMap); + } + this.optionMap = Collections.unmodifiableMap( map); + } + + + CalendarModelConfigurationImpl() { + } + + @Override + public boolean isResourceRootSelected() { + return resourceRootSelected; + } + + public void setResolver( EntityResolver resolver) { + super.setResolver( resolver ); + } + + public RaplaType getRaplaType() { + return TYPE; + } + + public Date getStartDate() { + return startDate; + } + + public Date getEndDate() { + return endDate; + } + + public Date getSelectedDate() { + return selectedDate; + } + + public String getTitle() { + return title; + } + + public String getView() { + return view; + } + + public Collection getSelected() { + ArrayList result = new ArrayList(); + for ( String id: selected) + { + Entity entity = resolver.tryResolve(id); + if ( entity != null) + { + result.add( entity); + } + } + return result; + } + + @Override + public Iterable getReferenceInfo() { + Iterable references = super.getReferenceInfo(); + List selectedInfo = new ArrayList(); + int size = selected.size(); + for ( int i = 0;i type = null; + RaplaType raplaType; + try { + raplaType = RaplaType.find(localname); + } + catch (RaplaException ex) + { + throw new IllegalArgumentException(ex.getMessage()); + } + try { + Class typeClass = raplaType.getTypeClass(); + //if ( Entity.class.isAssignableFrom(typeClass )) + { + @SuppressWarnings("unchecked") + Class casted = (Class)typeClass; + type = casted; + } + ReferenceInfo referenceInfo = new ReferenceInfo(id, type); + selectedInfo.add( referenceInfo); + } catch ( ClassCastException e) { + } + + } + return new IterableChain(references, selectedInfo); + } + + public Map getOptionMap() + { + return optionMap; + } + + public boolean isDefaultEventTypes() + { + return defaultEventTypes; + } + + public boolean isDefaultResourceTypes() + { + return defaultResourceTypes; + } + + static private void copy(CalendarModelConfigurationImpl source,CalendarModelConfigurationImpl dest) { + dest.view = source.view; + dest.defaultEventTypes = source.defaultEventTypes; + dest.defaultResourceTypes = source.defaultResourceTypes; + dest.title = source.title; + dest.startDate = source.startDate; + dest.endDate = source.endDate; + dest.selectedDate = source.selectedDate; + dest.resourceRootSelected = source.resourceRootSelected; + dest.setResolver( source.resolver); + List newFilter = new ArrayList(); + for ( ClassificationFilterImpl f: source.classificationFilters) + { + ClassificationFilterImpl clone = f.clone(); + newFilter.add( clone); + } + dest.setClassificationFilter(newFilter ); + dest.selected = new ArrayList(source.selected); + dest.typeList = new ArrayList(source.typeList); + LinkedHashMap optionMap = new LinkedHashMap(); + optionMap.putAll(source.optionMap); + dest.optionMap = Collections.unmodifiableMap(optionMap); + } + + public void copy(CalendarModelConfiguration obj) + { + copy((CalendarModelConfigurationImpl)obj, this); + + } + + public CalendarModelConfiguration deepClone() + { + CalendarModelConfigurationImpl clone = new CalendarModelConfigurationImpl(); + copy(this,clone); + return clone; + } + + public CalendarModelConfiguration clone() { + return deepClone(); + } + + public static boolean canReference(RaplaType raplaType) + { + return raplaType == DynamicType.TYPE || raplaType == Allocatable.TYPE || raplaType == User.TYPE; + } + + public List getSelectedIds() + { + return selected; + } + + public String toString() + { + return super.toString() + ",selected=" + selected; + } + + + @Override + public CalendarModelConfiguration cloneWithNewOptions(Map newMap) { + CalendarModelConfigurationImpl clone = (CalendarModelConfigurationImpl) deepClone(); + clone.optionMap = Collections.unmodifiableMap( newMap); + return clone; + } + + + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/entities/configuration/internal/PreferencesImpl.java b/rapla-source-1.8.2/src/org/rapla/entities/configuration/internal/PreferencesImpl.java new file mode 100644 index 0000000..1955940 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/configuration/internal/PreferencesImpl.java @@ -0,0 +1,366 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities.configuration.internal; + +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.Locale; +import java.util.Set; + +import org.rapla.components.util.iterator.IterableChain; +import org.rapla.entities.RaplaObject; +import org.rapla.entities.RaplaType; +import org.rapla.entities.User; +import org.rapla.entities.configuration.CalendarModelConfiguration; +import org.rapla.entities.configuration.Preferences; +import org.rapla.entities.configuration.RaplaConfiguration; +import org.rapla.entities.configuration.RaplaMap; +import org.rapla.entities.dynamictype.DynamicType; +import org.rapla.entities.internal.ModifiableTimestamp; +import org.rapla.entities.storage.CannotExistWithoutTypeException; +import org.rapla.entities.storage.DynamicTypeDependant; +import org.rapla.entities.storage.EntityResolver; +import org.rapla.entities.storage.internal.SimpleEntity; +import org.rapla.facade.RaplaComponent; +import org.rapla.framework.Configuration; +import org.rapla.framework.TypedComponentRole; +import org.rapla.storage.PreferencePatch; + +public class PreferencesImpl extends SimpleEntity + implements + Preferences + ,ModifiableTimestamp + , DynamicTypeDependant +{ + private Date lastChanged; + private Date createDate; + + RaplaMapImpl map = new RaplaMapImpl(); + Set removedKeys = new LinkedHashSet(); + final public RaplaType getRaplaType() {return TYPE;} + private transient PreferencePatch patch = new PreferencePatch(); + + PreferencesImpl() { + this(null,null); + } + + public PreferencesImpl(Date createDate,Date lastChanged ) { + super(); + this.createDate = createDate; + this.lastChanged = lastChanged; + } + + public Date getLastChanged() { + return lastChanged; + } + + @Deprecated + public Date getLastChangeTime() { + return lastChanged; + } + + public Date getCreateTime() { + return createDate; + } + + public void setLastChanged(Date date) { + checkWritable(); + lastChanged = date; + } + + @Override + public void putEntry(TypedComponentRole role, CalendarModelConfiguration entry) { + putEntryPrivate(role.getId(), entry); + } + + @Override + public void putEntry(TypedComponentRole role, RaplaConfiguration entry) { + putEntryPrivate(role.getId(), entry); + } + + @Override + public void putEntry(TypedComponentRole> role, RaplaMap entry) { + putEntryPrivate(role.getId(), entry); + } + + public void putEntryPrivate(String role,RaplaObject entry) { + updateMap(role, entry); + } + + private void updateMap(String role, Object entry) { + checkWritable(); + map.putPrivate(role, entry); + patch.putPrivate( role, entry); + if ( entry == null) + { + patch.addRemove( role); + } + } + + public void putEntryPrivate(String role,String entry) { + updateMap(role, entry); + } + + public void setResolver( EntityResolver resolver) { + super.setResolver(resolver); + map.setResolver(resolver); + patch.setResolver(resolver); + } + + public T getEntry(String role) { + return getEntry(role, null); + } + + public T getEntry(String role, T defaultValue) { + try + { + @SuppressWarnings("unchecked") + T result = (T) map.get( role ); + if ( result == null) + { + return defaultValue; + } + return result; + } + catch ( ClassCastException ex) + { + throw new ClassCastException( "Stored entry is not of requested Type: " + ex.getMessage()); + } + } + + private String getEntryAsString(String role) { + return (String) map.get( role ); + } + + public String getEntryAsString(TypedComponentRole role, String defaultValue) { + String value = getEntryAsString( role.getId()); + if ( value != null) + return value; + return defaultValue; + } + + public Iterable getPreferenceEntries() { + return map.keySet(); + } + + public void removeEntry(String role) { + updateMap(role, null); + } + + @Override + public Iterable getReferenceInfo() + { + Iterable parentReferences = super.getReferenceInfo(); + Iterable mapReferences = map.getReferenceInfo(); + IterableChain iteratorChain = new IterableChain(parentReferences,mapReferences); + return iteratorChain; + } + + public boolean isEmpty() { + return map.isEmpty(); + } + + + public PreferencesImpl clone() { + PreferencesImpl clone = new PreferencesImpl(); + super.deepClone(clone); + clone.map = map.deepClone(); + clone.createDate = createDate; + clone.lastChanged = lastChanged; + // we clear the patch on a clone + clone.patch = new PreferencePatch(); + clone.patch.setUserId( getOwnerId()); + return clone; + } + + @Override + public void setOwner(User owner) { + super.setOwner(owner); + patch.setUserId( getOwnerId()); + } + + public PreferencePatch getPatch() + { + return patch; + } + + /** + * @see org.rapla.entities.Named#getName(java.util.Locale) + */ + public String getName(Locale locale) { + StringBuffer buf = new StringBuffer(); + if ( getOwner() != null) { + buf.append( "Preferences of "); + buf.append( getOwner().getName( locale)); + } else { + buf.append( "Rapla Preferences!"); + } + return buf.toString(); + } + /* (non-Javadoc) + * @see org.rapla.entities.configuration.Preferences#getEntryAsBoolean(java.lang.String, boolean) + */ + public Boolean getEntryAsBoolean(TypedComponentRole role, boolean defaultValue) { + String entry = getEntryAsString( role.getId()); + if ( entry == null) + return defaultValue; + return Boolean.valueOf(entry).booleanValue(); + } + + /* (non-Javadoc) + * @see org.rapla.entities.configuration.Preferences#getEntryAsInteger(java.lang.String, int) + */ + public Integer getEntryAsInteger(TypedComponentRole role, int defaultValue) { + String entry = getEntryAsString( role.getId()); + if ( entry == null) + return defaultValue; + return Integer.parseInt(entry); + } + + public boolean needsChange(DynamicType type) { + return map.needsChange(type); + } + + public void commitChange(DynamicType type) { + map.commitChange(type); + patch.commitChange(type); + } + + + public void commitRemove(DynamicType type) throws CannotExistWithoutTypeException + { + map.commitRemove(type); + patch.commitRemove(type); + } + + + public String toString() + { + return super.toString() + " " + map.toString(); + } + + public void putEntry(TypedComponentRole role,T entry) + { + putEntryPrivate( role.getId(), entry); + } + + public void applyPatch(PreferencePatch patch) + { + checkWritable(); + Set removedEntries = patch.getRemovedEntries(); + for (String key:patch.keySet()) + { + Object value = patch.get( key); + updateMap(key, value); + } + for ( String remove:removedEntries) + { + updateMap(remove, null); + } + Date lastChangedPatch = patch.getLastChanged(); + if ( lastChangedPatch != null ) + { + Date lastChanged = getLastChanged(); + if ( lastChanged == null || lastChanged.before(lastChangedPatch)) + { + setLastChanged( lastChangedPatch ); + } + + } + } + + + public T getEntry(TypedComponentRole role) { + return getEntry( role, null); + } + + public T getEntry(TypedComponentRole role, T defaultValue) { + return getEntry( role.getId(), defaultValue); + } + + public boolean hasEntry(TypedComponentRole role) { + return map.get( role.getId() ) != null; + } + + public void putEntry(TypedComponentRole role, Boolean entry) { + putEntry_(role, entry != null ? entry.toString(): null); + } + + public void putEntry(TypedComponentRole role, Integer entry) + { + putEntry_(role, entry != null ? entry.toString() : null); + } + + public void putEntry(TypedComponentRole role, String entry) { + putEntry_(role, entry); + } + + protected void putEntry_(TypedComponentRole role, Object entry) { + checkWritable(); + String key = role.getId(); + updateMap(key, entry); + +// if ( entry == null) +// { +// map.remove( id); +// } +// else +// { +// map.put( id ,entry.toString()); +// } + } + + + public static String getPreferenceIdFromUser(String userId) { + String preferenceId = (userId != null ) ? Preferences.ID_PREFIX + userId : SYSTEM_PREFERENCES_ID; + return preferenceId.intern(); + } + + @Deprecated + public Configuration getOldPluginConfig(String pluginClassName) { + RaplaConfiguration raplaConfig = getEntry(RaplaComponent.PLUGIN_CONFIG); + Configuration pluginConfig = null; + if ( raplaConfig != null) { + pluginConfig = raplaConfig.find("class", pluginClassName); + } + if ( pluginConfig == null) { + pluginConfig = new RaplaConfiguration("plugin"); + } + return pluginConfig; + } + + +// public static boolean isServerEntry(String configRole) { +// if ( configRole == null) +// { +// return false; +// } +// if ( configRole.startsWith("server.") || configRole.contains(".server.")) +// { +// return true; +// } +// return false; +// } +} + + + + + + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/configuration/internal/RaplaMapImpl.java b/rapla-source-1.8.2/src/org/rapla/entities/configuration/internal/RaplaMapImpl.java new file mode 100644 index 0000000..af55172 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/configuration/internal/RaplaMapImpl.java @@ -0,0 +1,614 @@ +/*--------------------------------------------------------------------------* +| C +o//pyright (C) 2014 Christopher Kohlhaas | +| | +| This program is free software; you can redistribute it and/or modify | +| it under the terms of the GNU General Public License as published by the | +| Free Software Foundation. A copy of the license has been included with | +| these distribution in the COPYING file, if not go to www.fsf.org | +| | +| As a special exception, you are granted the permissions to link this | +| program with every library, which license fulfills the Open Source | +| Definition as published by the Open Source Initiative (OSI). | +*--------------------------------------------------------------------------*/ +package org.rapla.entities.configuration.internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import org.rapla.components.util.iterator.FilterIterable; +import org.rapla.components.util.iterator.IterableChain; +import org.rapla.components.util.iterator.NestedIterable; +import org.rapla.entities.Category; +import org.rapla.entities.Entity; +import org.rapla.entities.RaplaObject; +import org.rapla.entities.RaplaType; +import org.rapla.entities.ReadOnlyException; +import org.rapla.entities.configuration.CalendarModelConfiguration; +import org.rapla.entities.configuration.RaplaConfiguration; +import org.rapla.entities.configuration.RaplaMap; +import org.rapla.entities.domain.Allocatable; +import org.rapla.entities.dynamictype.DynamicType; +import org.rapla.entities.storage.CannotExistWithoutTypeException; +import org.rapla.entities.storage.DynamicTypeDependant; +import org.rapla.entities.storage.EntityReferencer; +import org.rapla.entities.storage.EntityResolver; +import org.rapla.entities.storage.internal.ReferenceHandler; + +/** Maps can only support one type value at a time. Especially a mixture out of references and other values is not supported*/ +public class RaplaMapImpl implements EntityReferencer, DynamicTypeDependant, RaplaObject, RaplaMap { + //this map stores all objects in the map + private Map constants; + private Map configurations; + private Map maps; + private Map calendars; + protected LinkReferenceHandler links; + transient protected Map map; + transient EntityResolver resolver; + + static private RaplaType[] SUPPORTED_TYPES = new RaplaType[] { Allocatable.TYPE, Category.TYPE, DynamicType.TYPE}; + // this map only stores the references + + // this map only stores the child objects (not the references) + + public RaplaMapImpl() { + } + + + public RaplaMapImpl( Collection list) { + this( makeMap(list) ); + } + + public RaplaType getRaplaType() { + return RaplaMap.TYPE; + } + + private static Map makeMap(Collection list) { + Map map = new TreeMap(); + int key = 0; + for ( Iterator it = list.iterator();it.hasNext();) { + T next = it.next(); + if ( next == null) + { + System.err.println("Adding null value in list" ); + } + map.put( new String( String.valueOf(key++)), next); + } + return map; + } + + public RaplaMapImpl( Map map) { + for ( Iterator it = map.keySet().iterator();it.hasNext();) { + String key = it.next(); + Object o = map.get(key ); + putPrivate(key, o); + } + } + + + /** This method is only used in storage operations, please dont use it from outside, as it skips type protection and resolving*/ + public void putPrivate(String key, Object value) + { + cachedEntries = null; + if ( value == null) + { + if (links != null) + { + links.removeWithKey(key); + } + if ( maps != null) + { + maps.remove( key); + } + if ( map != null) + { + map.remove( key); + } + if ( configurations != null) + { + configurations.remove(key); + } + if ( maps != null) + { + maps.remove(key); + } + if ( calendars != null) + { + calendars.remove(key); + } + if ( constants != null) + { + constants.remove(key); + } + return; + } +// if ( ! (value instanceof RaplaObject ) && !(value instanceof String) ) +// { +// } + if ( value instanceof Entity) + { + Entity entity = (Entity) value; + String id = entity.getId(); + RaplaType raplaType = entity.getRaplaType(); + if ( !isTypeSupportedAsLink( raplaType)) + { + throw new IllegalArgumentException("RaplaType " + raplaType + " cannot be stored as link in map"); + } + putIdPrivate(key, id, raplaType); + } + else if ( value instanceof RaplaConfiguration) { + if ( configurations == null) + { + configurations = new LinkedHashMap(); + } + configurations.put( key, (RaplaConfiguration) value); + getMap().put(key, value); + } + else if ( value instanceof RaplaMap) { + if ( maps == null) + { + maps = new LinkedHashMap(); + } + maps.put( key, (RaplaMapImpl) value); + getMap().put(key, value); + } + else if ( value instanceof CalendarModelConfiguration) { + if ( calendars == null) + { + calendars = new LinkedHashMap(); + } + calendars.put( key, (CalendarModelConfigurationImpl) value); + getMap().put(key, value); + } + else if ( value instanceof String) { + if ( constants == null) + { + constants = new LinkedHashMap(); + } + constants.put( key , (String) value); + getMap().put(key, value); + } else { + throw new IllegalArgumentException("Map type not supported only category, dynamictype, allocatable, raplamap, raplaconfiguration or String."); + } + } + + private Map getMap() { + if (links != null) + { + Map linkMap = links.getLinkMap(); + @SuppressWarnings("unchecked") + Map casted = (Map)linkMap; + return casted; + } + if ( maps == null && configurations == null && constants == null && calendars == null) + { + return Collections.emptyMap(); + } + if ( map == null) + { + map = new LinkedHashMap(); + fillMap(maps); + fillMap(configurations); + fillMap(constants); + fillMap(calendars); + } + return map; + } + + private void fillMap(Map map) { + if ( map == null) + { + return; + } + this.map.putAll( map); + } + + public void putIdPrivate(String key, String id, RaplaType raplaType) { + cachedEntries = null; + if ( links == null) + { + links = new LinkReferenceHandler(); + links.setLinkType( raplaType.getLocalName()); + if ( resolver != null) + { + links.setResolver( resolver); + } + } + links.putId( key,id); + map = null; + } + + @Override + public Iterable getReferenceInfo() + { + NestedIterable refIt = new NestedIterable( getEntityReferencers()) { + public Iterable getNestedIterable(EntityReferencer obj) { + Iterable referencedIds = obj.getReferenceInfo(); + return referencedIds; + } + }; + if ( links == null) + { + return refIt; + } + Iterable referencedLinks = links.getReferenceInfo(); + return new IterableChain( refIt, referencedLinks); + } + + private Iterable getEntityReferencers() { + return new FilterIterable( getMap().values()) { + protected boolean isInIterator(Object obj) { + return obj instanceof EntityReferencer; + } + }; + } + + /* + public Iterator getReferences() { + return getReferenceHandler().getReferences(); + } + + public boolean isRefering(Entity entity) { + return getReferenceHandler().isRefering( entity); + }*/ + + public void setResolver( EntityResolver resolver) { + this.resolver = resolver; + if ( links != null) + { + links.setResolver( resolver ); + } + setResolver( calendars); + setResolver( maps ); + map = null; + } + + + + private void setResolver(Map map) { + if ( map == null) + { + return; + } + for (EntityReferencer ref:map.values()) + { + ref.setResolver( resolver); + } + } + + + public Object get(Object key) { + if (links != null) + { + return links.getEntity((String)key); + } + return getMap().get(key); + } + + + /** + * @see java.util.Map#clear() + */ + public void clear() { + throw createReadOnlyException(); + } + + protected ReadOnlyException createReadOnlyException() { + return new ReadOnlyException("RaplaMap is readonly you must create a new Object"); + } + + /** + * @see java.util.Map#size() + */ + public int size() { + return getMap().size(); + } + + /** + * @see java.util.Map#isEmpty() + */ + public boolean isEmpty() { + return getMap().isEmpty(); + } + + /** + * @see java.util.Map#containsKey(java.lang.Object) + */ + public boolean containsKey(Object key) { + return getMap().containsKey( key); + } + + /** + * @see java.util.Map#containsValue(java.lang.Object) + */ + public boolean containsValue(Object key) { + return getMap().containsValue( key); + } + + /** + * @see java.util.Map#keySet() + */ + public Set keySet() { + return getMap().keySet(); + } + + public boolean needsChange(DynamicType type) { + for (Iterator it = getMap().values().iterator();it.hasNext();) { + Object obj = it.next(); + if ( obj instanceof DynamicTypeDependant) { + if (((DynamicTypeDependant) obj).needsChange( type )) + return true; + } + } + return false; + } + + public void commitChange(DynamicType type) { + for (Object obj:getMap().values()) { + if ( obj instanceof DynamicTypeDependant) { + ((DynamicTypeDependant) obj).commitChange( type ); + } + } + } + + public void commitRemove(DynamicType type) throws CannotExistWithoutTypeException { + for (Object obj:getMap().values()) { + if ( obj instanceof DynamicTypeDependant) { + ((DynamicTypeDependant) obj).commitRemove( type ); + } + } + } + /** Clones the entity and all subentities*/ + public RaplaMapImpl deepClone() + { + RaplaMapImpl clone = new RaplaMapImpl(getMap()); + clone.setResolver( resolver ); + return clone; + } + +// public Collection getLinkValues() +// { +// ArrayList result = new ArrayList(); +// EntityResolver resolver = getReferenceHandler().getResolver(); +// for (String id: getReferencedIds()) +// { +// result.add( resolver.tryResolve( id)); +// } +// return result; +// +// } + + + /** Clones the entity while preserving the references to the subentities*/ + public Object clone() + { + return deepClone(); + } + + + /** + * @see java.util.Map#put(java.lang.Object, java.lang.Object) + */ + public Object put(Object key, Object value) { + throw createReadOnlyException(); + } + + + public Object remove(Object arg0) { + throw createReadOnlyException(); + } + + /** + * @see java.util.Map#putAll(java.util.Map) + */ + public void putAll(Map m) { + throw createReadOnlyException(); + } + + /** + * @see java.util.Map#values() + */ + public Collection values() { + if ( links == null) + { + return getMap().values(); + } + else + { + List result = new ArrayList(); + for (Map.Entry entry:entrySet()) + { + result.add((Entity)entry.getValue()); + } +// Iterable values = links.getReferencedIds(); +// for (String id: values) +// { +// EntityResolver resovler = links.getResolver(); +// if (resovler == null) +// { +// throw new IllegalStateException("Resolver not set in map. "); +// } +// Entity resolved = resovler.tryResolve( id); +// result.add( resolved); +// } + return result; + } + } + + + public static final class LinkReferenceHandler extends ReferenceHandler { + protected String linkType; + transient private Class linkClass; + + protected Class getInfoClass(String key) { + return getLinkClass(); + } + + public Iterable getReferencedIds() + { + Set result = new HashSet(); + if (links != null) { + for (List entries:links.values()) { + for ( String id: entries) + { + result.add(id); + } + } + } + return result; + } + + + public Entity getEntity(String key) + { + Class linkClass = getLinkClass(); + return getEntity(key, linkClass); + } + + private Class getLinkClass() { + if ( linkClass != null) + { + return linkClass; + } + if ( linkType != null ) + { + for ( RaplaType type: SUPPORTED_TYPES ) + { + if (linkType.equals( type.getLocalName())) + { + @SuppressWarnings("unchecked") + Class casted = type.getTypeClass(); + this.linkClass = casted; + return linkClass; + } + } + } + return null; + } + + public void setLinkType(String type) + { + this.linkType = type; + linkClass = null; + } + + } + + + class Entry implements Map.Entry + { + String key; + String id; + + Entry(String key,String id) + { + this.key = key; + this.id = id; + if ( id == null) + { + throw new IllegalArgumentException("Empty id added"); + } + } + public String getKey() { + return key; + } + + public Object getValue() { + if ( id == null) + { + return null; + } + EntityResolver resolver = links.getResolver(); + if (resolver == null) + { + throw new IllegalStateException("Resolver not set in links map. "); + } + Entity resolve = resolver.tryResolve( id ); + return resolve; + } + + public Object setValue(Object value) { + throw new UnsupportedOperationException(); + } + + public int hashCode() { + return key.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return key.equals( ((Entry) obj).key); + } + + public String toString() + { + Entity value = links.getResolver().tryResolve( id ); + return key + "=" + ((value != null) ? value : "unresolvable_" + id); + } + } + + transient Set> cachedEntries; + public Set> entrySet() { + if ( links != null) + { + if ( cachedEntries == null) + { + cachedEntries = new HashSet>(); + for (String key:links.getReferenceKeys()) + { + String id = links.getId( key); + if ( id == null) + { + System.err.println("Empty id " + id); + } + cachedEntries.add(new Entry( key, id)); + } + } + return cachedEntries; + } + else + { + if ( cachedEntries == null) + { + cachedEntries = new HashSet>(); + for (Map.Entry entry:getMap().entrySet()) + { + if ( entry.getValue() == null) + { + System.err.println("Empty value for " + entry.getKey()); + } + cachedEntries.add((Map.Entry) entry); + } + } + return cachedEntries; + } + } + + public String toString() + { + return entrySet().toString(); + } + + + public boolean isTypeSupportedAsLink(RaplaType raplaType) + { + for ( RaplaType type: SUPPORTED_TYPES ) + { + if ( type == raplaType) + { + return true; + } + } + return false; + } + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/entities/domain/Allocatable.java b/rapla-source-1.8.2/src/org/rapla/entities/domain/Allocatable.java new file mode 100644 index 0000000..af9467e --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/domain/Allocatable.java @@ -0,0 +1,82 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender, Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities.domain; + +import java.util.Date; + +import org.rapla.components.util.TimeInterval; +import org.rapla.entities.Annotatable; +import org.rapla.entities.Named; +import org.rapla.entities.Ownable; +import org.rapla.entities.RaplaType; +import org.rapla.entities.Timestamp; +import org.rapla.entities.User; +import org.rapla.entities.dynamictype.Classifiable; + +/** Objects that implement allocatable can be allocated by reservations. + @see Reservation + */ +public interface Allocatable extends EntityPermissionContainer,Named,Classifiable,Ownable,Timestamp, Annotatable { + + final RaplaType TYPE = new RaplaType(Allocatable.class, "resource"); + + /** Conflicts for this allocatable should be ignored, if this flag is enabled. + * @deprecated use getAnnotation(IGNORE_CONFLICTS) instead*/ + @Deprecated + boolean isHoldBackConflicts(); + /** Static empty dummy Array. Mainly for using the toArray() method of the collection interface */ + Allocatable[] ALLOCATABLE_ARRAY = new Allocatable[0]; + + + /** returns if the user has the permission to allocate the resource in the given + time. It returns true if for at least one permission calling + permission.covers() + and permission.affectsUser yields true. + */ + boolean canAllocate( User user, Date start, Date end, Date today ); + + /** returns if the user has the permission to allocate the resource in at a time in the future without specifying the exact time */ + boolean canAllocate(User user, Date today); + + /** @deprecated use getPermissionList instead */ + @Deprecated + Permission[] getPermissions(); + + boolean canRead(User user); + + boolean canModify(User user); + + boolean canReadOnlyInformation(User user); + + /** returns the interval in which the user can allocate the resource. Returns null if the user can't allocate the resource */ + TimeInterval getAllocateInterval( User user, Date today); + + /** returns if the user has the permission to create a conflict for the resource.*/ + boolean canCreateConflicts( User user ); + + /** same as DynamicTypeAnnotations.VALUE_CLASSIFICATION_TYPE_PERSON.equals(allocatable.getType().getAnnotation(DynamicTypeAnnotations.KEY_CLASSIFICATION_TYPE)) + */ + boolean isPerson(); +} + + + + + + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/domain/Appointment.java b/rapla-source-1.8.2/src/org/rapla/entities/domain/Appointment.java new file mode 100644 index 0000000..839abec --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/domain/Appointment.java @@ -0,0 +1,153 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender, Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities.domain; +import java.util.Collection; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.rapla.components.util.TimeInterval; +import org.rapla.entities.Entity; +import org.rapla.entities.RaplaType; +import org.rapla.entities.User; +/** The basic building blocks of reservations. + @see Reservation + @see Repeating*/ +public interface Appointment extends Entity, Comparable { + final RaplaType TYPE = new RaplaType(Appointment.class, "appointment" ); + Date getStart(); + Date getEnd(); + /**

    + If no repeating is set this method will return the same + as getEnd(). +

    +

    + If the repeating has no end the method will return Null. + Oterwise the maximum of getEnd() and repeating.getEnd() will be returned. +

    + @see #getEnd + @see Repeating + */ + Date getMaxEnd(); + + User getOwner(); + + /** returns the reservation that owns the appointment. + @return the reservation that owns the appointment or null if + the appointment does not belong to a reservation. + */ + Reservation getReservation(); + + /** @return null if the appointment has no repeating + */ + Repeating getRepeating(); + + /** Enables repeating for this appointment. + Use getRepeating() to manipulate the repeating. */ + void setRepeatingEnabled(boolean enableRepeating); + + /** returns if the appointment has a repeating */ + boolean isRepeatingEnabled(); + + /** Changes the start- and end-time of the appointment. + */ + void move(Date start,Date end); + /** Moves the start-time of the appointment. + The end-time will be adjusted accordingly to the duration of the appointment. + */ + void move(Date newStart); + + /** Tests two appointments for overlap. + Important: Times like 13:00-14:00 and 14:00-15:00 do not overlap + The overlap-relation must be symmetric a1.overlaps(a2) == a2.overlaps(a1) + @return true if the appointment overlaps the given appointment. + */ + boolean overlaps(Appointment appointment); + + boolean overlaps(AppointmentBlock block); + + /** Test for overlap with a period. + * same as overlaps( start, end, true) + * @return true if the overlaps with the given period. + */ + boolean overlaps(Date start,Date end); + + /** Test for overlap with a period. + * same as overlaps( start, end, true) + * @return true if the overlaps with the given period. + */ + boolean overlaps(TimeInterval interval); + + /** Test for overlap with a period. You can specify if exceptions should be considered in the overlapping algorithm. + * if excludeExceptions is set an overlap will return false if all dates are excluded by exceptions in the specfied start-end intervall + @return true if the overlaps with the given period. + */ + boolean overlaps(Date start,Date end, boolean excludeExceptions); + + /** Returns if the exceptions, repeatings, start and end dates of the Appoinemnts are the same.*/ + boolean matches(Appointment appointment); + + /** @param maxDate must not be null, specifies the last date that should be searched + + returns the first date at which the two appointments differ (dates after maxDate will not be calculated) + */ + Date getFirstDifference( Appointment a2, Date maxDate ); + + /** @param maxDate must not be null, specifies the last date that should be searched + + returns the last date at which the two appointments differ. (dates after maxDate will not be calculated)*/ + Date getLastDifference( Appointment a2, Date maxDate ); + + /** this method will be used for future enhancements */ + boolean isWholeDaysSet(); + + /** this method will be used for future enhancements */ + void setWholeDays(boolean enable); + + /** adds all Appointment-blocks in the given period to the blocks collection. + A block is in the period if its starttime<end or its endtime>start. Exceptions are excluded, i.e. there is no block on an exception date. + */ + void createBlocks(Date start,Date end,Collection blocks); + + /** adds all Appointment-blocks in the given period to the blocks collection. + A block is in the period if its starttime<end or its endtime>start. You can specify if exceptions should be excluded. If this is set no blocks are added on an exception date. + */ + void createBlocks(Date start,Date end,Collection blocks, boolean excludeExceptions); + + final Appointment[] EMPTY_ARRAY = new Appointment[0]; + + public class AppointmentUtil + { + static public Map idMap(Appointment[] appointments) + { + Map idMap = new LinkedHashMap(); + for (Appointment app: appointments) + { + idMap.put( app.getId(), app ); + } + return idMap; + } + } +} + + + + + + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/domain/AppointmentBlock.java b/rapla-source-1.8.2/src/org/rapla/entities/domain/AppointmentBlock.java new file mode 100644 index 0000000..05a250e --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/domain/AppointmentBlock.java @@ -0,0 +1,153 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2011 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities.domain; + +import java.util.Date; + +import org.rapla.components.util.DateTools; + + + +/** + * This class represents a time block of an appointment. + * @since Rapla 1.4 + */ +public class AppointmentBlock implements Comparable +{ + long start; + long end; + boolean isException; + private Appointment appointment; + + /** + * Basic constructor + */ + public AppointmentBlock(long start, long end, Appointment appointment, boolean isException) + { + this.start = start; + this.end = end; + this.appointment = appointment; + this.isException = isException; + } + + public AppointmentBlock(Appointment appointment) + { + this.start = appointment.getStart().getTime(); + this.end = appointment.getEnd().getTime(); + this.appointment = appointment; + this.isException = false; + } + + public boolean includes(AppointmentBlock a2) + { + return start <= a2.start && end>= a2.end; + } + + public boolean intersects(AppointmentBlock a2) + { + return start < a2.end && end> a2.start; + } + + + /** + * Returns the start date of this block + * + * @return Date + */ + public long getStart() + { + return start; + } + + /** + * Returns the end date of this block + * + * @return Date + */ + public long getEnd() + { + return end; + } + + /** + * Returns if the block is an exception from the appointment rule + * + */ + public boolean isException() + { + return isException; + } + /** + * Returns the appointment to which this block belongs + * + * @return Appointment + */ + public Appointment getAppointment() + { + return appointment; + } + + /** + * This method is used to compare two appointment blocks by their start dates + */ + public int compareTo(AppointmentBlock a2) + { + if ( a2 == this) + { + return 0; + } + AppointmentBlock a1 =this ; + if (a2.start > a1.start) + return -1; + if (a2.start < a1.start) + return 1; + if (a2.end > a1.end) + return 1; + if (a2.end < a1.end) + return -1; + int compareTo = appointment.getId().compareTo(a2.appointment.getId()); + return compareTo; + } + + public boolean equals( Object obj) + { + if ( obj == this) + { + return true; + } + AppointmentBlock other = (AppointmentBlock) obj; + if ( other.start != start || other.end != end) + { + return false; + } + return appointment.equals( other.appointment); + } + + @Override + public int hashCode() + { + if ( appointment == null) + { + return super.hashCode(); + } + return appointment.hashCode(); + } + + + public String toString() + { + return DateTools.formatDateTime(new Date(start)) + " - " + DateTools.formatDateTime(new Date(end)); + } + + +} diff --git a/rapla-source-1.8.2/src/org/rapla/entities/domain/AppointmentFormater.java b/rapla-source-1.8.2/src/org/rapla/entities/domain/AppointmentFormater.java new file mode 100644 index 0000000..ecb3610 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/domain/AppointmentFormater.java @@ -0,0 +1,27 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities.domain; +import java.util.List; + + + +/** Formats the different appointment outputs. */ +public interface AppointmentFormater +{ + String getShortSummary(Appointment appointment); + String getVeryShortSummary(Appointment appointment); + String getSummary( Appointment a ); + String getSummary( Repeating r , List periods); + String getSummary( Repeating r ); + String getExceptionSummary( Repeating r ); +} diff --git a/rapla-source-1.8.2/src/org/rapla/entities/domain/AppointmentStartComparator.java b/rapla-source-1.8.2/src/org/rapla/entities/domain/AppointmentStartComparator.java new file mode 100644 index 0000000..8bb6614 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/domain/AppointmentStartComparator.java @@ -0,0 +1,69 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities.domain; +import java.util.Comparator; + + +public class AppointmentStartComparator implements Comparator { + public int compare(Appointment a1,Appointment a2) { + + if ( a1.equals(a2)) return 0; + if (a1.getStart().before(a2.getStart())) + return -1; + if (a1.getStart().after(a2.getStart())) + return 1; + + Reservation r1 = a1.getReservation(); + Reservation r2 = a2.getReservation(); + if ( r1 == null && r2 == null ) + { + @SuppressWarnings("unchecked") + int compareTo = ((Comparable)a1).compareTo( (Comparable)a2 ); + return compareTo; + } + if ( r1 == null) + { + return 1; + } + if ( r2 == null) + { + return -1; + } + if ( r1 == r2) + { + int i1 = r1.indexOf( a1); + int i2 = r1.indexOf( a2); + if ( i1 < i2) + { + return -1; + } + if ( i1 > i2) + { + return 1; + } + if ( i1 == i2) + { + throw new IllegalStateException(" appointment should have passed equal before "); + } + } + // compare the reservation ids + { + @SuppressWarnings("unchecked") + int compareTo = ((Comparable)r1).compareTo( (Comparable)r2 ); + return compareTo; + } + } + +} + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/domain/EntityPermissionContainer.java b/rapla-source-1.8.2/src/org/rapla/entities/domain/EntityPermissionContainer.java new file mode 100644 index 0000000..cd13028 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/domain/EntityPermissionContainer.java @@ -0,0 +1,21 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org . | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.entities.domain; + +import org.rapla.entities.Entity; + + +public interface EntityPermissionContainer extends Entity,PermissionContainer +{ +} diff --git a/rapla-source-1.8.2/src/org/rapla/entities/domain/Period.java b/rapla-source-1.8.2/src/org/rapla/entities/domain/Period.java new file mode 100644 index 0000000..7ff0375 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/domain/Period.java @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities.domain; + +import java.util.Date; + +import org.rapla.entities.Named; +import org.rapla.entities.RaplaObject; +import org.rapla.entities.RaplaType; +/** +Most universities and schools are planning for fixed periods/terms +rather than arbitrary dates. Rapla provides support for this periods. +*/ +public interface Period extends RaplaObject,Comparable,Named { + final RaplaType TYPE = new RaplaType(Period.class, "period"); + + Date getStart(); + Date getEnd(); + int getWeeks(); + String getName(); + + boolean contains(Date date); + String toString(); + public static Period[] PERIOD_ARRAY = new Period[0]; +} + + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/domain/Permission.java b/rapla-source-1.8.2/src/org/rapla/entities/domain/Permission.java new file mode 100644 index 0000000..451081a --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/domain/Permission.java @@ -0,0 +1,212 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org . | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.entities.domain; + +import java.util.Date; + +import org.rapla.entities.Category; +import org.rapla.entities.User; + +/** New feature to restrict the access to allocatables on a per user/group basis. + * Specify absolute and relative booking-timeframes for each resource + * per user/group. You can, for example, prevent modifing appointments + * in the past, by setting the relative start-time to 0. +*/ +public interface Permission +{ + String GROUP_CATEGORY_KEY = "user-groups"; + + @Deprecated + String GROUP_MODIFY_PREFERENCES_KEY = "modify-preferences"; + @Deprecated + String GROUP_CAN_EDIT_TEMPLATES = "edit-templates"; + @Deprecated + String GROUP_CAN_READ_EVENTS_FROM_OTHERS = "read-events-from-others"; + @Deprecated + String GROUP_CAN_CREATE_EVENTS = "create-events"; + @Deprecated + String GROUP_REGISTERER_KEY = "registerer"; + + enum AccessLevel + { + DENIED(0), + READ_TYPE(20), + CREATE(30), + READ_NO_ALLOCATION(50), + READ(100), + ALLOCATE(200), + ALLOCATE_CONFLICTS(300), + EDIT(350), + ADMIN(400); + AccessLevel(int level) + { + this.level = level; + } + private final int level; + public static AccessLevel find(int level) + { + for(AccessLevel v :values()) + { + if (v.level == level) + { + return v; + } + } + return null; + } + + @Deprecated + public int getNumericLevel() + { + return level; + } + + public boolean excludes(AccessLevel level) { + return level.level > this.level; + } + + public boolean includes(AccessLevel level) { + return level.level <= this.level; + } + + public static AccessLevel find(String accessLevel) { + AccessLevel valueOf = valueOf( accessLevel.toUpperCase()); + if ( valueOf == null && "READ_ONLY_INFORMATION".equalsIgnoreCase(accessLevel)) + { + return READ_NO_ALLOCATION; + } + return valueOf; + } + } + + AccessLevel DENIED = AccessLevel.DENIED; + AccessLevel READ_TYPE =AccessLevel.READ_TYPE; + AccessLevel CREATE = AccessLevel.CREATE; + AccessLevel READ_NO_ALLOCATION = AccessLevel.READ_NO_ALLOCATION; + AccessLevel READ = AccessLevel.READ; + AccessLevel ALLOCATE = AccessLevel.ALLOCATE; + AccessLevel ALLOCATE_CONFLICTS = AccessLevel.ALLOCATE_CONFLICTS; + AccessLevel EDIT = AccessLevel.EDIT; + AccessLevel ADMIN = AccessLevel.ADMIN; + +// public static class AccessTable +// { +// final LinkedHashMap map = new LinkedHashMap(); +// { +// map.put( READ_TYPE,"read_type"); +// map.put( CREATE, "create"); +// map.put( DENIED,"denied"); +// map.put( READ_NO_ALLOCATION,"read_no_allocation"); +// map.put( READ,"read"); +// map.put( ALLOCATE, "allocate"); +// map.put( ALLOCATE_CONFLICTS, "allocate_conflicts"); +// map.put( EDIT, "edit"); +// map.put( ADMIN, "admin"); +// } +// public String get(int accessLevel) +// { +// return map.get(accessLevel); +// } +// +// public Integer findAccessLevel(String accessLevelName) +// { +// AccessLevel.valueOf(arg0) +// for (Map.Entry entry: map.entrySet()) +// { +// if (entry.getValue().equals( accessLevelName)) +// { +// return entry.getKey(); +// } +// } +// return null; +// } +// +// public Set keySet() { +// return map.keySet(); +// } +// } + + //AccessTable ACCESS_LEVEL_NAMEMAP = new AccessTable(); + /* + * + static + { + Arrays. + for (int i=0;i getPermissionList(); + + + class Util + { + static public void addDifferences(Set invalidatePermissions, PermissionContainer oldContainer, PermissionContainer newContainer) { + Collection oldPermissions = oldContainer.getPermissionList(); + Collection newPermissions = newContainer.getPermissionList(); + addDifferences(invalidatePermissions, oldPermissions, newPermissions); + } + + + public static boolean differs(Collection oldPermissions, Collection newPermissions) { + HashSet set = new HashSet(); + addDifferences(set, oldPermissions, newPermissions); + return set.size() > 0; + } + + public static void replace(PermissionContainer permissionContainer, Collection permissions) { + Collection permissionList = new ArrayList(permissionContainer.getPermissionList()); + for (Permission p:permissionList) + { + permissionContainer.removePermission(p); + } + for (Permission p:permissions) + { + permissionContainer.addPermission( p ); + } + } + + public static void copyPermissions(DynamicType type, PermissionContainer permissionContainer) { + Collection permissionList = type.getPermissionList(); + for ( Permission p:permissionList) + { + Permission clone = p.clone(); + Permission.AccessLevel accessLevel = clone.getAccessLevel(); + if (!accessLevel.equals(Permission.CREATE) && !accessLevel.equals(Permission.READ_TYPE)) + { + permissionContainer.addPermission( clone); + } + } + } + + static public boolean hasAccess(PermissionContainer container, User user, Permission.AccessLevel accessLevel ) { + Iterable permissions = container.getPermissionList(); + if (isOwner(container, user)) + { + return true; + } + return hasAccess(permissions,user, accessLevel, null, null, null, false); + } + + /** returns if the user has the permission to read the information and the allocations of this resource.*/ + static public boolean canModify(PermissionContainer container,User user) { + if ( container instanceof DynamicType) + { + return user.isAdmin(); + } + return hasAccess( container,user, Permission.EDIT); + } + + static public boolean canAdmin(PermissionContainer container,User user) { + if ( container instanceof DynamicType) + { + return user.isAdmin(); + } + return hasAccess( container,user, Permission.ADMIN); + } + + /** returns if the user has the permission to modify the allocatable (and also its permission-table).*/ + static public boolean canRead(PermissionContainer container,User user) + { + if ( isOwner(container, user)) + { + return true; + } + if ( container instanceof Classifiable) + { + if (!canReadType((Classifiable)container, user)) + { + return false; + } + } + if ( container instanceof DynamicType) + { + return canRead( (DynamicType) container, user); + } + else + { + return hasAccess( container,user, Permission.READ ); + } + } + + private static boolean canReadType(Classifiable classifiable, User user) { + Classification classification = classifiable.getClassification(); + if ( classification != null) + { + DynamicType type = classification.getType(); + return canRead(type, user); + } + return true; + } + + public static boolean canCreate(Classifiable classifiable, User user) { + DynamicType type = classifiable.getClassification().getType(); + return canCreate(type, user); + } + + public static boolean canCreate(DynamicType type, User user) { + Collection permissionList = type.getPermissionList(); + boolean result = matchesAccessLevel( permissionList, user, Permission.CREATE,Permission.ADMIN); + return result; + } + + public static boolean canRead(DynamicType type, User user) { + Collection permissionList = type.getPermissionList(); + boolean result = matchesAccessLevel( permissionList, user, Permission.READ_TYPE, Permission.CREATE,Permission.ADMIN); + return result; + } + + /** + * + * @return NO_PERMISSION if permission does not effect user + * @return ALL_USER_PERMISSION if permission affects all users + * @return USER_PERMISSION if permission specifies the current user + * @return if the permission affects a users group the depth of the permission group category specified + */ + static public int getUserEffect(User user,Permission p, Collection groups) + { + User pUser = p.getUser(); + Category pGroup = p.getGroup(); + if ( pUser == null && pGroup == null ) + { + return PermissionImpl.ALL_USER_PERMISSION; + } + if ( pUser != null && user.equals( pUser ) ) + { + return PermissionImpl.USER_PERMISSION; + } + else if ( pGroup != null ) + { + if ( groups.contains(pGroup)) + { + return PermissionImpl.GROUP_PERMISSION; + } + } + return PermissionImpl.NO_PERMISSION; + } + + + static public TimeInterval getInterval(Iterable permissionList,User user,Date today, Permission.AccessLevel requestedAccessLevel ) { + if ( user == null || user.isAdmin() ) + return new TimeInterval( null, null); + + TimeInterval interval = null; + int maxEffectLevel = PermissionImpl.NO_PERMISSION; + Collection groups = getGroupsIncludingParents( user ); + for ( Permission p:permissionList) + { + int effectLevel = getUserEffect(user,p,groups); + Permission.AccessLevel accessLevel = p.getAccessLevel(); + if ( effectLevel >= maxEffectLevel && effectLevel > PermissionImpl.NO_PERMISSION && accessLevel.includes( requestedAccessLevel)) + { + Date start; + Date end; + if (accessLevel!= Permission.ADMIN ) + { + start = p.getMinAllowed( today); + end = p.getMaxAllowed(today); + if ( end != null && end.before( today)) + { + continue; + } + } + else + { + start = null; + end = null; + } + if ( interval == null || effectLevel > maxEffectLevel) + { + interval = new TimeInterval(start, end); + } + else + { + interval = interval.union(new TimeInterval(start, end)); + } + maxEffectLevel = effectLevel; + } + } + return interval; + } + + public static boolean hasPermissionToAllocate(User user, Allocatable a) { + Collection groups = getGroupsIncludingParents(user); + for ( Permission p: a.getPermissionList()) { + if (!affectsUser( user, p, groups )) + { + continue; + } + if ( p.getAccessLevel().includes(Permission.ALLOCATE)) + { + return true; + } + } + return false; + } + + public static boolean hasPermissionToAllocate( User user, Appointment appointment,Allocatable allocatable, Reservation original, Date today) { + if ( user.isAdmin()) { + return true; + } + Collection groups = getGroupsIncludingParents(user); + + Date start = appointment.getStart(); + Date end = appointment.getMaxEnd(); + + for ( Permission p:allocatable.getPermissionList()) + { + Permission.AccessLevel accessLevel = p.getAccessLevel(); + if ( (!affectsUser( user, p, groups )) || accessLevel.excludes(Permission.READ)) { + continue; + } + + if ( accessLevel == Permission.ADMIN) + { + // user has the right to allocate + return true; + } + + if ( accessLevel.includes(Permission.ALLOCATE) && p.covers( start, end, today ) ) + { + return true; + } + if ( original == null ) + { + continue; + } + + // We must check if the changes of the existing appointment + // are in a permisable timeframe (That should be allowed) + + // 1. check if appointment is old, + // 2. check if allocatable was already assigned to the appointment + Appointment originalAppointment = original.findAppointment( appointment ); + if ( originalAppointment == null || !original.hasAllocated( allocatable, originalAppointment)) + { + continue; + } + + // 3. check if the appointment has changed during + // that time + if ( appointment.matches( originalAppointment ) ) + { + return true; + } + if ( accessLevel.includes(Permission.ALLOCATE )) + { + Date maxTime = DateTools.max(appointment.getMaxEnd(), originalAppointment.getMaxEnd()); + if (maxTime == null) + { + maxTime = DateTools.addYears( today, 4); + } + + Date minChange = appointment.getFirstDifference( originalAppointment, maxTime ); + Date maxChange = appointment.getLastDifference( originalAppointment, maxTime ); + //System.out.println ( "minChange: " + minChange + ", maxChange: " + maxChange ); + + if ( p.covers( minChange, maxChange, today ) ) { + return true; + } + } + } + return false; + } + + public static boolean canCreateConflicts(Allocatable container, User user) { + Collection permissions = container.getPermissionList(); + if ( !canReadType(container, user)) + { + return false; + } + return hasAccess( permissions,user, Permission.ALLOCATE_CONFLICTS, null, null, null, false); + } + + /** + * Checks if the user is allowed to make an allocation in the passed time. + * @return + */ + public static boolean canAllocate(Allocatable container, User user, Date start, Date end, Date today) { + Collection permissions = container.getPermissionList(); + return hasAccess(permissions,user, Permission.ALLOCATE,start, end, today, false); + } + + /** + * Checks if the user is allowed to make an allocation in the future (starting with date today) + * @param container + * @param user + * @param today + * @return + */ + public static boolean canAllocate(Allocatable container, User user, Date today) { + Collection permissions = container.getPermissionList(); + if ( !canReadType(container, user)) + { + return false; + } + boolean hasAccess = hasAccess(permissions,user, Permission.ALLOCATE, null, null, today, true); + if ( !hasAccess ) + { + return false; + } + + return true; + } + + static private boolean matchesAccessLevel(Iterable permissions, User user, AccessLevel... accessLevels ) { + if ( user == null || user.isAdmin() ) + return true; + + Collection groups = getGroupsIncludingParents(user); + for ( Permission p:permissions ) + { + for ( AccessLevel accessLevel:accessLevels) + { + if (p.getAccessLevel() == accessLevel) + { + int effectLevel = getUserEffect(user, p, groups); + if ( effectLevel > PermissionImpl.NO_PERMISSION) + { + return true; + } + } + } + } + return false; + } + + + static private boolean hasAccess(Iterable permissions, User user, Permission.AccessLevel accessLevel, Date start, Date end, Date today, boolean checkOnlyToday ) { + if ( user == null || user.isAdmin() ) + return true; + + AccessLevel maxAccessLevel = AccessLevel.DENIED; + int maxEffectLevel = PermissionImpl.NO_PERMISSION; + Collection groups = getGroupsIncludingParents( user); + for ( Permission p:permissions ) { + int effectLevel = getUserEffect(user,p, groups); + + if ( effectLevel >= maxEffectLevel && effectLevel > PermissionImpl.NO_PERMISSION) + { + if ( p.hasTimeLimits() && accessLevel.includes( Permission.ALLOCATE) && today!= null) + { + if (p.getAccessLevel() != Permission.ADMIN ) + { + if ( checkOnlyToday ) + { + if (!((PermissionImpl)p).validInTheFuture(today)) + { + continue; + } + } + else + { + if (!p.covers( start, end, today )) + { + continue; + } + } + } + } + if ( maxAccessLevel.excludes( p.getAccessLevel()) || effectLevel > maxEffectLevel) + { + maxAccessLevel = p.getAccessLevel(); + } + maxEffectLevel = effectLevel; + } + } + boolean granted = maxAccessLevel.includes( accessLevel) ; + return granted; + } + + + + + static private Collection getGroupsIncludingParents(User user) { + Collection groups = new HashSet( ); + for ( Category group: ((UserImpl) user).getGroupList()) + { + groups.add( group); + Category parent = group.getParent(); + while ( parent != null) + { + if ( parent == group) + { + throw new IllegalStateException("Parent added to own child"); + } + if (parent == null || parent.getParent() == null || parent.getKey().equals("user-groups")) + { + break; + } + if ( ! groups.contains( parent)) + { + groups.add( parent); + } + parent = parent.getParent(); + + } + } + return groups; + } + + + private static void addDifferences(Set invalidatePermissions, Collection oldPermissions, Collection newPermissions) { + // we leave this condition for a faster equals check + int size = oldPermissions.size(); + if (size == newPermissions.size()) + { + Iterator newPermissionsIt = newPermissions.iterator(); + for (Permission oldPermission:oldPermissions) + { + Permission newPermission = newPermissionsIt.next(); + if (!oldPermission.equals(newPermission)) + { + invalidatePermissions.add( oldPermission); + invalidatePermissions.add( newPermission); + } + } + } + else + { + HashSet newSet = new HashSet(newPermissions); + HashSet oldSet = new HashSet(oldPermissions); + { + HashSet changed = new HashSet( newSet); + changed.removeAll( oldSet); + invalidatePermissions.addAll(changed); + } + { + HashSet changed = new HashSet(oldSet); + changed.removeAll( newSet); + invalidatePermissions.addAll(changed); + } + } + } + + + + static private boolean affectsUser(User user, Permission p, Collection groups) { + int userEffect = getUserEffect( user, p, groups ); + return userEffect> PermissionImpl.NO_PERMISSION; + } + + + static public boolean canReadOnlyInformation(Allocatable classifiable, User user) { + if ( !canReadType(classifiable, user)) + { + return false; + } + if (isOwner(classifiable, user)) + { + return true; + } + return hasAccess( classifiable,user, Permission.READ_NO_ALLOCATION ); + } + + + private static boolean isOwner(Ownable classifiable, User user) { + User owner = classifiable.getOwner(); + if ( owner != null && owner.equals( user)) + { + return true; + } + return false; + } + + + /** old permission_modify should sync with new permission model for a while or until permission_modify attribute is removed + * @deprecated + * @param entity + * @param persistant + */ + @Deprecated + static public void processOldPermissionModify(Classifiable entity, Classifiable persistant) + { + Classification classification = entity.getClassification(); + if ( classification == null) + { + return; + } + Attribute attribute = classification.getAttribute("permission_modify"); + if ( attribute == null || attribute.getType() != AttributeType.CATEGORY ) + { + return; + } + Collection newValues = classification.getValues(attribute); + Collection oldValues = persistant != null ? persistant.getClassification().getValues(attribute) : Collections.emptyList(); + boolean permissionModifyChanged = !newValues.equals( oldValues); + PermissionContainer permissionContainer = (PermissionContainer) entity; + Collection newPermissionList = permissionContainer.getPermissionList(); + boolean permissionChanged = persistant != null && differs(newPermissionList, ((PermissionContainer)persistant).getPermissionList()); + // changed permissions take precedence over changed permission_modify + if ( permissionChanged ) + { + List newCategories = new ArrayList(); + for ( Permission p:newPermissionList) + { + Category group = p.getGroup(); + Permission.AccessLevel accessLevel = p.getAccessLevel(); + if (group != null && accessLevel == Permission.AccessLevel.ADMIN) + { + Object rootCategory = attribute.getConstraint( ConstraintIds.KEY_ROOT_CATEGORY ); + if ( rootCategory == null ) + { + newCategories.add( group ); + } + else if ( rootCategory instanceof Category) + { + Category root = (Category) rootCategory; + if ( root.isAncestorOf( group )) + { + newCategories.add( group ); + } + } + } + } + classification.setValues( attribute, newCategories); + + } + else if ( permissionModifyChanged ) + { + Set existingAdminGroups = new HashSet(); + for ( Permission p:new ArrayList(newPermissionList)) + { + Category group = p.getGroup(); + Permission.AccessLevel accessLevel = p.getAccessLevel(); + if (group != null && accessLevel == Permission.AccessLevel.ADMIN) + { + // remove permission if not in permission modify group + if ( !newValues.contains(group )) + { + permissionContainer.removePermission( p); + continue; + } + existingAdminGroups.add( group ); + + } + } + + for (Object obj:newValues) + { + Category category = (Category) obj; + if ( !existingAdminGroups.contains( category )) + { + Permission permission = permissionContainer.newPermission(); + permission.setGroup(category ); + permission.setAccessLevel( Permission.AccessLevel.ADMIN); + permissionContainer.addPermission(permission); + } + } + + } + + } + + + + + + } +} diff --git a/rapla-source-1.8.2/src/org/rapla/entities/domain/RaplaObjectAnnotations.java b/rapla-source-1.8.2/src/org/rapla/entities/domain/RaplaObjectAnnotations.java new file mode 100644 index 0000000..8fad535 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/domain/RaplaObjectAnnotations.java @@ -0,0 +1,35 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities.domain; + +public interface RaplaObjectAnnotations +{ + /** Template Annotation */ + final String KEY_TEMPLATE = "template"; + final String KEY_TEMPLATE_COPYOF = "copyof"; + /** Template externalid annotation */ + final String KEY_EXTERNALID = "externalid"; + +} + + + + + + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/domain/Repeating.java b/rapla-source-1.8.2/src/org/rapla/entities/domain/Repeating.java new file mode 100644 index 0000000..2060307 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/domain/Repeating.java @@ -0,0 +1,91 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities.domain; +import java.util.Date; + +/** Encapsulates the repeating rule for an appointment. + @see Appointment*/ +public interface Repeating { + RepeatingType DAILY = RepeatingType.DAILY; + RepeatingType WEEKLY = RepeatingType.WEEKLY; + RepeatingType MONTHLY = RepeatingType.MONTHLY; + RepeatingType YEARLY = RepeatingType.YEARLY; + + void setInterval(int interval); + /** returns the number of intervals between two repeatings. + * That are in the selected context: + *
      + *
    • For weekly repeatings: Number of weeks.
    • + *
    • For dayly repeatings: Number of days.
    • + *
    + */ + int getInterval(); + /** The value returned depends which method was called last. + * If setNumber() has been called with a parameter + * >=0 fixedNumber() will return true. If + * setEnd() has been called + * fixedNumber() will return false. + * @see #setEnd + * @see #setNumber + */ + boolean isFixedNumber(); + /** Set the end of repeating. + * If this value is set to null and the + * number is set to -1 the appointment will repeat + * forever. + * @param end If not null isFixedNumber will return true. + * @see #setNumber + */ + void setEnd(Date end); + /* @return end of repeating or null if unlimited */ + Date getEnd(); + /** Set a fixed number of repeating. + * If this value is set to -1 + * and the repeating end is set to null the appointment will + * repeat forever. + * @param number If >=0 isFixedNumber will return true. + * @see #setEnd + * @see #isFixedNumber + */ + void setNumber(int number); + /* @return number of repeating or -1 if it repeats forever. */ + int getNumber(); + /* daily,weekly, monthly */ + RepeatingType getType(); + /* daily,weekly, monthly */ + void setType(RepeatingType type); + /* exceptions for this repeating. */ + Date[] getExceptions(); + boolean hasExceptions(); + + boolean isWeekly(); + boolean isDaily(); + boolean isMonthly(); + boolean isYearly(); + void addException(Date date); + void removeException(Date date); + void clearExceptions(); + + /** returns the appointment of this repeating. + @see Appointment + */ + Appointment getAppointment(); + + /** copy the values from another repeating */ + void setFrom(Repeating repeating); + + /** tests if an exception is added for the given date */ + boolean isException(long date); + Object clone(); +} + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/domain/RepeatingEnding.java b/rapla-source-1.8.2/src/org/rapla/entities/domain/RepeatingEnding.java new file mode 100644 index 0000000..d7dd883 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/domain/RepeatingEnding.java @@ -0,0 +1,73 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities.domain; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/**Currently Rapla supports the following types: + *
      +
    • weekly
    • +
    • daily
    • +
    + */ +public class RepeatingEnding implements Serializable { + // Don't forget to increase the serialVersionUID when you change the fields + private static final long serialVersionUID = 1; + + private String type; + + final static public RepeatingEnding END_DATE = new RepeatingEnding("repeating.end_date"); + final static public RepeatingEnding N_TIMES = new RepeatingEnding("repeating.n_times"); + final static public RepeatingEnding FOREVEVER = new RepeatingEnding("repeating.forever"); + + private static Map types; + + private RepeatingEnding(String type) { + this.type = type; + if (types == null) { + types = new HashMap(); + } + types.put( type, this); + } + + public boolean is(RepeatingEnding other) { + if ( other == null) + return false; + return type.equals( other.type); + } + + public static RepeatingEnding findForString(String string ) { + RepeatingEnding type = types.get( string ); + return type; + } + + public String toString() { + return type; + } + + public boolean equals( Object other) { + if ( !(other instanceof RepeatingEnding)) + return false; + return is( (RepeatingEnding)other); + } + + public int hashCode() { + return type.hashCode(); + } +} + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/domain/RepeatingType.java b/rapla-source-1.8.2/src/org/rapla/entities/domain/RepeatingType.java new file mode 100644 index 0000000..1ae01d8 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/domain/RepeatingType.java @@ -0,0 +1,67 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2014 Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities.domain; + + +/**Currently Rapla supports the following types: +
      +
    • weekly
    • +
    • daily
    • +
    • monthly
    • +
    • yearly
    • +
    + */ +public enum RepeatingType { + WEEKLY("weekly"), + DAILY("daily"), + MONTHLY("monthly"), + YEARLY("yearly"); + + String type; + RepeatingType(String type) { + this.type = type; + } +// public RepeatingType WEEKLY = new RepeatingType("weekly"); +// public RepeatingType DAILY = new RepeatingType("daily"); +// public RepeatingType MONTHLY = new RepeatingType("monthly"); +// public RepeatingType YEARLY = new RepeatingType("yearly"); +// + + + + public boolean is(RepeatingType other) { + if ( other == null) + return false; + return type.equals( other.type); + } + + public static RepeatingType findForString(String string ) { + for (RepeatingType type:values()) + { + if ( type.type.equals( string)) + { + return type; + } + } + return null; + } + + public String toString() { + return type; + } + +} + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/domain/Reservation.java b/rapla-source-1.8.2/src/org/rapla/entities/domain/Reservation.java new file mode 100644 index 0000000..50f9109 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/domain/Reservation.java @@ -0,0 +1,122 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender, Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org . | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ + +package org.rapla.entities.domain; + +import java.util.Collection; +import java.util.Date; +import java.util.Locale; + +import org.rapla.entities.Annotatable; +import org.rapla.entities.Named; +import org.rapla.entities.Ownable; +import org.rapla.entities.RaplaType; +import org.rapla.entities.Timestamp; +import org.rapla.entities.dynamictype.Classifiable; + +/** The Reservation interface is the central interface of + * Rapla. Objects implementing this interface are the courses or + * events to be scheduled. A Reservation consist + * of a group of appointments and a set of allocated + * resources (rooms, notebooks, ..) and persons. + * By default all resources and persons are allocated on every appointment. + * If you want to associate allocatable objects to special appointments + * use Restrictions. + * + * @see Classifiable + * @see Appointment + * @see Allocatable + */ +public interface Reservation extends EntityPermissionContainer,Classifiable,Named,Ownable,Timestamp, Annotatable,Comparable +{ + final RaplaType TYPE = new RaplaType(Reservation.class,"reservation",'e'); + + public final int MAX_RESERVATION_LENGTH = 100; + + void addAppointment(Appointment appointment); + void removeAppointment(Appointment appointment); + /** returns all appointments that are part off the reservation.*/ + + Collection getSortedAppointments(); + + Appointment[] getAppointments(); + /** Restrict an allocation to one ore more appointments. + * By default all objects of a reservation are allocated + * on every appointment. Restrictions allow to model + * relations between allocatables and appointments. + * A resource or person is restricted if its connected to + * one or more appointments instead the whole reservation. + */ + void setRestriction(Allocatable alloc,Appointment[] appointments); + + void setRestriction(Appointment appointment, Allocatable[] restrictedAllocatables); + + Appointment[] getRestriction(Allocatable alloc); + + /** returns all appointments for an allocatable. This are either the restrictions, if there are any or all appointments + * @see #getRestriction + * @see #getAppointments*/ + Appointment[] getAppointmentsFor(Allocatable alloc); + + /** find an appointment in the reservation that equals the specified appointment. This is usefull if you have the + * persistant version of an appointment and want to discover the editable appointment in the working copy of a reservation. + * This does only work with persistant appointments, that have an id.*/ + Appointment findAppointment(Appointment appointment); + + void addAllocatable(Allocatable allocatable); + void removeAllocatable(Allocatable allocatable); + Allocatable[] getAllocatables(); + + Allocatable[] getRestrictedAllocatables(Appointment appointment); + + /** get all allocatables that are allocated on the appointment, restricted and non restricted ones*/ + Allocatable[] getAllocatablesFor(Appointment appointment); + + /** returns if an the reservation has allocated the specified object. */ + boolean hasAllocated(Allocatable alloc); + + /** returns if the allocatable is reserved on the specified appointment. */ + boolean hasAllocated(Allocatable alloc,Appointment appointment); + + /** returns all persons that are associated with the reservation. + Need not necessarily to be users of the System. + */ + Allocatable[] getPersons(); + + /** returns all resources that are associated with the reservation. */ + Allocatable[] getResources(); + + + + public static final Reservation[] RESERVATION_ARRAY = new Reservation[0]; + + /** returns the first (in time) start of all appointments. Returns null when the reservation has no appointments*/ + Date getFirstDate(); + + /** returns the last (in time) maxEnd of all appointments. Returns null when one appointment has no end*/ + Date getMaxEnd(); + + String format(Locale locale, String annotationName); + + String format(Locale locale, String annotationName, AppointmentBlock block); + + int indexOf(Appointment a1); + +} + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/domain/ReservationHelper.java b/rapla-source-1.8.2/src/org/rapla/entities/domain/ReservationHelper.java new file mode 100644 index 0000000..db194c3 --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/domain/ReservationHelper.java @@ -0,0 +1,62 @@ +package org.rapla.entities.domain; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +import org.rapla.facade.PeriodModel; + +public class ReservationHelper +{ + + static public void makeRepeatingForPeriod(PeriodModel model, Appointment appointment, RepeatingType repeatingType, int repeatings) { + appointment.setRepeatingEnabled(true); + Repeating repeating = appointment.getRepeating(); + repeating.setType( repeatingType ); + Period period = model.getNearestPeriodForStartDate( appointment.getStart()); + if ( period != null && repeatings <=1) { + repeating.setEnd(period.getEnd()); + } else { + repeating.setNumber( repeatings ); + } + } + + /** find the first visible reservation*/ + static public Date findFirst( List reservationList) { + Date firstStart = null; + Iterator it = reservationList.iterator(); + while (it.hasNext()) { + Appointment[] appointments = ( it.next()).getAppointments(); + for (int i=0;i blocks = new ArrayList(); + appointments[i].createBlocks( start, firstStart, blocks ); + for (AppointmentBlock block: blocks) { + if (block.getStart() { + NamedComparator namedComp; + public ReservationStartComparator(Locale locale) { + namedComp = new NamedComparator( locale); + } + public int compare(Reservation o1,Reservation o2) { + + if ( o1.equals(o2)) return 0; + Reservation r1 = o1; + Reservation r2 = o2; + if (getStart(r1).before(getStart(r2))) + return -1; + if (getStart(r1).after(getStart(r2))) + return 1; + + return namedComp.compare(o1,o2); + } + + public static Date getStart(Reservation r) { + Date maxDate = null; + Appointment[] apps =r.getAppointments(); + for ( int i=0;i< apps.length;i++) { + Appointment app = apps[i]; + if (maxDate == null || app.getStart().before( maxDate)) { + maxDate = app.getStart() ; + } + } + if ( maxDate == null) { + maxDate = new Date(); + } + return maxDate; + } + + public int compare(Date d1,Object o2) { + if (o2 instanceof Date) + return d1.compareTo((Date) o2); + + Reservation r2 = (Reservation) o2; + if (d1.before(getStart(r2))) { + //System.out.println(a2 + ">" + d1); + return -1; + } + if (d1.after(getStart(r2))) { + // System.out.println(a2 + "<" + d1); + return 1; + } + + // If appointment.getStart().equals(date) + // set the appointment before the date + return 1; + } + +} + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/domain/ResourceAnnotations.java b/rapla-source-1.8.2/src/org/rapla/entities/domain/ResourceAnnotations.java new file mode 100644 index 0000000..ba5e68a --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/domain/ResourceAnnotations.java @@ -0,0 +1,31 @@ +/*--------------------------------------------------------------------------* + | Copyright (C) 2006 Gereon Fassbender, Christopher Kohlhaas | + | | + | This program is free software; you can redistribute it and/or modify | + | it under the terms of the GNU General Public License as published by the | + | Free Software Foundation. A copy of the license has been included with | + | these distribution in the COPYING file, if not go to www.fsf.org | + | | + | As a special exception, you are granted the permissions to link this | + | program with every library, which license fulfills the Open Source | + | Definition as published by the Open Source Initiative (OSI). | + *--------------------------------------------------------------------------*/ +package org.rapla.entities.domain; + +public interface ResourceAnnotations +{ + final String KEY_CONFLICT_CREATION = "conflictCreation"; + final String VALUE_CONFLICT_CREATION_IGNORE = "ignore"; +} + + + + + + + + + + + + diff --git a/rapla-source-1.8.2/src/org/rapla/entities/domain/Template.java b/rapla-source-1.8.2/src/org/rapla/entities/domain/Template.java new file mode 100644 index 0000000..fbe391a --- /dev/null +++ b/rapla-source-1.8.2/src/org/rapla/entities/domain/Template.java @@ -0,0 +1,53 @@ +package org.rapla.entities.domain; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class Template implements Comparable