Compare commits
No commits in common. "main" and "gh-pages" have entirely different histories.
648 changed files with 38 additions and 159032 deletions
|
@ -1,16 +0,0 @@
|
|||
# EditorConfig is awesome: https://EditorConfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = spaces
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.java]
|
||||
indent_size = 4
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
15
.eslintrc
15
.eslintrc
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"extends": "eslint:recommended",
|
||||
"env": {
|
||||
"es6": true,
|
||||
"commonjs": true
|
||||
},
|
||||
"globals": {
|
||||
"app": "readonly",
|
||||
"HopObject": "readonly",
|
||||
"java": "readonly",
|
||||
"Packages": "readonly",
|
||||
"req": "readonly",
|
||||
"res": "readonly"
|
||||
}
|
||||
}
|
42
.github/actions/ssh/action.yml
vendored
42
.github/actions/ssh/action.yml
vendored
|
@ -1,42 +0,0 @@
|
|||
name: SSH setup
|
||||
description: Set up the SSH agent
|
||||
|
||||
inputs:
|
||||
config:
|
||||
description: The SSH configuration
|
||||
required: true
|
||||
key:
|
||||
description: The private SSH key
|
||||
required: true
|
||||
known-hosts:
|
||||
description: The list of known hosts
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
|
||||
steps:
|
||||
- name: Configure SSH
|
||||
shell: sh
|
||||
env:
|
||||
CONFIG: ${{ inputs.config }}
|
||||
KNOWN_HOSTS: ${{ inputs.known-hosts }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "${CONFIG}" > ~/.ssh/config
|
||||
echo "${KNOWN_HOSTS}" > ~/.ssh/known_hosts
|
||||
|
||||
- name: Start SSH agent
|
||||
shell: bash
|
||||
env:
|
||||
SOCKET: /tmp/ssh-agent.sock
|
||||
run: |
|
||||
echo "SSH_AUTH_SOCK=${SOCKET}" >> $GITHUB_ENV
|
||||
ssh-agent -a ${SOCKET} > /dev/null
|
||||
|
||||
- name: Add SSH key
|
||||
shell: bash
|
||||
env:
|
||||
KEY: ${{ inputs.key }}
|
||||
run: |
|
||||
ssh-add - <<< "${KEY}"
|
22
.github/workflows/build.yml
vendored
22
.github/workflows/build.yml
vendored
|
@ -1,22 +0,0 @@
|
|||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- .github/workflows/build.yml
|
||||
- build.gradle
|
||||
- settings.gradle
|
||||
- src/**
|
||||
- launcher/build.gradle
|
||||
- launcher/src/**
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: antville
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Compile with Gradle
|
||||
run: ./gradlew :compileJava
|
15
.github/workflows/deploy.yml
vendored
15
.github/workflows/deploy.yml
vendored
|
@ -1,15 +0,0 @@
|
|||
name: Deploy (Production)
|
||||
|
||||
on: workflow_dispatch
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: antville
|
||||
|
||||
environment:
|
||||
name: antville.org
|
||||
url: https://antville.org
|
||||
|
||||
steps:
|
||||
- name: Copy files to production server
|
||||
run: ssh staging-server deploy-helma
|
59
.github/workflows/release.yml
vendored
59
.github/workflows/release.yml
vendored
|
@ -1,59 +0,0 @@
|
|||
name: Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
tags: '2*'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: antville
|
||||
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
LC_TIME: en_US.UTF-8
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Create release notes
|
||||
id: create_release_notes
|
||||
run: |
|
||||
release_notes=$(npx git-cliff@latest --latest)
|
||||
# Write the release notes as a heredoc to the workflow output
|
||||
# ⚠️ No white space around `<<` is crucial!
|
||||
echo "release_notes<<.eot0x03" >> $GITHUB_OUTPUT
|
||||
echo "$release_notes" >> $GITHUB_OUTPUT
|
||||
echo ".eot0x03" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew assembleDist
|
||||
|
||||
- name: Create release
|
||||
uses: actions/forgejo-release@v2
|
||||
with:
|
||||
direction: upload
|
||||
url: https://code.host.antville.org
|
||||
token: ${{ github.token }}
|
||||
title: Helma ${{ github.ref_name }}
|
||||
release-dir: build/distributions
|
||||
release-notes: ${{ steps.create_release_notes.outputs.release_notes }}
|
||||
verbose: true
|
||||
|
||||
- name: Create release at GitHub
|
||||
run: |
|
||||
gh release create "$GITHUB_REF_NAME" \
|
||||
--repo "$GITHUB_REPOSITORY" \
|
||||
--title "Helma ${{ github.ref_name }}" \
|
||||
--notes "${{ steps.create_release_notes.outputs.release_notes }}"
|
||||
|
||||
- name: Upload release assets to GitHub
|
||||
run: |
|
||||
gh release upload "$GITHUB_REF_NAME" build/distributions/helma-*.* \
|
||||
--repo "$GITHUB_REPOSITORY" \
|
||||
--clobber
|
44
.github/workflows/renovate.yml
vendored
44
.github/workflows/renovate.yml
vendored
|
@ -1,44 +0,0 @@
|
|||
name: Run Renovate
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "13 * * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
renovate:
|
||||
runs-on: antville
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Run Renovate
|
||||
# See <https://docs.renovatebot.com/troubleshooting/#log-debug-levels>
|
||||
# debug | info | warn | error | fatal
|
||||
run: LOG_LEVEL=info npx renovate
|
||||
env:
|
||||
# Renovate is using this token to retrieve release notes
|
||||
GITHUB_COM_TOKEN: ${{ secrets.renovate_github_com_token }}
|
||||
# Autodiscover is better suited for an extra repo running Renovate on all desired repos
|
||||
#RENOVATE_AUTODISCOVER: 'true'
|
||||
RENOVATE_CONFIG_FILE: renovate.json
|
||||
RENOVATE_ENDPOINT: ${{ github.api_url }}
|
||||
RENOVATE_GIT_AUTHOR: Renovate Bot <mail+renovate@antville.org>
|
||||
#RENOVATE_GIT_IGNORED_AUTHORS:
|
||||
# - 29139614+renovate[bot]@users.noreply.github.com
|
||||
RENOVATE_IGNORE_PR_AUTHOR: 'true'
|
||||
RENOVATE_LOG_FILE: renovate-log.ndjson
|
||||
RENOVATE_LOG_FILE_LEVEL: debug
|
||||
RENOVATE_PLATFORM: gitea
|
||||
RENOVATE_REPOSITORIES: ${{ github.repository }}
|
||||
RENOVATE_REPOSITORY_CACHE: 'enabled'
|
||||
# github.token is not working here, it lacks some permissions required by Renovate
|
||||
RENOVATE_TOKEN: ${{ secrets.renovate_token }}
|
||||
|
||||
- name: Save log file
|
||||
# FIXME: v4 of this action causes an error on Forgejo (“You must configure a GitHub token”)
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: renovate-log.ndjson
|
||||
path: renovate-log.ndjson
|
32
.github/workflows/stage.yml
vendored
32
.github/workflows/stage.yml
vendored
|
@ -1,32 +0,0 @@
|
|||
name: Deploy (Staging)
|
||||
|
||||
on: workflow_dispatch
|
||||
|
||||
jobs:
|
||||
stage:
|
||||
runs-on: antville
|
||||
|
||||
environment:
|
||||
name: stage
|
||||
url: ${{ vars.stage_url }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew installDist
|
||||
|
||||
- name: Publish to staging server
|
||||
run: |
|
||||
rsync ./build/install/helma/ staging-server:./ \
|
||||
--verbose --archive --delete --compress \
|
||||
--filter '+ /bin' \
|
||||
--filter '+ /extras' \
|
||||
--filter '+ /launcher.jar' \
|
||||
--filter '- /lib/ext' \
|
||||
--filter '+ /lib' \
|
||||
--filter '+ /modules' \
|
||||
--filter '- /*'
|
||||
|
||||
- name: Restart Helma
|
||||
run: ssh staging-server restart
|
30
.gitignore
vendored
30
.gitignore
vendored
|
@ -1,30 +0,0 @@
|
|||
# Generally ignore hidden files
|
||||
.*
|
||||
|
||||
# Manage some Codium configuration
|
||||
.vscode/*
|
||||
!.vscode
|
||||
!.vscode/extensions.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
|
||||
# Ignore files created during build or run
|
||||
/bin
|
||||
/backups
|
||||
build
|
||||
/docs
|
||||
/lib
|
||||
/licenses
|
||||
/log
|
||||
|
||||
# Ignore files managed in src/dist
|
||||
/*.properties
|
||||
/apps
|
||||
/db
|
||||
/extras
|
||||
/launcher.jar
|
||||
/static
|
||||
|
||||
# Manage Gradle configuration
|
||||
!/gradle.properties
|
|
@ -1 +0,0 @@
|
|||
11.0
|
6
.vscode/extensions.json
vendored
6
.vscode/extensions.json
vendored
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"vscjava.vscode-java-pack",
|
||||
"vscjava.vscode-gradle"
|
||||
]
|
||||
}
|
21
.vscode/launch.json
vendored
21
.vscode/launch.json
vendored
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "java",
|
||||
"name": "Current File",
|
||||
"request": "launch",
|
||||
"mainClass": "${file}"
|
||||
},
|
||||
{
|
||||
"type": "java",
|
||||
"name": "Debug",
|
||||
"request": "launch",
|
||||
"mainClass": "helma.main.Server",
|
||||
"projectName": "helma_"
|
||||
}
|
||||
]
|
||||
}
|
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"files.watcherExclude": {
|
||||
"apps/": true
|
||||
},
|
||||
"java.configuration.updateBuildConfiguration": "automatic"
|
||||
}
|
31
CHANGES.md
31
CHANGES.md
|
@ -1,31 +0,0 @@
|
|||
# Change Log
|
||||
|
||||
## May 17, 2020
|
||||
|
||||
* Added support for colored log output
|
||||
* Added xgettext and po2js tasks (only running with Antville right now)
|
||||
|
||||
## April 13, 2020
|
||||
|
||||
* Added support for gzip compressed response in helma.Http
|
||||
* Fixed helma.Http.getURL() not following redirects if protocol changes (e.g. http → https)
|
||||
* Fixed references to obsolete Base64 encoder in modules
|
||||
* Updated JavaMail library to implementation package
|
||||
|
||||
## March 21, 2020
|
||||
|
||||
* Completely rewrote build system with Gradle
|
||||
* Separated launcher from main source as Gradle subproject
|
||||
* Launcher now includes all JARs found in `lib`
|
||||
* Upgraded Rhino to version 1.7.12
|
||||
* Upgraded Jetty to version 9.x
|
||||
* Fixed compatibility issues with Java 11
|
||||
* Removed support for Apache JServ Protocol (AJP)
|
||||
* Added support for CommonJS require() method
|
||||
* Allow variable arguments in res.write() and res.writeln()
|
||||
* Replaced Helma’s MD5 and Base64 methods with equivalent methods from Apache Commons
|
||||
* Refactored String methods from Java to JavaScript: encode(), encodeForm(), encodeXml(), stripTags()
|
||||
* Replaced custom String methods with Rhino’s built-in ones: endsWith(), repeat(), startsWith(), trim()
|
||||
* Refactored custom String.pad() method with built-in methods
|
||||
* Redefined custom Array.contains() method with built-in Array.includes()
|
||||
* Refactored custom Array methods with built-in methods: intersection(), union()
|
1
CNAME
Normal file
1
CNAME
Normal file
|
@ -0,0 +1 @@
|
|||
helma.js.org
|
37
LICENSE.md
37
LICENSE.md
|
@ -1,37 +0,0 @@
|
|||
# License
|
||||
|
||||
Copyright (c) 1999-2025 Helma Project. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
3. Products derived from this software may not be called "Helma"
|
||||
or "Hop", nor may "Helma" or "Hop" appear in their name, without
|
||||
prior written permission of the Helma Project Group. For written
|
||||
permission, please contact helma@helma.org.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE HELMA PROJECT OR ITS
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Helma includes third party software released under different specific
|
||||
license terms. See the licenses directory in the Helma distribution
|
||||
for a list of these licenses.
|
71
README.md
71
README.md
|
@ -1,71 +0,0 @@
|
|||
# How to Helma
|
||||
|
||||
## TL;DR
|
||||
|
||||
- Make sure you have Java 11 or higher installed
|
||||
- Download and unpack the [latest release](https://code.host.antville.org/antville/helma/releases)
|
||||
- Invoke `./bin/helma`, resp. `./bin/helma.bat`, depending on your platform
|
||||
- Direct your web browser to <http://localhost:8080>
|
||||
|
||||
## Introduction
|
||||
|
||||
Helma is an open source web application framework for fast and efficient scripting and serving of your websites and Internet applications.
|
||||
|
||||
Helma is written in Java and employs JavaScript for its server-side scripting environment, removing the need for compilation cycles and reducing development costs while giving you instant access to leverage the whole wealth of Java libraries out there.
|
||||
|
||||
Helma pioneered the simple and codeless mapping of application objects to database tables, which has only recently come into vogue with other web frameworks. In addition, an embedded object-oriented database performs automatic data persistence of unmapped objects.
|
||||
|
||||
Helma has proven itself to be stable and fast, capable of serving high traffic sites with hundreds of thousands of dynamic pages per day. The Austrian Broadcasting Corporation, popular weblog hosting sites such as antville.org, twoday.net, and blogger.de, among many others, have successfully been deploying Helma for several years now.
|
||||
|
||||
Although Helma became a Grande Dame of server-side JavaScript already decades ago when she performed in cozy Finnish clubs, she appears somehow retired nowadays. Nevertheless, she is here to stay for those last ones out there still tinkering with this nostalgic and wonderful piece of software.
|
||||
|
||||
## System Requirements
|
||||
|
||||
You need a Java virtual machine version 11 or higher to run Helma.
|
||||
|
||||
Please consult the documentation of your platform how to obtain and install Java.
|
||||
|
||||
You also can directly download a [Java runtime or development kit](https://www.oracle.com/java/technologies/javase-downloads.html#javasejdk) from Oracle.
|
||||
|
||||
Helma is built with [Gradle](https://gradle.org), the build task depends on the binaries [rsync](https://rsync.samba.org) and [npx](https://www.npmjs.com/package/npx) being installed on your system.
|
||||
|
||||
## Development
|
||||
|
||||
### Additional Prerequisites
|
||||
|
||||
* [Node.js](https://nodejs.org) LTS version
|
||||
* [Rsync](https://rsync.samba.org) version ≥ 3.1.0
|
||||
|
||||
Clone this repository to your machine and run Helma with `./gradlew run`.
|
||||
|
||||
To update the installation from a build, run `./gradlew update` and enter `yes` at the prompt.
|
||||
|
||||
> ⚠️
|
||||
> Please be aware that this step is going to overwrite files in the installation directory – escpecially at a later time when there might be substantial changes. Should this happen by accident you find the previous installation in the `backups` directory.
|
||||
>
|
||||
> Alternatively, you could move or copy the desired files manually from the installation directory `build/install/helma`.
|
||||
|
||||
After all files are put into place start Helma by invoking `./bin/helma.bat` or `./bin/helma`, depending on whether you are on Windows or Linux / Unix / OS X, respectively. If the `java` command is not found, try setting the `JAVA_HOME` environment variable to the location of your Java installation.
|
||||
|
||||
You can adjust server-wide settings in the `server.properties` file. For example, you could set the `smtp` property to the name of the SMTP server that Helma should use to send e-mail. Applications can be started or stopped by editing the `apps.properties` file, or through the web interface using the management application that is part of Helma.
|
||||
|
||||
If all goes well you should be able to connect your browser to <http://localhost:8080> – port 8080 on the local machine, that is.
|
||||
|
||||
Helma comes with a version of [Jetty](http://eclipse.org/jetty/), a lightweight yet industrial strength web server.
|
||||
|
||||
While Jetty works well for development and in fact deploying real web sites, you might want to run Helma with the web server you are already using. This is most easily done by proxying Helma. Please consult the documentation of your web server how to achieve this.
|
||||
|
||||
Finally, Helma can be plugged into Servlet containers using Servlet classes that communicate with Helma either directly or via Java RMI. Be warned that these options may be harder to set up and maintain though, since most of the recent development efforts have been geared towards a proxied setup.
|
||||
|
||||
## Documentation and Further Information
|
||||
|
||||
After installing and running Helma, you will be able to access introductions to the features of Helma and the various included development tools. Further information you will find on the helma.org website:
|
||||
|
||||
> 😿
|
||||
> Unfortunately, the Helma website disappeard in the meantime. However, with some archaeological web digging and thanks to the great search engines and archive services out there it is still possible to find useful resources.
|
||||
|
||||
- [helma.org at Internet Archive](http://web.archive.org/web/20180122132315/http://helma.org)
|
||||
- [Documentation](http://web.archive.org/web/20100530234322/http://helma.org/documentation/)
|
||||
- [API Reference](https://helma.serverjs.org/reference/)
|
||||
- [Tutorial](http://web.archive.org/web/20100526182848/http://helma.org/Documentation/Object-Relational+Mapping+Tutorial/)
|
||||
- [DocBook](http://dev.orf.at/download/helma/documentation/documentation.pdf)
|
1
_config.yml
Normal file
1
_config.yml
Normal file
|
@ -0,0 +1 @@
|
|||
theme: jekyll-theme-slate
|
293
build.gradle
293
build.gradle
|
@ -1,293 +0,0 @@
|
|||
plugins {
|
||||
id 'application'
|
||||
id 'com.github.jk1.dependency-license-report' version '2.9'
|
||||
}
|
||||
|
||||
import org.apache.tools.ant.filters.FixCrLfFilter
|
||||
|
||||
def jettyLogLevel = '-Dorg.eclipse.jetty.LEVEL=WARN'
|
||||
|
||||
// Suppress menu bar and default icon being shown in macos dock (Radar #5754483)
|
||||
// See https://developer.apple.com/library/content/releasenotes/Java/JavaLeopardUpdate1RN/ResolvedIssues/ResolvedIssues.html
|
||||
def suppressMacosDockIcon = '-Dapple.awt.UIElement=true'
|
||||
|
||||
// This list is used to determine which files need processing of line endings
|
||||
def textFiles = ['**/*.hac', '**/.html', '**/*.js', '**/*.md', '**/*.properties', '**/*.skin', '**/*.txt', '**/*.xml']
|
||||
|
||||
allprojects {
|
||||
apply plugin: 'java'
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
version = new Date().format("yy.M.d")
|
||||
|
||||
tasks.build.dependsOn javadoc, 'jsdoc', 'generateLicenseReport'
|
||||
tasks.compileJava.dependsOn 'processSource'
|
||||
|
||||
// Disable DocLint for now
|
||||
// See <https://blog.joda.org/2014/02/turning-off-doclint-in-jdk-8-javadoc.html>
|
||||
if (JavaVersion.current().isJava8Compatible()) {
|
||||
allprojects {
|
||||
tasks.withType(Javadoc) {
|
||||
options.addStringOption('Xdoclint:none', '-quiet')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
// Wrapping implementation because it does not allow access to its files
|
||||
// (i.e. cannot be resolved)
|
||||
library.extendsFrom implementation
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.code.gson:gson:2.12.1'
|
||||
implementation 'commons-codec:commons-codec:1.18.0'
|
||||
implementation 'commons-fileupload:commons-fileupload:1.5'
|
||||
implementation 'commons-logging:commons-logging:1.3.5'
|
||||
implementation 'commons-net:commons-net:3.11.1'
|
||||
implementation 'com.sun.mail:javax.mail:1.6.2'
|
||||
implementation 'javax.servlet:javax.servlet-api:4.0.1'
|
||||
implementation 'org.ccil.cowan.tagsoup:tagsoup:1.2.1'
|
||||
implementation 'org.eclipse.jetty:jetty-servlet:9.4.57.v20241219'
|
||||
implementation 'org.eclipse.jetty:jetty-xml:9.4.57.v20241219'
|
||||
implementation 'org.mozilla:rhino-all:1.8.0'
|
||||
implementation 'org.sejda.imageio:webp-imageio:0.1.6'
|
||||
implementation 'xerces:xercesImpl:2.12.2'
|
||||
implementation 'xmlrpc:xmlrpc:2.0.1'
|
||||
}
|
||||
|
||||
def rhinoJar = configurations.library.files.find { jar ->
|
||||
jar.name.startsWith('rhino')
|
||||
}
|
||||
|
||||
run {
|
||||
jvmArgs jettyLogLevel, suppressMacosDockIcon
|
||||
classpath += fileTree(dir: 'lib/ext', include: '*.jar')
|
||||
}
|
||||
|
||||
application {
|
||||
mainClass = 'helma.main.Server'
|
||||
|
||||
applicationDistribution.from(projectDir) {
|
||||
include 'modules/**'
|
||||
include 'LICENSE.md'
|
||||
include 'README.md'
|
||||
include 'start.*'
|
||||
}
|
||||
|
||||
applicationDistribution.from(javadoc.destinationDir) {
|
||||
include '**'
|
||||
into 'docs/javadoc'
|
||||
}
|
||||
|
||||
applicationDistribution.from("${project.buildDir}/docs/jsdoc") {
|
||||
include '**'
|
||||
into 'docs/jsdoc'
|
||||
}
|
||||
|
||||
applicationDistribution.from("${project.buildDir}/reports/dependency-license") {
|
||||
include '**'
|
||||
into 'licenses'
|
||||
}
|
||||
}
|
||||
|
||||
startScripts {
|
||||
applicationName = 'helma'
|
||||
classpath = files('../launcher.jar')
|
||||
mainClass = 'helma.main.launcher.Main'
|
||||
|
||||
defaultJvmOpts = [jettyLogLevel, suppressMacosDockIcon]
|
||||
|
||||
doLast {
|
||||
// Work-around to make the classpath above work (launcher.jar is located outside of `lib` dir)
|
||||
// See https://discuss.gradle.org/t/classpath-in-application-plugin-is-building-always-relative-to-app-home-lib-directory/2012
|
||||
def unixScriptFile = file getUnixScript()
|
||||
def windowsScriptFile = file getWindowsScript()
|
||||
unixScriptFile.text = unixScriptFile.text.replace('$APP_HOME/lib', '$APP_HOME')
|
||||
windowsScriptFile.text = windowsScriptFile.text.replace('%APP_HOME%\\lib', '%APP_HOME%')
|
||||
}
|
||||
}
|
||||
|
||||
distributions {
|
||||
main {
|
||||
contents {
|
||||
from project(':launcher').jar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
distTar {
|
||||
dependsOn ':generateLicenseReport', ':javadoc', ':jsdoc'
|
||||
|
||||
compression = Compression.GZIP
|
||||
|
||||
filesMatching(textFiles) {
|
||||
filter(FixCrLfFilter.class, eol: FixCrLfFilter.CrLf.newInstance("lf"))
|
||||
}
|
||||
}
|
||||
|
||||
distZip {
|
||||
dependsOn ':generateLicenseReport', ':javadoc', ':jsdoc'
|
||||
|
||||
filesMatching(textFiles) {
|
||||
filter(FixCrLfFilter.class, eol: FixCrLfFilter.CrLf.newInstance("crlf"))
|
||||
}
|
||||
}
|
||||
|
||||
installDist {
|
||||
dependsOn build
|
||||
}
|
||||
|
||||
def processSource = tasks.register('processSource', Sync) {
|
||||
def gitOutput = new ByteArrayOutputStream()
|
||||
|
||||
outputs.dir "${project.buildDir}/src"
|
||||
|
||||
exec {
|
||||
commandLine 'git', 'rev-parse', '--short', 'HEAD'
|
||||
standardOutput = gitOutput
|
||||
errorOutput = new ByteArrayOutputStream()
|
||||
ignoreExitValue = true
|
||||
}
|
||||
|
||||
from 'src'
|
||||
|
||||
filter {
|
||||
line -> line
|
||||
.replaceAll('__builddate__', new Date().format("d MMM yyyy"))
|
||||
.replaceAll('__commithash__', gitOutput.toString().trim())
|
||||
.replaceAll('__version__', version)
|
||||
} into outputs.files.singleFile
|
||||
}
|
||||
|
||||
tasks.compileJava.source = processSource.map { it.outputs.files }
|
||||
|
||||
tasks.register('update') {
|
||||
dependsOn installDist
|
||||
|
||||
def rsyncArgs = ['--archive', '--filter', '- backups']
|
||||
|
||||
def confirm = {
|
||||
ant.input(message: 'Update this installation?', validargs: 'yes,no', addproperty: 'continue')
|
||||
return ant.continue == 'yes'
|
||||
}
|
||||
|
||||
onlyIf { confirm() }
|
||||
|
||||
doFirst {
|
||||
def backupDir = 'backups/' + new Date().format('yyyyMMdd-HHmmss')
|
||||
|
||||
mkdir backupDir
|
||||
|
||||
exec {
|
||||
// Create a backup with rsync instead of a CopyTask because the latter chokes on multi-byte characters
|
||||
// See https://github.com/gradle/gradle/issues/789
|
||||
executable 'rsync'
|
||||
args rsyncArgs
|
||||
args "$projectDir/", backupDir
|
||||
}
|
||||
|
||||
print "Created backup of ${projectDir} in ${backupDir}"
|
||||
}
|
||||
|
||||
doLast {
|
||||
exec {
|
||||
// Using rsync to selectively update the repo directory
|
||||
executable 'rsync'
|
||||
args '--delete'
|
||||
args rsyncArgs
|
||||
args '--filter', '+ bin/***'
|
||||
args '--filter', '+ docs/***'
|
||||
args '--filter', '+ extras/***'
|
||||
args '--filter', '+ launcher.jar'
|
||||
args '--filter', '+ lib'
|
||||
args '--filter', '+ *.jar'
|
||||
args '--filter', '- *'
|
||||
args "${installDist.destinationDir}/", projectDir
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register('jsdoc', Exec) {
|
||||
description 'Generates JSDoc API documentation for the included JavaScript modules.'
|
||||
group 'Documentation'
|
||||
|
||||
def sources = ['modules/core', 'modules/helma', 'modules/jala/code']
|
||||
def destination = "${project.buildDir}/docs/jsdoc"
|
||||
|
||||
sources.each { dir -> inputs.dir dir }
|
||||
outputs.dir destination
|
||||
|
||||
executable 'npx'
|
||||
args = ['jsdoc', '-d', "$destination"].plus(sources)
|
||||
}
|
||||
|
||||
tasks.register('xgettext', JavaExec) {
|
||||
description 'Extracts translatable message strings from source code.'
|
||||
group 'i18n'
|
||||
|
||||
classpath = files('launcher.jar')
|
||||
mainClass = 'helma.main.launcher.Commandline'
|
||||
|
||||
// TODO: Decouple from Antville app
|
||||
args = [
|
||||
// Root.extractMessages is currently located in antville/code/Global/i18n.js
|
||||
'antville.extractMessages',
|
||||
'modules/jala/util/HopKit/scripts/MessageParser.js',
|
||||
'code compat',
|
||||
'apps/antville/i18n/antville.pot'
|
||||
]
|
||||
}
|
||||
|
||||
tasks.register('po2js', JavaExec) {
|
||||
description 'Converts translated message strings from PO format to JavaScript.'
|
||||
group 'i18n'
|
||||
|
||||
classpath = files(rhinoJar)
|
||||
mainClass = 'org.mozilla.javascript.tools.shell.Main'
|
||||
|
||||
// TODO: Decouple from Antville app
|
||||
args = [
|
||||
'modules/jala/util/HopKit/scripts/PoParser.js',
|
||||
'apps/antville/i18n',
|
||||
'apps/antville/i18n'
|
||||
]
|
||||
}
|
||||
|
||||
tasks.register('rhinoShell', JavaExec) {
|
||||
description 'Runs the interactive Rhino JavaScript shell.'
|
||||
group 'Application'
|
||||
|
||||
classpath = files(rhinoJar)
|
||||
mainClass = 'org.mozilla.javascript.tools.shell.Main'
|
||||
|
||||
standardInput = System.in
|
||||
}
|
||||
|
||||
// Call this task with a function definition using the `-P` parameter, e.g.
|
||||
// `./gradlew commandLine -Pfunction=manage.getAllApplications`
|
||||
tasks.register('commandLine', JavaExec) {
|
||||
description 'Runs a function in a Helma application with `-Pfunction=app.functionName`.'
|
||||
group 'Application'
|
||||
|
||||
classpath = files('launcher.jar')
|
||||
mainClass = 'helma.main.launcher.Commandline'
|
||||
args '-h', projectDir, function
|
||||
}
|
||||
|
||||
tasks.register('debug', JavaExec) {
|
||||
group = 'application'
|
||||
main = 'helma.main.Server'
|
||||
classpath = sourceSets.main.runtimeClasspath
|
||||
jvmArgs = ['-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005']
|
||||
classpath += fileTree(dir: 'lib/ext', include: '*.jar')
|
||||
}
|
52
cliff.toml
52
cliff.toml
|
@ -1,52 +0,0 @@
|
|||
# git-cliff ~ default configuration file
|
||||
# https://git-cliff.org/docs/configuration
|
||||
#
|
||||
# Lines starting with "#" are comments.
|
||||
# Configuration options are organized into tables and keys.
|
||||
# See documentation for more information on available options.
|
||||
|
||||
[changelog]
|
||||
trim = true
|
||||
|
||||
header = "## Changes"
|
||||
|
||||
body = """
|
||||
{% for group, commits in commits | filter(attribute="merge_commit") | group_by(attribute="group") %}
|
||||
### {{ group | striptags | trim | upper_first }}
|
||||
{% for commit in commits %}
|
||||
* [<tt>{{ commit.id | split(pat="") | slice(end=11) | join() }}</tt>]\
|
||||
(https://code.host.antville.org/antville/helma/commit/{{ commit.id }}) \
|
||||
{% if commit.breaking %}**Breaking:** {% endif %}\
|
||||
{{ commit.message | split(pat="\\n") | first | upper_first | escape }}\
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
**Full Changelog:** [{{ previous.version }} → {{ version }}]\
|
||||
(https://code.host.antville.org/antville/helma/compare/\
|
||||
{{ previous.version | urlencode }}..{{ version | urlencode }})\n\n
|
||||
"""
|
||||
|
||||
footer = """
|
||||
Generated by [git-cliff](https://git-cliff.org/).
|
||||
"""
|
||||
|
||||
[git]
|
||||
conventional_commits = false
|
||||
filter_commits = false
|
||||
filter_unconventional = false
|
||||
protect_breaking_commits = false
|
||||
sort_commits = "newest"
|
||||
split_commits = false
|
||||
topo_order = false
|
||||
|
||||
commit_parsers = [
|
||||
{ message = "^Apply \\d+ suggestion", skip = true },
|
||||
{ message = "^Merge .*(branch|dependabot|dependency|renovate)", skip = true },
|
||||
{ message = "^Lock file maintenance", skip = true },
|
||||
{ message = "yarn\\.lock", skip = true },
|
||||
|
||||
{ message = "^[Ff]ix", group = "<!-- 0 --> 🐛 Bug Fixes" },
|
||||
{ field = "author.name", pattern = "[Rr]enovate|[Dd]ependabot", group = "<!-- 3 --> 📦 Dependency Updates" },
|
||||
{ message = "^Merge pull request", group = "<!-- 1 --> 🔀 Merges" },
|
||||
{ message = ".*", group = "<!-- 2 --> Uncategorized" },
|
||||
]
|
|
@ -1,3 +0,0 @@
|
|||
org.gradle.console = plain
|
||||
|
||||
function =
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
7
gradle/wrapper/gradle-wrapper.properties
vendored
7
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,7 +0,0 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
251
gradlew
vendored
251
gradlew
vendored
|
@ -1,251 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# https://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.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
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
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
94
gradlew.bat
vendored
94
gradlew.bat
vendored
|
@ -1,94 +0,0 @@
|
|||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@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 https://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 SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
36
index.md
Normal file
36
index.md
Normal file
|
@ -0,0 +1,36 @@
|
|||
## Server-side JavaScript is so 1999
|
||||
|
||||
It was the year when one of the earlier collaborative weblogs (yes, that’s what we called blogs at the time) called [Helma turned into a _corporate website_](http://web.archive.org/web/20010502043303/http://classic.helma.at/comment.asp?helmatic=hannes&item=7696)…
|
||||
|
||||
Thus, the life of Helma, the _web application framework_ begun. And with it, a serious effort of applying server-side JavaScript.
|
||||
|
||||
**JavaScript on the server.
|
||||
Long before NodeJS.
|
||||
Way long.**
|
||||
|
||||
Helma would not have been possible without the creative minds at the Austrian public broadcaster ORF, once called ORF Online, ORF.at nowadays.
|
||||
|
||||
They commissioned the precursor of Helma, a publishing system based on Marimba, and they used and further developed it for their in-house content management.
|
||||
|
||||
This early code blossomed into Helma and the content management organically grew into it, together with a bunch of sidelined applications, comprehending forum apps, podcast services and even SSL certificate management.
|
||||
|
||||
And all by writing JavaScript on the server.
|
||||
Long before NodeJS.
|
||||
Way long.
|
||||
|
||||
From ORF.at’s solid trunk a lot of colorful branches started to sprout, some of which still are around:
|
||||
|
||||
* [Antville](https://antville.org), the non-profit weblog hosting system, and its (at the time) corporate sibling [Twoday](https://twoday.net)
|
||||
* [Parq](http://www.parq.at) and [Coplaner](http://coplaner.net), two groupware platforms for “joint building ventures” (_Baugruppen_ in German)
|
||||
|
||||
All written in JavaScript on the server.
|
||||
Long before NodeJS.
|
||||
Way long.
|
||||
|
||||
The people using Helma thought it was very convenient to write code in the same programming language for both, the client _and_ the server. And they were not wrong: along came NodeJS and somehow suddenly JavaScript was everywhere.
|
||||
|
||||
Unfortunately, Helma was not. And so she became part of the JavaScript mythology. A blink of an eye in the history of the web. Almost forgotten. Blessed forever.
|
||||
|
||||
A little server-side JavaScript framework called Helma.
|
||||
Long before NodeJS.
|
||||
Way long ago.
|
|
@ -1,5 +0,0 @@
|
|||
jar {
|
||||
manifest {
|
||||
from 'src/main/java/helma/main/launcher/manifest.txt'
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2003 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile$
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
package helma.main.launcher;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
|
||||
/**
|
||||
* Helma bootstrap class. Figures out Helma home directory, sets up class path and
|
||||
* lauchnes main class. This class must be invoked from a jar file in order to work.
|
||||
*
|
||||
* @author Stefan Pollach
|
||||
*/
|
||||
public class Commandline {
|
||||
|
||||
/**
|
||||
* boot method for running a request from the command line.
|
||||
* This retrieves the Helma home directory, creates the
|
||||
* classpath, get the request properties, creates the app and
|
||||
* runs it
|
||||
*-
|
||||
* @param args command line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
String installDir = Main.getInstallDir(args);
|
||||
|
||||
ClassLoader loader = Main.createClassLoader(installDir);
|
||||
|
||||
// get the main server class
|
||||
Class clazz = loader.loadClass("helma.main.CommandlineRunner");
|
||||
Class[] cargs = new Class[]{args.getClass()};
|
||||
Method main = clazz.getMethod("main", cargs);
|
||||
Object[] nargs = new Object[]{args};
|
||||
|
||||
// and invoke the static main(String, String[]) method
|
||||
main.invoke(null, nargs);
|
||||
} catch (Exception x) {
|
||||
// unable to get Helma installation dir from launcher jar
|
||||
x.printStackTrace();
|
||||
System.err.println("Unable to get Helma installation directory: ");
|
||||
System.err.println(x.getMessage());
|
||||
System.exit(2);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,234 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2003 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile$
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
package helma.main.launcher;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Helma bootstrap class. Basically this is a convenience wrapper that takes over
|
||||
* the job of setting the class path and helma install directory before launching
|
||||
* the static main(String[]) method in <code>helma.main.Server</code>. This class
|
||||
* should be invoked from a jar file in the Helma install directory in order to
|
||||
* be able to set up class and install paths.
|
||||
*/
|
||||
public class Main {
|
||||
private Class serverClass;
|
||||
private Object server;
|
||||
|
||||
private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
|
||||
private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
|
||||
|
||||
/**
|
||||
* Helma boot method. This retrieves the Helma home directory, creates the
|
||||
* classpath and invokes main() in helma.main.Server.
|
||||
*
|
||||
* @param args command line arguments
|
||||
*
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
Main main = new Main();
|
||||
main.init(args);
|
||||
main.start();
|
||||
}
|
||||
|
||||
public void init(String[] args) {
|
||||
try {
|
||||
String installDir = getInstallDir(args);
|
||||
ClassLoader loader = createClassLoader(installDir);
|
||||
// get the main server class
|
||||
serverClass = loader.loadClass("helma.main.Server");
|
||||
Class[] cargs = new Class[]{args.getClass()};
|
||||
Method loadServer = serverClass.getMethod("loadServer", cargs);
|
||||
Object[] nargs = new Object[]{args};
|
||||
// and invoke the static loadServer(String[]) method
|
||||
server = loadServer.invoke(null, nargs);
|
||||
Method init = serverClass.getMethod("init", EMPTY_CLASS_ARRAY);
|
||||
init.invoke(server, EMPTY_OBJECT_ARRAY);
|
||||
} catch (Exception x) {
|
||||
// unable to get Helma installation dir from launcher jar
|
||||
System.err.println("Unable to load Helma: ");
|
||||
x.printStackTrace();
|
||||
System.exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
public void start() {
|
||||
try {
|
||||
Method start = serverClass.getMethod("start", EMPTY_CLASS_ARRAY);
|
||||
start.invoke(server, EMPTY_OBJECT_ARRAY);
|
||||
} catch (Exception x) {
|
||||
// unable to get Helma installation dir from launcher jar
|
||||
System.err.println("Unable to start Helma: ");
|
||||
x.printStackTrace();
|
||||
System.exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
try {
|
||||
Method start = serverClass.getMethod("stop", EMPTY_CLASS_ARRAY);
|
||||
start.invoke(server, EMPTY_OBJECT_ARRAY);
|
||||
} catch (Exception x) {
|
||||
// unable to get Helma installation dir from launcher jar
|
||||
System.err.println("Unable to stop Helma: ");
|
||||
x.printStackTrace();
|
||||
System.exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
try {
|
||||
Method start = serverClass.getMethod("shutdown", EMPTY_CLASS_ARRAY);
|
||||
start.invoke(server, EMPTY_OBJECT_ARRAY);
|
||||
} catch (Exception x) {
|
||||
// unable to get Helma installation dir from launcher jar
|
||||
System.err.println("Unable to shutdown Helma: ");
|
||||
x.printStackTrace();
|
||||
System.exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
static void addJars(ArrayList jarlist, File dir) throws MalformedURLException {
|
||||
File[] files = dir.listFiles(new FilenameFilter() {
|
||||
public boolean accept(File dir, String name) {
|
||||
String n = name.toLowerCase();
|
||||
return n.endsWith(".jar") || n.endsWith(".zip"); //$NON-NLS-1$//$NON-NLS-2$
|
||||
}
|
||||
});
|
||||
|
||||
if (files != null) {
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
jarlist.add(new URL("file:" + files[i].getAbsolutePath())); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a server-wide ClassLoader from our install directory.
|
||||
* This will be used as parent ClassLoader for all application
|
||||
* ClassLoaders.
|
||||
*
|
||||
* @param installDir
|
||||
* @return the main classloader we'll be using
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
public static ClassLoader createClassLoader(String installDir)
|
||||
throws MalformedURLException, UnsupportedEncodingException {
|
||||
|
||||
// decode installDir in case it is URL-encoded
|
||||
installDir = URLDecoder.decode(installDir, System.getProperty("helma.urlEncoding", "UTF-8"));
|
||||
|
||||
// set up the class path
|
||||
File libdir = new File(installDir, "lib");
|
||||
ArrayList jarlist = new ArrayList();
|
||||
|
||||
// add all jar files from the lib directory
|
||||
addJars(jarlist, libdir);
|
||||
|
||||
// add all jar files from the lib/ext directory
|
||||
addJars(jarlist, new File(libdir, "ext")); //$NON-NLS-1$
|
||||
|
||||
URL[] urls = new URL[jarlist.size()];
|
||||
|
||||
jarlist.toArray(urls);
|
||||
|
||||
// find out if system classes should be excluded from class path
|
||||
String excludeSystemClasses = System.getProperty("helma.excludeSystemClasses");
|
||||
|
||||
ClassLoader loader;
|
||||
|
||||
if ("true".equalsIgnoreCase(excludeSystemClasses)) {
|
||||
loader = new URLClassLoader(urls, null);
|
||||
} else {
|
||||
loader = new URLClassLoader(urls);
|
||||
}
|
||||
|
||||
// set the new class loader as context class loader
|
||||
Thread.currentThread().setContextClassLoader(loader);
|
||||
return loader;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the Helma install directory from the command line -i argument or
|
||||
* from the Jar URL from which this class was loaded. Additionally, the
|
||||
* System property "helma.home" is set to the install directory path.
|
||||
*
|
||||
* @param args
|
||||
* @return the base install directory we're running in
|
||||
* @throws IOException
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
public static String getInstallDir(String[] args)
|
||||
throws IOException, MalformedURLException {
|
||||
// check if home directory is set via command line arg. If not,
|
||||
// we'll get it from the location of the jar file this class
|
||||
// has been loaded from.
|
||||
String installDir = null;
|
||||
|
||||
// first, try to get helma home dir from command line options
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i].equals("-i") && ((i + 1) < args.length)) {
|
||||
installDir = args[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
// try to get Helma installation directory
|
||||
if (installDir == null) {
|
||||
URL launcherUrl = ClassLoader.getSystemClassLoader()
|
||||
.getResource("helma/main/launcher/Main.class"); //$NON-NLS-1$
|
||||
|
||||
// this is a JAR URL of the form
|
||||
// jar:<url>!/{entry}
|
||||
// we strip away the jar: prefix and the !/{entry} suffix
|
||||
// to get the original jar file URL
|
||||
|
||||
String jarUrl = launcherUrl.toString();
|
||||
|
||||
if (!jarUrl.startsWith("jar:") || jarUrl.indexOf("!") < 0) {
|
||||
installDir = System.getProperty("user.dir");
|
||||
System.err.println("Warning: Helma install dir not set by -i parameter ");
|
||||
System.err.println(" and not started from launcher.jar. Using ");
|
||||
System.err.println(" current working directory as install dir.");
|
||||
} else {
|
||||
jarUrl = jarUrl.substring(4);
|
||||
|
||||
int excl = jarUrl.indexOf("!");
|
||||
jarUrl = jarUrl.substring(0, excl);
|
||||
launcherUrl = new URL(jarUrl);
|
||||
|
||||
File f = new File(launcherUrl.getPath()).getAbsoluteFile();
|
||||
|
||||
installDir = f.getParentFile().getCanonicalPath();
|
||||
}
|
||||
}
|
||||
// set System property
|
||||
System.setProperty("helma.home", installDir);
|
||||
// and return install dir
|
||||
return installDir;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
Main-Class: helma.main.launcher.Main
|
||||
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
# Helma Modules
|
||||
|
||||
The Helma modules directory is organized in several groups:
|
||||
|
||||
* **modules/core** which contains extensions to core JavaScript types such as
|
||||
Object, Array, or Date.
|
||||
* **modules/helma** which provide new functionality to JavaScript, usually by
|
||||
wrapping a Java library.
|
||||
* **modules/jala**, a Git submodule providing the very useful ORF.at libraries for Helma
|
||||
|
||||
To use a HelmaLib module in your Helma application, you need to add it to the
|
||||
app's repositories. The simplest way to do so is by using the `app.addRepository()`
|
||||
function:
|
||||
|
||||
app.addRepository('modules/helma/Search.js');
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Array.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Adds useful methods to the JavaScript Array type.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/core/Array.js')
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check if this array contains a specific value.
|
||||
* @external
|
||||
* @memberof {Array}
|
||||
* @param {Object} val the value to check
|
||||
* @return {boolean} true if the value is contained
|
||||
*/
|
||||
Array.prototype.contains = Array.prototype.includes
|
||||
|
||||
/**
|
||||
* Retrieve the union set of a bunch of arrays
|
||||
* @external
|
||||
* @memberof {Array}
|
||||
* @param {Array} array1,... the arrays to unify
|
||||
* @return {Array} the union set
|
||||
*/
|
||||
Array.union = function() {
|
||||
return Array.from(arguments).reduce((result, array) => {
|
||||
return result.concat(array.filter(element => !result.includes(element)));
|
||||
}, []);
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve the intersection set of a bunch of arrays
|
||||
* @external
|
||||
* @memberof {Array}
|
||||
* @param {Array} array1,... the arrays to intersect
|
||||
* @return {Array} the intersection set
|
||||
*/
|
||||
Array.intersection = function() {
|
||||
return Array.from(arguments).reduce((result, array) => {
|
||||
return result.filter(element => array.includes(element));
|
||||
});
|
||||
};
|
||||
|
||||
// prevent any newly added properties from being enumerated
|
||||
for (var i in Array)
|
||||
Array.dontEnum(i);
|
||||
for (var i in Array.prototype)
|
||||
Array.prototype.dontEnum(i);
|
|
@ -1,212 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2005 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Date.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Adds useful methods to the JavaScript Date type.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/core/Date.js')
|
||||
*/
|
||||
|
||||
Date.ONESECOND = 1000;
|
||||
Date.ONEMINUTE = 60 * Date.ONESECOND;
|
||||
Date.ONEHOUR = 60 * Date.ONEMINUTE;
|
||||
Date.ONEDAY = 24 * Date.ONEHOUR;
|
||||
Date.ONEWEEK = 7 * Date.ONEDAY;
|
||||
Date.ONEMONTH = 30 * Date.ONEDAY;
|
||||
Date.ONEYEAR = 12 * Date.ONEMONTH;
|
||||
Date.ISOFORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
|
||||
|
||||
|
||||
/**
|
||||
* Format a Date to a string.
|
||||
* For details on the format pattern, see
|
||||
* http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html *
|
||||
* @external
|
||||
* @memberof {Date}
|
||||
*
|
||||
* @param String Format pattern
|
||||
* @param Object Java Locale Object (optional)
|
||||
* @param Object Java TimeZone Object (optional)
|
||||
* @return String formatted Date
|
||||
* @see http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html
|
||||
*/
|
||||
Date.prototype.format = function (format, locale, timezone) {
|
||||
if (!format)
|
||||
return this.toString();
|
||||
var sdf = locale ? new java.text.SimpleDateFormat(format, locale)
|
||||
: new java.text.SimpleDateFormat(format);
|
||||
if (timezone && timezone != sdf.getTimeZone())
|
||||
sdf.setTimeZone(timezone);
|
||||
return sdf.format(this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* set the date/time to UTC by subtracting
|
||||
* the timezone offset
|
||||
* @external
|
||||
* @memberof {Date}
|
||||
*/
|
||||
Date.prototype.toUtc = function() {
|
||||
this.setMinutes(this.getMinutes() + this.getTimezoneOffset());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* set the date/time to local time by adding
|
||||
* the timezone offset
|
||||
* @external
|
||||
* @memberof {Date}
|
||||
*/
|
||||
Date.prototype.toLocalTime = function() {
|
||||
this.setMinutes(this.getMinutes() - this.getTimezoneOffset());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* returns the difference between this and another
|
||||
* date object in milliseconds
|
||||
* @external
|
||||
* @memberof {Date}
|
||||
*/
|
||||
Date.prototype.diff = function(dateObj) {
|
||||
return this.getTime() - dateObj.getTime();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* return the timespan to current date/time or a different Date object
|
||||
* @external
|
||||
* @memberof {Date}
|
||||
* @param Object parameter object containing optional properties:
|
||||
* .now = String to use if difference is < 1 minute
|
||||
* .day|days = String to use for single|multiple day(s)
|
||||
* .hour|hours = String to use for single|multiple hour(s)
|
||||
* .minute|minutes = String to use for single|multiple minute(s)
|
||||
* .date = Date object to use for calculating the timespan
|
||||
* @return Object containing properties:
|
||||
* .isFuture = (Boolean)
|
||||
* .span = (String) timespan
|
||||
* @see Date.prototype.getAge
|
||||
* @see Date.prototype.getExpiry
|
||||
*/
|
||||
Date.prototype.getTimespan = function(param) {
|
||||
if (!param)
|
||||
param = {date: new Date()};
|
||||
else if (!param.date)
|
||||
param.date = new Date();
|
||||
|
||||
var result = {isFuture: this > param.date};
|
||||
var diff = Math.abs(param.date.diff(this));
|
||||
var age = {days: Math.floor(diff / Date.ONEDAY),
|
||||
hours: Math.floor((diff % Date.ONEDAY) / Date.ONEHOUR),
|
||||
minutes: Math.floor((diff % Date.ONEHOUR) / Date.ONEMINUTE)};
|
||||
|
||||
res.push();
|
||||
if (diff < Date.ONEMINUTE)
|
||||
res.write(param.now || "now");
|
||||
else {
|
||||
var arr = [{one: "day", many: "days"},
|
||||
{one: "hour", many: "hours"},
|
||||
{one: "minute", many: "minutes"}];
|
||||
for (var i in arr) {
|
||||
var value = age[arr[i].many];
|
||||
if (value != 0) {
|
||||
var prop = (value == 1 ? arr[i].one : arr[i].many);
|
||||
res.write(value);
|
||||
res.write(" ");
|
||||
res.write(param[prop] || prop);
|
||||
if (i < arr.length -1)
|
||||
res.write(param.delimiter || ", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
result.span = res.pop();
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* return the past timespan between this Date object and
|
||||
* the current Date or a different Date object
|
||||
* @see Date.prototype.getTimespan
|
||||
* @external
|
||||
* @memberof {Date}
|
||||
*/
|
||||
Date.prototype.getAge = function(param) {
|
||||
var age = this.getTimespan(param);
|
||||
if (!age.isFuture)
|
||||
return age.span;
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* return the future timespan between this Date object and
|
||||
* the current Date or a different Date object
|
||||
* @see Date.prototype.getTimespan
|
||||
* @external
|
||||
* @memberof {Date}
|
||||
*/
|
||||
Date.prototype.getExpiry = function(param) {
|
||||
var age = this.getTimespan(param);
|
||||
if (age.isFuture)
|
||||
return age.span;
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* checks if a date object equals another date object
|
||||
* @external
|
||||
* @memberof {Date}
|
||||
* @param Object Date object to compare
|
||||
* @param Int indicating how far the comparison should go
|
||||
* @return Boolean
|
||||
*/
|
||||
Date.prototype.equals = function(date, extend) {
|
||||
if (!extend)
|
||||
extend = Date.ONEDAY;
|
||||
switch (extend) {
|
||||
case Date.ONESECOND:
|
||||
if (this.getSeconds() != date.getSeconds())
|
||||
return false;
|
||||
case Date.ONEMINUTE:
|
||||
if (this.getMinutes() != date.getMinutes())
|
||||
return false;
|
||||
case Date.ONEHOUR:
|
||||
if (this.getHours() != date.getHours())
|
||||
return false;
|
||||
case Date.ONEDAY:
|
||||
if (this.getDate() != date.getDate())
|
||||
return false;
|
||||
case Date.ONEMONTH:
|
||||
if (this.getMonth() != date.getMonth())
|
||||
return false;
|
||||
case Date.ONEYEAR:
|
||||
if (this.getFullYear() != date.getFullYear())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
// prevent any newly added properties from being enumerated
|
||||
for (var i in Date)
|
||||
Date.dontEnum(i);
|
||||
for (var i in Date.prototype)
|
||||
Date.prototype.dontEnum(i);
|
|
@ -1,208 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2007 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile$
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Implements some useful macro filters.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/core/Filters.js')
|
||||
*/
|
||||
|
||||
app.addRepository('modules/core/String.js');
|
||||
|
||||
/**
|
||||
* Transforms a string to lowercase.
|
||||
*
|
||||
* @see String.prototype.toLowerCase
|
||||
*/
|
||||
function lowercase_filter(input) {
|
||||
return (input || "").toString().toLowerCase();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transforms a string to uppercase.
|
||||
*
|
||||
* @see String.prototype.toUpperCase
|
||||
*/
|
||||
function uppercase_filter(input) {
|
||||
return (input || "").toString().toUpperCase();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transforms the first Character of a string to uppercase.
|
||||
*
|
||||
* @see String.prototype.capitalize
|
||||
*/
|
||||
function capitalize_filter(input) {
|
||||
return (input || "").toString().capitalize();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transforms the first Character of each word in a string
|
||||
* to uppercase.
|
||||
*
|
||||
* @see String.prototype.titleize
|
||||
*/
|
||||
function titleize_filter(input) {
|
||||
return (input || "").toString().titleize();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cuts a String at a certain position, and
|
||||
* optionally appends a suffix, if truncation
|
||||
* has occurred.
|
||||
*
|
||||
* @see String.prototype.head
|
||||
* @param limit Maximum length
|
||||
* @param clipping Appended String, default is the empty String
|
||||
*/
|
||||
function truncate_filter(input, param, limit, clipping) {
|
||||
var limit = param.limit != null ? param.limit : limit;
|
||||
var clipping = param.clipping || clipping || "";
|
||||
return (input || "").toString().head(limit, clipping);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes leading and trailing whitespaces.
|
||||
*
|
||||
* @see String.prototype.trim
|
||||
*/
|
||||
function trim_filter(input) {
|
||||
return (input || "").toString().trim();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes all tags from a String.
|
||||
* Currently simply wraps Helma's stripTags-method.
|
||||
*
|
||||
* @see global.stripTags
|
||||
*/
|
||||
function stripTags_filter(input) {
|
||||
return stripTags((input || "").toString());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Escapes the characters in a String using XML entities.
|
||||
* Currently simply wraps Helma's encodeXml-method.
|
||||
*
|
||||
* @see global.encodeXml
|
||||
*/
|
||||
function escapeXml_filter(input) {
|
||||
return encodeXml((input || "").toString());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Escapes the characters in a String using HTML entities.
|
||||
*
|
||||
* @see http://www.google.com/codesearch?q=escapeHtml
|
||||
*/
|
||||
function escapeHtml_filter(input) {
|
||||
var replace = Packages.org.eclipse.jetty.util.StringUtil.replace;
|
||||
var str = (input || "").toString();
|
||||
return replace(replace(replace(replace(str, '&', '&'), '"', '"'), '>', '>'), '<', '<');
|
||||
}
|
||||
|
||||
var h_filter = escapeHtml_filter;
|
||||
|
||||
|
||||
/**
|
||||
* Escapes the characters in a String to be suitable
|
||||
* to use as an HTTP parameter value.
|
||||
*
|
||||
* @see http://www.google.com/codesearch?q=escapeUrl
|
||||
* @param charset Optional String. The name of a supported
|
||||
* character encoding.
|
||||
*/
|
||||
function escapeUrl_filter(input, param, charset) {
|
||||
var charset = param.charset || charset || app.getCharset();
|
||||
return java.net.URLEncoder.encode(input || "", charset);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Escapes a string so it may be used in JavaScript String
|
||||
* definitions.
|
||||
*/
|
||||
function escapeJavaScript_filter(input) {
|
||||
var replace = Packages.org.eclipse.jetty.util.StringUtil.replace;
|
||||
var str = (input || "").toString();
|
||||
return replace(replace(replace(replace(replace(str, '"', '\\"'), "'", "\\'"), '\n', '\\n'), '\r', '\\r'), '\t', '\\t');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replaces linebreaks with HTML linebreaks.
|
||||
*/
|
||||
function linebreakToHtml_filter(input) {
|
||||
var replace = Packages.org.eclipse.jetty.util.StringUtil.replace;
|
||||
var str = (input || "").toString();
|
||||
return replace(str, '\n', '<br />');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a string replacement.
|
||||
*
|
||||
* @param old
|
||||
* @param new
|
||||
*/
|
||||
function replace_filter(input, param, oldString, newString) {
|
||||
var str = String(input || '');
|
||||
var oldString = param.old || oldString;
|
||||
var newString = param['new'] || newString;
|
||||
return str.replace(new RegExp(oldString, 'g'), newString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a substring. Simply wraps the javascript
|
||||
* method 'substring'.
|
||||
*
|
||||
* @see String.prototype.substring
|
||||
* @param from
|
||||
* @param to
|
||||
*/
|
||||
function substring_filter(input, param, from, to) {
|
||||
var from = param.from != null ? param.from : from;
|
||||
var to = param.to != null ? param.to : to;
|
||||
var str = (input || "").toString();
|
||||
return str.substring(from, to);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a formatted string representation of a Date.
|
||||
* Simply wraps javascripts Date.format-method.
|
||||
*
|
||||
* @see Date.prototype.format
|
||||
* @param format
|
||||
*/
|
||||
function dateFormat_filter(input, param, format) {
|
||||
var format = param.format || format;
|
||||
if (!input) {
|
||||
return;
|
||||
} else {
|
||||
return input.format(format);
|
||||
}
|
||||
}
|
|
@ -1,256 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2005 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Global.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Adds useful global macros.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/core/Global.js')
|
||||
*/
|
||||
|
||||
app.addRepository("modules/core/String.js");
|
||||
|
||||
|
||||
/**
|
||||
* write out a property contained in app.properties
|
||||
* @param Object containing the name of the property
|
||||
*/
|
||||
function property_macro(param, name) {
|
||||
res.write(getProperty(name || param.name) || String.NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wrapper to output a string from within a skin
|
||||
* just to be able to use different encodings
|
||||
* @param Object containing the string as text property
|
||||
*/
|
||||
function write_macro(param, text) {
|
||||
res.write(param.text || text || String.NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* renders the current datetime
|
||||
* @param Object containing a formatting string as format property
|
||||
*/
|
||||
function now_macro(param) {
|
||||
var d = new Date();
|
||||
if (param.format) {
|
||||
try {
|
||||
res.write(d.format(param.format));
|
||||
} catch (e) {
|
||||
res.write('<span title="' + e + '">[Invalid date format]</span>');
|
||||
}
|
||||
} else if (param.as == "timestamp") {
|
||||
res.write(d.getTime());
|
||||
} else {
|
||||
res.write(d);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* renders a global skin
|
||||
*/
|
||||
var skin_macro = function(param, name) {
|
||||
var skinName = name || param.name;
|
||||
if (skinName) {
|
||||
renderSkin(skinName, param);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a string for HTML output and inserts linebreak tags.
|
||||
*
|
||||
* Performs the following string manipulations:
|
||||
* All line breaks (i.e. line feeds) are replaced with <br/> tags.
|
||||
* All special characters are being replaced with their equivalent HTML entity.
|
||||
* Existing markup tags are being encoded.
|
||||
*
|
||||
* @param {string} text
|
||||
* The string to encode for HTML output.
|
||||
* @param {boolean} [encodeNewLine = true]
|
||||
* If or if not to encode line breaks (i.e. line feeds).
|
||||
* @return {string}
|
||||
* The encoded string.
|
||||
*/
|
||||
function encode(text, encodeNewLine) {
|
||||
text = String(text);
|
||||
|
||||
if (text === null || !text.length) return text;
|
||||
var buffer = [];
|
||||
if (typeof encodeNewLine === 'undefined') encodeNewLine = true;
|
||||
|
||||
for (var i = 0, len = text.length; i < len; i += 1) {
|
||||
var char = text.charAt(i);
|
||||
|
||||
switch (char) {
|
||||
case '<':
|
||||
buffer.push('<');
|
||||
break;
|
||||
|
||||
case '>':
|
||||
buffer.push('>');
|
||||
break;
|
||||
|
||||
case '&':
|
||||
buffer.push('&');
|
||||
break;
|
||||
|
||||
case '"':
|
||||
buffer.push('"');
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
if (encodeNewLine) {
|
||||
buffer.push("<br/>");
|
||||
}
|
||||
buffer.push('\n');
|
||||
break;
|
||||
|
||||
default:
|
||||
buffer.push(char);
|
||||
}
|
||||
}
|
||||
|
||||
return buffer.join('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a string for XML output.
|
||||
*
|
||||
* Performs the following string manipulations:
|
||||
* All special characters are being replaced with their equivalent HTML entity.
|
||||
* Existing tags, single and double quotes, as well as ampersands are being encoded.
|
||||
* Some invalid XML characters below '0x20' are removed
|
||||
*
|
||||
* @param {string} text
|
||||
* The string to encode for XML output.
|
||||
* @return {string}
|
||||
* The string encoded for XML output.
|
||||
*/
|
||||
function encodeXml(text) {
|
||||
text = String(text);
|
||||
|
||||
if (text === null || !text.length) return text;
|
||||
var buffer = [];
|
||||
|
||||
for (var i = 0, len = text.length; i < len; i += 1) {
|
||||
var char = text.charAt(i);
|
||||
|
||||
switch (char) {
|
||||
case '<':
|
||||
buffer.push('<');
|
||||
break;
|
||||
|
||||
case '>':
|
||||
buffer.push('>');
|
||||
break;
|
||||
|
||||
case '&':
|
||||
buffer.push('&');
|
||||
break;
|
||||
|
||||
case '"':
|
||||
buffer.push('"');
|
||||
break;
|
||||
|
||||
case '\'':
|
||||
buffer.push(''');
|
||||
break;
|
||||
|
||||
default:
|
||||
var charCode = text.charCodeAt(i);
|
||||
if (charCode < 0x20) {
|
||||
// sort out invalid XML characters below 0x20 - all but 0x9, 0xA and 0xD.
|
||||
// The trick is an adaption of java.lang.Character.isSpace().
|
||||
if (((((1 << 0x9) | (1 << 0xA) | (1 << 0xD)) >> charCode) & 1) !== 0) {
|
||||
buffer.push(char);
|
||||
}
|
||||
} else {
|
||||
buffer.push(char);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buffer.join('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a string for HTML output, leaving linebreaks untouched.
|
||||
*
|
||||
* Performs the following string manipulations:
|
||||
* Unlike encode, leaves linebreaks untouched. This is what you usually want to do for encoding form content (esp.
|
||||
* with text input values).
|
||||
* All special characters (i.e. non ASCII) are being replaced with their equivalent HTML entity.
|
||||
* Existing markup tags are being encoded.
|
||||
*
|
||||
* @param {string} text
|
||||
* The string to format for HTML output.
|
||||
* @return {string}
|
||||
* The string formatted for HTML output.
|
||||
*/
|
||||
var encodeForm = function(text) {
|
||||
text = String(text);
|
||||
|
||||
if (text === null || !text.length) return text;
|
||||
|
||||
return encode(text, false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes any markup tags contained in the passed string, and returns the modified string.
|
||||
*
|
||||
* @param {string} markup
|
||||
* The text that is to be stripped of tags.
|
||||
* @return {string}
|
||||
* The text with the tags stripped out.
|
||||
*/
|
||||
var stripTags = function (markup) {
|
||||
if (!markup) return '';
|
||||
|
||||
var chars = String(markup).split('');
|
||||
var charCounter = 0;
|
||||
var inTag = false;
|
||||
|
||||
for (var i = 0, len = markup.length; i < len; i += 1) {
|
||||
if (chars[i] === '<') inTag = true;
|
||||
|
||||
if (!inTag) {
|
||||
if (i > charCounter) {
|
||||
chars[charCounter] = chars[i];
|
||||
}
|
||||
|
||||
charCounter += 1;
|
||||
}
|
||||
|
||||
if (chars[i] === '>') {
|
||||
inTag = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (i > charCounter) {
|
||||
chars.length = charCounter;
|
||||
return chars.join('');
|
||||
}
|
||||
|
||||
return markup;
|
||||
};
|
|
@ -1,210 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2005 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: HopObject.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Adds useful methods to Helma's built-in HopObject prototype.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/core/HopObject.js')
|
||||
*/
|
||||
|
||||
app.addRepository("modules/core/Number.js");
|
||||
app.addRepository("modules/core/String.js");
|
||||
|
||||
|
||||
/**
|
||||
* Iterates over each child node of the HopObject.
|
||||
* @external
|
||||
* @memberof {HopObject}
|
||||
* @param {Function} callback The callback function to be
|
||||
* called for each child node. On every call the first
|
||||
* argument of this function is set to the current value
|
||||
* of the counter variable <code>i</code>.
|
||||
*/
|
||||
HopObject.prototype.forEach = function(callback) {
|
||||
if (!callback || callback instanceof Function == false) {
|
||||
return;
|
||||
}
|
||||
for (var i=0; i<this.size(); i+=1) {
|
||||
callback.call(this.get(i), i);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* macro returns the id of a HopObject
|
||||
* @external
|
||||
* @memberof {HopObject}
|
||||
*/
|
||||
HopObject.prototype.id_macro = function() {
|
||||
res.write(this._id);
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* macro returns the url for any hopobject
|
||||
* @external
|
||||
* @memberof {HopObject}
|
||||
*/
|
||||
HopObject.prototype.href_macro = function(param, action) {
|
||||
res.write(this.href(action || param.action || String.NULLSTR));
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* macro rendering a skin or displaying
|
||||
* its source (param.as == "source")
|
||||
* @external
|
||||
* @memberof {HopObject}
|
||||
*/
|
||||
HopObject.prototype.skin_macro = function(param, name) {
|
||||
var skinName = name || param.name;
|
||||
if (skinName) {
|
||||
if (param.as == "source") {
|
||||
var str = app.skinfiles[this._prototype][skinName];
|
||||
if (str && param.unwrap == "true") {
|
||||
str = str.unwrap();
|
||||
}
|
||||
} else {
|
||||
var str = this.renderSkinAsString(skinName, param);
|
||||
}
|
||||
res.write(str);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* this macro renders a text depending on
|
||||
* the value of a given property
|
||||
* @external
|
||||
* @memberof {HopObject}
|
||||
*/
|
||||
HopObject.prototype.switch_macro = function(param) {
|
||||
if (param.name) {
|
||||
res.write(this[param.name] ? param.on : param.off);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* generic macro that loops over the childobjects
|
||||
* and renders a specified skin for each of them
|
||||
* @external
|
||||
* @memberof {HopObject}
|
||||
* @param Object providing the following properties:
|
||||
* skin: the skin to render for each item (required)
|
||||
* collection: the collection containing the items
|
||||
* limit: max. number of items per page
|
||||
* (req.data.page determines the page number)
|
||||
* sort: property name to use for sorting
|
||||
* order: sort order (either "asc" or "desc")
|
||||
* itemPrefix: text to prepend to each items skin render
|
||||
* itemSuffix: text to append to each items skin render
|
||||
*/
|
||||
HopObject.prototype.loop_macro = function(param, collection) {
|
||||
if (!param.skin) {
|
||||
return;
|
||||
}
|
||||
if (!collection) {
|
||||
collection = param.collection;
|
||||
}
|
||||
var items = collection ? this[collection] : this;
|
||||
if (!items || !items.size || items.size() < 1) {
|
||||
return;
|
||||
}
|
||||
// set default values
|
||||
var min = 0, max = items.size();
|
||||
var pagesize = max;
|
||||
if (param.limit) {
|
||||
var n = parseInt(param.limit, 10);
|
||||
if (!isNaN(n)) {
|
||||
pagesize = n;
|
||||
}
|
||||
var pagenr = parseInt(req.data.page, 10);
|
||||
if (isNaN(pagenr)) {
|
||||
pagenr = 0;
|
||||
}
|
||||
min = Math.min(max, pagenr * pagesize);
|
||||
max = Math.min(max, min + pagesize);
|
||||
}
|
||||
if (param.sort) {
|
||||
var allitems = items.list();
|
||||
var test = allitems[0][param.sort];
|
||||
if (test == null || isNaN(test)) {
|
||||
var Sorter = String.Sorter;
|
||||
} else {
|
||||
var Sorter = Number.Sorter;
|
||||
}
|
||||
allitems.sort(new Sorter(param.sort, Sorter[param.order.toUpperCase()]));
|
||||
var itemlist = allitems.slice(min, max);
|
||||
} else {
|
||||
var itemlist = items.list(min, max);
|
||||
}
|
||||
var skinParam = {};
|
||||
var itemPrefix = param.itemPrefix || "";
|
||||
var itemSuffix = param.itemSuffix || "";
|
||||
for (var i=0; i<itemlist.length; i+=1) {
|
||||
skinParam.index = pagenr * pagesize + i + 1;
|
||||
res.write(itemPrefix);
|
||||
itemlist[i].renderSkin(param.skin, skinParam);
|
||||
res.write(itemSuffix);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Render the number of child nodes of the HopObject.
|
||||
* Three cases are distinguished which can be customized
|
||||
* by setting param.verbose to "true" and defining the
|
||||
* corresponding field of the <code>param</code>
|
||||
* argument:
|
||||
* <ol>
|
||||
* <li>param.none - not a single child node</li>
|
||||
* <li>param.one - exactly one child node</li>
|
||||
* <li>param.many - more than one child node</li>
|
||||
* </ol>
|
||||
* @external
|
||||
* @memberof {HopObject}
|
||||
* @param {Object} param The default macro parameter
|
||||
* @param {String} name The default name for a child node
|
||||
*/
|
||||
HopObject.prototype.size_macro = function(param, name) {
|
||||
var EMPTYSTR = "";
|
||||
var n = this.size();
|
||||
if (name) {
|
||||
var text;
|
||||
var plural = name.endsWith("s") ? "es" : "s";
|
||||
if (n > 0) {
|
||||
if (n > 1) {
|
||||
text = n + " " + name + plural;
|
||||
} else {
|
||||
text = (param.one !== null) ? param.one : "one " + name;
|
||||
}
|
||||
} else {
|
||||
text = (param.none !== null) ? param.none : "no " + name + plural;
|
||||
}
|
||||
res.write(text);
|
||||
} else {
|
||||
res.write(n);
|
||||
}
|
||||
return;
|
||||
};
|
|
@ -1,2 +0,0 @@
|
|||
// This file intentionally left blank to prevent legacy code from
|
||||
// breaking when trying to include the obsolete JSON module.
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Number.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Adds useful methods to the JavaScript Number type.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/core/Number.js')
|
||||
*/
|
||||
|
||||
/**
|
||||
* format a Number to a String
|
||||
* @external
|
||||
* @memberof {Number}
|
||||
* @param String Format pattern
|
||||
* @param java.util.Locale An optional Locale instance
|
||||
* @return String Number formatted to a String
|
||||
*/
|
||||
Number.prototype.format = function(fmt, locale) {
|
||||
var symbols;
|
||||
if (locale != null) {
|
||||
symbols = new java.text.DecimalFormatSymbols(locale);
|
||||
} else {
|
||||
symbols = new java.text.DecimalFormatSymbols();
|
||||
}
|
||||
var df = new java.text.DecimalFormat(fmt || "###,##0.##", symbols);
|
||||
return df.format(0 + this); // addition with 0 prevents exception
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* return the percentage of a Number
|
||||
* according to a given total Number
|
||||
* @external
|
||||
* @memberof {Number}
|
||||
* @param Int Total
|
||||
* @param String Format Pattern
|
||||
* @param java.util.Locale An optional Locale instance
|
||||
* @return Int Percentage
|
||||
*/
|
||||
Number.prototype.toPercent = function(total, fmt, locale) {
|
||||
if (!total)
|
||||
return (0).format(fmt, locale);
|
||||
var p = this / (total / 100);
|
||||
return p.format(fmt, locale);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* factory to create functions for sorting objects in an array
|
||||
* @external
|
||||
* @memberof {Number}
|
||||
* @param String name of the field each object is compared with
|
||||
* @param Number order (ascending or descending)
|
||||
* @return Function ready for use in Array.prototype.sort
|
||||
*/
|
||||
Number.Sorter = function(field, order) {
|
||||
if (!order)
|
||||
order = 1;
|
||||
return function(a, b) {
|
||||
return (a[field] - b[field]) * order;
|
||||
};
|
||||
};
|
||||
|
||||
Number.Sorter.ASC = 1;
|
||||
Number.Sorter.DESC = -1;
|
||||
|
||||
|
||||
// prevent any newly added properties from being enumerated
|
||||
for (var i in Number)
|
||||
Number.dontEnum(i);
|
||||
for (var i in Number.prototype)
|
||||
Number.prototype.dontEnum(i);
|
|
@ -1,145 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Object.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Adds useful methods to the JavaScript Object type.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/core/Object.js')
|
||||
*/
|
||||
|
||||
app.addRepository('modules/core/Global.js');
|
||||
|
||||
/**
|
||||
* Copies the properties of this object into a clone.
|
||||
* @external
|
||||
* @memberof {Object}
|
||||
* @param {Object} clone The optional target object
|
||||
* @param {Boolean} recursive If true child objects are cloned as well, otherwise
|
||||
* the clone contains references to the child objects
|
||||
* @returns The resulting object
|
||||
*/
|
||||
Object.prototype.clone = function(clone, recursive) {
|
||||
|
||||
var getValue = function(value, recursive) {
|
||||
if (recursive !== true || value == null
|
||||
|| (typeof (value) !== "object" && typeof (value) !== "function")) {
|
||||
return value;
|
||||
}
|
||||
return value.clone(null, recursive);
|
||||
};
|
||||
|
||||
if (typeof (this) === "object") {
|
||||
if (this === null) {
|
||||
return null;
|
||||
}
|
||||
switch (this.constructor) {
|
||||
case String:
|
||||
case Number:
|
||||
case Boolean:
|
||||
case Date:
|
||||
return new this.constructor(this.valueOf());
|
||||
|
||||
case Array:
|
||||
return this.map(function(value) {
|
||||
return getValue(value, recursive);
|
||||
});
|
||||
|
||||
default:
|
||||
if (clone == null) {
|
||||
clone = new this.constructor();
|
||||
}
|
||||
for ( var propName in this) {
|
||||
clone[propName] = getValue(this[propName], recursive);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
} else if (typeof (this) === "function" && this.constructor === RegExp) {
|
||||
return new RegExp(this.valueOf());
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* reduce an extended object (ie. a HopObject)
|
||||
* to a generic javascript object
|
||||
* @external
|
||||
* @memberof {Object}
|
||||
* @param HopObject the HopObject to be reduced
|
||||
* @return Object the resulting generic object
|
||||
*/
|
||||
Object.prototype.reduce = function(recursive) {
|
||||
var result = {};
|
||||
for (var i in this) {
|
||||
if (this[i] instanceof HopObject == false)
|
||||
result[i] = this[i];
|
||||
else if (recursive)
|
||||
result[i] = this.reduce(true);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* print the contents of an object for debugging
|
||||
* @external
|
||||
* @memberof {Object}
|
||||
* @param Object the object to dump
|
||||
* @param Boolean recursive flag (if true, dump child objects, too)
|
||||
*/
|
||||
Object.prototype.dump = function(recursive) {
|
||||
var beginList = "<ul>";
|
||||
var endList = "</ul>";
|
||||
var beginItem = "<li>";
|
||||
var endItem = "</li>";
|
||||
var beginKey = "<strong>";
|
||||
var endKey = ":</strong> ";
|
||||
res.write(beginList);
|
||||
for (var p in this) {
|
||||
res.write(beginItem);
|
||||
res.write(beginKey);
|
||||
res.write(p);
|
||||
res.write(endKey);
|
||||
if (recursive && typeof this[p] == "object") {
|
||||
var recurse = true;
|
||||
var types = [Function, Date, String, Number];
|
||||
for (var i in types) {
|
||||
if (this[p] instanceof types[i]) {
|
||||
recurse = false
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (recurse == true)
|
||||
this[p].dump(true);
|
||||
else {
|
||||
res.write(this[p].toSource());
|
||||
}
|
||||
} else if (this[p]) {
|
||||
res.write(encode(this[p].toSource()));
|
||||
}
|
||||
res.write(endItem);
|
||||
}
|
||||
res.write(endList);
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
// prevent any newly added properties from being enumerated
|
||||
for (var i in Object)
|
||||
Object.dontEnum(i);
|
||||
for (var i in Object.prototype)
|
||||
Object.prototype.dontEnum(i);
|
|
@ -1,684 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: String.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
|
||||
String.ANUMPATTERN = /[^a-zA-Z0-9]/;
|
||||
String.APATTERN = /[^a-zA-Z]/;
|
||||
String.NUMPATTERN = /[^0-9]/;
|
||||
String.FILEPATTERN = /[^a-zA-Z0-9-_\. ]/;
|
||||
String.HEXPATTERN = /[^a-fA-F0-9]/;
|
||||
String.LEFT = -1
|
||||
String.BALANCE = 0
|
||||
String.RIGHT = 1
|
||||
String.ISOFORMAT = "yyyy-MM-dd'T'HH:mm:ssZ";
|
||||
String.SPACE = " ";
|
||||
String.EMPTY = "";
|
||||
String.NULL = String.EMPTY; // to be deprecated?
|
||||
|
||||
// Email and URL RegExps contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
|
||||
// licensed unter MIT license - http://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
String.EMAILPATTERN = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i;
|
||||
|
||||
String.URLPATTERN = /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i;
|
||||
|
||||
/**
|
||||
* @fileoverview Adds useful methods to the JavaScript String type.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/core/String.js')
|
||||
*/
|
||||
|
||||
app.addRepository('modules/core/Global.js');
|
||||
|
||||
/**
|
||||
* checks if a date format pattern is correct
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @return Boolean true if the pattern is correct
|
||||
*/
|
||||
String.prototype.isDateFormat = function() {
|
||||
try {
|
||||
new java.text.SimpleDateFormat(this);
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* parse a timestamp into a date object. This is used when users
|
||||
* want to set createtime explicitly when creating/editing stories.
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @param String date format to be applied
|
||||
* @param Object Java TimeZone Object (optional)
|
||||
* @return Object contains the resulting date
|
||||
*/
|
||||
String.prototype.toDate = function(format, timezone) {
|
||||
var sdf = res.data._dateformat;
|
||||
if (!sdf) {
|
||||
sdf = new java.text.SimpleDateFormat(format);
|
||||
res.data._dateformat = sdf;
|
||||
} else if (format != sdf.toPattern())
|
||||
sdf.applyPattern(format);
|
||||
if (timezone && timezone != sdf.getTimeZone())
|
||||
sdf.setTimeZone(timezone);
|
||||
try {
|
||||
return new Date(sdf.parse(this).getTime());
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* function checks if the string passed contains any characters that
|
||||
* are forbidden in URLs and tries to create a java.net.URL from it
|
||||
* FIXME: probably deprecated -> helma.Url
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @return Boolean
|
||||
* @see helma.Url.PATTERN
|
||||
*/
|
||||
String.prototype.isUrl = function() {
|
||||
return String.URLPATTERN.test(this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* function checks if the string passed contains any characters
|
||||
* that are forbidden in image- or filenames
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @return Boolean
|
||||
*/
|
||||
String.prototype.isFileName = function() {
|
||||
return !String.FILEPATTERN.test(this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* function cleans the string passed as argument from any characters
|
||||
* that are forbidden or shouldn't be used in filenames
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @return Boolean
|
||||
*/
|
||||
String.prototype.toFileName = function() {
|
||||
return this.replace(new RegExp(String.FILEPATTERN.source, "g"), String.NULL);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* function checks a string for a valid color value in hexadecimal format.
|
||||
* it may also contain # as first character
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @returns Boolean false, if string length (without #) > 6 or < 6 or
|
||||
* contains any character which is not a valid hex value
|
||||
*/
|
||||
String.prototype.isHexColor = function() {
|
||||
var str = this;
|
||||
if (this.indexOf("#") == 0)
|
||||
str = this.substring(1);
|
||||
if (str.length != 6)
|
||||
return false;
|
||||
return !String.HEXPATTERN.test(str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* converts a string into a hexadecimal color
|
||||
* representation (e.g. "ffcc33"). also knows how to
|
||||
* convert a color string like "rgb (255, 204, 51)".
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @return String the resulting hex color (w/o "#")
|
||||
*/
|
||||
String.prototype.toHexColor = function() {
|
||||
if (this.startsWith("rgb")) {
|
||||
res.push();
|
||||
var col = this.replace(/[^0-9,]/g, String.NULL);
|
||||
var parts = col.split(",");
|
||||
for (var i in parts) {
|
||||
var num = parseInt(parts[i], 10);
|
||||
var hex = num.toString(16);
|
||||
res.write(hex.pad("0", 2, String.LEFT));
|
||||
}
|
||||
return res.pop();
|
||||
}
|
||||
var col = this.replace(new RegExp(String.HEXPATTERN.source), String.NULL);
|
||||
return col.toLowerCase().pad("0", 6, String.LEFT);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* function returns true if the string contains
|
||||
* only a-z and 0-9 (case insensitive!)
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @return Boolean true in case string is alpha, false otherwise
|
||||
*/
|
||||
String.prototype.isAlphanumeric = function() {
|
||||
if (!this.length)
|
||||
return false;
|
||||
return !String.ANUMPATTERN.test(this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* function cleans a string by throwing away all
|
||||
* non-alphanumeric characters
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @return cleaned string
|
||||
*/
|
||||
String.prototype.toAlphanumeric = function() {
|
||||
return this.replace(new RegExp(String.ANUMPATTERN.source, "g"), String.NULL);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* function returns true if the string contains
|
||||
* only characters a-z
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @return Boolean true in case string is alpha, false otherwise
|
||||
*/
|
||||
String.prototype.isAlpha = function() {
|
||||
if (!this.length)
|
||||
return false;
|
||||
return !String.APATTERN.test(this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* function returns true if the string contains
|
||||
* only 0-9
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @return Boolean true in case string is numeric, false otherwise
|
||||
*/
|
||||
String.prototype.isNumeric = function() {
|
||||
if (!this.length)
|
||||
return false;
|
||||
return !String.NUMPATTERN.test(this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* transforms the first n characters of a string to uppercase
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @param Number amount of characters to transform
|
||||
* @return String the resulting string
|
||||
*/
|
||||
String.prototype.capitalize = function(limit) {
|
||||
if (limit == null)
|
||||
limit = 1;
|
||||
var head = this.substring(0, limit);
|
||||
var tail = this.substring(limit, this.length);
|
||||
return head.toUpperCase() + tail.toLowerCase();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* transforms the first n characters of each
|
||||
* word in a string to uppercase
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @return String the resulting string
|
||||
*/
|
||||
String.prototype.titleize = function() {
|
||||
var parts = this.split(" ");
|
||||
res.push();
|
||||
for (var i in parts) {
|
||||
res.write(parts[i].capitalize());
|
||||
if (i < parts.length-1)
|
||||
res.write(" ");
|
||||
}
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* translates all characters of a string into HTML entities
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @return String translated result
|
||||
*/
|
||||
String.prototype.entitize = function() {
|
||||
res.push();
|
||||
for (var i=0; i<this.length; i++) {
|
||||
res.write("&#");
|
||||
res.write(this.charCodeAt(i).toString());
|
||||
res.write(";");
|
||||
}
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* breaks up a string into two parts called
|
||||
* head and tail at the given position
|
||||
* don't apply this to HTML, i.e. use stripTags() in advance
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @param Number number of charactrers or of segments separated by the delimiter
|
||||
* @param String pre-/suffix to be pre-/appended to shortened string
|
||||
* @param String delimiter
|
||||
* @return Object containing head and tail properties
|
||||
*/
|
||||
String.prototype.embody = function(limit, clipping, delimiter) {
|
||||
if (typeof limit == "string")
|
||||
limit = parseInt(limit, 10);
|
||||
var result = {head: this, tail: String.NULL};
|
||||
if (!limit || limit < 1)
|
||||
return result;
|
||||
if (!delimiter || delimiter == String.NULL)
|
||||
result.head= this.substring(0, limit);
|
||||
else {
|
||||
var re = new RegExp ("(" + delimiter + "+)");
|
||||
result.head = this.split(re, 2*limit - 1).join(String.NULL);
|
||||
}
|
||||
if (result.head != this) {
|
||||
result.tail = this.substring(result.head.length).trim();
|
||||
if (result.tail) {
|
||||
if (clipping == null)
|
||||
clipping = "...";
|
||||
result.head = result.head.trim() + clipping;
|
||||
result.tail = clipping + result.tail;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* get the head of a string
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @see String.prototype.embody()
|
||||
*/
|
||||
String.prototype.head = function(limit, clipping, delimiter) {
|
||||
return this.embody(limit, clipping, delimiter).head;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* get the tail of a string
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @see String.prototype.embody()
|
||||
*/
|
||||
String.prototype.tail = function(limit, clipping, delimiter) {
|
||||
return this.embody(limit, clipping, delimiter).tail;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FIXME: we eventually have to get rid of this one...
|
||||
* set clip method out of compatibility/convenience reason
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @deprecated
|
||||
* @see String.prototype.head()
|
||||
*/
|
||||
String.prototype.clip = String.prototype.head;
|
||||
|
||||
|
||||
/**
|
||||
* function inserts a string every number of characters
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @param Int number of characters after which insertion should take place
|
||||
* @param String string to be inserted
|
||||
* @param Boolean definitely insert at each interval position
|
||||
* @return String resulting string
|
||||
*/
|
||||
String.prototype.group = function(interval, str, ignoreWhiteSpace) {
|
||||
if (!interval || interval < 1)
|
||||
interval = 20;
|
||||
if (!str || this.length < interval)
|
||||
return this;
|
||||
res.push();
|
||||
for (var i=0; i<this.length; i=i+interval) {
|
||||
var strPart = this.substring(i, i+interval);
|
||||
res.write(strPart);
|
||||
if (ignoreWhiteSpace == true ||
|
||||
(strPart.length == interval && !/\s/g.test(strPart))) {
|
||||
res.write(str);
|
||||
}
|
||||
}
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* replace all linebreaks and optionally all w/br tags
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @param Boolean flag indicating if html tags should be replaced
|
||||
* @param String replacement for the linebreaks / html tags
|
||||
* @return String the unwrapped string
|
||||
*/
|
||||
String.prototype.unwrap = function(removeTags, replacement) {
|
||||
if (replacement == null)
|
||||
replacement = String.NULL;
|
||||
var str = this.replace(/[\n|\r]/g, replacement);
|
||||
if (removeTags)
|
||||
str = str.replace(/<[w]?br *\/?>/g, replacement);
|
||||
return str;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* function calculates the md5 hash of a string
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @return String md5 hash of the string
|
||||
*/
|
||||
String.prototype.md5 = function() {
|
||||
return Packages.org.apache.commons.codec.digest.DigestUtils.md5Hex(this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* fills a string with another string up to a desired length
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @param String the filling string
|
||||
* @param Number the desired length of the resulting string
|
||||
* @param Number the direction which the string will be padded in:
|
||||
* -1: left 0: both (balance) 1: right
|
||||
* (you can use the constants String.LEFT,
|
||||
* String.BALANCE and String.RIGHT here as well.)
|
||||
* @return String the resulting string
|
||||
*/
|
||||
String.prototype.pad = function(str, length, mode) {
|
||||
if (mode === null || mode === String.RIGHT) return this.padEnd(length, str);
|
||||
if (mode === String.LEFT) return this.padStart(length, str);
|
||||
|
||||
if (mode === String.BALANCE && str && length) {
|
||||
const pos = Math.ceil(this.length / 2);
|
||||
const head = this.substr(0, pos);
|
||||
const tail = this.substr(pos);
|
||||
const additionalLength = (length - this.length) / 2;
|
||||
const startLength = head.length + Math.floor(additionalLength);
|
||||
const endLength = tail.length + Math.ceil(additionalLength);
|
||||
return head.padStart(startLength, str) + tail.padEnd(endLength, str);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* function returns true if a string contains the string
|
||||
* passed as argument
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @param String string to search for
|
||||
* @param Int Position to start search
|
||||
* @param Boolean
|
||||
*/
|
||||
String.prototype.contains = function(str, fromIndex) {
|
||||
return this.indexOf(str, fromIndex || 0) > -1;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* function compares a string with the one passed as argument
|
||||
* using diff
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @param String String to compare against String object value
|
||||
* @param String Optional regular expression string to use for
|
||||
* splitting. If not defined, newlines will be used.
|
||||
* @return Object Array containing one JS object for each line
|
||||
* with the following properties:
|
||||
* .num Line number
|
||||
* .value String line if unchanged
|
||||
* .deleted Obj Array containing deleted lines
|
||||
* .inserted Obj Array containing added lines
|
||||
*/
|
||||
String.prototype.diff = function(mod, separator) {
|
||||
// if no separator use line separator
|
||||
var regexp = (typeof(separator) == "undefined") ?
|
||||
new RegExp("\r\n|\r|\n") :
|
||||
new RegExp(separator);
|
||||
// split both strings into arrays
|
||||
var orig = this.split(regexp);
|
||||
var mod = mod.split(regexp);
|
||||
// create the Diff object
|
||||
var diff = new Packages.helma.util.Diff(orig, mod);
|
||||
// get the diff.
|
||||
var d = diff.diff();
|
||||
if (!d)
|
||||
return null;
|
||||
|
||||
var max = Math.max(orig.length, mod.length);
|
||||
var result = new Array();
|
||||
for (var i=0;i<max;i++) {
|
||||
var line = result[i];
|
||||
if (!line) {
|
||||
line = new Object();
|
||||
line.num = (i+1);
|
||||
result[i] = line;
|
||||
}
|
||||
if (d && i == d.line1) {
|
||||
if (d.deleted) {
|
||||
var del = new Array();
|
||||
for (var j=d.line0; j<d.line0+d.deleted; j++)
|
||||
del[del.length] = orig[j];
|
||||
line.deleted = del;
|
||||
}
|
||||
if (d.inserted) {
|
||||
var ins = new Array();
|
||||
for (var j=d.line1; j<d.line1+d.inserted; j++)
|
||||
ins[ins.length] = mod[j];
|
||||
line.inserted = ins;
|
||||
}
|
||||
i = d.line1 + d.inserted -1;
|
||||
d = d.link;
|
||||
} else {
|
||||
line.value = mod[i];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* returns true if the string looks like an e-mail
|
||||
* @external
|
||||
* @memberof {String}
|
||||
*/
|
||||
String.prototype.isEmail = function() {
|
||||
return String.EMAILPATTERN.test(this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* returns the amount of occurences of one string in another
|
||||
* @external
|
||||
* @memberof {String}
|
||||
*/
|
||||
String.prototype.count = function(str) {
|
||||
var count = 0;
|
||||
var offset = 0;
|
||||
while ((offset = this.indexOf(str, offset)) > -1) {
|
||||
count += 1;
|
||||
offset += 1;
|
||||
}
|
||||
return count;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* returns the string encoded using the base64 algorithm
|
||||
* @external
|
||||
* @memberof {String}
|
||||
*/
|
||||
String.prototype.enbase64 = function() {
|
||||
var bytes = java.lang.String(this).getBytes('utf-8');
|
||||
return String(java.lang.String(Packages.org.apache.commons.codec.binary.Base64.encodeBase64(bytes), 'utf-8'));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* returns the decoded string using the base64 algorithm
|
||||
* @external
|
||||
* @memberof {String}
|
||||
*/
|
||||
String.prototype.debase64 = function() {
|
||||
var bytes = Packages.org.apache.commons.codec.binary.Base64.decodeBase64(this);
|
||||
return String(java.lang.String(bytes, 'utf-8'));
|
||||
};
|
||||
|
||||
|
||||
// wrapper methods for string-related
|
||||
// global helma functions
|
||||
|
||||
String.prototype.encode = function() {
|
||||
return encode(this);
|
||||
};
|
||||
|
||||
String.prototype.encodeXml = function() {
|
||||
return encodeXml(this);
|
||||
};
|
||||
|
||||
String.prototype.encodeForm = function() {
|
||||
return encodeForm(this);
|
||||
};
|
||||
|
||||
String.prototype.format = function() {
|
||||
return format(this);
|
||||
};
|
||||
|
||||
String.prototype.stripTags = function() {
|
||||
return stripTags(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* factory to create functions for sorting objects in an array
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @param String name of the field each object is compared with
|
||||
* @param Number order (ascending or descending)
|
||||
* @return Function ready for use in Array.prototype.sort
|
||||
*/
|
||||
String.Sorter = function(field, order) {
|
||||
if (!order)
|
||||
order = 1;
|
||||
var key = field + ":" + order;
|
||||
if (!String.Sorter.cache[key]) {
|
||||
String.Sorter.cache[key] = function(a, b) {
|
||||
var str1 = String(a[field] || String.NULL).toLowerCase();
|
||||
var str2 = String(b[field] || String.NULL).toLowerCase();
|
||||
if (str1 > str2)
|
||||
return order * 1;
|
||||
if (str1 < str2)
|
||||
return order * -1;
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
return String.Sorter.cache[key];
|
||||
};
|
||||
|
||||
String.Sorter.ASC = 1;
|
||||
String.Sorter.DESC = -1;
|
||||
String.Sorter.cache = {};
|
||||
|
||||
|
||||
/**
|
||||
* create a string from a bunch of substrings
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @param String one or more strings as arguments
|
||||
* @return String the resulting string
|
||||
*/
|
||||
String.compose = function() {
|
||||
res.push();
|
||||
for (var i=0; i<arguments.length; i++)
|
||||
res.write(arguments[i]);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* creates a random string (numbers and chars)
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @param len length of key
|
||||
* @param mode determines which letters to use. null or 0 = all letters;
|
||||
* 1 = skip 0, 1, l and o which can easily be mixed with numbers;
|
||||
* 2 = use numbers only
|
||||
* @returns random string
|
||||
*/
|
||||
String.random = function(len, mode) {
|
||||
if (mode == 2) {
|
||||
var x = Math.random() * Math.pow(10,len);
|
||||
return Math.floor(x);
|
||||
}
|
||||
var keystr = String.NULL;
|
||||
for (var i=0; i<len; i++) {
|
||||
var x = Math.floor((Math.random() * 36));
|
||||
if (mode == 1) {
|
||||
// skip 0,1
|
||||
x = (x<2) ? x + 2 : x;
|
||||
// don't use the letters l (charCode 21+87) and o (24+87)
|
||||
x = (x==21) ? 22 : x;
|
||||
x = (x==24) ? 25 : x;
|
||||
}
|
||||
if (x<10) {
|
||||
keystr += String(x);
|
||||
} else {
|
||||
keystr += String.fromCharCode(x+87);
|
||||
}
|
||||
}
|
||||
return keystr;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* append one string onto another and add some "glue"
|
||||
* if none of the strings is empty or null.
|
||||
* @external
|
||||
* @memberof {String}
|
||||
* @param String the first string
|
||||
* @param String the string to be appended onto the first one
|
||||
* @param String the "glue" to be inserted between both strings
|
||||
* @return String the resulting string
|
||||
*/
|
||||
String.join = function(str1, str2, glue) {
|
||||
if (glue == null)
|
||||
glue = String.NULL;
|
||||
if (str1 && str2)
|
||||
return str1 + glue + str2;
|
||||
else if (str2)
|
||||
return str2;
|
||||
return str1;
|
||||
};
|
||||
|
||||
|
||||
// prevent any newly added properties from being enumerated
|
||||
for (var i in String)
|
||||
String.dontEnum(i);
|
||||
for (var i in String.prototype)
|
||||
String.prototype.dontEnum(i);
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: all.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// convenience SingleFileRepository to load all the
|
||||
// Javascript library files in ./modules/core
|
||||
|
||||
app.addRepository('modules/core/Array.js');
|
||||
app.addRepository('modules/core/Date.js');
|
||||
app.addRepository('modules/core/Number.js');
|
||||
app.addRepository('modules/core/Object.js');
|
||||
app.addRepository('modules/core/String.js');
|
||||
app.addRepository('modules/core/HopObject.js');
|
||||
app.addRepository('modules/core/Global.js');
|
||||
app.addRepository('modules/core/Filters.js');
|
|
@ -1,145 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2008 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Aspects.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Methods of the helma.Aspects module.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/helma/Aspects.js')
|
||||
*/
|
||||
|
||||
/**
|
||||
* Define the global namespace if not existing
|
||||
*/
|
||||
if (!global.helma) {
|
||||
global.helma = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Library for adding Aspects
|
||||
* <br /><br />
|
||||
* Provides static methods to wrap existing functions
|
||||
* inside a javascript closure in order to add additional
|
||||
* behavior without overriding the existing one.
|
||||
* <br /><br />
|
||||
* Based on code by roman porotnikov,
|
||||
* http://www.jroller.com/page/deep/20030701
|
||||
* <br /><br />
|
||||
* Note: Each prototype that uses aspects must implement a method
|
||||
* onCodeUpdate() to prevent aspects being lost when the prototype
|
||||
* is re-compiled
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
helma.Aspects = function() {
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/** @ignore */
|
||||
helma.Aspects.toString = function() {
|
||||
return "[helma.Aspects]";
|
||||
};
|
||||
|
||||
|
||||
/** @ignore */
|
||||
helma.Aspects.prototype.toString = function() {
|
||||
return "[helma.Aspects Object]";
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a function to be called before the orginal function.
|
||||
* <br /><br />
|
||||
* The return value of the added function needs to provide the
|
||||
* array of arguments that is passed to the original function.
|
||||
* The added function receives an array of the original arguments,
|
||||
* the original function and the scope object of the original
|
||||
* function as its parameters.
|
||||
*
|
||||
* @param {Object} obj The object of which the original function is a property
|
||||
* @param {String} fname The property name of the original function
|
||||
* @param {Function} before The function to be called before the original function
|
||||
* @returns Function A new function, wrapping the original function
|
||||
* @type Function
|
||||
*/
|
||||
helma.Aspects.prototype.addBefore = function(obj, fname, before) {
|
||||
var oldFunc = obj[fname];
|
||||
obj[fname] = function() {
|
||||
return oldFunc.apply(this, before(arguments, oldFunc, this));
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a function to be called after an existing function.
|
||||
* <br /><br />
|
||||
* The return value of the original function is passed to the
|
||||
* added function as its first argument. In addition, the added
|
||||
* function also receives an array of the original arguments,
|
||||
* the original function and the scope object of the original
|
||||
* function as additional parameters.
|
||||
*
|
||||
* @param {Object} obj as Object, the object of which the original function is a property
|
||||
* @param {String} fname as String, the property name of the original function
|
||||
* @param {Function} after as Function, the function to be called after the original function
|
||||
* @returns Function A new function, wrapping the original function
|
||||
* @type Function
|
||||
*/
|
||||
helma.Aspects.prototype.addAfter = function(obj, fname, after) {
|
||||
var oldFunc = obj[fname];
|
||||
obj[fname] = function() {
|
||||
return after(oldFunc.apply(this, arguments), arguments, oldFunc, this);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Wraps an additional function around the original function.
|
||||
* <br /><br />
|
||||
* The added function receives as its arguments an array of the original
|
||||
* arguments, the original function and the scope object of the original
|
||||
* function. The original function is not called directly and needs
|
||||
* to be invoked by the added function.
|
||||
*
|
||||
* @param {Object} obj as Object, the object of which the original function is a property
|
||||
* @param {String} fname as String, the property name of the original function
|
||||
* @param {Function} around as Function, the function to be called inside the original function
|
||||
* @returns Function A new function, wrapping the original function
|
||||
* @type Function
|
||||
*/
|
||||
helma.Aspects.prototype.addAround = function(obj, fname, around) {
|
||||
var oldFunc = obj[fname];
|
||||
obj[fname] = function() {
|
||||
return around(arguments, oldFunc, this);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
helma.lib = "Aspects";
|
||||
helma.dontEnum(helma.lib);
|
||||
for (var i in helma[helma.lib])
|
||||
helma[helma.lib].dontEnum(i);
|
||||
for (var i in helma[helma.lib].prototype)
|
||||
helma[helma.lib].prototype.dontEnum(i);
|
||||
delete helma.lib;
|
||||
|
||||
|
||||
helma.aspects = new helma.Aspects();
|
||||
helma.dontEnum("aspects");
|
201
modules/helma/Chart.js
vendored
201
modules/helma/Chart.js
vendored
|
@ -1,201 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Chart.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the helma.Chart prototype
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/helma/Chart.js')
|
||||
*/
|
||||
|
||||
// take care of any dependencies
|
||||
app.addRepository('modules/helma/jxl-2.5.7.jar');
|
||||
|
||||
/**
|
||||
* Define the global namespace if not existing
|
||||
*/
|
||||
if (!global.helma) {
|
||||
global.helma = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of helma.Chart
|
||||
* @class Instances of this class are capable of reading
|
||||
* Excel spreadsheets and rendering them as XHTML table. Internally
|
||||
* helma.Chart uses the <a href="http://www.jexcelapi.org/ ">Java Excel API</a>
|
||||
* by <a href="http://www.andykhan.com/">Andy Khan</a>.
|
||||
* @param {String} fpath The path to the spreadsheet file
|
||||
* @param {String} prefix An optional prefix to use for all
|
||||
* stylesheet classes within the rendered table
|
||||
* @param {String} sheetName The name of the sheet within the
|
||||
* spreadsheet file to render. If this argument is omitted, the
|
||||
* first sheet is rendered.
|
||||
* @returns A newly created helma.Chart instance.
|
||||
* @constructor
|
||||
* @author Tobi Schaefer
|
||||
*/
|
||||
helma.Chart = function(fpath, prefix, sheetName) {
|
||||
var JXLPKG = Packages.jxl.Workbook;
|
||||
var JXLPKGNAME = "jxl.jar";
|
||||
var JXLPKGURL = "http://www.andykhan.com/jexcelapi/";
|
||||
|
||||
var workbook, file;
|
||||
try {
|
||||
file = new java.io.File(fpath);
|
||||
workbook = JXLPKG.getWorkbook(file);
|
||||
} catch (e) {
|
||||
if (e instanceof TypeError == false)
|
||||
throw(e);
|
||||
throw("helma.Chart needs " + JXLPKGNAME +
|
||||
" in lib/ext or application directory " +
|
||||
"[" + JXLPKGURL + "]");
|
||||
}
|
||||
|
||||
var getCellStyle = function(c) {
|
||||
if (!c)
|
||||
return;
|
||||
var result = new Object();
|
||||
var format = c.getCellFormat();
|
||||
var font = format.getFont();
|
||||
if (font.getBoldWeight() > 400)
|
||||
result.bold = true;
|
||||
result.italic = font.isItalic();
|
||||
result.wrap = format.getWrap();
|
||||
var type = c.getType();
|
||||
var align = format.getAlignment().getDescription();
|
||||
if (align == "right" || type == "Number" || type == "Date")
|
||||
result.align = "right";
|
||||
else if (align == "centre")
|
||||
result.align = "center";
|
||||
return result;
|
||||
}
|
||||
|
||||
if (sheetName) {
|
||||
var sheet = workbook.getSheet(sheetName);
|
||||
} else {
|
||||
var sheet = workbook.getSheet(0);
|
||||
}
|
||||
if (!sheet)
|
||||
return;
|
||||
|
||||
prefix = prefix ? prefix + "_" : "chart_";
|
||||
|
||||
/**
|
||||
* Renders the Excel spreadsheet as XHTML table.
|
||||
*/
|
||||
this.render = function() {
|
||||
res.write('<table border="0" cellspacing="1" class="' +
|
||||
prefix + 'table">\n');
|
||||
|
||||
var rowBuf = [];
|
||||
var rows = sheet.getRows();
|
||||
var max = 0;
|
||||
for (var i=0; i<rows; i+=1) {
|
||||
var row = sheet.getRow(i);
|
||||
if (row.length > max)
|
||||
max = row.length;
|
||||
rowBuf.push(row);
|
||||
}
|
||||
|
||||
for (var i in rowBuf) {
|
||||
res.write('<tr class="' + prefix + 'row">\n');
|
||||
for (var n=0; n<max; n+=1) {
|
||||
if (n < rowBuf[i].length) {
|
||||
var c = rowBuf[i][n];
|
||||
var str = c.getContents();
|
||||
if (str)
|
||||
var style = getCellStyle(c);
|
||||
}
|
||||
res.write('<td class="' + prefix + 'cell"');
|
||||
if (style) {
|
||||
if (!style.wrap)
|
||||
res.write(' nowrap="nowrap"');
|
||||
if (style.align)
|
||||
res.write(' align="' + style.align + '"');
|
||||
res.write(">");
|
||||
if (style.bold)
|
||||
res.write("<b>");
|
||||
if (style.italic)
|
||||
res.write("<i>");
|
||||
}
|
||||
else
|
||||
res.write(">");
|
||||
res.write(str);
|
||||
if (style) {
|
||||
if (style.italic)
|
||||
res.write("</i>");
|
||||
if (style.bold)
|
||||
res.write("</b>");
|
||||
}
|
||||
res.write('</td>\n');
|
||||
}
|
||||
res.write('</tr>\n');
|
||||
}
|
||||
|
||||
res.write('</table>\n');
|
||||
workbook.close();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the spreadsheet as rendered XHTML table.
|
||||
* @returns The rendered spreadsheet table
|
||||
* @type String
|
||||
*/
|
||||
this.renderAsString = function() {
|
||||
res.push();
|
||||
this.render();
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
this.toString = function() {
|
||||
return "[helma.Chart " + file + "]";
|
||||
};
|
||||
|
||||
for (var i in this)
|
||||
this.dontEnum(i);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/** @ignore */
|
||||
helma.Chart.toString = function() {
|
||||
return "[helma.Chart]";
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A simple example for using helma.Chart that renders
|
||||
* the passed file as XHTML table to response.
|
||||
* @param {String} file The path to the Excel spreadsheet file
|
||||
*/
|
||||
helma.Chart.example = function(file) {
|
||||
// var file = "/path/to/file.xls";
|
||||
var chart = new helma.Chart(file);
|
||||
chart.render();
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
helma.lib = "Chart";
|
||||
helma.dontEnum(helma.lib);
|
||||
for (var i in helma[helma.lib])
|
||||
helma[helma.lib].dontEnum(i);
|
||||
for (var i in helma[helma.lib].prototype)
|
||||
helma[helma.lib].prototype.dontEnum(i);
|
||||
delete helma.lib;
|
|
@ -1,396 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Color.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the helma.Chart prototype
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/helma/Color.js')
|
||||
*/
|
||||
|
||||
// take care of any dependencies
|
||||
app.addRepository("modules/core/String.js");
|
||||
|
||||
/**
|
||||
* Define the global namespace if not existing
|
||||
*/
|
||||
if (!global.helma) {
|
||||
global.helma = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of helma.Color.
|
||||
* @class Instances of this class provide methods for
|
||||
* converting HTML color names into their corresponding
|
||||
* RGB values and vice versa, or retrieving single RGB color values.
|
||||
* @param {Number|String} R Either the red fraction of the color,
|
||||
* or the name of the color.
|
||||
* @param {Number} G The green fraction
|
||||
* @param {Number} B The blue fraction
|
||||
* @returns A newly created helma.Color instance
|
||||
* @constructor
|
||||
*/
|
||||
helma.Color = function(R, G, B) {
|
||||
var value = null;
|
||||
var name = null;
|
||||
var hex = null;
|
||||
var rgb = null;
|
||||
|
||||
/**
|
||||
* Returns the decimal value of this color, or of a specified
|
||||
* color channel.
|
||||
* @param {String} channel An optional color channel which
|
||||
* decimal value should be returned. Must be either "red",
|
||||
* "green" or "blue". If no channel is specified this
|
||||
* method returns the decimal value of the color itself.
|
||||
* @returns The decimal value of this color or a single channel.
|
||||
* @type Number
|
||||
*/
|
||||
this.valueOf = function(channel) {
|
||||
if (channel) {
|
||||
if (!rgb) {
|
||||
var compose = function(n, bits) {
|
||||
var div = Math.pow(2, bits);
|
||||
remainder = n % div;
|
||||
return Math.floor(n/div);
|
||||
}
|
||||
var remainder = value;
|
||||
rgb = {
|
||||
red: compose(remainder, 16),
|
||||
green: compose(remainder, 8),
|
||||
blue: compose(remainder, 0)
|
||||
};
|
||||
}
|
||||
return rgb[channel];
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the hexidecimal value of this color (without
|
||||
* a leading hash sign).
|
||||
* @returns The hexidecimal value of this color
|
||||
* @type String
|
||||
*/
|
||||
this.toString = function() {
|
||||
if (!value)
|
||||
return null;
|
||||
if (!hex)
|
||||
hex = value.toString(16).pad("0", 6, String.LEFT);
|
||||
return hex;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the trivial name of this color
|
||||
* @returns The trivial name of this color
|
||||
* @type String
|
||||
*/
|
||||
this.getName = function() {
|
||||
return helma.Color.COLORVALUES[value];
|
||||
};
|
||||
|
||||
/**
|
||||
* Main constructor body
|
||||
*/
|
||||
if (arguments.length % 2 == 0)
|
||||
throw("Insufficient arguments for creating Color");
|
||||
if (arguments.length == 1) {
|
||||
if (R.constructor == Number) {
|
||||
value = R;
|
||||
} else if (R.constructor == String) {
|
||||
R = R.toLowerCase();
|
||||
if (helma.Color.COLORNAMES[R]) {
|
||||
this.name = R;
|
||||
value = helma.Color.COLORNAMES[R];
|
||||
} else {
|
||||
if (R.startsWith("#")) {
|
||||
R = R.substring(1);
|
||||
}
|
||||
value = parseInt(R, 16);
|
||||
this.name = helma.Color.COLORVALUES[value];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
value = R * Math.pow(2, 16) + G * Math.pow(2, 8) + B;
|
||||
}
|
||||
|
||||
if (value == null || isNaN(value))
|
||||
throw("helma.Color: invalid argument " + R);
|
||||
|
||||
for (var i in this)
|
||||
this.dontEnum(i);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new helma.Color instance based on a color name.
|
||||
* @param {String} name The color name (eg. "darkseagreen")
|
||||
* @returns An instance of helma.Color representing the color specified
|
||||
* @type helma.Color
|
||||
*/
|
||||
helma.Color.fromName = function(name) {
|
||||
var value = helma.Color.COLORNAMES[name.toLowerCase()];
|
||||
return new helma.Color(value || 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new helma.Color instance based on a HSL color
|
||||
* representation. This method is adapted from the HSLtoRGB
|
||||
* conversion method as described at
|
||||
* <a href="http://www1.tip.nl/~t876506/ColorDesign.html#hr">http://www1.tip.nl/~t876506/ColorDesign.html#hr</a>.
|
||||
* @param {Number} H The hue fraction of the color definition
|
||||
* @param {Number} S The saturation fraction
|
||||
* @param {Number} L The lightness fraction
|
||||
* @returns An instance of helma.Color representing the corresponding
|
||||
* RGB color definition.
|
||||
* @type helma.Color
|
||||
*/
|
||||
helma.Color.fromHsl = function(H,S,L) {
|
||||
function H1(H,S,L) {
|
||||
var R = 1; var G = 6*H; var B = 0;
|
||||
G = G*S + 1 - S; B = B*S + 1 - S;
|
||||
R = R*L; G = G*L; B = B*L;
|
||||
return [R,G,B];
|
||||
}
|
||||
|
||||
function H2(H,S,L) {
|
||||
var R = 1-6*(H - 1/6); var G = 1; var B = 0;
|
||||
R = R*S + 1 - S; B = B*S + 1 - S;
|
||||
R = R*L; G = G*L; B = B*L;
|
||||
return [R,G,B];
|
||||
}
|
||||
|
||||
function H3(H,S,L) {
|
||||
var R = 0; var G = 1; var B = 6*(H - 1/3);
|
||||
R = R*S + 1 - S; B = B*S + 1 - S;
|
||||
R = R*L; G = G*L; B = B*L
|
||||
return [R,G,B];
|
||||
}
|
||||
|
||||
function H4(H,S,L) {
|
||||
var R = 0; var G = 1-6*(H - 1/2); var B = 1;
|
||||
R = R*S + 1 - S; G = G*S + 1 - S;
|
||||
R = R*L; G = G*L; B = B*L;
|
||||
return [R,G,B];
|
||||
}
|
||||
|
||||
function H5(H,S,L) {
|
||||
var R = 6*(H - 2/3); var G = 0; var B = 1;
|
||||
R = R*S + 1 - S; G = G*S + 1 - S;
|
||||
R = R*L; G = G*L; B = B*L;
|
||||
return [R,G,B];
|
||||
}
|
||||
|
||||
function H6(H,S,L) {
|
||||
var R = 1; var G = 0; var B = 1-6*(H - 5/6);
|
||||
G = G*S + 1 - S; B = B*S + 1 - S;
|
||||
R = R*L; G = G*L; B = B*L;
|
||||
return [R,G,B];
|
||||
}
|
||||
|
||||
// H [0-1] is divided into 6 equal sectors.
|
||||
// From within each sector the proper conversion function is called.
|
||||
var rgb;
|
||||
if (H < 1/6) rgb = H1(H,S,L);
|
||||
else if (H < 1/3) rgb = H2(H,S,L);
|
||||
else if (H < 1/2) rgb = H3(H,S,L);
|
||||
else if (H < 2/3) rgb = H4(H,S,L);
|
||||
else if (H < 5/6) rgb = H5(H,S,L);
|
||||
else rgb = H6(H,S,L);
|
||||
|
||||
return new helma.Color(
|
||||
Math.round(rgb[0]*255),
|
||||
Math.round(rgb[1]*255),
|
||||
Math.round(rgb[2]*255)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Contains the hexadecimal values of named colors.
|
||||
* @type Object
|
||||
* @final
|
||||
*/
|
||||
helma.Color.COLORNAMES = {
|
||||
black: 0x000000,
|
||||
maroon: 0x800000,
|
||||
green: 0x008000,
|
||||
olive: 0x808000,
|
||||
navy: 0x000080,
|
||||
purple: 0x800080,
|
||||
teal: 0x008080,
|
||||
silver: 0xc0c0c0,
|
||||
gray: 0x808080,
|
||||
red: 0xff0000,
|
||||
lime: 0x00ff00,
|
||||
yellow: 0xffff00,
|
||||
blue: 0x0000ff,
|
||||
fuchsia: 0xff00ff,
|
||||
aqua: 0x00ffff,
|
||||
white: 0xffffff,
|
||||
aliceblue: 0xf0f8ff,
|
||||
antiquewhite: 0xfaebd7,
|
||||
aquamarine: 0x7fffd4,
|
||||
azure: 0xf0ffff,
|
||||
beige: 0xf5f5dc,
|
||||
blueviolet: 0x8a2be2,
|
||||
brown: 0xa52a2a,
|
||||
burlywood: 0xdeb887,
|
||||
cadetblue: 0x5f9ea0,
|
||||
chartreuse: 0x7fff00,
|
||||
chocolate: 0xd2691e,
|
||||
coral: 0xff7f50,
|
||||
cornflowerblue: 0x6495ed,
|
||||
cornsilk: 0xfff8dc,
|
||||
crimson: 0xdc143c,
|
||||
darkblue: 0x00008b,
|
||||
darkcyan: 0x008b8b,
|
||||
darkgoldenrod: 0xb8860b,
|
||||
darkgray: 0xa9a9a9,
|
||||
darkgreen: 0x006400,
|
||||
darkkhaki: 0xbdb76b,
|
||||
darkmagenta: 0x8b008b,
|
||||
darkolivegreen: 0x556b2f,
|
||||
darkorange: 0xff8c00,
|
||||
darkorchid: 0x9932cc,
|
||||
darkred: 0x8b0000,
|
||||
darksalmon: 0xe9967a,
|
||||
darkseagreen: 0x8fbc8f,
|
||||
darkslateblue: 0x483d8b,
|
||||
darkslategray: 0x2f4f4f,
|
||||
darkturquoise: 0x00ced1,
|
||||
darkviolet: 0x9400d3,
|
||||
deeppink: 0xff1493,
|
||||
deepskyblue: 0x00bfff,
|
||||
dimgray: 0x696969,
|
||||
dodgerblue: 0x1e90ff,
|
||||
firebrick: 0xb22222,
|
||||
floralwhite: 0xfffaf0,
|
||||
forestgreen: 0x228b22,
|
||||
gainsboro: 0xdcdcdc,
|
||||
ghostwhite: 0xf8f8ff,
|
||||
gold: 0xffd700,
|
||||
goldenrod: 0xdaa520,
|
||||
greenyellow: 0xadff2f,
|
||||
honeydew: 0xf0fff0,
|
||||
hotpink: 0xff69b4,
|
||||
indianred: 0xcd5c5c,
|
||||
indigo: 0x4b0082,
|
||||
ivory: 0xfffff0,
|
||||
khaki: 0xf0e68c,
|
||||
lavender: 0xe6e6fa,
|
||||
lavenderblush: 0xfff0f5,
|
||||
lawngreen: 0x7cfc00,
|
||||
lemonchiffon: 0xfffacd,
|
||||
lightblue: 0xadd8e6,
|
||||
lightcoral: 0xf08080,
|
||||
lightcyan: 0xe0ffff,
|
||||
lightgoldenrodyellow: 0xfafad2,
|
||||
lightgreen: 0x90ee90,
|
||||
lightgrey: 0xd3d3d3,
|
||||
lightpink: 0xffb6c1,
|
||||
lightsalmon: 0xffa07a,
|
||||
lightseagreen: 0x20b2aa,
|
||||
lightskyblue: 0x87cefa,
|
||||
lightslategray: 0x778899,
|
||||
lightsteelblue: 0xb0c4de,
|
||||
lightyellow: 0xffffe0,
|
||||
limegreen: 0x32cd32,
|
||||
linen: 0xfaf0e6,
|
||||
mediumaquamarine: 0x66cdaa,
|
||||
mediumblue: 0x0000cd,
|
||||
mediumorchid: 0xba55d3,
|
||||
mediumpurple: 0x9370db,
|
||||
mediumseagreen: 0x3cb371,
|
||||
mediumslateblue: 0x7b68ee,
|
||||
mediumspringgreen: 0x00fa9a,
|
||||
mediumturquoise: 0x48d1cc,
|
||||
mediumvioletred: 0xc71585,
|
||||
midnightblue: 0x191970,
|
||||
mintcream: 0xf5fffa,
|
||||
mistyrose: 0xffe4e1,
|
||||
moccasin: 0xffe4b5,
|
||||
navajowhite: 0xffdead,
|
||||
oldlace: 0xfdf5e6,
|
||||
olivedrab: 0x6b8e23,
|
||||
orange: 0xffa500,
|
||||
orangered: 0xff4500,
|
||||
orchid: 0xda70d6,
|
||||
palegoldenrod: 0xeee8aa,
|
||||
palegreen: 0x98fb98,
|
||||
paleturquoise: 0xafeeee,
|
||||
palevioletred: 0xdb7093,
|
||||
papayawhip: 0xffefd5,
|
||||
peachpuff: 0xffdab9,
|
||||
peru: 0xcd853f,
|
||||
pink: 0xffc0cb,
|
||||
plum: 0xdda0dd,
|
||||
powderblue: 0xb0e0e6,
|
||||
rosybrown: 0xbc8f8f,
|
||||
royalblue: 0x4169e1,
|
||||
saddlebrown: 0x8b4513,
|
||||
salmon: 0xfa8072,
|
||||
sandybrown: 0xf4a460,
|
||||
seagreen: 0x2e8b57,
|
||||
seashell: 0xfff5ee,
|
||||
sienna: 0xa0522d,
|
||||
skyblue: 0x87ceeb,
|
||||
slateblue: 0x6a5acd,
|
||||
slategray: 0x708090,
|
||||
snow: 0xfffafa,
|
||||
springgreen: 0x00ff7f,
|
||||
steelblue: 0x4682b4,
|
||||
tan: 0xd2b48c,
|
||||
thistle: 0xd8bfd8,
|
||||
tomato: 0xff6347,
|
||||
turquoise: 0x40e0d0,
|
||||
violet: 0xee82ee,
|
||||
wheat: 0xf5deb3,
|
||||
whitesmoke: 0xf5f5f5,
|
||||
yellowgreen: 0x9acd32
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Contains the color names for specific hex values
|
||||
* @type Object
|
||||
* @final
|
||||
*/
|
||||
helma.Color.COLORVALUES = {};
|
||||
|
||||
for (var i in helma.Color.COLORNAMES) {
|
||||
helma.Color.COLORVALUES[helma.Color.COLORNAMES[i]] = i;
|
||||
}
|
||||
|
||||
|
||||
/** @ignore */
|
||||
helma.Color.toString = function() {
|
||||
return "[helma.Color]";
|
||||
};
|
||||
|
||||
|
||||
helma.lib = "Color";
|
||||
helma.dontEnum(helma.lib);
|
||||
for (var i in helma[helma.lib])
|
||||
helma[helma.lib].dontEnum(i);
|
||||
for (var i in helma[helma.lib].prototype)
|
||||
helma[helma.lib].prototype.dontEnum(i);
|
||||
delete helma.lib;
|
|
@ -1,341 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Database.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Properties and methods of the helma.Database prototype.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/helma/Database.js')
|
||||
*/
|
||||
|
||||
if (!global.helma) {
|
||||
global.helma = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for Database objects, providing access through relational
|
||||
* databases through JDBC. It is usually simpler to use one of the factory
|
||||
* methods {@link #createInstance} or {@link #getInstance}.
|
||||
* @class <p>This class provides access to a relational database through JDBC.
|
||||
* There are two convenient ways to create instances of this class.</p>
|
||||
*
|
||||
* <p>The first is to use {@link #getInstance helma.Database.getInstance()}
|
||||
* to obtain a connection to a DB that is defined in the application's
|
||||
* db.properties and managed by Helma. The second way is to define and create
|
||||
* a database connection locally using
|
||||
* {@link #createInstance helma.Database.createInstance()} and passing it
|
||||
* all necessary parameters.</p>
|
||||
*
|
||||
* <p>This class provides two ways of interaction:
|
||||
* The {@link #query} method allows to issue SQL queries, returning a result set.
|
||||
* The {@link #execute} provides a way to issue SQL statements that do not
|
||||
* return a result set.</p>
|
||||
*
|
||||
* <p>Database connections allocated by this class are be managed and eventually
|
||||
* disposed by Helma.</p>
|
||||
*
|
||||
* @param {DbSource} source instance of a helma.objectmodel.db.DbSource
|
||||
* @constructor
|
||||
*/
|
||||
helma.Database = function(source) {
|
||||
var Types = java.sql.Types;
|
||||
var DbSource = Packages.helma.objectmodel.db.DbSource;
|
||||
|
||||
if (typeof(source) == "string")
|
||||
source = app.getDbSource(source);
|
||||
if (!(source instanceof DbSource))
|
||||
throw "helma.Database requires a helma.objectmodel.db.DbSource argument";
|
||||
|
||||
/**
|
||||
* Get the java.sql.Connection for this Database instance. This can be used
|
||||
* to operate on the connection directly, without going through the helma.Database
|
||||
* class.
|
||||
* @return {java.sql.Connection} the JDBC connection
|
||||
*/
|
||||
this.getConnection = function() {
|
||||
return source.getConnection();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the lower case name of the underlying database product.
|
||||
* @return {String} the name of the DB product
|
||||
*/
|
||||
this.getProductName = function() {
|
||||
return source.getConnection().getMetaData().getDatabaseProductName().toLowerCase();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if this is an Oracle database.
|
||||
* @return {boolean} true if this is an Oracle database.
|
||||
*/
|
||||
this.isOracle = function() {
|
||||
return source.isOracle();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if this is a MySQL database.
|
||||
* @return {boolean} true if this is an MySQL database.
|
||||
*/
|
||||
this.isMySql = function() {
|
||||
return source.isMySQL();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if this is a PostgreSQL database.
|
||||
* @return {boolean} true if this is a PostgreSQL database.
|
||||
*/
|
||||
this.isPostgreSql = function() {
|
||||
return source.isPostgreSQL();
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes the given SQL statement. The result set is returned
|
||||
* as JavaScript Array containing a JavaScript Object for each result.
|
||||
* @param {String} sql an SQL query statement
|
||||
* @return {Array} an Array containing the result set
|
||||
*/
|
||||
this.query = function(sql) {
|
||||
var isLogSqlEnabled = (getProperty("logSQL", "false").toLowerCase() == "true");
|
||||
var logTimeStart = isLogSqlEnabled ? java.lang.System.currentTimeMillis() : 0;
|
||||
var connection = source.getConnection();
|
||||
connection.setReadOnly(true);
|
||||
var statement = connection.createStatement();
|
||||
var resultSet = statement.executeQuery(sql);
|
||||
var metaData = resultSet.getMetaData();
|
||||
var max = metaData.getColumnCount();
|
||||
var types = [];
|
||||
for (var i=1; i <= max; i++) {
|
||||
types[i] = metaData.getColumnType(i);
|
||||
}
|
||||
var result = [];
|
||||
while (resultSet.next()) {
|
||||
var row = {}
|
||||
for (var i=1; i<=max; i+=1) {
|
||||
switch (types[i]) {
|
||||
case Types.BIT:
|
||||
case Types.BOOLEAN:
|
||||
row[metaData.getColumnLabel(i)] = resultSet.getBoolean(i);
|
||||
break;
|
||||
case Types.TINYINT:
|
||||
case Types.BIGINT:
|
||||
case Types.SMALLINT:
|
||||
case Types.INTEGER:
|
||||
row[metaData.getColumnLabel(i)] = resultSet.getLong(i);
|
||||
break;
|
||||
case Types.REAL:
|
||||
case Types.FLOAT:
|
||||
case Types.DOUBLE:
|
||||
case Types.DECIMAL:
|
||||
case Types.NUMERIC:
|
||||
row[metaData.getColumnLabel(i)] = resultSet.getDouble(i);
|
||||
break;
|
||||
case Types.VARBINARY:
|
||||
case Types.BINARY:
|
||||
case Types.LONGVARBINARY:
|
||||
case Types.LONGVARCHAR:
|
||||
case Types.CHAR:
|
||||
case Types.VARCHAR:
|
||||
case Types.CLOB:
|
||||
case Types.OTHER:
|
||||
row[metaData.getColumnLabel(i)] = resultSet.getString(i);
|
||||
break;
|
||||
case Types.DATE:
|
||||
case Types.TIME:
|
||||
case Types.TIMESTAMP:
|
||||
row[metaData.getColumnLabel(i)] = resultSet.getTimestamp(i);
|
||||
break;
|
||||
case Types.NULL:
|
||||
row[metaData.getColumnLabel(i)] = null;
|
||||
break;
|
||||
default:
|
||||
row[metaData.getColumnLabel(i)] = resultSet.getString(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
result[result.length] = row;
|
||||
}
|
||||
var logTimeStop = isLogSqlEnabled ? java.lang.System.currentTimeMillis() : 0;
|
||||
if (isLogSqlEnabled) {
|
||||
var tableName = metaData.getColumnCount() > 0 ? metaData.getTableName(1) : null;
|
||||
app.getLogger("helma." + app.name + ".sql").info("SQL DIRECT_QUERY " + (tableName || "-") + " " + (logTimeStop - logTimeStart) + ": " + sql);
|
||||
}
|
||||
try {
|
||||
statement.close();
|
||||
resultSet.close();
|
||||
} catch (error) {
|
||||
// ignore
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes the given SQL statement, which may be an INSERT, UPDATE,
|
||||
* or DELETE statement or an SQL statement that returns nothing,
|
||||
* such as an SQL data definition statement. The return value is an integer that
|
||||
* indicates the number of rows that were affected by the statement.
|
||||
* @param {String} sql an SQL statement
|
||||
* @return {int} either the row count for INSERT, UPDATE or
|
||||
* DELETE statements, or 0 for SQL statements that return nothing
|
||||
*/
|
||||
this.execute = function(sql) {
|
||||
var isLogSqlEnabled = (getProperty("logSQL", "false").toLowerCase() == "true");
|
||||
var logTimeStart = isLogSqlEnabled ? java.lang.System.currentTimeMillis() : 0;
|
||||
var connection = source.getConnection();
|
||||
connection.setReadOnly(false);
|
||||
var statement = connection.createStatement();
|
||||
var result;
|
||||
try {
|
||||
result = statement.executeUpdate(sql);
|
||||
} finally {
|
||||
try {
|
||||
statement.close();
|
||||
} catch (error) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
var logTimeStop = isLogSqlEnabled ? java.lang.System.currentTimeMillis() : 0;
|
||||
if (isLogSqlEnabled) {
|
||||
app.getLogger("helma." + app.name + ".sql").info("SQL DIRECT_EXECUTE - " + (logTimeStop - logTimeStart) + ": " + sql);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the name of the Helma DbSource object.
|
||||
* @return {String} the DbSource name
|
||||
*/
|
||||
this.getName = function() {
|
||||
return source.getName();
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the name of the JDBC driver used by this Database instance.
|
||||
* @return {String} the JDBC driver name
|
||||
*/
|
||||
this.getDriverName = function() {
|
||||
return source.getDriverName();
|
||||
};
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
this.toString = function() {
|
||||
return "[helma.Database " + this.getName() + "]";
|
||||
};
|
||||
|
||||
for (var i in this)
|
||||
this.dontEnum(i);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new Database instance using the given parameters.
|
||||
* <p>Some of the parameters support shortcuts for known database products.
|
||||
* The <code>url</code> parameter recognizes the values "mysql", "oracle" and
|
||||
* "postgresql". For those databases, it is also possible to pass just
|
||||
* <code>hostname</code> or <code>hostname:port</code> as <code>url</code>
|
||||
* parameters instead of the full JDBC URL.</p>
|
||||
* @param {String} driver the class name of the JDBC driver. As
|
||||
* shortcuts, the values "mysql", "oracle" and "postgresql" are
|
||||
* recognized.
|
||||
* @param {String} url the JDBC URL.
|
||||
* @param {String} name the name of the database to use
|
||||
* @param {String} user the the username
|
||||
* @param {String} password the password
|
||||
* @return {helma.Database} a helma.Database instance
|
||||
*/
|
||||
helma.Database.createInstance = function(driver, url, name, user, password) {
|
||||
var DbSource = Packages.helma.objectmodel.db.DbSource;
|
||||
|
||||
if (!driver || !url || !name)
|
||||
throw("Insufficient arguments to create helma.db.Connection");
|
||||
if (typeof password != "string")
|
||||
password = "";
|
||||
|
||||
var MYSQL = "mysql";
|
||||
var ORACLE = "oracle";
|
||||
var POSTGRESQL = "postgresql";
|
||||
var JDBC = "jdbc:";
|
||||
var DRIVER_MYSQL = "com.mysql.jdbc.Driver";
|
||||
var DRIVER_ORACLE = "oracle.jdbc.driver.OracleDriver";
|
||||
var DRIVER_POSTGRESQL = "org.postgresql.Driver";
|
||||
|
||||
if (driver == MYSQL) {
|
||||
driver = DRIVER_MYSQL;
|
||||
if (url.indexOf(JDBC) != 0)
|
||||
url = "jdbc:mysql://" + url + "/" + name;
|
||||
} else if (driver == ORACLE) {
|
||||
driver = DRIVER_ORACLE;
|
||||
if (url.indexOf(JDBC) != 0)
|
||||
url = "jdbc:oracle:thin:@" + url + ":" + name;
|
||||
} else if (driver == POSTGRESQL) {
|
||||
driver = DRIVER_POSTGRESQL;
|
||||
if (url.indexOf(JDBC) != 0)
|
||||
url = "jdbc:postgresql://" + url + "/" + name;
|
||||
}
|
||||
var props = new Packages.helma.util.ResourceProperties();
|
||||
props.put(name + ".url", url);
|
||||
props.put(name + ".driver", driver);
|
||||
if (user) {
|
||||
props.put(name + ".user", user)
|
||||
}
|
||||
if (password) {
|
||||
props.put(name + ".password", password);
|
||||
}
|
||||
return new helma.Database(new DbSource(name, props));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Database instance using the Database source defined in the
|
||||
* application's db.properties file with the given name.
|
||||
* @param {String} name the name of the DB source as defined in db.properties
|
||||
* @return {helma.Database} a helma.Database instance
|
||||
*/
|
||||
helma.Database.getInstance = function(name) {
|
||||
return new helma.Database(app.getDbSource(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
helma.Database.toString = function() {
|
||||
return "[helma.Database]";
|
||||
};
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
helma.Database.example = function() {
|
||||
var type = "mysql";
|
||||
var host = "localhost";
|
||||
var user = "root";
|
||||
var pw = "";
|
||||
var name = "mysql";
|
||||
var db = new helma.Database(type, host, user, pw, name);
|
||||
var result = db.query("select count(*) from db");
|
||||
res.write(result.toSource());
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
helma.lib = "Database";
|
||||
helma.dontEnum(helma.lib);
|
||||
for (var i in helma[helma.lib])
|
||||
helma[helma.lib].dontEnum(i);
|
||||
for (var i in helma[helma.lib].prototype)
|
||||
helma[helma.lib].prototype.dontEnum(i);
|
||||
delete helma.lib;
|
|
@ -1,760 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2007 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: File.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Default properties and methods of the File prototype.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/helma/File.js')
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Define the global namespace if not existing
|
||||
*/
|
||||
if (!global.helma) {
|
||||
global.helma = {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for File objects, providing read and
|
||||
* write access to the file system.
|
||||
* @class This class represents a local file or directory
|
||||
* @param {String} path as String, can be either absolute or relative to the helma home directory
|
||||
* @constructor
|
||||
*/
|
||||
helma.File = function(path) {
|
||||
var BufferedReader = java.io.BufferedReader;
|
||||
var File = java.io.File;
|
||||
var Writer = java.io.Writer;
|
||||
var FileReader = java.io.FileReader;
|
||||
var PrintWriter = java.io.PrintWriter;
|
||||
var FileOutputStream = java.io.FileOutputStream;
|
||||
var OutputStreamWriter = java.io.OutputStreamWriter;
|
||||
var FileInputStream = java.io.FileInputStream;
|
||||
var InputStreamReader = java.io.InputStreamReader;
|
||||
var EOFException = java.io.EOFException;
|
||||
var IllegalStateException = java.lang.IllegalStateException;
|
||||
var IllegalArgumentException = java.lang.IllegalArgumentException
|
||||
|
||||
var self = this;
|
||||
|
||||
var file;
|
||||
try {
|
||||
// immediately convert to absolute path - java.io.File is
|
||||
// incredibly stupid when dealing with relative file names
|
||||
if (arguments.length > 1)
|
||||
file = new File(path, arguments[1]).getAbsoluteFile();
|
||||
else
|
||||
file = new File(path).getAbsoluteFile();
|
||||
} catch (e) {
|
||||
throw(e);
|
||||
}
|
||||
|
||||
var readerWriter;
|
||||
var atEOF = false;
|
||||
var lastLine = null;
|
||||
|
||||
var setError = function(e) {
|
||||
self.lastError = e;
|
||||
};
|
||||
|
||||
this.lastError = null;
|
||||
|
||||
/** @ignore */
|
||||
this.toString = function() {
|
||||
return file.toString();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the name of the file or directory represented by this File object.
|
||||
* <br /><br />
|
||||
* This is just the last name in the pathname's name sequence.
|
||||
* If the pathname's name sequence is empty, then the empty
|
||||
* string is returned.
|
||||
*
|
||||
* @returns String containing the name of the file or directory
|
||||
* @type String
|
||||
*/
|
||||
this.getName = function() {
|
||||
var name = file.getName();
|
||||
return (name == null ? "" : name);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the file represented by this File object
|
||||
* is currently open.
|
||||
*
|
||||
* @returns Boolean
|
||||
* @type Boolean
|
||||
*/
|
||||
this.isOpened = function() {
|
||||
return (readerWriter != null);
|
||||
};
|
||||
|
||||
/**
|
||||
* Opens the file represented by this File object. If the file exists,
|
||||
* it is used for reading, otherwise it is opened for writing.
|
||||
* If the encoding argument is specified, it is used to read or write
|
||||
* the file. Otherwise, the platform's default encoding is used.
|
||||
*
|
||||
* @param {Object} options an optional argument holder object.
|
||||
* The following options are supported:
|
||||
* <ul><li>charset name of encoding to use for reading or writing</li>
|
||||
* <li>append whether to append to the file if it exists</li></ul>
|
||||
* @returns Boolean true if the operation succeeded
|
||||
* @type Boolean
|
||||
*/
|
||||
this.open = function(options) {
|
||||
if (self.isOpened()) {
|
||||
setError(new IllegalStateException("File already open"));
|
||||
return false;
|
||||
}
|
||||
// We assume that the BufferedReader and PrintWriter creation
|
||||
// cannot fail except if the FileReader/FileWriter fails.
|
||||
// Otherwise we have an open file until the reader/writer
|
||||
// get garbage collected.
|
||||
var charset = options && options.charset;
|
||||
var append = options && options.append;
|
||||
try {
|
||||
if (file.exists() && !append) {
|
||||
if (charset) {
|
||||
readerWriter = new BufferedReader(
|
||||
new InputStreamReader(new FileInputStream(file), charset));
|
||||
} else {
|
||||
readerWriter = new BufferedReader(new FileReader(file));
|
||||
}
|
||||
} else {
|
||||
if (append && charset) {
|
||||
readerWriter = new PrintWriter(
|
||||
new OutputStreamWriter(new FileOutputStream(file, true), charset));
|
||||
} else if (append) {
|
||||
readerWriter = new PrintWriter(
|
||||
new OutputStreamWriter(new FileOutputStream(file, true)));
|
||||
} else if (charset) {
|
||||
readerWriter = new PrintWriter(file, charset);
|
||||
} else {
|
||||
readerWriter = new PrintWriter(file);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (e) {
|
||||
setError(e);
|
||||
return false;
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests whether the file or directory represented by this File object exists.
|
||||
*
|
||||
* @returns Boolean true if the file or directory exists; false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
this.exists = function() {
|
||||
return file.exists();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the pathname string of this File object's parent directory.
|
||||
*
|
||||
* @returns String containing the pathname of the parent directory
|
||||
* @type String
|
||||
*/
|
||||
this.getParent = function() {
|
||||
if (!file.getParent())
|
||||
return null;
|
||||
return new helma.File(file.getParent());
|
||||
};
|
||||
|
||||
/**
|
||||
* This methods reads characters until an end of line/file is encountered
|
||||
* then returns the string for these characters (without any end of line
|
||||
* character).
|
||||
*
|
||||
* @returns String of the next unread line in the file
|
||||
* @type String
|
||||
*/
|
||||
this.readln = function() {
|
||||
if (!self.isOpened()) {
|
||||
setError(new IllegalStateException("File not opened"));
|
||||
return null;
|
||||
}
|
||||
if (!(readerWriter instanceof BufferedReader)) {
|
||||
setError(new IllegalStateException("File not opened for reading"));
|
||||
return null;
|
||||
}
|
||||
if (atEOF) {
|
||||
setError(new EOFException());
|
||||
return null;
|
||||
}
|
||||
if (lastLine != null) {
|
||||
var line = lastLine;
|
||||
lastLine = null;
|
||||
return line;
|
||||
}
|
||||
var reader = readerWriter;
|
||||
// Here lastLine is null, return a new line
|
||||
try {
|
||||
var line = readerWriter.readLine();
|
||||
if (line == null) {
|
||||
atEOF = true;
|
||||
setError(new EOFException());
|
||||
}
|
||||
return line;
|
||||
} catch (e) {
|
||||
setError(e);
|
||||
return null;
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Appends a string to the file represented by this File object.
|
||||
*
|
||||
* @param {String} what as String, to be written to the file
|
||||
* @returns Boolean
|
||||
* @type Boolean
|
||||
* @see #writeln
|
||||
*/
|
||||
this.write = function(what) {
|
||||
if (!self.isOpened()) {
|
||||
setError(new IllegalStateException("File not opened"));
|
||||
return false;
|
||||
}
|
||||
if (!(readerWriter instanceof PrintWriter)) {
|
||||
setError(new IllegalStateException("File not opened for writing"));
|
||||
return false;
|
||||
}
|
||||
if (what != null) {
|
||||
readerWriter.print(what.toString());
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Appends a string with a platform specific end of
|
||||
* line to the file represented by this File object.
|
||||
*
|
||||
* @param {String} what as String, to be written to the file
|
||||
* @returns Boolean
|
||||
* @type Boolean
|
||||
* @see #write
|
||||
*/
|
||||
this.writeln = function(what) {
|
||||
if (self.write(what)) {
|
||||
readerWriter.println();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests whether this File object's pathname is absolute.
|
||||
* <br /><br />
|
||||
* The definition of absolute pathname is system dependent.
|
||||
* On UNIX systems, a pathname is absolute if its prefix is "/".
|
||||
* On Microsoft Windows systems, a pathname is absolute if its prefix
|
||||
* is a drive specifier followed by "\\", or if its prefix is "\\".
|
||||
*
|
||||
* @returns Boolean if this abstract pathname is absolute, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
this.isAbsolute = function() {
|
||||
return file.isAbsolute();
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes the file or directory represented by this File object.
|
||||
*
|
||||
* @returns Boolean
|
||||
* @type Boolean
|
||||
*/
|
||||
this.remove = function() {
|
||||
if (self.isOpened()) {
|
||||
setError(new IllegalStateException("An openened file cannot be removed"));
|
||||
return false;
|
||||
}
|
||||
return file["delete"]();
|
||||
};
|
||||
|
||||
/**
|
||||
* List of all files within the directory represented by this File object.
|
||||
* <br /><br />
|
||||
* You may pass a RegExp Pattern to return just files matching this pattern.
|
||||
* <br /><br />
|
||||
* Example: var xmlFiles = dir.list(/.*\.xml/);
|
||||
*
|
||||
* @param {RegExp} pattern as RegExp, optional pattern to test each file name against
|
||||
* @returns Array the list of file names
|
||||
* @type Array
|
||||
*/
|
||||
this.list = function(pattern) {
|
||||
if (self.isOpened())
|
||||
return null;
|
||||
if (!file.isDirectory())
|
||||
return null;
|
||||
if (pattern) {
|
||||
var fileList = file.list();
|
||||
var result = [];
|
||||
for (var i in fileList) {
|
||||
if (pattern.test(fileList[i]))
|
||||
result.push(fileList[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return file.list();
|
||||
};
|
||||
|
||||
/**
|
||||
* Purges the content of the file represented by this File object.
|
||||
*
|
||||
* @returns Boolean
|
||||
* @type Boolean
|
||||
*/
|
||||
this.flush = function() {
|
||||
if (!self.isOpened()) {
|
||||
setError(new IllegalStateException("File not opened"));
|
||||
return false;
|
||||
}
|
||||
if (readerWriter instanceof Writer) {
|
||||
try {
|
||||
readerWriter.flush();
|
||||
} catch (e) {
|
||||
setError(e);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
setError(new IllegalStateException("File not opened for write"));
|
||||
return false; // not supported by reader
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes the file represented by this File object.
|
||||
*
|
||||
* @returns Boolean
|
||||
* @type Boolean
|
||||
*/
|
||||
this.close = function() {
|
||||
if (!self.isOpened())
|
||||
return false;
|
||||
try {
|
||||
atEOF = false;
|
||||
lastLine = null;
|
||||
readerWriter.close();
|
||||
readerWriter = null;
|
||||
return true;
|
||||
} catch (e) {
|
||||
setError(e);
|
||||
readerWriter = null;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the pathname string of this File object.
|
||||
* <br /><br />
|
||||
* The resulting string uses the default name-separator character
|
||||
* to separate the names in the name sequence.
|
||||
*
|
||||
* @returns String of this file's pathname
|
||||
* @type String
|
||||
*/
|
||||
this.getPath = function() {
|
||||
var path = file.getPath();
|
||||
return (path == null ? "" : path);
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains the last error that occured, if any.
|
||||
* @returns String
|
||||
* @type String
|
||||
* @see #clearError
|
||||
*/
|
||||
this.error = function() {
|
||||
if (this.lastError == null) {
|
||||
return "";
|
||||
} else {
|
||||
var exceptionName = this.lastError.getClass().getName();
|
||||
var l = exceptionName.lastIndexOf(".");
|
||||
if (l > 0)
|
||||
exceptionName = exceptionName.substring(l + 1);
|
||||
return exceptionName + ": " + this.lastError.getMessage();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears any error message that may otherwise be returned by the error method.
|
||||
*
|
||||
* @see #error
|
||||
*/
|
||||
this.clearError = function() {
|
||||
this.lastError = null;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests whether the application can read the file
|
||||
* represented by this File object.
|
||||
*
|
||||
* @returns Boolean true if the file exists and can be read; false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
this.canRead = function() {
|
||||
return file.canRead();
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests whether the file represented by this File object is writable.
|
||||
*
|
||||
* @returns Boolean true if the file exists and can be modified; false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.canWrite = function() {
|
||||
return file.canWrite();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the absolute pathname string of this file.
|
||||
* <br /><br />
|
||||
* If this File object's pathname is already absolute, then the pathname
|
||||
* string is simply returned as if by the getPath() method. If this
|
||||
* abstract pathname is the empty abstract pathname then the pathname
|
||||
* string of the current user directory, which is named by the system
|
||||
* property user.dir, is returned. Otherwise this pathname is resolved
|
||||
* in a system-dependent way. On UNIX systems, a relative pathname is
|
||||
* made absolute by resolving it against the current user directory.
|
||||
* On Microsoft Windows systems, a relative pathname is made absolute
|
||||
* by resolving it against the current directory of the drive named by
|
||||
* the pathname, if any; if not, it is resolved against the current user
|
||||
* directory.
|
||||
*
|
||||
* @returns String The absolute pathname string
|
||||
* @type String
|
||||
*/
|
||||
this.getAbsolutePath = function() {
|
||||
var absolutPath = file.getAbsolutePath();
|
||||
return (absolutPath == null ? "" : absolutPath);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the length of the file represented by this File object.
|
||||
* <br /><br />
|
||||
* The return value is unspecified if this pathname denotes a directory.
|
||||
*
|
||||
* @returns Number The length, in bytes, of the file, or 0L if the file does not exist
|
||||
* @type Number
|
||||
*/
|
||||
this.getLength = function() {
|
||||
return file.length();
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests whether the file represented by this File object is a directory.
|
||||
*
|
||||
* @returns Boolean true if this File object is a directory and exists; false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
this.isDirectory = function() {
|
||||
return file.isDirectory();
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests whether the file represented by this File object is a normal file.
|
||||
* <br /><br />
|
||||
* A file is normal if it is not a directory and, in addition, satisfies
|
||||
* other system-dependent criteria. Any non-directory file created by a
|
||||
* Java application is guaranteed to be a normal file.
|
||||
*
|
||||
* @returns Boolean true if this File object is a normal file and exists; false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
this.isFile = function() {
|
||||
return file.isFile();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the time when the file represented by this File object was last modified.
|
||||
* <br /><br />
|
||||
* A number representing the time the file was last modified,
|
||||
* measured in milliseconds since the epoch (00:00:00 GMT, January 1, 1970),
|
||||
* or 0L if the file does not exist or if an I/O error occurs.
|
||||
*
|
||||
* @returns Number in milliseconds since 00:00:00 GMT, January 1, 1970
|
||||
* @type Number
|
||||
*/
|
||||
this.lastModified = function() {
|
||||
return file.lastModified();
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates the directory represented by this File object.
|
||||
*
|
||||
* @returns Boolean true if the directory was created; false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
this.makeDirectory = function() {
|
||||
if (self.isOpened())
|
||||
return false;
|
||||
// don't do anything if file exists or use multi directory version
|
||||
return (file.exists() || file.mkdirs());
|
||||
};
|
||||
|
||||
/**
|
||||
* Renames the file represented by this File object.
|
||||
* <br /><br />
|
||||
* Whether or not this method can move a file from one
|
||||
* filesystem to another is platform-dependent. The return
|
||||
* value should always be checked to make sure that the
|
||||
* rename operation was successful.
|
||||
*
|
||||
* @param {FileObject} toFile as FileObject of the new path
|
||||
* @returns true if the renaming succeeded; false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
this.renameTo = function(toFile) {
|
||||
if (toFile == null) {
|
||||
setError(new IllegalArgumentException("Uninitialized target File object"));
|
||||
return false;
|
||||
}
|
||||
if (self.isOpened()) {
|
||||
setError(new IllegalStateException("An openened file cannot be renamed"));
|
||||
return false;
|
||||
}
|
||||
if (toFile.isOpened()) {
|
||||
setError(new IllegalStateException("You cannot rename to an openened file"));
|
||||
return false;
|
||||
}
|
||||
return file.renameTo(new java.io.File(toFile.getAbsolutePath()));
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the file represented by this File object
|
||||
* has been read entirely and the end of file has been reached.
|
||||
*
|
||||
* @returns Boolean
|
||||
* @type Boolean
|
||||
*/
|
||||
this.eof = function() {
|
||||
if (!self.isOpened()) {
|
||||
setError(new IllegalStateException("File not opened"));
|
||||
return true;
|
||||
}
|
||||
if (!(readerWriter instanceof BufferedReader)) {
|
||||
setError(new IllegalStateException("File not opened for read"));
|
||||
return true;
|
||||
}
|
||||
if (atEOF)
|
||||
return true;
|
||||
if (lastLine != null)
|
||||
return false;
|
||||
try {
|
||||
lastLine = readerWriter.readLine();
|
||||
if (lastLine == null)
|
||||
atEOF = true;
|
||||
return atEOF;
|
||||
} catch (e) {
|
||||
setError(e);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This methods reads all the lines contained in the
|
||||
* file and returns them.
|
||||
*
|
||||
* @return String of all the lines in the file
|
||||
* @type String
|
||||
*/
|
||||
this.readAll = function() {
|
||||
// Open the file for readAll
|
||||
if (self.isOpened()) {
|
||||
setError(new IllegalStateException("File already open"));
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
if (file.exists()) {
|
||||
readerWriter = new BufferedReader(new FileReader(file));
|
||||
} else {
|
||||
setError(new IllegalStateException("File does not exist"));
|
||||
return null;
|
||||
}
|
||||
if (!file.isFile()) {
|
||||
setError(new IllegalStateException("File is not a regular file"));
|
||||
return null;
|
||||
}
|
||||
|
||||
// read content line by line to setup proper eol
|
||||
var buffer = new java.lang.StringBuffer(file.length() * 1.10);
|
||||
while (true) {
|
||||
var line = readerWriter.readLine();
|
||||
if (line == null)
|
||||
break;
|
||||
if (buffer.length() > 0)
|
||||
buffer.append("\n"); // EcmaScript EOL
|
||||
buffer.append(line);
|
||||
}
|
||||
|
||||
// Close the file
|
||||
readerWriter.close();
|
||||
readerWriter = null;
|
||||
return buffer.toString();
|
||||
} catch (e) {
|
||||
readerWriter = null;
|
||||
setError(e);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This method removes a directory recursively .
|
||||
* <br /><br />
|
||||
* DANGER! DANGER! HIGH VOLTAGE!
|
||||
* The directory is deleted recursively without
|
||||
* any warning or precautious measures.
|
||||
*/
|
||||
this.removeDirectory = function() {
|
||||
if (!file.isDirectory())
|
||||
return false;
|
||||
var arr = file.list();
|
||||
for (var i=0; i<arr.length; i++) {
|
||||
var f = new helma.File(file, arr[i]);
|
||||
if (f.isDirectory())
|
||||
f.removeDirectory();
|
||||
else
|
||||
f.remove();
|
||||
}
|
||||
file["delete"]();
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Recursivly lists all files below a given directory
|
||||
* you may pass a RegExp Pattern to return just
|
||||
* files matching this pattern.
|
||||
*
|
||||
* @param {RegExp} pattern as RegExp, to test each file name against
|
||||
* @returns Array the list of absolute file paths
|
||||
*/
|
||||
this.listRecursive = function(pattern) {
|
||||
if (!file.isDirectory())
|
||||
return false;
|
||||
if (!pattern || pattern.test(file.getName()))
|
||||
var result = [file.getAbsolutePath()];
|
||||
else
|
||||
var result = [];
|
||||
var arr = file.list();
|
||||
for (var i=0; i<arr.length; i++) {
|
||||
var f = new helma.File(file, arr[i]);
|
||||
if (f.isDirectory())
|
||||
result = result.concat(f.listRecursive(pattern));
|
||||
else if (!pattern || pattern.test(arr[i]))
|
||||
result.push(f.getAbsolutePath());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a copy of a file over partitions.
|
||||
*
|
||||
* @param {String|helma.File} dest as a File object or the String of full path of the new file
|
||||
*/
|
||||
this.hardCopy = function(dest) {
|
||||
var inStream = new java.io.BufferedInputStream(
|
||||
new java.io.FileInputStream(file)
|
||||
);
|
||||
var outStream = new java.io.BufferedOutputStream(
|
||||
new java.io.FileOutputStream(dest)
|
||||
);
|
||||
var buffer = java.lang.reflect.Array.newInstance(
|
||||
java.lang.Byte.TYPE, 4096
|
||||
);
|
||||
var bytesRead = 0;
|
||||
while ((bytesRead = inStream.read(buffer, 0, buffer.length)) != -1) {
|
||||
outStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
outStream.flush();
|
||||
inStream.close();
|
||||
outStream.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a file to a new destination directory.
|
||||
*
|
||||
* @param {String} dest as String, the full path of the new file
|
||||
* @returns Boolean true in case file could be moved, false otherwise
|
||||
*/
|
||||
this.move = function(dest) {
|
||||
// instead of using the standard File method renameTo()
|
||||
// do a hardCopy and then remove the source file. This way
|
||||
// file locking shouldn't be an issue
|
||||
self.hardCopy(dest);
|
||||
// remove the source file
|
||||
file["delete"]();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns file as ByteArray.
|
||||
* <br /><br />
|
||||
* Useful for passing it to a function instead of an request object.
|
||||
*/
|
||||
this.toByteArray = function() {
|
||||
if (!this.exists())
|
||||
return null;
|
||||
var body = new java.io.ByteArrayOutputStream();
|
||||
var stream = new java.io.BufferedInputStream(
|
||||
new java.io.FileInputStream(this.getAbsolutePath())
|
||||
);
|
||||
var buf = java.lang.reflect.Array.newInstance(
|
||||
java.lang.Byte.TYPE, 1024
|
||||
);
|
||||
var read;
|
||||
while ((read = stream.read(buf)) > -1)
|
||||
body.write(buf, 0, read);
|
||||
stream.close();
|
||||
return body.toByteArray();
|
||||
};
|
||||
|
||||
for (var i in this)
|
||||
this.dontEnum(i);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/** @ignore */
|
||||
helma.File.toString = function() {
|
||||
return "[helma.File]";
|
||||
};
|
||||
|
||||
|
||||
helma.File.separator = java.io.File.separator;
|
||||
|
||||
|
||||
helma.lib = "File";
|
||||
helma.dontEnum(helma.lib);
|
||||
for (var i in helma[helma.lib])
|
||||
helma[helma.lib].dontEnum(i);
|
||||
for (var i in helma[helma.lib].prototype)
|
||||
helma[helma.lib].prototype.dontEnum(i);
|
||||
delete helma.lib;
|
|
@ -1,568 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2007 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Ftp.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Default properties and methods of the FTP prototype.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/helma/Ftp.js')
|
||||
*/
|
||||
|
||||
// requires helma.File
|
||||
app.addRepository("modules/helma/File.js");
|
||||
|
||||
/**
|
||||
* Define the global namespace if not existing
|
||||
*/
|
||||
if (!global.helma) {
|
||||
global.helma = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for FTP client objects, to send and receive files from an FTP server.
|
||||
* <br /><br />
|
||||
* @class This class represents a FTP client, providing
|
||||
* access to an FTP server.
|
||||
*
|
||||
* @example var ftp = new helma.Ftp("ftp.mydomain.com");
|
||||
* @param {String} server as String, the address of the FTP Server to connect to
|
||||
* @constructor
|
||||
*/
|
||||
helma.Ftp = function(server) {
|
||||
var OK = 0;
|
||||
var SOCKET = 1;
|
||||
var TIMEOUT = 2;
|
||||
var LOGIN = 10;
|
||||
var LOGOUT = 11;
|
||||
var BINARY = 20;
|
||||
var ASCII = 21;
|
||||
var ACTIVE = 22;
|
||||
var PASSIVE = 23;
|
||||
var CD = 30;
|
||||
var LCD = 31;
|
||||
var PWD = 32;
|
||||
var DIR = 33;
|
||||
var MKDIR = 34;
|
||||
var RMDIR = 35;
|
||||
var GET = 40;
|
||||
var PUT = 41;
|
||||
var DELETE = 42;
|
||||
var RENAME = 43;
|
||||
|
||||
var FTP = Packages.org.apache.commons.net.ftp.FTP;
|
||||
var FtpClient = Packages.org.apache.commons.net.ftp.FTPClient;
|
||||
var BufferedInputStream = java.io.BufferedInputStream;
|
||||
var BufferedOutputStream = java.io.BufferedOutputStream;
|
||||
var FileInputStream = java.io.FileInputStream;
|
||||
var FileOutputStream = java.io.FileOutputStream;
|
||||
var ByteArrayInputStream = java.io.ByteArrayInputStream;
|
||||
var ByteArrayOutputStream = java.io.ByteArrayOutputStream;
|
||||
|
||||
var self = this;
|
||||
var className = "helma.Ftp";
|
||||
|
||||
var ftpclient = new FtpClient();
|
||||
var localDir;
|
||||
|
||||
var error = function(methName, errMsg) {
|
||||
var tx = java.lang.Thread.currentThread();
|
||||
tx.dumpStack();
|
||||
app.log("Error in " + className + ":" + methName + ": " + errMsg);
|
||||
return;
|
||||
};
|
||||
|
||||
var debug = function(methName, msg) {
|
||||
msg = msg ? " " + msg : "";
|
||||
app.debug(className + ":" + methName + msg);
|
||||
return;
|
||||
};
|
||||
|
||||
var setStatus = function(status) {
|
||||
if (self.status === OK) {
|
||||
self.status = status;
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
var getStatus = function() {
|
||||
return self.status;
|
||||
};
|
||||
|
||||
this.server = server;
|
||||
this.status = OK;
|
||||
|
||||
/** @ignore */
|
||||
this.toString = function() {
|
||||
return "[helma.Ftp " + server + "]";
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the default timeout in milliseconds to use when opening a socket.
|
||||
*/
|
||||
this.setReadTimeout = function(timeout) {
|
||||
try {
|
||||
ftpclient.setDefaultTimeout(timeout);
|
||||
debug("setReadTimeout", timeout);
|
||||
return true;
|
||||
} catch(x) {
|
||||
error("setReadTimeout", x);
|
||||
setStatus(SOCKET);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the timeout in milliseconds to use when reading from the data connection.
|
||||
*/
|
||||
this.setTimeout = function(timeout) {
|
||||
try {
|
||||
ftpclient.setDataTimeout(timeout);
|
||||
debug("setTimeout", timeout);
|
||||
return true;
|
||||
} catch(x) {
|
||||
error("setTimeout", x);
|
||||
setStatus(TIMEOUT);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Logs in to the FTP server.
|
||||
*
|
||||
* @param {String} username as String
|
||||
* @param {String} password as String
|
||||
* @return Boolean true if the login was successful, otherwise false
|
||||
* @type Boolean
|
||||
*/
|
||||
this.login = function(username, password) {
|
||||
try {
|
||||
ftpclient.connect(this.server);
|
||||
var result = ftpclient.login(username, password);
|
||||
debug("login", username + "@" + server);
|
||||
return result;
|
||||
} catch(x) {
|
||||
error("login", x);
|
||||
setStatus(LOGIN);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets transfer mode to binary for transmitting images and other non-text files.
|
||||
*
|
||||
* @example ftp.binary();
|
||||
*/
|
||||
this.binary = function() {
|
||||
try {
|
||||
var result = ftpclient.setFileType(FTP.BINARY_FILE_TYPE);
|
||||
debug("binary");
|
||||
return result;
|
||||
} catch(x) {
|
||||
error("binary", x);
|
||||
setStatus(BINARY);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets transfer mode to ascii for transmitting text-based data.
|
||||
*
|
||||
* @example ftp.ascii();
|
||||
*/
|
||||
this.ascii = function() {
|
||||
try {
|
||||
var result = ftpclient.setFileType(FTP.ASCII_FILE_TYPE);
|
||||
debug("ascii");
|
||||
return result;
|
||||
} catch(x) {
|
||||
error("ascii", x);
|
||||
setStatus(ASCII);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Switches the connection to use active mode.
|
||||
*
|
||||
* @example ftp.active();
|
||||
*/
|
||||
this.active = function() {
|
||||
try {
|
||||
ftpclient.enterLocalActiveMode();
|
||||
debug("active");
|
||||
return true;
|
||||
} catch(x) {
|
||||
error("active", x);
|
||||
setStatus(ACTIVE);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Switches the connection to use passive mode.
|
||||
*
|
||||
* @example ftp.passive();
|
||||
*/
|
||||
this.passive = function() {
|
||||
try {
|
||||
ftpclient.enterLocalPassiveMode();
|
||||
debug("passive");
|
||||
return true;
|
||||
} catch(x) {
|
||||
error("passive", x);
|
||||
setStatus(PASSIVE);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the path of the current working directory.
|
||||
*
|
||||
* @example var remotepath = ftp.pwd();
|
||||
* @type String
|
||||
* @return String containing the current working directory path
|
||||
*/
|
||||
this.pwd = function() {
|
||||
try {
|
||||
debug("pwd");
|
||||
return ftpclient.printWorkingDirectory();
|
||||
} catch(x) {
|
||||
error("pwd", x);
|
||||
setStatus(PWD);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a listing of the files contained in a directory on the FTP server.
|
||||
* <br /><br />
|
||||
* Lists the files contained in the current working
|
||||
* directory or, if an alternative path is specified, the
|
||||
* files contained in the specified directory.
|
||||
*
|
||||
* @example var filelist = ftp.dir();
|
||||
* @param {String} path as String, optional alternative directory
|
||||
* @return Array containing the list of files in that directory
|
||||
* @type Array
|
||||
*/
|
||||
this.dir = function(path) {
|
||||
try {
|
||||
debug("dir", path);
|
||||
return ftpclient.listNames(path ? path : ".");
|
||||
} catch(x) {
|
||||
error("dir", x);
|
||||
setStatus(DIR);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new directory on the server.
|
||||
* <br /><br />
|
||||
* The name of the directory is determined as the function's
|
||||
* string parameter. Returns false when an error occured
|
||||
* (e.g. due to access restrictions, directory already
|
||||
* exists etc.), otherwise true.
|
||||
*
|
||||
* @param {String} dir as String, the name of the directory to be created
|
||||
* @return Boolean true if the directory was successfully created, false if there was an error
|
||||
* @type Boolean
|
||||
*/
|
||||
this.mkdir = function(dir) {
|
||||
try {
|
||||
var result = ftpclient.makeDirectory(dir);
|
||||
debug("mkdir", dir);
|
||||
return result;
|
||||
} catch(x) {
|
||||
error("mkdir", x);
|
||||
setStatus(MKDIR);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes a directory on the FTP server.
|
||||
*
|
||||
* @param {String} dir as String, the name of the directory to be deleted
|
||||
* @return Boolean true if the deletion was successful, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
this.rmdir = function(dir) {
|
||||
try {
|
||||
var result = ftpclient.removeDirectory(dir);
|
||||
debug("rmdir", dir);
|
||||
return result;
|
||||
} catch(x) {
|
||||
error("rmdir", x);
|
||||
setStatus(RMDIR);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Changes the working directory on the FTP server.
|
||||
*
|
||||
* @example ftp.cd("/home/users/fred/www"); // use absolute pathname
|
||||
* @example ftp.cd(".."); // change to parent directory
|
||||
* @example ftp.cd("images"); // use relative pathname
|
||||
* @param {String} dir as String, the path that the remote working directory should be changed to
|
||||
*/
|
||||
this.cd = function(path) {
|
||||
try {
|
||||
var result = ftpclient.changeWorkingDirectory(path);
|
||||
debug("cd", path);
|
||||
return result;
|
||||
} catch(x) {
|
||||
error("cd", x);
|
||||
setStatus(CD);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Changes the working directory of the local machine when being connected to an FTP server.
|
||||
*
|
||||
* @example ftp.lcd("/home/users/fred/www"); // use absolute pathname
|
||||
* @example ftp.lcd(".."); // change to parent directory
|
||||
* @example ftp.lcd("images"); // use relative pathname
|
||||
* @param {String} dir as String, the path that the local working directory should be changed to
|
||||
*/
|
||||
this.lcd = function(dir) {
|
||||
try {
|
||||
localDir = new helma.File(dir);
|
||||
if (!localDir.exists()) {
|
||||
localDir.mkdir();
|
||||
debug("lcd", dir);
|
||||
}
|
||||
return true;
|
||||
} catch(x) {
|
||||
error("lcd", x);
|
||||
setStatus(LCD);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Transfers a file from the local file system to the remote server.
|
||||
* <br /><br />
|
||||
* Returns true if the transmission was successful, otherwise false.
|
||||
*
|
||||
* @param {String} localFile as String, the name of the file to be uploaded
|
||||
* @param {String} remoteFile as String, the name of the remote destination file
|
||||
* @return Boolean true if the file was successfully uploaded, false if there was an error
|
||||
* @type Boolean
|
||||
*/
|
||||
this.putFile = function(localFile, remoteFile) {
|
||||
try {
|
||||
if (localFile instanceof File || localFile instanceof helma.File) {
|
||||
var f = localFile;
|
||||
} else if (typeof localFile == "string") {
|
||||
if (localDir == null)
|
||||
var f = new helma.File(localFile);
|
||||
else
|
||||
var f = new helma.File(localDir, localFile);
|
||||
}
|
||||
var stream = new BufferedInputStream(
|
||||
new FileInputStream(f.getPath())
|
||||
);
|
||||
if (!remoteFile) {
|
||||
remoteFile = f.getName();
|
||||
}
|
||||
var result = ftpclient.storeFile(remoteFile, stream);
|
||||
stream.close();
|
||||
debug("putFile", remoteFile);
|
||||
return result;
|
||||
} catch(x) {
|
||||
error("putFile", x);
|
||||
setStatus(PUT);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Transfers text from a string to a file on the FTP server.
|
||||
*
|
||||
* @example ftp.putString("Hello, World!", "message.txt");
|
||||
* @param {String} str as String, the text content that should be uploaded
|
||||
* @param {String} remoteFile as String, the name of the remote destination file
|
||||
* @param {String} charset as String, optional
|
||||
* @return Boolean true if the file was successfully uploaded, false if there was an error
|
||||
* @type Boolean
|
||||
*/
|
||||
this.putString = function(str, remoteFile, charset) {
|
||||
try {
|
||||
str = new java.lang.String(str);
|
||||
var bytes = charset ? str.getBytes(charset) : str.getBytes();
|
||||
var stream = ByteArrayInputStream(bytes);
|
||||
var result = ftpclient.storeFile(remoteFile, stream);
|
||||
debug("putString", remoteFile);
|
||||
return result;
|
||||
} catch(x) {
|
||||
error("putString", x);
|
||||
setStatus(PUT);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Transfers a byte array to a file on the FTP server.
|
||||
* @param {Array} bytes The byte array that should be uploaded
|
||||
* @param {String} remoteFile The name of the remote destination file
|
||||
* @return Boolean True if the file was successfully uploaded, false if there was an error
|
||||
* @type Boolean
|
||||
*/
|
||||
this.putBytes = function(bytes, remoteFile) {
|
||||
try {
|
||||
var stream = ByteArrayInputStream(bytes);
|
||||
var result = ftpclient.storeFile(remoteFile, stream);
|
||||
debug("putBytes", remoteFile);
|
||||
return result;
|
||||
} catch(x) {
|
||||
error("putBytes", x);
|
||||
setStatus(PUT);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Transfers a file from the FTP server to the local file system.
|
||||
*
|
||||
* @example ftp.getFile(".htaccess", "htaccess.txt");
|
||||
* @param {String} remoteFile as String, the name of the file that should be downloaded
|
||||
* @param {String} localFile as String, the name which the file should be stored under
|
||||
* @see #cd
|
||||
* @see #lcd
|
||||
*/
|
||||
this.getFile = function(remoteFile, localFile) {
|
||||
try {
|
||||
if (localDir == null)
|
||||
var f = new helma.File(localFile);
|
||||
else
|
||||
var f = new helma.File(localDir, localFile);
|
||||
var stream = new BufferedOutputStream(
|
||||
new FileOutputStream(f.getPath())
|
||||
);
|
||||
var result = ftpclient.retrieveFile(remoteFile, stream);
|
||||
stream.close();
|
||||
debug("getFile", remoteFile);
|
||||
return result;
|
||||
} catch(x) {
|
||||
error("getFile", x);
|
||||
setStatus(GET);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves a file from the FTP server and returns it as string.
|
||||
*
|
||||
* @example var str = ftp.getString("messages.txt");
|
||||
* @param {String} remoteFile as String, the name of the file that should be downloaded
|
||||
* @return String containing the data of the downloaded file
|
||||
* @type String
|
||||
* @see #cd
|
||||
*/
|
||||
this.getString = function(remoteFile) {
|
||||
try {
|
||||
var stream = ByteArrayOutputStream();
|
||||
ftpclient.retrieveFile(remoteFile, stream);
|
||||
debug("getString", remoteFile);
|
||||
return stream.toString();
|
||||
} catch(x) {
|
||||
error("getString", x);
|
||||
setStatus(GET);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes a file on the FTP server.
|
||||
*
|
||||
* @example var str = ftp.deleteFile("messages.txt");
|
||||
* @param {String} remoteFile as String, the name of the file to be deleted
|
||||
* @return Boolean true if the deletion was successful, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
this.deleteFile = function(remoteFile) {
|
||||
try {
|
||||
var result = ftpclient.deleteFile(remoteFile);
|
||||
debug("deleteFile", remoteFile);
|
||||
return result;
|
||||
} catch(x) {
|
||||
error("deleteFile", x);
|
||||
setStatus(DELETE);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Renames a file on the FTP server.
|
||||
*
|
||||
* @example var success = ftp.renameFile("messages.tmp", "messages.txt");
|
||||
* @param {String} from the name of the original file
|
||||
* @param {String} to the new name the original file should get
|
||||
* @return Boolean true if renaming the remote file was successful, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
this.renameFile = function(from, to) {
|
||||
try {
|
||||
var result = ftpclient.rename(from, to);
|
||||
debug("renameFile", from + "->" + to);
|
||||
return result;
|
||||
} catch(x) {
|
||||
error("renameFile", x);
|
||||
setStatus(RENAME);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Terminates the current FTP session.
|
||||
*/
|
||||
this.logout = function() {
|
||||
try {
|
||||
var result = ftpclient.logout();
|
||||
ftpclient.disconnect();
|
||||
debug("logout");
|
||||
return result;
|
||||
} catch(x) {
|
||||
error("logout", x);
|
||||
setStatus(LOGOUT);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
for (var i in this)
|
||||
this.dontEnum(i);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/** @ignore */
|
||||
helma.Ftp.toString = function() {
|
||||
return "[helma.Ftp]";
|
||||
};
|
||||
|
||||
|
||||
helma.lib = "Ftp";
|
||||
helma.dontEnum(helma.lib);
|
||||
for (var i in helma[helma.lib])
|
||||
helma[helma.lib].dontEnum(i);
|
||||
for (var i in helma[helma.lib].prototype)
|
||||
helma[helma.lib].prototype.dontEnum(i);
|
||||
delete helma.lib;
|
|
@ -1,875 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Group.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview A JavaScript library wrapping
|
||||
* Packages.helma.extensions.helmagroups
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/helma/Group.js')
|
||||
*/
|
||||
|
||||
// Define the global namespace if not existing
|
||||
if (!global.helma) {
|
||||
global.helma = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new helma.Group Object.
|
||||
* @class This is what is retrieved through groups.get(groupName),
|
||||
* wrapping the root object of each group tree.
|
||||
* @param {FIXME} javaGroup FIXME
|
||||
* @constructor
|
||||
*/
|
||||
helma.Group = function(javaGroup) {
|
||||
// private variable containing the wrapper object
|
||||
var groupRoot = new helma.Group.GroupObject(javaGroup.getRoot());
|
||||
|
||||
/**
|
||||
* @returns the wrapped java object Group
|
||||
*/
|
||||
this.getJavaObject = function() {
|
||||
return javaGroup;
|
||||
};
|
||||
|
||||
/**
|
||||
* sets a key/value pair on the group's root,
|
||||
* wraps the function of the wrapper object
|
||||
*/
|
||||
this.set = function(key, val, sendMode) {
|
||||
groupRoot.set(key, val, sendMode);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* removes a key from the group's root,
|
||||
* wraps the function of the root GroupObject
|
||||
*/
|
||||
this.remove = function(key, sendMode) {
|
||||
return groupRoot.remove(key, sendMode);
|
||||
};
|
||||
|
||||
/**
|
||||
* retrieves a key from the group's root,
|
||||
* wraps the function of the root GroupObject
|
||||
*/
|
||||
this.get = function(key) {
|
||||
return groupRoot.get(key);
|
||||
};
|
||||
|
||||
/**
|
||||
* @see helma.Group.GroupObject.listChildren
|
||||
*/
|
||||
this.listChildren = function() {
|
||||
return groupRoot.listChildren();
|
||||
};
|
||||
|
||||
/**
|
||||
* @see helma.Group.GroupObject.listProperties
|
||||
*/
|
||||
this.listProperties = function() {
|
||||
return groupRoot.listProperties();
|
||||
};
|
||||
|
||||
/**
|
||||
* @see helma.Group.GroupObject.countChildren
|
||||
*/
|
||||
this.countChildren = function() {
|
||||
return groupRoot.countChildren();
|
||||
};
|
||||
|
||||
/**
|
||||
* @see helma.Group.GroupObject.countProperties
|
||||
*/
|
||||
this.countProperties = function() {
|
||||
return groupRoot.countProperties();
|
||||
};
|
||||
|
||||
/**
|
||||
* calls a function in all connected applications
|
||||
* (to be specific: in all registered localClients).
|
||||
* @param method name of the method in xmlrpc-style: test
|
||||
* is called as root.test(), stories.137.render
|
||||
* is called as root.stories.get("137").render() etc etc.
|
||||
* @param argArr array of arguments to the remote method
|
||||
* @param sendMode as defined for helma.Group.GroupObject
|
||||
* @returns array of result objects
|
||||
*/
|
||||
this.callFunction = function(method, argArr, sendMode) {
|
||||
groups.checkWriteAccess(javaGroup);
|
||||
if (sendMode == null) {
|
||||
sendMode = helma.Group.GroupObject.DEFAULT_GET;
|
||||
}
|
||||
var argVec = new java.util.Vector();
|
||||
for (var i=0; i<argArr.length; i++) {
|
||||
argVec.add(argArr[i]);
|
||||
}
|
||||
var resVec = javaGroup.execute(method, argVec, sendMode,
|
||||
javaGroup.DEFAULT_EXECUTE_TIMEOUT);
|
||||
var resArr = [];
|
||||
for (var i=0; i<resVec.size(); i++) {
|
||||
resArr[i] = resVec.get(i);
|
||||
}
|
||||
return resArr;
|
||||
};
|
||||
|
||||
this.toString = function() {
|
||||
return javaGroup.toString();
|
||||
};
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a new helma.Group.GroupObject.
|
||||
* @class This class wraps the java GroupObject
|
||||
* and provides several methods for retrieving and manipulating properties.
|
||||
* @param {Object} Instance of helma.extensions.helmagroups.GroupObject
|
||||
* @constructor
|
||||
*/
|
||||
helma.Group.GroupObject = function(javaGroupObject) {
|
||||
var helmagroups = Packages.helma.extensions.helmagroups;
|
||||
|
||||
if (!javaGroupObject) {
|
||||
var javaGroupObject = new helmagroups.GroupObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* private method that returns true if the group
|
||||
* is writable
|
||||
* @returns Boolean
|
||||
*/
|
||||
var checkWriteAccess = function() {
|
||||
if (javaGroupObject.getState() == helmagroups.GroupObject.REPLICATED) {
|
||||
groups.checkWriteAccess(javaGroupObject.getGroup());
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the key passed as argument is a path
|
||||
* (either an Array or a String that contains separator characters)
|
||||
* @returns Boolean
|
||||
*/
|
||||
var keyIsPath = function(key) {
|
||||
var separator = helmagroups.GroupObject.SEPARATOR;
|
||||
if ((key instanceof Array) || key.indexOf(separator) != -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the last element if the key passed as argument is a path.
|
||||
* @returns Boolean
|
||||
*/
|
||||
var getLastKeyElement = function(key) {
|
||||
var separator = helmagroups.GroupObject.SEPARATOR;
|
||||
if (!(key instanceof Array) && key.indexOf(separator) != -1) {
|
||||
if (key.charAt(key.length-1)==separator) {
|
||||
key = key.substring(0, key.length-1);
|
||||
}
|
||||
key = key.split(separator);
|
||||
}
|
||||
if (key instanceof Array) {
|
||||
return key[key.length-1];
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* if key is a path, walks through the path and returns the lowest GroupObject.
|
||||
* if tree ends somewhere in the path, function returns null.
|
||||
* @returns null or GroupObject
|
||||
*/
|
||||
var walkPath = function(obj, key) {
|
||||
var separator = helmagroups.GroupObject.SEPARATOR;
|
||||
if (!(key instanceof Array) && key.indexOf(separator) != -1) {
|
||||
if (key.charAt(key.length-1)==separator) {
|
||||
key = key.substring(0, key.length-1);
|
||||
}
|
||||
key = key.split(separator);
|
||||
}
|
||||
if (key instanceof Array) {
|
||||
// loop down until end of array
|
||||
for (var i=0; i<key.length-1; i++) {
|
||||
var nextObj = obj.get(key[i]);
|
||||
if (nextObj == null || !(nextObj instanceof helma.Group.GroupObject)) {
|
||||
return null;
|
||||
}
|
||||
obj = nextObj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* if key is a path, walks through the path and returns the lowest GroupObject.
|
||||
* if tree ends somewhere in the path, function creates the missing GroupObjects.
|
||||
* @returns helma.Group.GroupObject
|
||||
*/
|
||||
var createPath = function(obj, key) {
|
||||
var separator = helmagroups.GroupObject.SEPARATOR;
|
||||
if (!(key instanceof Array) && key.indexOf(separator) != -1) {
|
||||
if (key.charAt(key.length-1)==separator) {
|
||||
key = key.substring(0, key.length-1);
|
||||
}
|
||||
key = key.split(separator);
|
||||
}
|
||||
if (key instanceof Array) {
|
||||
// loop down until end of array
|
||||
for (var i=0; i<key.length-1; i++) {
|
||||
var nextObj = obj.get(key[i]);
|
||||
if (nextObj == null || !(nextObj instanceof helma.Group.GroupObject)) {
|
||||
nextObj = new helma.Group.GroupObject();
|
||||
obj.set(key[i], nextObj);
|
||||
}
|
||||
obj = nextObj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the wrapped java GroupObject.
|
||||
* @return Instance of helma.extensions.helmagroups.GroupObject;
|
||||
* @type helma.extensions.helmagroups.GroupObject
|
||||
*/
|
||||
this.getJavaObject = function() {
|
||||
return javaGroupObject;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets a property or a child GroupObject in this instance.
|
||||
* The Key may be a String, an Array or a String with separator characters ("/").
|
||||
* In the latter two cases the argument is considered a path and
|
||||
* all GroupObjects along this path are created if necessary.
|
||||
* @param {Object} key Either
|
||||
* <ul>
|
||||
* <li>a String</li>
|
||||
* <li>a String containing slashes</li>
|
||||
* <li>an Array containing String keys</li>
|
||||
* </ul>
|
||||
* @param {Number} The value to set the property to.
|
||||
* @param {Object} The mode to use when committing the change to
|
||||
* the helma.Group
|
||||
*/
|
||||
this.set = function(key, val, sendMode) {
|
||||
if (!key) {
|
||||
throw "helma.Group.GroupObject.set(): key can't be null";
|
||||
}
|
||||
checkWriteAccess();
|
||||
// check content type of value:
|
||||
var ok = false;
|
||||
if (val == null)
|
||||
ok = true;
|
||||
else if (typeof(val) == "string")
|
||||
ok = true;
|
||||
else if (typeof(val) == "number")
|
||||
ok = true;
|
||||
else if (typeof(val) == "boolean")
|
||||
ok = true;
|
||||
else if (val instanceof Date)
|
||||
ok = true;
|
||||
else if (val instanceof helma.Group.GroupObject)
|
||||
ok = true;
|
||||
if (ok == false) {
|
||||
throw "only primitive values, Date and helma.Group.GroupObject allowed in helma.Group.GroupObject.set()";
|
||||
}
|
||||
if (sendMode == null) {
|
||||
sendMode = helma.Group.GroupObject.DEFAULT_GET;
|
||||
}
|
||||
|
||||
if (keyIsPath(key)) {
|
||||
var obj = createPath(this, key);
|
||||
if (obj != null) {
|
||||
obj.set(getLastKeyElement(key), val, sendMode);
|
||||
}
|
||||
} else {
|
||||
// set a property/child of this object
|
||||
if (val == null) {
|
||||
// null values aren't permitted in the group,
|
||||
// setting a property to null is the same as deleting it
|
||||
this.remove(key, sendMode);
|
||||
} else if (val instanceof helma.Group.GroupObject) {
|
||||
// replicate helma.Group.GroupObject
|
||||
javaGroupObject.put(key, val.getJavaObject(), sendMode);
|
||||
} else {
|
||||
// put the primitive property (or maybe replicate,
|
||||
// decision's up to helma.Group.GroupObject)
|
||||
if (val instanceof Date) {
|
||||
// convert javascript dates to java dates
|
||||
val = new java.util.Date(val.getTime());
|
||||
}
|
||||
javaGroupObject.put(key, val, sendMode);
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Removes a property or a child GroupObject from this instance.
|
||||
* The Key may be a String, an Array or a String with separator characters ("/").
|
||||
* In the latter two cases the argument is considered a path and
|
||||
* the function walks down that path to find the GroupObject and
|
||||
* deletes it.
|
||||
* @param {Object} key Either
|
||||
* <ul>
|
||||
* <li>a String</li>
|
||||
* <li>a String containing slashes</li>
|
||||
* <li>an Array containing String keys</li>
|
||||
* </ul>
|
||||
* @param {Number} The mode to use when committing the change to
|
||||
* the helma.Group
|
||||
*/
|
||||
this.remove = function(key, sendMode) {
|
||||
checkWriteAccess();
|
||||
if (sendMode == null) {
|
||||
sendMode = helma.Group.GroupObject.DEFAULT_GET;
|
||||
}
|
||||
if (keyIsPath(key)) {
|
||||
var obj = walkPath(this, key);
|
||||
if (obj != null) {
|
||||
obj.remove(getLastKeyElement(key));
|
||||
}
|
||||
} else {
|
||||
javaGroupObject.remove(key, sendMode);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns either a property or a child GroupObject from
|
||||
* this GroupObject instance. The key passed as argument
|
||||
* may be a String, an Array containing Strings or a
|
||||
* String containing separator characters ("/"). In the latter
|
||||
* two cases the argument is considered a path and
|
||||
* the function walks down that path to find the requested
|
||||
* GroupObject.
|
||||
* @param {Object} key Either
|
||||
* <ul>
|
||||
* <li>a String</li>
|
||||
* <li>a String containing slashes</li>
|
||||
* <li>an Array containing String keys</li>
|
||||
* </ul>
|
||||
* @return Depending on the argument either the appropriate property
|
||||
* value or a helma.Group.GroupObject
|
||||
* @type Object
|
||||
*/
|
||||
this.get = function(key) {
|
||||
if (key == null) {
|
||||
return null;
|
||||
}
|
||||
if (keyIsPath(key)) {
|
||||
var obj = walkPath(this, key);
|
||||
if (obj != null) {
|
||||
return obj.get(getLastKeyElement(key));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else if (javaGroupObject.hasProperty(key)) {
|
||||
// we got a primitive property
|
||||
var val = javaGroupObject.getProperty(key);
|
||||
if (val instanceof java.util.Date) {
|
||||
// convert java dates to javascript dates
|
||||
val = new Date(val);
|
||||
}
|
||||
return val;
|
||||
} else if (javaGroupObject.hasChild(key)) {
|
||||
// we got a child object
|
||||
return new helma.Group.GroupObject(javaGroupObject.getChild(key));
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets a property from this GroupObject. The key passed as argument
|
||||
* is always considered a property even if it contains a slash.
|
||||
* This is actually a workaround for the fact that other
|
||||
* instances of the group not using the javascript extension aren't forbidden
|
||||
* to add properties containing a slash in the property's name.
|
||||
* So, using this extension we can at least read the property.
|
||||
* @param {String} key The name of the property to return
|
||||
* @returns The value of the property
|
||||
* @type Object
|
||||
*/
|
||||
this.getProperty = function(key) {
|
||||
if (key == null) {
|
||||
return null;
|
||||
} else if (javaGroupObject.hasProperty(key)) {
|
||||
// we got a primitive property
|
||||
var val = javaGroupObject.getProperty(key);
|
||||
if (val instanceof java.util.Date) {
|
||||
// convert java dates to javascript dates
|
||||
val = new Date(val);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Exchanges this GroupObject with the one passed
|
||||
* as argument. This is done by exchanging the wrapped
|
||||
* instance of helma.extensions.helmagroups.GroupObject
|
||||
* @param {GroupObject} The GroupObject to use
|
||||
* @returns The GroupObject with the exchanged wrapped java object
|
||||
* @type GroupObject
|
||||
*/
|
||||
this.wrap = function(newGroupObject) {
|
||||
checkWriteAccess();
|
||||
if (javaGroupObject.getState() != helmagroups.GroupObject.REPLICATED) {
|
||||
throw "helma.Group.GroupObject.wrap() may only be called on replicated GroupObjects";
|
||||
}
|
||||
if (newGroupObject == null || !(newGroupObject instanceof helma.Group.GroupObject)) {
|
||||
throw "helma.Group.GroupObject.wrap() requires a helma.Group.GroupObject as an argument";
|
||||
}
|
||||
javaGroupObject.wrap(newGroupObject.getJavaObject());
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clones this GroupObject and returns it.
|
||||
* This method should be considered if many properties
|
||||
* of a GroupObject must be set or modified since every
|
||||
* change to an already replicated GroupObject will
|
||||
* result in immediate network traffic. Using unwrap
|
||||
* one can modify several properties and then commit
|
||||
* the GroupObject at once using {@link #wrap).
|
||||
* @returns A clone of this GroupObject
|
||||
* @type GroupObject
|
||||
*/
|
||||
this.unwrap = function() {
|
||||
var javaGroupObjectClone = javaGroupObject.clone();
|
||||
javaGroupObjectClone.setChildren(new java.util.Hashtable());
|
||||
javaGroupObjectClone.setState(helmagroups.GroupObject.LOCAL);
|
||||
javaGroupObjectClone.setPath(null);
|
||||
return new helma.Group.GroupObject(javaGroupObjectClone);
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts this GroupObject into a vanilla Object
|
||||
* @returns An Object containing all properties of this GroupObject
|
||||
* @type Object
|
||||
*/
|
||||
this.toJSObject = function() {
|
||||
var key;
|
||||
var obj = {};
|
||||
var e = javaGroupObject.properties();
|
||||
while(e.hasMoreElements()) {
|
||||
obj[key = e.nextElement()] = javaGroupObject.getProperty(key);
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an Array containing all child GroupObjects
|
||||
* @returns An Array containing GroupObjects
|
||||
* @type Array
|
||||
*/
|
||||
this.listChildren = function() {
|
||||
var arr = [];
|
||||
var e = javaGroupObject.children();
|
||||
while(e.hasMoreElements()) {
|
||||
arr.push(e.nextElement());
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an Array containing all property
|
||||
* names of this GroupObject instance
|
||||
* @returns An Array containing property names
|
||||
* @type Array
|
||||
*/
|
||||
this.listProperties = function() {
|
||||
var arr = [];
|
||||
var e = javaGroupObject.properties();
|
||||
while(e.hasMoreElements()) {
|
||||
arr.push(e.nextElement());
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the number of child GroupObjects
|
||||
* @returns The number of child GroupObjects of this
|
||||
* helma.Group.GroupObject instance
|
||||
* @type Number
|
||||
*/
|
||||
this.countChildren = function() {
|
||||
var ht = javaGroupObject.getChildren();
|
||||
if (ht == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return ht.size();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the number of properties of this GroupObject
|
||||
* @return The number of properties
|
||||
* @type Number
|
||||
*/
|
||||
this.countProperties = function() {
|
||||
var ht = javaGroupObject.getProperties();
|
||||
return (ht == null) ? 0 : ht.size();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the GroupObject is <em>not</em> replicated
|
||||
* @returns True if this GroupObject is still local
|
||||
* @type Boolean
|
||||
*/
|
||||
this.isLocal = function() {
|
||||
return (javaGroupObject.getState()
|
||||
== helmagroups.GroupObject.LOCAL);
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
this.toString = function() {
|
||||
return javaGroupObject.toString();
|
||||
};
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Static properties of GroupObject constructor function.
|
||||
* These values determine if and for how many confirmation of the
|
||||
* group members this instance waits after a modification.
|
||||
* These values are passed through to org.jgroups.blocks.GroupRequest,
|
||||
* for further comments see the sourcecode of that class
|
||||
*/
|
||||
// wait just for the first response
|
||||
helma.Group.GroupObject.GET_FIRST = 1;
|
||||
// wait until all members have responded
|
||||
helma.Group.GroupObject.GET_ALL = 2;
|
||||
// wait for majority (50% + 1) to respond
|
||||
helma.Group.GroupObject.GET_MAJORITY = 3;
|
||||
// wait for majority of all members (may block!)
|
||||
helma.Group.GroupObject.GET_ABS_MAJORITY = 4;
|
||||
// don't wait for any response (fire & forget)
|
||||
helma.Group.GroupObject.GET_NONE = 6;
|
||||
// default: wait for all responses
|
||||
helma.Group.GroupObject.DEFAULT_GET = helma.Group.GroupObject.GET_ALL;
|
||||
|
||||
/**
|
||||
* This is mounted as "groups".
|
||||
* @class The root for all groups started in this application
|
||||
* @constructor
|
||||
*/
|
||||
helma.Group.Manager = function() {
|
||||
var helmagroups = Packages.helma.extensions.helmagroups;
|
||||
var extension = helmagroups.GroupExtension.self;
|
||||
|
||||
if (extension == null) {
|
||||
throw("helma.Group.Manager requires the HelmaGroups Extension \
|
||||
located in lib/ext or the application's top-level directory \
|
||||
[http://adele.helma.org/download/helma/contrib/helmagroups/]");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get a java object Group for a groupname.
|
||||
* object is fetched regardless of connection status
|
||||
* @returns null if group is not defined
|
||||
*/
|
||||
var getJavaGroup = function(name) {
|
||||
return extension.checkAppLink(app.name).get(name);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* visible to scripting env: get a group, wrapped as a javascript helma.Group object.
|
||||
* the group must be defined in app.properties: group.nameXX = <configfile>
|
||||
* and can then be accessed like this group.get("nameXX")
|
||||
* @returns null if group is not defined or not connected
|
||||
*/
|
||||
this.get = function(name) {
|
||||
var javaGroup = getJavaGroup(name);
|
||||
if (javaGroup == null || javaGroup.isConnected() == false) {
|
||||
return null;
|
||||
} else {
|
||||
return new helma.Group(javaGroup);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* checks for write access to a group according to app.properties
|
||||
* group.nameXX.writable must be true so that this function returns
|
||||
* @param nameOrJGroup can be the name of a group or a java Group itself
|
||||
* @throws an error if group is not writable
|
||||
*/
|
||||
this.checkWriteAccess = function(nameOrJGroup) {
|
||||
var extension = helmagroups.GroupExtension.self;
|
||||
var jAppLink = extension.checkAppLink(app.name);
|
||||
if (nameOrJGroup instanceof helmagroups.Group) {
|
||||
// arg was a Group
|
||||
var javaGroup = nameOrJGroup;
|
||||
} else {
|
||||
// arg was the name of the group
|
||||
var javaGroup = jAppLink.get(nameOrJGroup);
|
||||
}
|
||||
if (javaGroup != null && jAppLink.isWritable(javaGroup) == false) {
|
||||
throw("tried to access write-protected group");
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* try to connect a group
|
||||
* @returns false if group is not found
|
||||
*/
|
||||
this.connect = function(name) {
|
||||
var javaGroup = getJavaGroup(name);
|
||||
if (javaGroup == null) {
|
||||
return false;
|
||||
}
|
||||
javaGroup.connect();
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* try to disconnect from a group
|
||||
* @returns false if group is not found
|
||||
*/
|
||||
this.disconnect = function(name) {
|
||||
var javaGroup = getJavaGroup(name);
|
||||
if (javaGroup == null) {
|
||||
return false;
|
||||
}
|
||||
javaGroup.disconnect();
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* try to disconnect and connect again to a group
|
||||
* @returns false if group is not found
|
||||
*/
|
||||
this.reconnect = function(name) {
|
||||
var javaGroup = getJavaGroup(name);
|
||||
if (javaGroup == null) {
|
||||
return false;
|
||||
}
|
||||
javaGroup.reconnect();
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* try to reset a group (if application may write in group).
|
||||
* all instances of the group empty their cache.
|
||||
* @returns false if group is not found
|
||||
*/
|
||||
this.reset = function(name) {
|
||||
var javaGroup = getJavaGroup(name);
|
||||
if (javaGroup == null) {
|
||||
return false;
|
||||
}
|
||||
groups.checkWriteAccess(javaGroup);
|
||||
javaGroup.reset();
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* try to destroy a group (if application may write in group).
|
||||
* all other instances of the group disconnect
|
||||
* @returns false if group is not found
|
||||
*/
|
||||
this.destroy = function(name) {
|
||||
var javaGroup = getJavaGroup(name);
|
||||
if (javaGroup == null) {
|
||||
return false;
|
||||
}
|
||||
groups.checkWriteAccess(javaGroup);
|
||||
javaGroup.destroy();
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* try to restart a group (if application may write in group).
|
||||
* all other instances of the group disconnect and reconnect - each app after a different pause
|
||||
* so that they don't all come up at the same moment
|
||||
* @returns false if group is not found
|
||||
*/
|
||||
this.restart = function(name) {
|
||||
var javaGroup = getJavaGroup(name);
|
||||
if (javaGroup == null) {
|
||||
return false;
|
||||
}
|
||||
groups.checkWriteAccess(javaGroup);
|
||||
javaGroup.restart();
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* list the members of this group (ie instances of Group, one helma server is one instance)
|
||||
* @returns array of strings, false if group is not found
|
||||
*/
|
||||
this.listMembers = function(name) {
|
||||
var javaGroup = getJavaGroup(name);
|
||||
if (javaGroup == null) {
|
||||
return false;
|
||||
}
|
||||
var addrArr = javaGroup.info.listMembers();
|
||||
var arr = [];
|
||||
for (var i=0; i<addrArr.length; i++) {
|
||||
arr[arr.length] = helmagroups.Config.addressToString(addrArr[i]);
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* lists the members applications of this group (may be more than one per instance but also none)
|
||||
* @returns array of strings, false if group is not found
|
||||
*/
|
||||
this.listMemberApps = function(name) {
|
||||
var javaGroup = getJavaGroup(name);
|
||||
if (javaGroup == null) {
|
||||
return false;
|
||||
}
|
||||
var appsArr = javaGroup.info.listMemberApps();
|
||||
var arr = [];
|
||||
for (var i=0; i<appsArr.length; i++) {
|
||||
arr[arr.length] = appsArr[i];
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* dumps the keys of the group to a string
|
||||
* @returns string, notice if group is not found
|
||||
*/
|
||||
this.getContent = function(name) {
|
||||
var javaGroup = getJavaGroup(name);
|
||||
if (javaGroup == null) {
|
||||
return "[not connected]";
|
||||
}
|
||||
return javaGroup.info.print();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* dumps the keys and the content of the group to a string
|
||||
* @returns string, notice if group is not found
|
||||
*/
|
||||
this.getFullContent = function(name) {
|
||||
var javaGroup = getJavaGroup(name);
|
||||
if (javaGroup == null) {
|
||||
return "[not connected]";
|
||||
}
|
||||
return javaGroup.info.printFull();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* dumps the config of the jgroups stack to a string
|
||||
* @returns string, false if group is not found
|
||||
*/
|
||||
this.getConfig = function(name) {
|
||||
var javaGroup = getJavaGroup(name);
|
||||
if (javaGroup == null) {
|
||||
return false;
|
||||
}
|
||||
return javaGroup.info.printStack(false);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* dumps the config of the jgroups stack including all properties to a string
|
||||
* @returns string, false if group is not found
|
||||
*/
|
||||
this.getFullConfig = function(name) {
|
||||
var javaGroup = getJavaGroup(name);
|
||||
if (javaGroup == null) {
|
||||
return false;
|
||||
}
|
||||
return javaGroup.info.printStack(true);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* returns the connection identifier of the Group instance (localname + multicast-target)
|
||||
* @returns string, false if group is not found
|
||||
*/
|
||||
this.getConnection = function(name) {
|
||||
var javaGroup = getJavaGroup(name);
|
||||
if (javaGroup == null) {
|
||||
return false;
|
||||
}
|
||||
return javaGroup.info.getConnection();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* returns true/false if the group is connected
|
||||
*/
|
||||
this.isConnected = function(name) {
|
||||
var javaGroup = getJavaGroup(name);
|
||||
if (javaGroup == null) {
|
||||
return false;
|
||||
}
|
||||
return javaGroup.isConnected();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* returns the total number of groupobjects in this group
|
||||
*/
|
||||
this.size = function(name) {
|
||||
var javaGroup = getJavaGroup(name);
|
||||
if (javaGroup == null) {
|
||||
return false;
|
||||
}
|
||||
return javaGroup.size();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* returns the total number of groupobjects in this group
|
||||
*/
|
||||
this.count = function(name) {
|
||||
return this.size(name);
|
||||
};
|
||||
|
||||
this.toString = function() {
|
||||
return "[helma.Group.Manager]";
|
||||
};
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// Instantiate helma.Group.Manager as "groups" variable
|
||||
var groups = new helma.Group.Manager();
|
|
@ -1,961 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Html.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the helma.Html
|
||||
* and helma.Html.Tablewriter classes.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/helma/Html.js')
|
||||
*/
|
||||
|
||||
// take care of any dependencies
|
||||
app.addRepository('modules/core/String.js');
|
||||
app.addRepository('modules/core/Object.js');
|
||||
app.addRepository('modules/core/Array.js');
|
||||
|
||||
/**
|
||||
* Define the global namespace if not existing
|
||||
*/
|
||||
if (!global.helma) {
|
||||
global.helma = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of helma.Html
|
||||
* @class This class provides various methods for rendering
|
||||
* X/Html tags.
|
||||
* @returns A newly created instance of helma.Html
|
||||
* @constructor
|
||||
*/
|
||||
helma.Html = function() {
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Static helper method that renders an arbitrary markup part.
|
||||
* @param {String} name The element's name
|
||||
* @param {String} start Prefix of each rendered element
|
||||
* @param {String} end Suffix of each rendered element
|
||||
* @param {Object} attr Optional element attributes
|
||||
*/
|
||||
helma.Html.renderMarkupPart = function(name, start, end, attr) {
|
||||
res.write(start);
|
||||
res.write(name);
|
||||
if (attr) {
|
||||
for (var i in attr) {
|
||||
if (i == "prefix" || i == "suffix" ||
|
||||
i == "default" || attr[i] == null) {
|
||||
continue;
|
||||
}
|
||||
res.write(" ");
|
||||
res.write(i);
|
||||
res.write("=\"");
|
||||
res.write(attr[i]);
|
||||
res.write("\"");
|
||||
}
|
||||
}
|
||||
res.write(end);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Static helper method used in helma.Html.checkBox
|
||||
* and helma.Html.dropDown to check if a current value
|
||||
* matches against one or more selected values passed
|
||||
* as argument
|
||||
* @param {String} value The current value to check
|
||||
* @param {String|Array} selectedValue Either a single
|
||||
* value to check against the current value, or an array
|
||||
* containing values.
|
||||
* @returns True in case the value is among the selected
|
||||
* values, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
helma.Html.isSelected = function(value, selectedValue) {
|
||||
if (selectedValue == null || value == null)
|
||||
return false;
|
||||
if (selectedValue instanceof Array)
|
||||
return selectedValue.contains(value);
|
||||
return value == selectedValue;
|
||||
};
|
||||
|
||||
|
||||
/** @ignore */
|
||||
helma.Html.prototype.toString = function() {
|
||||
return "[helma.Html]";
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the opening tag of an arbitrary x/html tag
|
||||
* @param {String} name The tag name
|
||||
* @param {Object} attr An optional object containing element attributes
|
||||
*/
|
||||
helma.Html.prototype.openTag = function(name, attr) {
|
||||
helma.Html.renderMarkupPart(name, "<", ">", attr);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the opening tag of an arbitrary x/html tag
|
||||
* @param {String} name The tag name
|
||||
* @param {Object} attr An optional object containing element attributes
|
||||
* @returns The rendered x/html opening tag
|
||||
* @type String
|
||||
* @see #openTag
|
||||
*/
|
||||
helma.Html.prototype.openTagAsString = function(name, attr) {
|
||||
res.push();
|
||||
helma.Html.renderMarkupPart(name, "<", ">", attr);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the closing tag of an arbitrary x/html tag
|
||||
* @param {String} name The tag name
|
||||
*/
|
||||
helma.Html.prototype.closeTag = function(name) {
|
||||
helma.Html.renderMarkupPart(name, "</", ">", null);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the closing tag of an arbitray x/html element
|
||||
* @param {String} name The tag name
|
||||
* @returns The rendered closing tag
|
||||
* @type String
|
||||
* @see #closeTag
|
||||
*/
|
||||
helma.Html.prototype.closeTagAsString = function(name) {
|
||||
res.push();
|
||||
helma.Html.renderMarkupPart(name, "</", ">", null);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders an empty arbitrary x/html tag ("contentless tag")
|
||||
* @param {String} name The tag name
|
||||
* @param {Object} attr An optional object containing tag attributes
|
||||
*/
|
||||
helma.Html.prototype.tag = function(name, attr) {
|
||||
helma.Html.renderMarkupPart(name, "<", " />", attr);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an empty arbitrary x/html tag ("contentless tag")
|
||||
* @param {String} name The tag name
|
||||
* @param {Object} attr An optional object containing tag attributes
|
||||
* @returns The rendered element
|
||||
* @type String
|
||||
* @see #tag
|
||||
*/
|
||||
helma.Html.prototype.tagAsString = function(name, attr) {
|
||||
res.push();
|
||||
helma.Html.renderMarkupPart(name, "<", " />", attr);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders an arbitrary x/html element
|
||||
* @param {String} name The element name
|
||||
* @param {String} str The content of the element
|
||||
* @param {Object} attr An optional object containing element attributes
|
||||
*/
|
||||
helma.Html.prototype.element = function(name, str, attr) {
|
||||
helma.Html.renderMarkupPart(name, "<", ">", attr);
|
||||
res.write(str);
|
||||
helma.Html.renderMarkupPart(name, "</", ">");
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return an arbitrary x/html element
|
||||
* @param {String} name The element name
|
||||
* @param {String} str The content of the element
|
||||
* @param {Object} attr An optional object containing element attributes
|
||||
* @returns The rendered element
|
||||
* @type String
|
||||
* @see #element
|
||||
*/
|
||||
helma.Html.prototype.elementAsString = function(name, str, attr) {
|
||||
res.push();
|
||||
this.element(name, str, attr);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders an x/html link tag
|
||||
* @param {Object} attr An object containing the link attributes
|
||||
* @param {String} text The text to appear as link
|
||||
*/
|
||||
helma.Html.prototype.link = function(attr, text) {
|
||||
if (!attr) {
|
||||
res.write("[Html.link: insufficient arguments]");
|
||||
return;
|
||||
}
|
||||
this.openTag("a", attr);
|
||||
res.write(text);
|
||||
this.closeTag("a");
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a rendered x/html link tag
|
||||
* @param {Object} attr An object containing the link attributes
|
||||
* @param {String} text The text to appear as link
|
||||
* @returns The rendered link tag
|
||||
* @type String
|
||||
* @see #link
|
||||
*/
|
||||
helma.Html.prototype.linkAsString = function(attr, text) {
|
||||
res.push();
|
||||
this.link(attr, text);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders an x/html input tag of type "hidden"
|
||||
* @param {Object} param An object containing the tag attributes
|
||||
*/
|
||||
helma.Html.prototype.hidden = function(param) {
|
||||
if (!param) {
|
||||
res.write("[Html.hidden: insufficient arguments]");
|
||||
return;
|
||||
}
|
||||
var attr = Object.prototype.reduce.call(param);
|
||||
attr.type = "hidden";
|
||||
attr.value = (attr.value != null) ? encodeForm(attr.value) : "";
|
||||
this.tag("input", attr);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a rendered x/html input tag of type "hidden"
|
||||
* @param {Object} attr An object containing the tag attributes
|
||||
* @returns The rendered input element
|
||||
* @type String
|
||||
* @see #hidden
|
||||
*/
|
||||
helma.Html.prototype.hiddenAsString = function(attr) {
|
||||
res.push();
|
||||
this.hidden(attr);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders an x/html text input tag
|
||||
* @param {Object} param An object containing the tag attributes
|
||||
*/
|
||||
helma.Html.prototype.input = function(param) {
|
||||
if (!param) {
|
||||
res.write("[Html.input: insufficient arguments]");
|
||||
return;
|
||||
}
|
||||
var attr = Object.prototype.reduce.call(param);
|
||||
attr.type = param.type || "text";
|
||||
attr.value = (attr.value != null) ? encodeForm(attr.value) : "";
|
||||
this.tag("input", attr);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a rendered x/html text input tag
|
||||
* @param {Object} attr An object containing the tag attributes
|
||||
* @returns The rendered text input tag
|
||||
* @type String
|
||||
* @see #input
|
||||
*/
|
||||
helma.Html.prototype.inputAsString = function(attr) {
|
||||
res.push();
|
||||
this.input(attr);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders an x/html textarea tag
|
||||
* @param {Object} param An object containing the tag attributes
|
||||
*/
|
||||
helma.Html.prototype.textArea = function(param) {
|
||||
if (!param) {
|
||||
res.write("[Html.textArea: insufficient arguments]");
|
||||
return;
|
||||
}
|
||||
var attr = Object.prototype.reduce.call(param);
|
||||
var value = (attr.value != null) ? encodeForm(attr.value) : "";
|
||||
delete attr.value;
|
||||
this.openTag("textarea", attr);
|
||||
res.write(value);
|
||||
this.closeTag("textarea");
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a rendered x/html textarea tag
|
||||
* @param {Object} attr An object containing the tag attributes
|
||||
* @returns The rendered textarea tag
|
||||
* @type String
|
||||
* @see #textArea
|
||||
*/
|
||||
helma.Html.prototype.textAreaAsString = function(attr) {
|
||||
res.push();
|
||||
this.textArea(attr);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders an x/html checkbox input tag
|
||||
* @param {Object} param An object containing the tag attributes
|
||||
*/
|
||||
helma.Html.prototype.checkBox = function(param) {
|
||||
if (!param) {
|
||||
res.write("[Html.checkBox: insufficient arguments]");
|
||||
return;
|
||||
}
|
||||
var attr = Object.prototype.reduce.call(param);
|
||||
attr.type = "checkbox";
|
||||
if (attr.selectedValue != null) {
|
||||
if (helma.Html.isSelected(param.value, param.selectedValue))
|
||||
attr.checked = "checked";
|
||||
else
|
||||
delete attr.checked;
|
||||
delete attr.selectedValue;
|
||||
}
|
||||
this.tag("input", attr);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a rendered x/html checkbox input tag
|
||||
* @param {Object} attr An object containing the tag attributes
|
||||
* @returns The rendered checkbox tag
|
||||
* @type String
|
||||
* @see #checkBox
|
||||
*/
|
||||
helma.Html.prototype.checkBoxAsString = function(attr) {
|
||||
res.push();
|
||||
this.checkBox(attr);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders an x/html radiobutton input tag
|
||||
* @param {Object} param An object containing the tag attributes
|
||||
*/
|
||||
helma.Html.prototype.radioButton = function(param) {
|
||||
if (!param) {
|
||||
res.write("[Html.radioButton: insufficient arguments]");
|
||||
return;
|
||||
}
|
||||
var attr = Object.prototype.reduce.call(param);
|
||||
attr.type = "radio";
|
||||
if (attr.selectedValue != null) {
|
||||
if (attr.value == attr.selectedValue)
|
||||
attr.checked = "checked";
|
||||
else
|
||||
delete attr.checked;
|
||||
delete attr.selectedValue;
|
||||
}
|
||||
this.tag("input", attr);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a rendered x/html radio input tag
|
||||
* @param {Object} attr An object containing the tag attributes
|
||||
* @returns The rendered element
|
||||
* @type String
|
||||
* @see #radioButton
|
||||
*/
|
||||
helma.Html.prototype.radioButtonAsString = function(attr) {
|
||||
res.push();
|
||||
this.radioButton(attr);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders an x/html submit input tag
|
||||
* @param {Object} param An object containing the tag attributes
|
||||
*/
|
||||
helma.Html.prototype.submit = function(param) {
|
||||
if (!param) {
|
||||
res.write("[Html.submit: insufficient arguments]");
|
||||
return;
|
||||
}
|
||||
var attr = Object.prototype.reduce.call(param);
|
||||
attr.type = "submit";
|
||||
if (!attr.name)
|
||||
attr.name = attr.type;
|
||||
attr.value = (attr.value != null) ? encodeForm(attr.value) : attr.type;
|
||||
this.tag("input", attr);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a rendered x/html submit input tag
|
||||
* @param {Object} attr An object containing the tag attributes
|
||||
* @returns The rendered submit input tag
|
||||
* @type String
|
||||
* @see #submit
|
||||
*/
|
||||
helma.Html.prototype.submitAsString = function(attr) {
|
||||
res.push();
|
||||
this.submit(attr);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders an x/html button input tag
|
||||
* @param {Object} param An object containing the tag attributes
|
||||
*/
|
||||
helma.Html.prototype.button = function(param) {
|
||||
if (!param) {
|
||||
res.write("[Html.button: insufficient arguments]");
|
||||
return;
|
||||
}
|
||||
var attr = Object.prototype.reduce.call(param);
|
||||
attr.type = "button";
|
||||
if (!attr.name)
|
||||
attr.name = attr.type;
|
||||
attr.value = (attr.value != null) ? encodeForm(attr.value) : attr.type;
|
||||
this.tag("input", attr);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a rendered x/html button input tag
|
||||
* @param {Object} param An object containing the tag attributes
|
||||
* @returns The rendered button input tag
|
||||
* @type String
|
||||
* @see #button
|
||||
*/
|
||||
helma.Html.prototype.buttonAsString = function(attr) {
|
||||
res.push();
|
||||
this.button(attr);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a x/html drop down select box
|
||||
* @param {Object} param An object containing the tag attributes
|
||||
* @param {Array} options Either an array of strings, an array with
|
||||
* several <code>{value: v, display: d}</code> objects, or a collection
|
||||
* of <code>["value", "display"]</code> arrays in an array
|
||||
* @param {String} selectedValue The value to pre-select
|
||||
* @param {String} firstOption An optional first option to display in the
|
||||
* select box (this option will always have no value)
|
||||
*/
|
||||
helma.Html.prototype.dropDown = function(param, options, selectedValue, firstOption) {
|
||||
if (!param) {
|
||||
res.write("[Html.dropDown: insufficient arguments]");
|
||||
return;
|
||||
}
|
||||
var attr = Object.prototype.reduce.call(param);
|
||||
this.openTag("select", attr);
|
||||
res.write("\n ");
|
||||
if (firstOption) {
|
||||
this.openTag("option", {value: ""});
|
||||
res.write(firstOption);
|
||||
this.closeTag("option");
|
||||
res.write("\n ");
|
||||
}
|
||||
var hasOpenGroup = false;
|
||||
for (var i in options) {
|
||||
if (options[i].group) {
|
||||
hasOpenGroup && html.closeTag("optgroup");
|
||||
html.openTag("optgroup", {label: options[i].group});
|
||||
hasOpenGroup = true;
|
||||
}
|
||||
var attr = new Object();
|
||||
var display = "";
|
||||
if ((options[i] instanceof Array) && options[i].length > 0) {
|
||||
// option is an array
|
||||
attr.value = options[i][0];
|
||||
display = options[i][1];
|
||||
} else if (options[i].value != null && options[i].display != null) {
|
||||
// option is an object
|
||||
attr.value = options[i].value;
|
||||
if (options[i]["class"] != null) {
|
||||
attr["class"] = options[i]["class"];
|
||||
}
|
||||
display = options[i].display;
|
||||
} else {
|
||||
// assume option is a string
|
||||
attr.value = i;
|
||||
display = options[i];
|
||||
}
|
||||
if (helma.Html.isSelected(attr.value, selectedValue))
|
||||
attr.selected = "selected";
|
||||
this.openTag("option", attr);
|
||||
res.write(display);
|
||||
this.closeTag("option");
|
||||
res.write("\n ");
|
||||
}
|
||||
hasOpenGroup && html.closeTag("optgroup");
|
||||
this.closeTag("select");
|
||||
res.write("\n ");
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a rendered x/html drop down select box
|
||||
* @param {Object} param An object containing the tag attributes
|
||||
* @param {Array} options Either an array of strings, an array with
|
||||
* several <code>{value: v, display: d}</code> objects, or a collection
|
||||
* of <code>["value", "display"]</code> arrays in an array
|
||||
* @param {String} selectedValue The value to pre-select
|
||||
* @param {String} firstOption An optional first option to display in the
|
||||
* select box (this option will always have no value)
|
||||
* @returns The rendered drop down select box
|
||||
* @type String
|
||||
* @see #dropDown
|
||||
*/
|
||||
helma.Html.prototype.dropDownAsString = function(attr, options, selectedValue, firstOption) {
|
||||
res.push();
|
||||
this.dropDown(attr, options, selectedValue, firstOption);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders an image map based on an array containing the map parameters.
|
||||
* @param {String} name The name of the image map
|
||||
* @param {Array} param An array containing objects, where each of them
|
||||
* contains the attributes for a single image map entry
|
||||
*/
|
||||
helma.Html.prototype.map = function(name, param) {
|
||||
if (!name || !param) {
|
||||
res.write("[Html.map: insufficient arguments]");
|
||||
return;
|
||||
}
|
||||
this.openTag("map", {name: name});
|
||||
var attr = Object.prototype.reduce.call(param);
|
||||
for (var i in areas) {
|
||||
if (!areas[i].alt)
|
||||
areas[i].alt = "";
|
||||
if (!areas[i].shape)
|
||||
areas[i].shape = "rect";
|
||||
this.openTag("area", areas[i]);
|
||||
}
|
||||
this.closeTag("map");
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a rendered image map based on an array containing the map parameters.
|
||||
* @param {String} name The name of the image map
|
||||
* @param {Array} areas An array containing objects, where each of them
|
||||
* contains the attributes for a single image map entry
|
||||
* @returns The rendered image map
|
||||
* @type String
|
||||
* @see #map
|
||||
*/
|
||||
helma.Html.prototype.mapAsString = function(name, areas) {
|
||||
res.push();
|
||||
this.map(name, areas);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a complete x/html table.
|
||||
* @param {Array} headers An array containing table headers
|
||||
* @param {Array} data A two-dimensional array containing the table data
|
||||
* @param {Object} param An object containing the following properties:
|
||||
* <ul>
|
||||
* <li><code>table</code>: Attributes to render within the opening <code><table></code> tag</li>
|
||||
* <li><code>tr</code>: Attributes to render within each <code><tr></code> tag</li>
|
||||
* <li><code>td</code>: Attributes to render within each <code><td></code> tag</li>
|
||||
* <li><code>th</code>: Attributes to render within each <code><th></code> tag</li>
|
||||
* <li><code>trHead</code>: Attributes to render within each <code><tr></code> tag
|
||||
in the header area of the table</li>
|
||||
* <li><code>trEven</code>: Attributes to render within each even <code><tr></code> tag</li>
|
||||
* <li><code>trOdd</code>: Attributes to render within each odd <code><tr></code> tag</li>
|
||||
* <li><code>tdEven</code>: Attributes to render within each even <code><td></code> tag</li>
|
||||
* <li><code>tdOdd</code>: Attributes to render within each odd <code><td></code> tag</li>
|
||||
* <li><code>thEven</code>: Attributes to render within each even <code><th></code> tag</li>
|
||||
* <li><code>thOdd</code>: Attributes to render within each odd <code><th></code> tag</li>
|
||||
* </ul>
|
||||
*/
|
||||
helma.Html.prototype.table = function(headers, data, param) {
|
||||
if (!param) {
|
||||
res.write("[Html.table: insufficient arguments]");
|
||||
return;
|
||||
}
|
||||
var attr = Object.prototype.reduce.call(param);
|
||||
if (!attr.trHead) attr.trHead = attr.tr;
|
||||
if (!attr.trEven) attr.trEven = attr.tr;
|
||||
if (!attr.trOdd) attr.trOdd = attr.tr;
|
||||
if (!attr.tdEven) attr.tdEven = attr.td;
|
||||
if (!attr.tdOdd) attr.tdOdd = attr.td;
|
||||
if (!attr.thEven) attr.thEven = attr.th;
|
||||
if (!attr.thOdd) attr.thOdd = attr.th;
|
||||
this.openTag("table", attr.table);
|
||||
if (headers) {
|
||||
this.openTag("tr", attr.trHead);
|
||||
for (var i in headers) {
|
||||
var evenOdd = i % 2 == 0 ? "Even" : "Odd";
|
||||
this.openTag("th", attr["th"+evenOdd]);
|
||||
res.write(headers[i]);
|
||||
this.closeTag("th");
|
||||
}
|
||||
this.closeTag("tr");
|
||||
}
|
||||
for (var i in data) {
|
||||
var evenOdd = i % 2 == 0 ? "Even" : "Odd";
|
||||
this.openTag("tr", attr["tr"+evenOdd]);
|
||||
for (var j in data[i]) {
|
||||
var evenOddCell = j % 2 == 0 ? "Even" : "Odd";
|
||||
this.openTag("td", attr["td"+evenOddCell]);
|
||||
res.write(data[i][j]);
|
||||
this.closeTag("td");
|
||||
}
|
||||
this.closeTag("tr");
|
||||
}
|
||||
this.closeTag("table");
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a rendered x/html table
|
||||
* @param {Array} headers An array containing table headers
|
||||
* @param {Array} data A two-dimensional array containing the table data
|
||||
* @param {Object} attr For a description see {@link #table}
|
||||
* @returns The rendered table
|
||||
* @type String
|
||||
* @see #table
|
||||
*/
|
||||
helma.Html.prototype.tableAsString = function(headers, data, attr) {
|
||||
res.push();
|
||||
this.table(headers, data, attr);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/*********************************************************************/
|
||||
/* */
|
||||
/* the following functions should be deliberately altered or removed */
|
||||
/* (most of these can easily be replaced by the methods they call) */
|
||||
/* */
|
||||
/*********************************************************************/
|
||||
|
||||
/**
|
||||
* Renders an x/html opening link tag
|
||||
* @param {Object} attr An object containing the tag attributes
|
||||
*/
|
||||
helma.Html.prototype.openLink = function(attr) {
|
||||
this.openTag("a", attr);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an x/html opening link tag
|
||||
* @param {Object} attr An object containing the tag attributes
|
||||
* @returns The rendered open link tag
|
||||
* @type String
|
||||
* @see #openTag
|
||||
*/
|
||||
helma.Html.prototype.openLinkAsString = function(attr) {
|
||||
return this.openTagAsString("a", attr);
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders an x/html closing link tag
|
||||
*/
|
||||
helma.Html.prototype.closeLink = function() {
|
||||
this.closeTag("a");
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a rendered x/html closing link tag
|
||||
* @returns Rhe rendered closing link tag
|
||||
* @type String
|
||||
* @see #closeLink
|
||||
*/
|
||||
helma.Html.prototype.closeLinkAsString = function() {
|
||||
return this.closeTagAsString("a");
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a color definition string. If the string passed as
|
||||
* argument contains only hex characters it will be prefixed with a
|
||||
* hash sign if necessary, otherwise this method assumes that the
|
||||
* value is a named color (eg. "yellow").
|
||||
* @param {String} c The color definintion
|
||||
* @deprecated
|
||||
*/
|
||||
helma.Html.prototype.color = function(c) {
|
||||
if (c) {
|
||||
var nonhex = /[^0-9,a-f]/gi;
|
||||
if (!c.match(nonhex)) {
|
||||
c = c.pad("0", 6);
|
||||
res.write("#");
|
||||
}
|
||||
}
|
||||
res.write(c);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a color definition.
|
||||
* @param {String} c The color definintion
|
||||
* @returns The rendered color definition
|
||||
* @type String
|
||||
* @see #color
|
||||
* @deprecated
|
||||
*/
|
||||
helma.Html.prototype.colorAsString = function(c) {
|
||||
res.push();
|
||||
this.color(c);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders an x/html opening form tag
|
||||
* @param {Object} attr An object containing the tag attributes
|
||||
*/
|
||||
helma.Html.prototype.form = function(attr) {
|
||||
this.openTag("form", attr);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an x/html opening form tag
|
||||
* @param {Object} attr An object containing the tag attributes
|
||||
* @returns The rendered opening form tag
|
||||
* @type String
|
||||
* @see #form
|
||||
*/
|
||||
helma.Html.prototype.formAsString = function(attr) {
|
||||
res.push();
|
||||
this.form(attr);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders an x/html password input tag
|
||||
* @param {Object} attr An object containing the tag attributes
|
||||
*/
|
||||
helma.Html.prototype.password = function(attr) {
|
||||
if (!attr) {
|
||||
res.write("[Html.password: insufficient arguments]");
|
||||
return;
|
||||
}
|
||||
attr.type = "password";
|
||||
this.tag("input", attr);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a rendered x/html password input tag
|
||||
* @param {Object} attr An object containing the tag attributes
|
||||
* @returns The rendered password input tag
|
||||
* @type String
|
||||
* @see #password
|
||||
*/
|
||||
helma.Html.prototype.passwordAsString = function(attr) {
|
||||
res.push();
|
||||
this.password(attr);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders an x/html file input tag
|
||||
* @param {Object} attr An object containing the tag attributes
|
||||
*/
|
||||
helma.Html.prototype.file = function(attr) {
|
||||
if (!attr) {
|
||||
res.write("[Html.file: insufficient arguments]");
|
||||
return;
|
||||
}
|
||||
attr.type = "file";
|
||||
this.tag("input", attr);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a rendered x/html file input tag
|
||||
* @param {Object} attr An object containing the tag attributes
|
||||
* @returns The rendered file input tag
|
||||
* @type String
|
||||
* @see #file
|
||||
*/
|
||||
helma.Html.prototype.fileAsString = function(attr) {
|
||||
res.push();
|
||||
this.file(attr);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses the string passed as argument and converts any
|
||||
* URL in it into a link tag
|
||||
* @param {String} str The string wherein URLs should be
|
||||
* converted into link tags
|
||||
* @returns The string containing URLs converted into link tags
|
||||
* @type String
|
||||
*/
|
||||
helma.Html.prototype.activateUrls = function(str) {
|
||||
var re = /(^|\/>|\s+)([fhtpsr]+:\/\/[^\s]+?)([\.,;:\)\]\"]?)(?=[\s<]|$)/gim;
|
||||
var func = function(str, p1, p2, p3) {
|
||||
res.push();
|
||||
res.write(p1);
|
||||
res.write('<a href="');
|
||||
res.write(p2);
|
||||
res.write('">');
|
||||
res.write(p2.clip(50, "...", true));
|
||||
res.write('</a>');
|
||||
res.write(p3);
|
||||
return res.pop();
|
||||
};
|
||||
return str.replace(re, func);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new TableWriter instance
|
||||
* @class This class provides various methods for
|
||||
* programmatically creating an x/html table.
|
||||
* @param {Number} numberOfColumns The number of columns in the table
|
||||
* @param {Object} attr An object containing attributes to use when
|
||||
* rendering the single table elements. For a description see {@link #table}.
|
||||
* @returns An instance of TableWriter
|
||||
* @constructor
|
||||
*/
|
||||
helma.Html.TableWriter = function(numberOfColumns, attr) {
|
||||
if (isNaN(numberOfColumns))
|
||||
throw "Illegal argument in TableWriter(): first argument must be a number";
|
||||
if (numberOfColumns < 1)
|
||||
throw "Illegal argument in TableWriter(): first argument must be > 1";
|
||||
/** @private */
|
||||
this.ncols = numberOfColumns;
|
||||
/** @private */
|
||||
this.written = 0;
|
||||
// if no attributes object given, create an empty one
|
||||
if (!attr)
|
||||
attr = {};
|
||||
if (!attr.trEven) attr.trEven = attr.tr;
|
||||
if (!attr.trOdd) attr.trOdd = attr.tr;
|
||||
if (!attr.trHead) attr.trHead = attr.trEven;
|
||||
if (!attr.tdEven) attr.tdEven = attr.td;
|
||||
if (!attr.tdOdd) attr.tdOdd = attr.td;
|
||||
if (!attr.thEven) attr.thEven = attr.th;
|
||||
if (!attr.thOdd) attr.thOdd = attr.th;
|
||||
/** @private */
|
||||
this.attr = attr;
|
||||
|
||||
/**
|
||||
* If set to true the first row of the table data is rendered
|
||||
* using <code><th></code> tags (defaults to false).
|
||||
* @type Boolean
|
||||
*/
|
||||
this.writeHeader = false;
|
||||
|
||||
/**
|
||||
* If set to true the TableWriter returns the rendered table
|
||||
* as string, otherwise the table is written directly to response,
|
||||
* which is the default.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.writeString = false;
|
||||
|
||||
this.dontEnum("ncols", "written", "attr", "writeHeader", "writeString");
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
helma.Html.TableWriter.prototype.toString = function() {
|
||||
return "[helma.Html.TableWriter]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a single table cell to response.
|
||||
* @param {String} text The content of the table cess
|
||||
* @param {Object} attr An optional object containig attributes
|
||||
* to render for this table cell
|
||||
*/
|
||||
helma.Html.TableWriter.prototype.write = function(text, attr) {
|
||||
// set up some variables
|
||||
var isHeaderRow = (this.writeHeader && this.written < this.ncols);
|
||||
var isNewRow = (this.written % this.ncols == 0);
|
||||
var isEvenRow = ((this.written / this.ncols) % 2 == 0);
|
||||
var isEvenCol = ((this.written % this.ncols) % 2 == 0);
|
||||
// write out table and table row tags
|
||||
if (this.written == 0) {
|
||||
if (this.writeString)
|
||||
res.push();
|
||||
helma.Html.prototype.openTag.call(this, "table", this.attr.table);
|
||||
helma.Html.prototype.openTag.call(this, "tr", this.attr.trHead);
|
||||
} else if (isNewRow) {
|
||||
helma.Html.prototype.closeTag.call(this, "tr");
|
||||
if (isEvenRow)
|
||||
helma.Html.prototype.openTag.call(this, "tr", this.attr.trEven);
|
||||
else
|
||||
helma.Html.prototype.openTag.call(this, "tr", this.attr.trOdd);
|
||||
}
|
||||
// get the attribute object for the table cell
|
||||
if (!attr) {
|
||||
// no explicit attribute given
|
||||
if (isEvenCol) {
|
||||
attr = isHeaderRow ? this.attr.thEven : this.attr.tdEven;
|
||||
} else {
|
||||
attr = isHeaderRow ? this.attr.thOdd : this.attr.tdOdd;
|
||||
}
|
||||
}
|
||||
// write out table cell tag
|
||||
helma.Html.prototype.openTag.call(this, isHeaderRow ? "th" : "td", attr);
|
||||
// write out table cell contents
|
||||
if (text) {
|
||||
res.write(text);
|
||||
}
|
||||
// close table cell
|
||||
helma.Html.prototype.closeTag.call(this, isHeaderRow ? "th" : "td");
|
||||
if (attr && !isNaN(attr.colspan)) {
|
||||
this.written += attr.colspan;
|
||||
} else {
|
||||
this.written += 1;
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes all open table tags. If {@link #writeString} is set to
|
||||
* true, this method returns the rendered table.
|
||||
* @returns The rendered table, if {@link #writeString} is set to
|
||||
* true, otherwise void.
|
||||
* @type String
|
||||
*/
|
||||
helma.Html.TableWriter.prototype.close = function() {
|
||||
if (this.written > 0) {
|
||||
while (this.written++ % this.ncols != 0)
|
||||
res.write("<td></td>");
|
||||
res.write("</tr></table>");
|
||||
this.written = 0;
|
||||
}
|
||||
if (this.writeString)
|
||||
return res.pop();
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
|
||||
helma.lib = "Html";
|
||||
helma.dontEnum(helma.lib);
|
||||
for (var i in helma[helma.lib])
|
||||
helma[helma.lib].dontEnum(i);
|
||||
for (var i in helma[helma.lib].prototype)
|
||||
helma[helma.lib].prototype.dontEnum(i);
|
||||
for (var i in helma[helma.lib].TableWriter.prototype)
|
||||
helma[helma.lib].TableWriter.prototype.dontEnum(i);
|
||||
delete helma.lib;
|
|
@ -1,833 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Http.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the helma.Http class.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/helma/Http.js')
|
||||
*/
|
||||
|
||||
// take care of any dependencies
|
||||
app.addRepository('modules/core/Date.js');
|
||||
|
||||
|
||||
/**
|
||||
* Define the global namespace if not existing
|
||||
*/
|
||||
if (!global.helma) {
|
||||
global.helma = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of helma.Http
|
||||
* @class This class provides functionality to programatically issue
|
||||
* an Http request based on java.net.HttpUrlConnection.
|
||||
* By default the request will use method <code>GET</code>.
|
||||
* @returns A newly created helma.Http instance
|
||||
* @constructor
|
||||
*/
|
||||
helma.Http = function() {
|
||||
var self = this;
|
||||
var proxy = null;
|
||||
var content = "";
|
||||
var userAgent = "Helma Http Client";
|
||||
var method = "GET";
|
||||
var cookies = null;
|
||||
var credentials = null;
|
||||
var followRedirects = true;
|
||||
var binaryMode = false;
|
||||
var headers = {};
|
||||
var timeout = {
|
||||
"connect": 0,
|
||||
"socket": 0
|
||||
};
|
||||
var maxResponseSize = null;
|
||||
var maxTries = 5;
|
||||
var currentTries = 0;
|
||||
|
||||
var responseHandler = function(connection, result) {
|
||||
var input;
|
||||
var stream;
|
||||
try {
|
||||
stream = connection.getInputStream();
|
||||
} catch (error) {
|
||||
stream = connection.getErrorStream();
|
||||
}
|
||||
if (stream) {
|
||||
if (connection.getContentEncoding() === 'gzip') {
|
||||
stream = new java.util.zip.GZIPInputStream(stream);
|
||||
}
|
||||
input = new java.io.BufferedInputStream(stream);
|
||||
}
|
||||
if (input) {
|
||||
var body = new java.io.ByteArrayOutputStream();
|
||||
var buf = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 1024);
|
||||
var len;
|
||||
var currentSize = 0;
|
||||
while ((len = input.read(buf)) > -1) {
|
||||
body.write(buf, 0, len);
|
||||
currentSize += len;
|
||||
if (maxResponseSize && currentSize > maxResponseSize) {
|
||||
throw new Error("Maximum allowed response size is exceeded");
|
||||
}
|
||||
}
|
||||
try {
|
||||
input.close();
|
||||
} catch (error) {
|
||||
// safe to ignore
|
||||
}
|
||||
if (binaryMode) {
|
||||
result.content = body.toByteArray();
|
||||
} else {
|
||||
result.content = result.charset ?
|
||||
body.toString(result.charset) :
|
||||
body.toString();
|
||||
}
|
||||
// adjust content length
|
||||
if (result.content) {
|
||||
result.length = result.content.length;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** @private */
|
||||
var setTimeout = function(type, value) {
|
||||
var v = java.lang.System.getProperty("java.specification.version");
|
||||
if (parseFloat(v, 10) >= 1.5) {
|
||||
timeout[type] = value;
|
||||
} else {
|
||||
app.logger.warn("helma.Http: Timeouts can only be set with Java Runtime version >= 1.5");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the proxy host and port for later use. The argument must
|
||||
* be in <code>host:port</code> format (eg. "proxy.example.com:3128").
|
||||
* @param {String} proxyString The proxy to use for this request
|
||||
* @see #getProxy
|
||||
*/
|
||||
this.setProxy = function(proxyString) {
|
||||
var idx = proxyString.indexOf(":");
|
||||
var host = proxyString.substring(0, idx);
|
||||
var port = proxyString.substring(idx+1);
|
||||
if (java.lang.Class.forName("java.net.Proxy") != null) {
|
||||
// construct a proxy instance
|
||||
var socket = new java.net.InetSocketAddress(host, port);
|
||||
proxy = new java.net.Proxy(java.net.Proxy.Type.HTTP, socket);
|
||||
} else {
|
||||
// the pre jdk1.5 way: set the system properties
|
||||
var sys = java.lang.System.getProperties();
|
||||
if (host) {
|
||||
app.logger.warn("[Helma Http Client] WARNING: setting system http proxy to " + host + ":" + port);
|
||||
sys.put("http.proxySet", "true");
|
||||
sys.put("http.proxyHost", host);
|
||||
sys.put("http.proxyPort", port);
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the proxy in <code>host:port</code> format
|
||||
* @return The proxy defined for this request
|
||||
* @type String
|
||||
* @see #setProxy
|
||||
*/
|
||||
this.getProxy = function() {
|
||||
if (proxy != null) {
|
||||
return proxy.address().getHostName() + ":" + proxy.address().getPort();
|
||||
} else if (sys.get("http.proxySet") == "true") {
|
||||
return sys.get("http.proxyHost") + ":" + sys.get("http.proxyPort");
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the credentials for basic http authentication
|
||||
* @param {String} username The username
|
||||
* @param {String} password The password
|
||||
*/
|
||||
this.setCredentials = function(username, password) {
|
||||
var str = username + ":" + password;
|
||||
credentials = str.enbase64();
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the content to send to the remote server within this request.
|
||||
* @param {String|Object} stringOrObject The content of the request, which
|
||||
* can be either a string or an object. In the latter case all properties
|
||||
* and their values are concatenated into a single string.
|
||||
* If a property is an array, then for each value the propertyname and value pair is added.
|
||||
* If the name of an array property ends with "_array" then the _array part is removed.
|
||||
*/
|
||||
this.setContent = function(stringOrObject) {
|
||||
if (stringOrObject != null) {
|
||||
if (stringOrObject.constructor == Object) {
|
||||
res.push();
|
||||
var value;
|
||||
for (var key in stringOrObject) {
|
||||
value = stringOrObject[key];
|
||||
if (value instanceof Array) {
|
||||
if (key.substring(key.length - 6) == "_array")
|
||||
key = key.substring(0,key.length - 6);
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
res.write(encodeURIComponent(key));
|
||||
res.write("=");
|
||||
res.write(encodeURIComponent(value[i]));
|
||||
res.write("&");
|
||||
}
|
||||
} else {
|
||||
res.write(encodeURIComponent(key));
|
||||
res.write("=");
|
||||
res.write(encodeURIComponent(value));
|
||||
res.write("&");
|
||||
}
|
||||
}
|
||||
content = res.pop();
|
||||
content = content.substring(0, content.length-1);
|
||||
} else {
|
||||
content = stringOrObject.toString();
|
||||
}
|
||||
} else {
|
||||
content = null;
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the request method to use.
|
||||
* @param {String} m The method to use (<code>GET</code>, <code>POST</code> ...)
|
||||
* @see #getMethod
|
||||
*/
|
||||
this.setMethod = function(m) {
|
||||
method = m;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the currently defined request method.
|
||||
* @returns The method used
|
||||
* @type String
|
||||
* @see #setMethod
|
||||
*/
|
||||
this.getMethod = function() {
|
||||
return method;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a single HTTP request header field
|
||||
* @param {String} name The name of the header field
|
||||
* @param {String} value The value of the header field
|
||||
* @see #getHeader
|
||||
*/
|
||||
this.setHeader = function(name, value) {
|
||||
headers[name] = value;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the value of the request header field with the given name
|
||||
* @param {String} name The name of the request header field
|
||||
* @returns The value of the request header field
|
||||
* @type String
|
||||
* @see #setHeader
|
||||
*/
|
||||
this.getHeader = function(name) {
|
||||
return headers[name];
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a cookie with the name and value passed as arguments
|
||||
* to the list of cookies to send to the remote server.
|
||||
* @param {String} name The name of the cookie
|
||||
* @param {String} value The value of the cookie
|
||||
* @see #getCookie
|
||||
* @see #getCookies
|
||||
*/
|
||||
this.setCookie = function(name, value) {
|
||||
if (name != null && value != null) {
|
||||
// store the cookie in the cookies map
|
||||
if (!cookies) {
|
||||
cookies = {};
|
||||
}
|
||||
cookies[name] = new helma.Http.Cookie(name, value);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the value of the cookie with the given name
|
||||
* @param {String} name The name of the cookie
|
||||
* @returns The value of the cookie
|
||||
* @type String
|
||||
* @see #setCookie
|
||||
*/
|
||||
this.getCookie = function(name) {
|
||||
return (cookies != null) ? cookies[name] : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds the cookies passed as argument to the list of cookies to send
|
||||
* to the remote server.
|
||||
* @param {Array} cookies An array containing objects with the properties
|
||||
* "name" (the name of the cookie) and "value" (the value of the cookie) set.
|
||||
*/
|
||||
this.setCookies = function(cookies) {
|
||||
if (cookies != null) {
|
||||
for (var i=0; i<cookies.length; i++) {
|
||||
this.setCookie(cookies[i].name, cookies[i].value);
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns all cookies set for this client
|
||||
* @return An object containing all cookies, where the property
|
||||
* name is the name of the cookie, and the value is the cookie value
|
||||
* @see #setCookie
|
||||
*/
|
||||
this.getCookies = function() {
|
||||
return cookies;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the connection timeout to the amount of milliseconds
|
||||
* passed as argument
|
||||
* @param {Number} timeout The connection timeout in milliseconds
|
||||
* @see #getTimeout
|
||||
*/
|
||||
this.setTimeout = function(timeout) {
|
||||
setTimeout("connect", timeout);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the read timeout (the maximum time a request may take after
|
||||
* the connection has been successfully established) to the amount of
|
||||
* milliseconds passed as argument.
|
||||
* @param {Number} timeout The read timeout in milliseconds
|
||||
* @see #getReadTimeout
|
||||
*/
|
||||
this.setReadTimeout = function(timeout) {
|
||||
setTimeout("socket", timeout);
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the connection timeout
|
||||
* @returns The connection timeout in milliseconds
|
||||
* @type Number
|
||||
* @see #setTimeout
|
||||
*/
|
||||
this.getTimeout = function() {
|
||||
return timeout.connect;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the read timeout (the maximum time a request may take after
|
||||
* the connection has been successfully established).
|
||||
* @returns The read timeout in milliseconds
|
||||
* @type Number
|
||||
* @see #setReadTimeout
|
||||
*/
|
||||
this.getReadTimeout = function() {
|
||||
return timeout.socket;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enables or disables following redirects
|
||||
* @param {Boolean} value If false this client won't follow redirects (the default is
|
||||
* to follow them)
|
||||
* @see #getFollowRedirects
|
||||
*/
|
||||
this.setFollowRedirects = function(value) {
|
||||
followRedirects = value;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the client follows redirects
|
||||
* @returns True if the client follows redirects, false otherwise.
|
||||
* @see #setFollowRedirects
|
||||
*/
|
||||
this.getFollowRedirects = function() {
|
||||
return followRedirects;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the HTTP "User-Agent" header field to the string passed as argument
|
||||
* @param {String} agent The string to use as value of the
|
||||
* "User-Agent" header field (defaults to "Helma Http Client")
|
||||
* @see #getUserAgent
|
||||
*/
|
||||
this.setUserAgent = function(agent) {
|
||||
userAgent = agent;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the value of the HTTP "User-Agent" header field
|
||||
* @returns The value of the field
|
||||
* @type String
|
||||
* @see #setUserAgent
|
||||
*/
|
||||
this.getUserAgent = function() {
|
||||
return userAgent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Switches content text encoding on or off. Depending on this
|
||||
* the content received from the remote server will be either a
|
||||
* string or a byte array.
|
||||
* @param {Boolean} mode If true binary mode is activated
|
||||
* @see #getBinaryMode
|
||||
*/
|
||||
this.setBinaryMode = function(mode) {
|
||||
binaryMode = mode;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the currently defined binary mode of this client
|
||||
* @returns The binary mode of this client
|
||||
* @type Boolean
|
||||
* @see #setBinaryMode
|
||||
*/
|
||||
this.getBinaryMode = function() {
|
||||
return binaryMode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the max allowed size for the response stream
|
||||
* @param {Integer} Size in Byte
|
||||
*/
|
||||
this.setMaxResponseSize = function(size) {
|
||||
maxResponseSize = size;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the currently set max response size
|
||||
* @returns The max responsesize
|
||||
* @type Integer
|
||||
* @see #setMaxResponseSize
|
||||
*/
|
||||
this.getMaxResponseSize = function() {
|
||||
return maxResponseSize;
|
||||
};
|
||||
|
||||
/**
|
||||
* Overloads the default response handler.
|
||||
* Use this do implement your own response handling, like storing the response directly to the harddisk
|
||||
* The handler function gets two parameter, first is the java.net.URLConnection and second is the result object.
|
||||
* Note that custom response handler functions should check the HTTP status code before reading
|
||||
* the response. The status code for successful requests is 200. Response bodies for requests with
|
||||
* status codes less than 400 can be read from the connection's input stream, while response bodies
|
||||
* with 4xx or 5xx status codes must be read using the error stream.
|
||||
* @param {function} Response handler function
|
||||
*/
|
||||
this.setResponseHandler = function(callback) {
|
||||
responseHandler = callback;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the response handler. This is the function used to read the HTTP response body.
|
||||
* @returns The response handler function
|
||||
*/
|
||||
this.getResponseHandler = function() {
|
||||
return responseHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a http request
|
||||
* @param {String} url The url to request
|
||||
* @param {Date|String} opt If this argument is a string, it is used
|
||||
* as value for the "If-None-Match" request header field. If it is a
|
||||
* Date instance it is used as "IfModifiedSince" condition for this request.
|
||||
* @return A result object containing the following properties:
|
||||
* <ul>
|
||||
* <li><code>url</code>: (String) The Url of the request</li>
|
||||
* <li><code>location</code>: (String) The value of the location header field</li>
|
||||
* <li><code>code</code>: (Number) The HTTP response code</li>
|
||||
* <li><code>message</code>: (String) An optional HTTP response message</li>
|
||||
* <li><code>length</code>: (Number) The content length of the response</li>
|
||||
* <li><code>type</code>: (String) The mimetype of the response</li>
|
||||
* <li><code>charset</code>: (String) The character set of the response</li>
|
||||
* <li><code>encoding</code>: (String) An optional encoding to use with the response</li>
|
||||
* <li><code>lastModified</code>: (String) The value of the lastModified response header field</li>
|
||||
* <li><code>eTag</code>: (String) The eTag as received from the remote server</li>
|
||||
* <li><code>cookie</code>: (helma.Http.Cookie) An object containing the cookie parameters, if the remote
|
||||
server has set the "Set-Cookie" header field</li>
|
||||
* <li><code>headers</code>: (java.util.Map) A map object containing the headers, access them using get("headername")
|
||||
* <li><code>content</code>: (String|ByteArray) The response received from the server. Can be either
|
||||
a string or a byte array (see #setBinaryMode)</li>
|
||||
* </ul>
|
||||
*/
|
||||
this.getUrl = function(url, opt) {
|
||||
if (typeof url == "string") {
|
||||
if (!(url = helma.Http.evalUrl(url)))
|
||||
throw new Error("'" + url + "' is not a valid URL.");
|
||||
} else if (!(url instanceof java.net.URL)) {
|
||||
throw new Error("'" + url + "' is not a valid URL.");
|
||||
}
|
||||
|
||||
var conn = proxy ? url.openConnection(proxy) : url.openConnection();
|
||||
// Note: we must call setInstanceFollowRedirects() instead of
|
||||
// static method setFollowRedirects(), as the latter will
|
||||
// set the default value for all url connections, and will not work for
|
||||
// url connections that have already been created.
|
||||
conn.setInstanceFollowRedirects(followRedirects);
|
||||
conn.setAllowUserInteraction(false);
|
||||
conn.setRequestMethod(method);
|
||||
conn.setRequestProperty("User-Agent", userAgent);
|
||||
|
||||
if (opt) {
|
||||
if (opt instanceof Date)
|
||||
conn.setIfModifiedSince(opt.getTime());
|
||||
else if ((typeof opt == "string") && (opt.length > 0))
|
||||
conn.setRequestProperty("If-None-Match", opt);
|
||||
}
|
||||
|
||||
var userinfo;
|
||||
if (userinfo = url.getUserInfo()) {
|
||||
userinfo = userinfo.split(/:/, 2);
|
||||
this.setCredentials(userinfo[0], userinfo[1]);
|
||||
}
|
||||
if (credentials != null) {
|
||||
conn.setRequestProperty("Authorization", "Basic " + credentials);
|
||||
}
|
||||
// set timeouts
|
||||
if (parseFloat(java.lang.System.getProperty("java.specification.version"), 10) >= 1.5) {
|
||||
conn.setConnectTimeout(timeout.connect);
|
||||
conn.setReadTimeout(timeout.socket);
|
||||
}
|
||||
// set header fields
|
||||
for (var i in headers) {
|
||||
conn.setRequestProperty(i, headers[i]);
|
||||
}
|
||||
// set cookies
|
||||
if (cookies != null) {
|
||||
var arr = [];
|
||||
for (var i in cookies) {
|
||||
arr[arr.length] = cookies[i].getFieldValue();
|
||||
}
|
||||
conn.setRequestProperty("Cookie", arr.join(";"));
|
||||
}
|
||||
// set content
|
||||
if (content) {
|
||||
conn.setRequestProperty("Content-Length", content.length);
|
||||
conn.setDoOutput(true);
|
||||
var out = new java.io.OutputStreamWriter(conn.getOutputStream());
|
||||
out.write(content);
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
|
||||
var result = {
|
||||
url: conn.getURL(),
|
||||
location: conn.getHeaderField("location"),
|
||||
code: conn.getResponseCode(),
|
||||
message: conn.getResponseMessage(),
|
||||
length: conn.getContentLength(),
|
||||
type: conn.getContentType(),
|
||||
encoding: conn.getContentEncoding(),
|
||||
lastModified: null,
|
||||
eTag: conn.getHeaderField("ETag"),
|
||||
cookies: null,
|
||||
headers: conn.getHeaderFields(),
|
||||
content: null,
|
||||
}
|
||||
|
||||
// java.net.URLConnection does not follow redirects from http to https
|
||||
// See https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4620571
|
||||
if (followRedirects && [301, 303].contains(result.code) && result.location) {
|
||||
currentTries += 1;
|
||||
if (currentTries >= maxTries) throw new Error('Too many redirects');
|
||||
return this.getUrl(result.location, opt);
|
||||
}
|
||||
|
||||
// parse all "Set-Cookie" header fields into an array of
|
||||
// helma.Http.Cookie instances
|
||||
var setCookies = conn.getHeaderFields().get("Set-Cookie");
|
||||
if (setCookies != null) {
|
||||
var arr = [];
|
||||
var cookie;
|
||||
for (var i=0; i<setCookies.size(); i++) {
|
||||
if ((cookie = helma.Http.Cookie.parse(setCookies.get(i))) != null) {
|
||||
arr.push(cookie);
|
||||
}
|
||||
}
|
||||
if (arr.length > 0) {
|
||||
result.cookies = arr;
|
||||
}
|
||||
}
|
||||
|
||||
var lastmod = conn.getLastModified();
|
||||
if (lastmod) {
|
||||
result.lastModified = new Date(lastmod);
|
||||
}
|
||||
|
||||
if (maxResponseSize && result.length > maxResponseSize) {
|
||||
throw new Error("Maximum allowed response size is exceeded");
|
||||
}
|
||||
|
||||
if (result.type && result.type.indexOf("charset=") != -1) {
|
||||
var charset = result.type.substring(result.type.indexOf("charset=") + 8);
|
||||
charset = charset.replace(/[;"]/g, '').trim();
|
||||
result.charset = charset;
|
||||
}
|
||||
|
||||
// invoke response handler
|
||||
responseHandler(conn, result);
|
||||
|
||||
conn.disconnect();
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
this.toString = function() {
|
||||
return "[Helma Http Client]";
|
||||
};
|
||||
|
||||
for (var i in this)
|
||||
this.dontEnum(i);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Evaluates the url passed as argument.
|
||||
* @param {String} url The url or uri string to evaluate
|
||||
* @returns If the argument is a valid url, this method returns
|
||||
* a new instance of java.net.URL, otherwise it returns null.
|
||||
* @type java.net.URL
|
||||
*/
|
||||
helma.Http.evalUrl = function(url) {
|
||||
try {
|
||||
return new java.net.URL(url);
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the global http proxy setting. If no proxy definition
|
||||
* is passed to this method, any existing proxy setting is
|
||||
* cleared. Internally this method sets the system properties
|
||||
* <code>http.proxySet</code>, <code>http.proxyHost</code> and
|
||||
* <code>http.proxyPort</code>. Keep in mind that this is valid for
|
||||
* the whole Java Virtual Machine, therefor using this method
|
||||
* can potentially influence other running Helma applications too!
|
||||
* @param {String} proxyString A proxy definition in <code>host:port</code>
|
||||
* format (eg. "proxy.example.com:3128");
|
||||
* @member helma.Http
|
||||
*/
|
||||
helma.Http.setProxy = function(proxyString) {
|
||||
var sys = java.lang.System.getProperties();
|
||||
if (proxyString) {
|
||||
var idx = proxyString.indexOf(":");
|
||||
var host = proxyString.substring(0, idx);
|
||||
var port = proxyString.substring(idx+1);
|
||||
if (!port)
|
||||
port = "3128";
|
||||
else if (typeof port == "number")
|
||||
port = port.toString();
|
||||
app.logger.info("helma.Http.setProxy " + proxyString);
|
||||
sys.put("http.proxySet", "true");
|
||||
sys.put("http.proxyHost", host);
|
||||
sys.put("http.proxyPort", port);
|
||||
} else {
|
||||
sys.put("http.proxySet", "false");
|
||||
sys.put("http.proxyHost", "");
|
||||
sys.put("http.prodyPort", "");
|
||||
}
|
||||
return;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the proxy setting of the Java Virtual Machine
|
||||
* the Helma application server is running in. If no
|
||||
* proxy is set, this method returns boolean false.
|
||||
* @returns The global proxy setting in <code>host:port</code>
|
||||
* format (eg. "proxy.example.com:3128"), or boolean false.
|
||||
* @type String|Boolean
|
||||
* @member helma.Http
|
||||
*/
|
||||
helma.Http.getProxy = function() {
|
||||
var sys = java.lang.System.getProperties();
|
||||
if (sys.get("http.proxySet") == "true")
|
||||
return sys.get("http.proxyHost") + ":" + sys.get("http.proxyPort");
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static helper method to check if a request issued agains a
|
||||
* Helma application is authorized or not.
|
||||
* @param {String} name The username to check req.username against
|
||||
* @param {String} pwd The password to check req.password against
|
||||
* @return True if the request is authorized, false otherwise. In
|
||||
* the latter case the current response is reset and the response code
|
||||
* is set to "401" ("Authentication required").
|
||||
* @type Boolean
|
||||
*/
|
||||
helma.Http.isAuthorized = function(name, pwd) {
|
||||
if (!req.username || !req.password ||
|
||||
req.username != name || req.password != pwd) {
|
||||
res.reset();
|
||||
res.status = 401;
|
||||
res.realm = "Helma Http Authorization";
|
||||
res.write("Authorization required.");
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
helma.Http.toString = function() {
|
||||
return "[helma.Http]";
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new instance of helma.Http.Cookie
|
||||
* @class Instances of this object represent a HTTP cookie
|
||||
* @param {String} name The name of the cookie
|
||||
* @param {String} value The value of the cookie
|
||||
* @returns A newly created Cookie instance
|
||||
* @constructor
|
||||
*/
|
||||
helma.Http.Cookie = function(name, value) {
|
||||
/**
|
||||
* The name of the Cookie
|
||||
* @type String
|
||||
*/
|
||||
this.name = name;
|
||||
|
||||
/**
|
||||
* The value of the Cookie
|
||||
* @type String
|
||||
*/
|
||||
this.value = value;
|
||||
|
||||
/**
|
||||
* An optional date defining the lifetime of this cookie
|
||||
* @type Date
|
||||
*/
|
||||
this.expires = null;
|
||||
|
||||
/**
|
||||
* An optional path where this cookie is valid
|
||||
* @type String
|
||||
*/
|
||||
this.path = null;
|
||||
|
||||
/**
|
||||
* An optional domain where this cookie is valid
|
||||
* @type String
|
||||
*/
|
||||
this.domain = null;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* An instance of java.text.SimpleDateFormat used for both parsing
|
||||
* an "expires" string into a date and vice versa
|
||||
* @type java.text.SimpleDateFormat
|
||||
* @final
|
||||
*/
|
||||
helma.Http.Cookie.DATEFORMAT = new java.text.SimpleDateFormat("EEE, dd-MMM-yy HH:mm:ss z");
|
||||
|
||||
|
||||
/**
|
||||
* A regular expression used for parsing cookie strings
|
||||
* @type RegExp
|
||||
* @final
|
||||
*/
|
||||
helma.Http.Cookie.PATTERN = /([^=;]+)=?([^;]*)(?:;\s*|$)/g;
|
||||
|
||||
|
||||
/**
|
||||
* Parses the cookie string passed as argument into an instance of helma.Http
|
||||
* @param {String} cookieStr The cookie string as received from the remote server
|
||||
* @returns An instance of helma.Http.Cookie containing the cookie parameters
|
||||
* @type helma.Http.Cookie
|
||||
*/
|
||||
helma.Http.Cookie.parse = function(cookieStr) {
|
||||
if (cookieStr != null) {
|
||||
var cookie = new helma.Http.Cookie;
|
||||
var m = helma.Http.Cookie.PATTERN.exec(cookieStr);
|
||||
if (m) {
|
||||
cookie.name = m[1].trim();
|
||||
cookie.value = m[2] ? m[2].trim() : "";
|
||||
}
|
||||
while ((m = helma.Http.Cookie.PATTERN.exec(cookieStr)) != null) {
|
||||
var key = m[1].trim();
|
||||
var value = m[2] ? m[2].trim() : "";
|
||||
switch (key.toLowerCase()) {
|
||||
case "expires":
|
||||
// try to parse the expires date string into a date object
|
||||
try {
|
||||
cookie.expires = helma.Http.Cookie.DATEFORMAT.parse(value);
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cookie[key.toLowerCase()] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cookie;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns this cookie in a format useable to set the HTTP header field "Cookie"
|
||||
* @return This cookie formatted as HTTP header field value
|
||||
* @type String
|
||||
*/
|
||||
helma.Http.Cookie.prototype.getFieldValue = function() {
|
||||
return this.name + "=" + this.value;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
helma.Http.Cookie.prototype.toString = function() {
|
||||
return "[helma.Http.Cookie " + this.name + " " + this.value + "]";
|
||||
};
|
||||
|
||||
helma.lib = "Http";
|
||||
helma.dontEnum(helma.lib);
|
||||
for (var i in helma[helma.lib])
|
||||
helma[helma.lib].dontEnum(i);
|
||||
for (var i in helma[helma.lib].prototype)
|
||||
helma[helma.lib].prototype.dontEnum(i);
|
||||
for (var i in helma[helma.lib].Cookie.prototype)
|
||||
helma[helma.lib].Cookie.prototype.dontEnum(i);
|
||||
delete helma.lib;
|
|
@ -1,150 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Image.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Methods of the helma.Image module.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/helma/Image.js')
|
||||
*/
|
||||
|
||||
if (!global.helma) {
|
||||
global.helma = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Image object, generated from the specified source.
|
||||
* <br /><br />
|
||||
* If the JIMI package is installed, an instance of
|
||||
* helma.image.jimi.JimiGenerator will be returned. Otherwise,
|
||||
* if the javax.imageio package is available, an instance of
|
||||
* helma.image.imageio.ImageIOGenerator is returned.
|
||||
* Additionally, the class of the ImageGenerator implementation
|
||||
* to be used can be set using the <code>imageGenerator</code>
|
||||
* property in either the app.properties or server.properties
|
||||
* file.
|
||||
*
|
||||
*
|
||||
* @param {helma.File|java.io.File|String} arg image source, filename or url
|
||||
* @return a new Image object
|
||||
* @singleton
|
||||
* @see Packages.helma.image.ImageGenerator
|
||||
* @see Packages.helma.image.jimi.JimiGenerator
|
||||
* @see Packages.helma.image.imageio.ImageIOGenerator
|
||||
*/
|
||||
helma.Image = function(arg) {
|
||||
// according to
|
||||
// http://grazia.helma.org/pipermail/helma-dev/2004-June/001253.html
|
||||
var generator = Packages.helma.image.ImageGenerator.getInstance();
|
||||
return generator.createImage(arg);
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
helma.Image.toString = function() {
|
||||
return "[helma.Image]";
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns an ImageInfo object for the specified image file.
|
||||
*
|
||||
* @param {helma.File|java.io.File|String} arg image source, filename or url
|
||||
* @returns an ImageInfo object
|
||||
* @memberof helma.Image
|
||||
* @see Packages.helma.image.ImageInfo
|
||||
*/
|
||||
helma.Image.getInfo = function(arg) {
|
||||
if (arguments.length != 1) {
|
||||
throw new java.lang.IllegalArgumentException(
|
||||
"Image.getInfo() expects one argument"
|
||||
);
|
||||
}
|
||||
|
||||
var inp, result;
|
||||
var info = new Packages.helma.image.ImageInfo();
|
||||
// FIXME: we need a byte array for class comparison
|
||||
var b = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 0);
|
||||
|
||||
try {
|
||||
if (arg instanceof java.io.InputStream) {
|
||||
inp = new java.io.InputStream(arg);
|
||||
// FIXME: here comes a dirty hack to check for a byte array
|
||||
} else if (arg.getClass && arg.getClass() == b.getClass()) {
|
||||
inp = new java.io.ByteArrayInputStream(arg);
|
||||
} else if (arg instanceof java.io.File) {
|
||||
inp = new java.io.FileInputStream(arg);
|
||||
} else if (arg instanceof helma.File) {
|
||||
inp = new java.io.FileInputStream(arg.getFile());
|
||||
} else if (typeof arg == "string") {
|
||||
var str = arg;
|
||||
// try to interpret argument as URL if it contains a colon,
|
||||
// otherwise or if URL is malformed interpret as file name.
|
||||
if (str.indexOf(":") > -1) {
|
||||
try {
|
||||
var url = new java.net.URL(str);
|
||||
inp = url.openStream();
|
||||
} catch (mux) {
|
||||
inp = new java.io.FileInputStream(str);
|
||||
}
|
||||
} else {
|
||||
inp = new java.io.FileInputStream(str);
|
||||
}
|
||||
}
|
||||
if (inp == null) {
|
||||
var msg = "Unrecognized argument in Image.getInfo(): ";
|
||||
msg += (arg == null ? "null" : arg.getClass().toString());
|
||||
throw new java.lang.IllegalArgumentException(msg);
|
||||
}
|
||||
info.setInput(inp);
|
||||
if (info.check()) {
|
||||
result = info;
|
||||
}
|
||||
} catch (e) {
|
||||
// do nothing, returns null later
|
||||
} finally {
|
||||
if (inp != null) {
|
||||
try {
|
||||
inp.close();
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes a 1x1 pixel transparent spacer GIF image to the
|
||||
* response buffer and sets the content type to image/gif.
|
||||
*
|
||||
* @memberof helma.Image
|
||||
*/
|
||||
helma.Image.spacer = function() {
|
||||
res.contentType = "image/gif";
|
||||
res.writeBinary([71,73,70,56,57,97,2,0,2,0,-128,-1,0,-64,-64,-64,0,0,0,33,-7,4,1,0,0,0,0,44,0,0,0,0,1,0,1,0,64,2,2,68,1,0,59]);
|
||||
return;
|
||||
};
|
||||
|
||||
helma.lib = "Image";
|
||||
helma.dontEnum(helma.lib);
|
||||
for (var i in helma[helma.lib])
|
||||
helma[helma.lib].dontEnum(i);
|
||||
for (var i in helma[helma.lib].prototype)
|
||||
helma[helma.lib].prototype.dontEnum(i);
|
||||
delete helma.lib;
|
||||
|
||||
|
||||
|
|
@ -1,705 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2007 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Mail.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the helma.Mail class.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/helma/Mail.js')
|
||||
*/
|
||||
|
||||
// take care of any dependencies
|
||||
app.addRepository('modules/helma/File.js');
|
||||
|
||||
/**
|
||||
* Define the global namespace if not existing
|
||||
*/
|
||||
if (!global.helma) {
|
||||
global.helma = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Mail client enabling you to send e-mail via SMTP using Packages.javax.mail.
|
||||
* <br /><br />
|
||||
* @class This class provides functionality to sending
|
||||
* Email messages.
|
||||
* A mail client object is created by using the helma.Mail()
|
||||
* constructor. The mail object then can be manipulated and sent
|
||||
* using the methods listed below.
|
||||
* <br /><br />
|
||||
* You will either need to set your mail server via the smtp
|
||||
* property in the app.properties or server.properties file
|
||||
* or pass the hostname of the mail server you want to use as a
|
||||
* parameter to the constructor.
|
||||
* <br /><br />
|
||||
* Note: Make sure that the SMTP server itself is well-configured,
|
||||
* so that it accepts e-mails coming from your server and does
|
||||
* not deny relaying. Best and fastest configuration is of course
|
||||
* if you run your own SMTP server (e.g. postfix) which might be
|
||||
* a bit tricky to set up, however.</p>
|
||||
*
|
||||
* @param {String} smtp as String, the hostname of the mail server
|
||||
* @constructor
|
||||
*/
|
||||
helma.Mail = function(host, port) {
|
||||
// Error code values for this.status
|
||||
var OK = 0;
|
||||
var SUBJECT = 10;
|
||||
var TEXT = 11;
|
||||
var MIMEPART = 12;
|
||||
var TO = 20;
|
||||
var CC = 21;
|
||||
var BCC = 22;
|
||||
var FROM = 23;
|
||||
var REPLYTO = 24;
|
||||
var SETHEADER = 25;
|
||||
var ADDHEADER = 26;
|
||||
var GETHEADER = 27;
|
||||
var REMOVEHEADER = 28;
|
||||
var SEND = 30;
|
||||
var MAILPKG = Packages.javax.mail;
|
||||
|
||||
var self = this;
|
||||
var errStr = "Error in helma.Mail";
|
||||
|
||||
var System = java.lang.System;
|
||||
var Properties = java.util.Properties;
|
||||
var IOException = java.io.IOException;
|
||||
var Wrapper = Packages.org.mozilla.javascript.Wrapper;
|
||||
var FileDataSource = Packages.javax.activation.FileDataSource;
|
||||
var DataHandler = Packages.javax.activation.DataHandler;
|
||||
|
||||
var MimePart = Packages.helma.util.MimePart;
|
||||
var MimePartDataSource = Packages.helma.util.MimePartDataSource;
|
||||
|
||||
var BodyPart = MAILPKG.BodyPart;
|
||||
var Message = MAILPKG.Message;
|
||||
var Session = MAILPKG.Session;
|
||||
var InternetAddress = MAILPKG.internet.InternetAddress;
|
||||
var AddressException = MAILPKG.internet.AddressException;
|
||||
var MimeBodyPart = MAILPKG.internet.MimeBodyPart;
|
||||
var MimeMessage = MAILPKG.internet.MimeMessage;
|
||||
var MimeUtility = MAILPKG.internet.MimeUtility;
|
||||
var MimeMultipart = MAILPKG.internet.MimeMultipart;
|
||||
|
||||
var buffer, multipart, multipartType = "mixed";
|
||||
var username, password;
|
||||
|
||||
var setStatus = function(status) {
|
||||
if (self.status === OK) {
|
||||
self.status = status;
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
var getStatus = function() {
|
||||
return self.status;
|
||||
};
|
||||
|
||||
var addRecipient = function(addstr, name, type) {
|
||||
if (addstr.indexOf("@") < 0) {
|
||||
throw new AddressException();
|
||||
}
|
||||
if (name != null) {
|
||||
var address = new InternetAddress(addstr,
|
||||
MimeUtility.encodeWord(name.toString()));
|
||||
} else {
|
||||
var address = new InternetAddress(addstr);
|
||||
}
|
||||
message.addRecipient(type, address);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds the content stored in this helma.Mail instance
|
||||
* to the wrapped message.
|
||||
* @private
|
||||
*/
|
||||
var setContent = function() {
|
||||
if (buffer != null) {
|
||||
if (multipart != null) {
|
||||
var part = new MimeBodyPart();
|
||||
part.setContent(buffer.toString(), "text/plain");
|
||||
multipart.addBodyPart(part, 0);
|
||||
message.setContent(multipart);
|
||||
} else {
|
||||
message.setText(buffer.toString());
|
||||
}
|
||||
} else if (multipart != null) {
|
||||
message.setContent(multipart);
|
||||
} else {
|
||||
message.setText("");
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the text buffer of this mail message
|
||||
* @returns The text buffer of this mail message
|
||||
* @type java.lang.StringBuffer
|
||||
* @private
|
||||
*/
|
||||
this.getBuffer = function() {
|
||||
return buffer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the mime multipart object of this mail message
|
||||
* @returns The mime multipart object of this mail message
|
||||
* @type javax.mail.internet.MimeMultipart
|
||||
* @private
|
||||
*/
|
||||
this.getMultipart = function() {
|
||||
return multipart;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets username and password to use for SMTP authentication.
|
||||
* @param {String} uname The username to use
|
||||
* @param {String} pwd The password to use
|
||||
*/
|
||||
this.setAuthentication = function(uname, pwd) {
|
||||
if (uname && pwd) {
|
||||
username = uname;
|
||||
password = pwd;
|
||||
// enable smtp authentication
|
||||
props.put("mail.smtp.auth", "true");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the wrapped message
|
||||
* @returns The wrapped message
|
||||
* @type javax.mail.internet.MimeMessage
|
||||
*/
|
||||
this.getMessage = function() {
|
||||
return message;
|
||||
};
|
||||
|
||||
/**
|
||||
* Switches debug mode on or off.
|
||||
* @param {Boolean} debug If true debug mode is enabled
|
||||
*/
|
||||
this.setDebug = function(debug) {
|
||||
session.setDebug(debug === true);
|
||||
};
|
||||
|
||||
/**
|
||||
* The status of this Mail object. This equals <code>0</code> unless
|
||||
* an error occurred. See {@link helma.Mail Mail.js} source code for a list of
|
||||
* possible error codes.
|
||||
*/
|
||||
this.status = OK;
|
||||
|
||||
/**
|
||||
* Sets the sender of an e-mail message.
|
||||
* <br /><br />
|
||||
* The first argument specifies the receipient's
|
||||
* e-mail address. The optional second argument
|
||||
* specifies the name of the recipient.
|
||||
*
|
||||
* @param {String} addstr as String, sender email address
|
||||
* @param {String} name as String, optional sender name
|
||||
*/
|
||||
this.setFrom = function(addstr, name) {
|
||||
try {
|
||||
if (addstr.indexOf("@") < 0) {
|
||||
throw new AddressException();
|
||||
}
|
||||
if (name != null) {
|
||||
var address = new InternetAddress(addstr,
|
||||
MimeUtility.encodeWord(name.toString()));
|
||||
} else {
|
||||
var address = new InternetAddress(addstr);
|
||||
}
|
||||
message.setFrom(address);
|
||||
} catch (mx) {
|
||||
app.logger.error(errStr + ".setFrom(): " + mx);
|
||||
setStatus(FROM);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set a header in the e-mail message. If the given header is already set the previous
|
||||
* value is replaced with the new one.
|
||||
* @param name a header name
|
||||
* @param value the header value
|
||||
*/
|
||||
this.setHeader = function(name, value) {
|
||||
try {
|
||||
message.addHeader(name, MimeUtility.encodeText(value));
|
||||
} catch (mx) {
|
||||
app.logger.error(errStr + ".setHeader(): " + mx);
|
||||
setStatus(SETHEADER);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a header in the e-mail message. If the given header is already set the previous
|
||||
* value is replaced with the new one.
|
||||
* @param name a header name
|
||||
* @param value the header value
|
||||
*/
|
||||
this.addHeader = function(name, value) {
|
||||
try {
|
||||
message.addHeader(name, MimeUtility.encodeText(value));
|
||||
} catch (mx) {
|
||||
app.logger.error(errStr + ".addHeader(): " + mx);
|
||||
setStatus(ADDHEADER);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the headers for this header name.
|
||||
* Returns null if no headers for this header name are available.
|
||||
* @param name a header name
|
||||
* @return {String[]} a string array of header values, or null
|
||||
*/
|
||||
this.getHeader = function(name) {
|
||||
var value = null;
|
||||
try {
|
||||
value = message.getHeader(name);
|
||||
if (value && value.length) {
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
value[i] = MimeUtility.decodeText(value[i]);
|
||||
}
|
||||
}
|
||||
} catch (mx) {
|
||||
app.logger.error(errStr + ".getHeader(): " + mx);
|
||||
setStatus(GETHEADER);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all headers with this name.
|
||||
* @param name the header name
|
||||
*/
|
||||
this.removeHeader = function(name) {
|
||||
try {
|
||||
message.removeHeader(name);
|
||||
} catch (mx) {
|
||||
app.logger.error(errStr + ".removeHeader(): " + mx);
|
||||
setStatus(REMOVEHEADER);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Reply-To address of an e-mail message.
|
||||
*
|
||||
* @param {String} addstr as String, the reply-to email address
|
||||
*/
|
||||
this.setReplyTo = function(addstr) {
|
||||
try {
|
||||
if (addstr.indexOf("@") < 0) {
|
||||
throw new AddressException();
|
||||
}
|
||||
var address = [new InternetAddress(addstr)];
|
||||
message.setReplyTo(address);
|
||||
} catch (mx) {
|
||||
app.logger.error(errStr + ".setReplyTo(): " + mx);
|
||||
setStatus(REPLYTO);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the recipient of an e-mail message.
|
||||
*
|
||||
* The first argument specifies the receipient's
|
||||
* e-mail address. The optional second argument
|
||||
* specifies the name of the recipient.
|
||||
*
|
||||
* @param {String} addstr as String, receipients email address
|
||||
* @param {String} name as String, optional receipients name
|
||||
* @see #addTo
|
||||
*/
|
||||
this.setTo = function(addstr, name) {
|
||||
try {
|
||||
addRecipient(addstr, name, Message.RecipientType.TO);
|
||||
} catch (mx) {
|
||||
app.logger.error(errStr + ".setTo(): " + mx);
|
||||
setStatus(TO);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a recipient to the address list of an e-mail message.
|
||||
* <br /><br />
|
||||
* The first argument specifies the receipient's
|
||||
* e-mail address. The optional second argument
|
||||
* specifies the name of the recipient.
|
||||
*
|
||||
* @param {String} addstr as String, receipients email address
|
||||
* @param {String} name as String, optional receipients name
|
||||
* @see setTo
|
||||
*/
|
||||
this.addTo = function(addstr, name) {
|
||||
try {
|
||||
addRecipient(addstr, name, Message.RecipientType.TO);
|
||||
} catch (mx) {
|
||||
app.logger.error(errStr + ".addTo(): " + mx);
|
||||
setStatus(TO);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a recipient to the list of addresses to get a "carbon copy"
|
||||
* of an e-mail message.
|
||||
* <br /><br />
|
||||
* The first argument specifies the receipient's
|
||||
* e-mail address. The optional second argument
|
||||
* specifies the name of the recipient.
|
||||
*
|
||||
* @param {String} addstr as String, receipients email address
|
||||
* @param {String} name as String, optional receipients name
|
||||
*/
|
||||
this.addCC = function(addstr, name) {
|
||||
try {
|
||||
addRecipient(addstr, name, Message.RecipientType.CC);
|
||||
} catch (mx) {
|
||||
app.logger.error(errStr + ".addCC(): " + mx);
|
||||
setStatus(CC);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a recipient to the list of addresses to get a "blind carbon copy" of an e-mail message.
|
||||
* <br /><br />
|
||||
* The first argument specifies the receipient's
|
||||
* e-mail address. The optional second argument
|
||||
* specifies the name of the recipient.
|
||||
*
|
||||
* @param {String} addstr as String, receipients email address
|
||||
* @param {String} name as String, optional receipients name
|
||||
*/
|
||||
this.addBCC = function(addstr, name) {
|
||||
try {
|
||||
addRecipient(addstr, name, Message.RecipientType.BCC);
|
||||
} catch (mx) {
|
||||
app.logger.error(errStr + ".addBCC(): " + mx);
|
||||
setStatus(BCC);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the subject of an e-mail message.
|
||||
*
|
||||
* @param {String} subject as String, the email subject
|
||||
*/
|
||||
this.setSubject = function(subject) {
|
||||
if (!subject) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
message.setSubject(MimeUtility.encodeWord(subject.toString()));
|
||||
} catch (mx) {
|
||||
app.logger.error(errStr + ".setSubject(): " + mx);
|
||||
setStatus(SUBJECT);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the body text of an e-mail message.
|
||||
*
|
||||
* @param {String} text as String, to be appended to the message body
|
||||
* @see #addText
|
||||
*/
|
||||
this.setText = function(text) {
|
||||
if (text) {
|
||||
buffer = new java.lang.StringBuffer(text);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Appends a string to the body text of an e-mail message.
|
||||
*
|
||||
* @param {String} text as String, to be appended to the message body
|
||||
* @see #setText
|
||||
*/
|
||||
this.addText = function(text) {
|
||||
if (buffer == null) {
|
||||
buffer = new java.lang.StringBuffer(text);
|
||||
} else {
|
||||
buffer.append(text);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the MIME multiparte message subtype. The default value is
|
||||
* "mixed" for messages of type multipart/mixed. A common value
|
||||
* is "alternative" for the multipart/alternative MIME type.
|
||||
* @param {String} messageType the MIME subtype such as "mixed" or "alternative".
|
||||
* @see #getMultipartType
|
||||
* @see #addPart
|
||||
*/
|
||||
this.setMultipartType = function(messageType) {
|
||||
multipartType = messageType;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the MIME multiparte message subtype. The default value is
|
||||
* "mixed" for messages of type multipart/mixed.
|
||||
* @return the MIME subtype
|
||||
* @type String
|
||||
* @see #setMultipartType
|
||||
* @see #addPart
|
||||
*/
|
||||
this.getMultipartType = function(messageType) {
|
||||
return multipartType;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds an attachment to an e-mail message.
|
||||
* <br /><br />
|
||||
* The attachment needs to be either a helma.util.MimePart Object retrieved
|
||||
* through the global getURL function, or a {@link helma.File} object, or a String.
|
||||
* <br /><br />
|
||||
* Use the getURL() function to retrieve a MIME object or wrap a
|
||||
* helma.File object around a file of the local file system.
|
||||
*
|
||||
* @param {fileOrMimeObjectOrString} obj File, Mime object or String to attach to the email
|
||||
* @param {String} filename optional name of the attachment
|
||||
* @param {String} contentType optional content type (only if first argument is a string)
|
||||
* @see global.getURL
|
||||
* @see helma.util.MimePart
|
||||
* @see helma.File
|
||||
*/
|
||||
this.addPart = function(obj, filename, contentType) {
|
||||
try {
|
||||
if (obj == null) {
|
||||
throw new IOException(
|
||||
errStr + ".addPart: method called with wrong number of arguments."
|
||||
);
|
||||
}
|
||||
if (multipart == null) {
|
||||
multipart = new MimeMultipart(multipartType);
|
||||
}
|
||||
if (obj instanceof Wrapper) {
|
||||
obj = obj.unwrap();
|
||||
}
|
||||
|
||||
var part;
|
||||
if (obj instanceof BodyPart) {
|
||||
// we already got a body part, no need to convert it
|
||||
part = obj;
|
||||
} else {
|
||||
part = new MimeBodyPart();
|
||||
if (typeof obj == "string") {
|
||||
part.setContent(obj.toString(), contentType || "text/plain");
|
||||
} else if (obj instanceof File || obj instanceof helma.File) {
|
||||
var source = new FileDataSource(obj.getPath());
|
||||
part.setDataHandler(new DataHandler(source));
|
||||
} else if (obj instanceof MimePart) {
|
||||
var source = new MimePartDataSource(obj);
|
||||
part.setDataHandler(new DataHandler(source));
|
||||
}
|
||||
}
|
||||
if (filename != null) {
|
||||
try {
|
||||
part.setFileName(filename.toString());
|
||||
} catch (x) {}
|
||||
} else if (obj instanceof File || obj instanceof helma.File) {
|
||||
try {
|
||||
part.setFileName(obj.getName());
|
||||
} catch (x) {}
|
||||
}
|
||||
multipart.addBodyPart(part);
|
||||
} catch (mx) {
|
||||
app.logger.error(errStr + ".addPart(): " + mx);
|
||||
setStatus(MIMEPART);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Saves this mail RFC 822 formatted into a file. The name of the
|
||||
* file is prefixed with "helma.Mail" followed by the current time
|
||||
* in milliseconds and a random number.
|
||||
* @param {helma.File} dir An optional directory where to save
|
||||
* this mail to. If omitted the mail will be saved in the system's
|
||||
* temp directory.
|
||||
*/
|
||||
this.writeToFile = function(dir) {
|
||||
if (!dir || !dir.exists() || !dir.canWrite()) {
|
||||
dir = new java.io.File(System.getProperty("java.io.tmpdir"));
|
||||
}
|
||||
var fileName = "helma.Mail." + (new Date()).getTime() +
|
||||
"." + Math.round(Math.random() * 1000000);
|
||||
var file = new java.io.File(dir, fileName);
|
||||
if (file.exists()) {
|
||||
file["delete"]();
|
||||
}
|
||||
try {
|
||||
setContent();
|
||||
var fos = new java.io.FileOutputStream(file);
|
||||
var os = new java.io.BufferedOutputStream(fos);
|
||||
message.writeTo(os);
|
||||
os.close();
|
||||
app.logger.info("helma.Mail.saveTo(): saved mail to " +
|
||||
file.getAbsolutePath());
|
||||
} catch (e) {
|
||||
app.logger.error(errStr + ".saveTo(): " + e);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the source of this mail as RFC 822 formatted string.
|
||||
* @returns The source of this mail as RFC 822 formatted string
|
||||
* @type String
|
||||
*/
|
||||
this.getSource = function() {
|
||||
try {
|
||||
setContent();
|
||||
var buf = new java.io.ByteArrayOutputStream();
|
||||
var os = new java.io.BufferedOutputStream(buf);
|
||||
message.writeTo(os);
|
||||
os.close();
|
||||
return buf.toString();
|
||||
} catch (e) {
|
||||
app.logger.error(errStr + ".getSource(): " + e);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends an e-mail message.
|
||||
* <br /><br />
|
||||
* This function sends the message using the SMTP
|
||||
* server as specified when the Mail object was
|
||||
* constructed using helma.Mail.
|
||||
* <br /><br />
|
||||
* If no smtp hostname was specified when the Mail
|
||||
* object was constructed, the smtp property in either
|
||||
* the app.properties or server.properties file needs
|
||||
* to be set in order for this to work.
|
||||
* <br /><br />
|
||||
* As a fallback, the message will then be written to
|
||||
* file using the {@link #writeToFile} method.
|
||||
* Additionally, the location of the message files can
|
||||
* be determined by setting smtp.dir in app.properties
|
||||
* to the desired file path.
|
||||
*/
|
||||
this.send = function() {
|
||||
if (this.status > OK) {
|
||||
app.logger.error(errStr + ".send(): Status is " + this.status);
|
||||
return;
|
||||
}
|
||||
if (host != null) {
|
||||
try {
|
||||
setContent();
|
||||
message.setSentDate(new Date());
|
||||
var transport = session.getTransport("smtp");
|
||||
if (username && password) {
|
||||
transport.connect(host, username, password);
|
||||
} else {
|
||||
transport.connect();
|
||||
}
|
||||
message.saveChanges();
|
||||
transport.sendMessage(message, message.getAllRecipients());
|
||||
} catch (mx) {
|
||||
app.logger.error(errStr + ".send(): " + mx);
|
||||
setStatus(SEND);
|
||||
} finally {
|
||||
if (transport != null && transport.isConnected()) {
|
||||
transport.close();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// no smtp host is given, so write the mail to a file
|
||||
this.writeToFile(getProperty("smtp.dir"));
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Main constructor body
|
||||
*/
|
||||
var props = new Properties();
|
||||
if (host || (host = getProperty("smtp"))) {
|
||||
props.put("mail.transport.protocol", "smtp");
|
||||
props.put("mail.smtp.host", String(host));
|
||||
props.put("mail.smtp.port", String(port || 25));
|
||||
props.put("mail.smtp.starttls.enable",
|
||||
getProperty("smtp.tls") || "false");
|
||||
props.put("mail.mime.charset",
|
||||
getProperty("smtp.charset") ||
|
||||
System.getProperty("mail.charset") ||
|
||||
"ISO-8859-15");
|
||||
}
|
||||
|
||||
this.setAuthentication(getProperty("smtp.username"),
|
||||
getProperty("smtp.password"));
|
||||
var session = Session.getInstance(props);
|
||||
var message = new MimeMessage(session);
|
||||
|
||||
for (var i in this)
|
||||
this.dontEnum(i);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/** @ignore */
|
||||
helma.Mail.toString = function() {
|
||||
return "[helma.Mail]";
|
||||
};
|
||||
|
||||
|
||||
/** @ignore */
|
||||
helma.Mail.prototype.toString = function() {
|
||||
return "[helma.Mail Object]";
|
||||
};
|
||||
|
||||
helma.Mail.example = function(host, sender, addr, subject, text) {
|
||||
// var smtp = "smtp.host.dom";
|
||||
// var sender = "sender@host.dom";
|
||||
// var addr = "recipient@host.dom";
|
||||
// var subject = "Hello, World!";
|
||||
// var text = "This is a test.";
|
||||
var port = 25;
|
||||
var msg = new helma.Mail(host, port);
|
||||
msg.setFrom(sender);
|
||||
msg.addTo(addr);
|
||||
msg.setSubject(subject);
|
||||
msg.setText(text);
|
||||
msg.send();
|
||||
res.write(msg.status);
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
helma.lib = "Mail";
|
||||
helma.dontEnum(helma.lib);
|
||||
for (var i in helma[helma.lib])
|
||||
helma[helma.lib].dontEnum(i);
|
||||
for (var i in helma[helma.lib].prototype)
|
||||
helma[helma.lib].prototype.dontEnum(i);
|
||||
delete helma.lib;
|
File diff suppressed because it is too large
Load diff
|
@ -1,124 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Skin.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the helma.Skin class.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/helma/Skin.js')
|
||||
*/
|
||||
|
||||
|
||||
// define the helma namespace, if not existing
|
||||
if (!global.helma) {
|
||||
global.helma = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of helma.Skin
|
||||
* @class Instances of this class represent a Helma skin. In addition
|
||||
* to the standard skin functionality this class allows creation of
|
||||
* a skin based on a Base64 encoded source.
|
||||
* @param {String} source The source of the skin
|
||||
* @param {Boolean} encFlag If true the source will be Base64-decoded.
|
||||
* @constructor
|
||||
* @returns A newly created instance of helma.Skin
|
||||
*/
|
||||
helma.Skin = function(source, encFlag) {
|
||||
/** @ignore */
|
||||
var Base64 = Packages.helma.util.Base64;
|
||||
|
||||
if (!encFlag) {
|
||||
var skin = createSkin(source);
|
||||
} else {
|
||||
var encoded = source;
|
||||
source = new java.lang.String(source);
|
||||
var bytes = Base64.decode(source.toCharArray());
|
||||
var skin = createSkin(new java.lang.String(bytes, "UTF-8"));
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
this.toString = function() {
|
||||
return source;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the source of the skin as Base64 encoded string
|
||||
* @returns The source of the skin as Base64 encoded string
|
||||
* @type String
|
||||
*/
|
||||
this.valueOf = function() {
|
||||
if (encFlag) {
|
||||
return encoded;
|
||||
}
|
||||
var bytes = new java.lang.String(source).getBytes("UTF-8");
|
||||
return new java.lang.String(Base64.encode(bytes));
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the skin.
|
||||
* @param {Object} param An optional parameter object to pass to the skin.
|
||||
*/
|
||||
this.render = function(param) {
|
||||
return renderSkin(skin, param);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the rendered skin.
|
||||
* @param {Object} param An optional parameter object to pass to the skin.
|
||||
* @type String
|
||||
*/
|
||||
this.renderAsString = function(param) {
|
||||
return renderSkinAsString(skin, param);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the skin contains a macro with the name
|
||||
* and optional handler passed as argument.
|
||||
* @param {String} name The name of the macro
|
||||
* @param {String} handler An optional macro handler name
|
||||
* @returns True if the skin contains this macro at least once,
|
||||
* false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.containsMacro = function(name, handler) {
|
||||
res.push();
|
||||
res.write("<% *");
|
||||
if (handler) {
|
||||
res.write(handler);
|
||||
res.write(".");
|
||||
}
|
||||
res.write(name);
|
||||
res.write(" *%>");
|
||||
var re = new RegExp(res.pop(), "g");
|
||||
return re.test(source);
|
||||
};
|
||||
|
||||
for (var i in this)
|
||||
this.dontEnum(i);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
helma.lib = "Skin";
|
||||
helma.dontEnum(helma.lib);
|
||||
for (var i in helma[helma.lib])
|
||||
helma[helma.lib].dontEnum(i);
|
||||
for (var i in helma[helma.lib].prototype)
|
||||
helma[helma.lib].prototype.dontEnum(i);
|
||||
delete helma.lib;
|
|
@ -1,375 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Ssh.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the helma.Ssh class.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/helma/Ssh.js')
|
||||
*/
|
||||
|
||||
// take care of any dependencies
|
||||
app.addRepository('modules/helma/File.js');
|
||||
app.addRepository('modules/helma/ganymed-ssh2-build208.jar');
|
||||
|
||||
// define the helma namespace, if not existing
|
||||
if (!global.helma) {
|
||||
global.helma = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of helma.Ssh
|
||||
* @class This class provides methods for connecting to a remote
|
||||
* server via secure shell (ssh) and copying files from/to a remote
|
||||
* server using secure copy (scp). It utilizes "Ganymed SSH-2 for Java"
|
||||
* (see <a href="http://www.ganymed.ethz.ch/ssh2/">http://www.ganymed.ethz.ch/ssh2/</a>).
|
||||
* @param {String} server The server to connect to
|
||||
* @param {helma.File|java.io.File|String} hosts Either a file
|
||||
* containing a list of known hosts, or the path pointing to a
|
||||
* file. This argument is optional.
|
||||
* @constructor
|
||||
* @returns A newly created instance of helma.Ssh
|
||||
* @author Robert Gaggl <robert@nomatic.org>
|
||||
*/
|
||||
helma.Ssh = function(server, hosts) {
|
||||
var SSHPKG = Packages.ch.ethz.ssh2;
|
||||
var SSHPKGNAME = "ganymed-ssh2.jar";
|
||||
var SSHPKGURL = "http://www.ganymed.ethz.ch/ssh2";
|
||||
var className = "helma.Ssh";
|
||||
var paranoid = false;
|
||||
var verifier = null;
|
||||
var knownHosts, connection;
|
||||
|
||||
// check if necessary jar file is in classpath
|
||||
try {
|
||||
knownHosts = new SSHPKG.KnownHosts();
|
||||
connection = new SSHPKG.Connection(server);
|
||||
} catch (e) {
|
||||
if (e instanceof TypeError == false)
|
||||
throw(e);
|
||||
throw("helma.Ssh needs " + SSHPKGNAME +
|
||||
" in lib/ext or application directory " +
|
||||
"[" + SSHPKGURL + "]");
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple verifier for verifying host keys
|
||||
* @private
|
||||
*/
|
||||
var SimpleVerifier = {
|
||||
verifyServerHostKey: function(hostname, port, serverHostKeyAlgorithm, serverHostKey) {
|
||||
var result = knownHosts.verifyHostkey(hostname, serverHostKeyAlgorithm, serverHostKey);
|
||||
switch (result) {
|
||||
case SSHPKG.KnownHosts.HOSTKEY_IS_OK:
|
||||
debug("verifyServerHostKey", "received known host key, proceeding");
|
||||
return true;
|
||||
case SSHPKG.KnownHosts.HOSTKEY_IS_NEW:
|
||||
if (paranoid == true) {
|
||||
debug("verifyServerHostKey", "received unknown host key, rejecting");
|
||||
return false;
|
||||
} else {
|
||||
debug("verifyServerHostKey", "received new host key, adding temporarily to known hosts");
|
||||
var hn = java.lang.reflect.Array.newInstance(java.lang.String, 1);
|
||||
hn[0] = hostname;
|
||||
knownHosts.addHostkey(hn, serverHostKeyAlgorithm, serverHostKey);
|
||||
return true;
|
||||
}
|
||||
case SSHPKG.KnownHosts.HOSTKEY_HAS_CHANGED:
|
||||
debug("verifyServerHostKey", "WARNING: host key has changed, rejecting");
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts the argument into an instance of java.io.File
|
||||
* @param {helma.File|java.io.File|String} file Either a file
|
||||
* object or the path to a file as string
|
||||
* @returns The argument converted into a file object
|
||||
* @type java.io.File
|
||||
* @private
|
||||
*/
|
||||
var getFile = function(file) {
|
||||
if (file instanceof helma.File) {
|
||||
return new java.io.File(file.getAbsolutePath());
|
||||
} else if (file instanceof java.io.File) {
|
||||
return file;
|
||||
} else if (file.constructor == String) {
|
||||
return new java.io.File(file);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Connects to the remote server
|
||||
* @return Boolean
|
||||
* @private
|
||||
*/
|
||||
var connect = function() {
|
||||
try {
|
||||
var info = connection.connect(verifier);
|
||||
debug("connect", "connected to server " + server);
|
||||
return true;
|
||||
} catch (e) {
|
||||
error("connect", "connection to " + server + " failed.");
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Private helper method for debugging output using app.logger
|
||||
* @param {String} methodName The name of the method
|
||||
* @param {String} msg The debug message to write to event log file
|
||||
* @private
|
||||
*/
|
||||
var debug = function(methodName, msg) {
|
||||
var msg = msg ? " " + msg : "";
|
||||
app.logger.debug(className + ":" + methodName + msg);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Private helper method for error output using app.logger
|
||||
* @param {String} methodName The name of the method
|
||||
* @param {String} msg The error message to write to event log file
|
||||
* @private
|
||||
*/
|
||||
var error = function(methodName, msg) {
|
||||
var tx = java.lang.Thread.currentThread();
|
||||
tx.dumpStack();
|
||||
app.logger.error(className + ":" + methodName + ": " + msg);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Opens the file passed as argument and adds the known hosts
|
||||
* therein to the list of known hosts for this client.
|
||||
* @param {helma.File|java.io.File|String} file Either a file object
|
||||
* or the path to a file containing a list of known hosts
|
||||
* @returns True if adding the list was successful, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
this.addKnownHosts = function(file) {
|
||||
try {
|
||||
knownHosts.addHostkeys(getFile(file));
|
||||
verifier = new SSHPKG.ServerHostKeyVerifier(SimpleVerifier);
|
||||
return true;
|
||||
} catch (e) {
|
||||
error("addKnownHosts", "Missing or invalid known hosts file '" + file + "'");
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Connects to a remote host using plain username/password authentication.
|
||||
* @param {String} username The username
|
||||
* @param {String} password The password
|
||||
* @returns True in case the connection attempt was successful, false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.connect = function(username, password) {
|
||||
if (!username || !password) {
|
||||
error("connect", "Insufficient arguments.");
|
||||
} else if (connect() && connection.authenticateWithPassword(username, password)) {
|
||||
debug("connect", "authenticated using password");
|
||||
return true;
|
||||
} else {
|
||||
error("connect", "Authentication failed!");
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Connects to a remote host using a private key and the corresponding
|
||||
* passphrase.
|
||||
* @param {String} username The username
|
||||
* @param {helma.File|java.io.File|String} key Either a file object
|
||||
* representing the private key file, or the path to it.
|
||||
* @param {String} passphrase The passphrase of the private key, if necessary.
|
||||
* @returns True in case the connection attempt was successful, false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.connectWithKey = function(username, key, passphrase) {
|
||||
var keyFile;
|
||||
if (!username || !(keyFile = getFile(key))) {
|
||||
error("connectWithKey", "Insufficient or wrong arguments.");
|
||||
} else if (connect() && connection.authenticateWithPublicKey(username, keyFile, passphrase)) {
|
||||
debug("connectWithKey", "authenticated with key");
|
||||
return true;
|
||||
} else {
|
||||
error("connectWithKey", "Authentication failed!");
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Disconnects this client from the remote server.
|
||||
*/
|
||||
this.disconnect = function() {
|
||||
connection.close();
|
||||
debug("disconnect", "disconnected from server " + server);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if this client is currently connected.
|
||||
* @returns True in case this client is connected, false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.isConnected = function() {
|
||||
return (connection != null && connection.isAuthenticationComplete());
|
||||
};
|
||||
|
||||
/**
|
||||
* Copies a local file to the remote server
|
||||
* @param {String|Array} localFile Either the path to a single local
|
||||
* file or an array containing multiple file paths that should be
|
||||
* copied to the remote server.
|
||||
* @param {String} remoteDir The path to the remote destination directory
|
||||
* @param {String} mode An optional 4-digit permission mode string (eg.
|
||||
* <code>0755</code>);
|
||||
* @returns True in case the operation was successful, false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.put = function(localFile, remoteDir, mode) {
|
||||
if (!localFile || !remoteDir) {
|
||||
error("put", "Insufficient arguments.");
|
||||
} else if (!this.isConnected()) {
|
||||
error("put", "Not connected. Please establish a connection first.");
|
||||
} else {
|
||||
try {
|
||||
var scp = connection.createSCPClient();
|
||||
if (mode != null)
|
||||
scp.put(localFile, remoteDir, mode);
|
||||
else
|
||||
scp.put(localFile, remoteDir);
|
||||
debug("put", "copied '" + localFile + "' to '" + remoteDir + "'");
|
||||
return true;
|
||||
} catch (e) {
|
||||
error("put", e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves a file from the remote server and stores it locally.
|
||||
* @param {String|Array} remoteFile Either the path to a single remote
|
||||
* file or an array containing multiple file paths that should be
|
||||
* copied onto the local disk.
|
||||
* @param {String} targetDir The path to the local destination directory
|
||||
* @returns True if the copy process was successful, false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.get = function(remoteFile, targetDir) {
|
||||
if (!remoteFile || !targetDir) {
|
||||
error("get", "Insufficient arguments.");
|
||||
} else if (!this.isConnected()) {
|
||||
error("get", "Not connected. Please establish a connection first.");
|
||||
} else {
|
||||
try {
|
||||
var scp = connection.createSCPClient();
|
||||
scp.get(remoteFile, targetDir);
|
||||
debug("get", "copied '" + remoteFile + "' to '" + targetDir + "'");
|
||||
return true;
|
||||
} catch (e) {
|
||||
error("get", e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes a single command on the remote server.
|
||||
* @param {String} cmd The command to execute on the remote server.
|
||||
* @return The result of the command execution
|
||||
* @type String
|
||||
*/
|
||||
this.execCommand = function(cmd) {
|
||||
if (!this.isConnected()) {
|
||||
error("execCommand", "Not connected. Please establish a connection first.");
|
||||
} else {
|
||||
var session = connection.openSession();
|
||||
try {
|
||||
session.execCommand(cmd);
|
||||
var stdout = new SSHPKG.StreamGobbler(session.getStdout());
|
||||
var br = new java.io.BufferedReader(new java.io.InputStreamReader(stdout));
|
||||
res.push();
|
||||
while (true) {
|
||||
if (!(line = br.readLine()))
|
||||
break;
|
||||
res.writeln(line);
|
||||
}
|
||||
debug("execCommand", "executed command '" + cmd + "'");
|
||||
return res.pop();
|
||||
} catch (e) {
|
||||
error("execCommand", e);
|
||||
} finally {
|
||||
session.close();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggles paranoid mode. If set to true this client tries to
|
||||
* verify the host key against the its list of known hosts
|
||||
* during connection and rejects if the host key is not found
|
||||
* therein or is different.
|
||||
* @param {Boolean} p Either true or false
|
||||
*/
|
||||
this.setParanoid = function(p) {
|
||||
paranoid = (p === true);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if this client is in paranoid mode.
|
||||
* @return Boolean
|
||||
* @see #setParanoid
|
||||
*/
|
||||
this.isParanoid = function() {
|
||||
return paranoid;
|
||||
};
|
||||
|
||||
/**
|
||||
* main constructor body
|
||||
*/
|
||||
if (hosts) {
|
||||
this.addKnownHosts(hosts);
|
||||
}
|
||||
|
||||
for (var i in this)
|
||||
this.dontEnum(i);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/** @ignore */
|
||||
helma.Ssh.toString = function() {
|
||||
return "[helma.Ssh]";
|
||||
};
|
||||
|
||||
|
||||
helma.lib = "Ssh";
|
||||
helma.dontEnum(helma.lib);
|
||||
for (var i in helma[helma.lib])
|
||||
helma[helma.lib].dontEnum(i);
|
||||
for (var i in helma[helma.lib].prototype)
|
||||
helma[helma.lib].prototype.dontEnum(i);
|
||||
delete helma.lib;
|
|
@ -1,126 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2007 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Url.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the helma.Url class.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/helma/Url.js')
|
||||
*/
|
||||
|
||||
if (!global.helma) {
|
||||
global.helma = {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a helma.Url object from a provided url string.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
helma.Url = function(str) {
|
||||
if (!str || !helma.Url.PATTERN.test(str))
|
||||
throw Error("Cannot create helma.Url: insufficient arguments");
|
||||
|
||||
// filter punctuation from user-generated urls
|
||||
// FIXME: a) can this be done in helma.Url.PATTERN?
|
||||
// b) should it be done rather in methods like activateUrls?
|
||||
str = str.replace(/[,.;:]\s/, "");
|
||||
|
||||
var parts = helma.Url.PATTERN.exec(str);
|
||||
/**
|
||||
* Protocol segment of this URL
|
||||
*/
|
||||
this.protocol = parts[1];
|
||||
|
||||
if (!parts[2]) {
|
||||
if (parts[3])
|
||||
/**
|
||||
* User name segment of this URL
|
||||
*/
|
||||
this.user = parts[3];
|
||||
} else {
|
||||
this.user = parts[2];
|
||||
if (parts[3])
|
||||
/**
|
||||
* Password segment of this URL
|
||||
*/
|
||||
this.password = parts[3];
|
||||
}
|
||||
|
||||
if (!parts[4])
|
||||
throw Error("Cannot create helma.Url: missing host part");
|
||||
|
||||
/**
|
||||
* Fully qualified domain name segment of this URL
|
||||
*/
|
||||
this.domainName = parts[4]; // actually, the fully-qualified domain name
|
||||
var fqdnParts = this.domainName.split(".");
|
||||
if (fqdnParts.length < 3)
|
||||
this.host = "";
|
||||
else {
|
||||
/**
|
||||
* Host name segment of this URL
|
||||
*/
|
||||
this.host = fqdnParts[0];
|
||||
fqdnParts.splice(0, 1);
|
||||
}
|
||||
/**
|
||||
* Top level domain name segment of this URL
|
||||
*/
|
||||
this.topLevelDomain = fqdnParts[fqdnParts.length-1];
|
||||
/**
|
||||
* Domain name segment of this URL
|
||||
*/
|
||||
this.domain = fqdnParts.join(".");
|
||||
|
||||
/**
|
||||
* Request path segment of this URL as string
|
||||
*/
|
||||
this.pathString = parts[5] || "";
|
||||
if (this.pathString.indexOf("/") == 0)
|
||||
this.pathString = this.pathString.substring(1);
|
||||
/**
|
||||
* Request path segment of this URL as array
|
||||
*/
|
||||
this.path = this.pathString.split("/");
|
||||
/**
|
||||
* File name segment of this URL
|
||||
*/
|
||||
this.file = this.path.pop();
|
||||
|
||||
if (parts[6]) {
|
||||
/**
|
||||
* Query parameter segment of this URL as string
|
||||
*/
|
||||
this.queryString = parts[6];
|
||||
var pairs;
|
||||
/**
|
||||
* Query parameter segment of this URL as object
|
||||
*/
|
||||
this.query = {};
|
||||
parts = parts[6].split("&");
|
||||
for (var i in parts) {
|
||||
pairs = parts[i].split("=");
|
||||
this.query[pairs[0]] = pairs[1];
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
helma.Url.PATTERN = /^([^:]*):\/\/+(?:([^\/]*):)?(?:([^\/]*)@)?([\w\-_.]*[^.])(\/[^?]*)?(?:\?(.*))?$/;
|
|
@ -1,523 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Zip.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the helma.Zip class.
|
||||
* <br /><br />
|
||||
* To use this optional module, its repository needs to be added to the
|
||||
* application, for example by calling app.addRepository('modules/helma/Zip.js')
|
||||
*/
|
||||
|
||||
// take care of any dependencies
|
||||
app.addRepository('modules/helma/File.js');
|
||||
|
||||
// define the helma namespace, if not existing
|
||||
if (!global.helma) {
|
||||
global.helma = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new helma.Zip instance
|
||||
* @class Instances of this class represent a single zip archive
|
||||
* and provide various methods for extracting entries or manipulating
|
||||
* the contents of the archive.
|
||||
* @param {helma.File|java.io.File|String} file Either
|
||||
* a file object representing the .zip file on disk, or the
|
||||
* path to the .zip file as string.
|
||||
* @constructor
|
||||
* @returns A newly created instance of helma.Zip.
|
||||
* @author Robert Gaggl <robert@nomatic.org>
|
||||
*/
|
||||
helma.Zip = function(file) {
|
||||
|
||||
/**
|
||||
* Private method that extracts the data of a single file
|
||||
* in a .zip archive. If a destination path is given it
|
||||
* writes the extracted data directly to disk using the
|
||||
* name of the ZipEntry Object, otherwise it returns the
|
||||
* byte array containing the extracted data.
|
||||
* @param {java.util.zip.ZipFile} zFile The zip archive to extract
|
||||
* the file from.
|
||||
* @param {java.util.zip.ZipEntry} entry The zip entry to extract
|
||||
* @param {String} destPath The destination path where the extracted
|
||||
* file should be stored.
|
||||
* @returns If no destination path is given, this method returns
|
||||
* the contents of the extracted file as ByteArray, otherwise
|
||||
* it returns null.
|
||||
* @private
|
||||
*/
|
||||
var extractEntry = function(zFile, entry, destPath) {
|
||||
var size = entry.getSize();
|
||||
if (entry.isDirectory() || size <= 0)
|
||||
return null;
|
||||
|
||||
var zInStream = new java.io.BufferedInputStream(zFile.getInputStream(entry));
|
||||
var buf = new java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, size);
|
||||
zInStream.read(buf, 0, size);
|
||||
zInStream.close();
|
||||
|
||||
if (!destPath) {
|
||||
// no filesystem destination given, so return
|
||||
// the byte array containing the extracted data
|
||||
return buf;
|
||||
}
|
||||
// extract the file to the given path
|
||||
var dest = new java.io.File(destPath, entry.getName());
|
||||
if (entry.isDirectory())
|
||||
dest.mkdirs();
|
||||
else if (buf) {
|
||||
if (!dest.getParentFile().exists())
|
||||
dest.getParentFile().mkdirs();
|
||||
try {
|
||||
var outStream = new java.io.BufferedOutputStream(new java.io.FileOutputStream(dest));
|
||||
outStream.write(buf, 0, size);
|
||||
} finally {
|
||||
if (outStream) outStream.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Private method for adding a single file to the Zip archive
|
||||
* represented by this helma.Zip instance
|
||||
* @param {java.util.zip.ZipOutputStream} zOutStream The output
|
||||
* stream to write to
|
||||
* @param {java.io.File} f The file that should be added to the
|
||||
* Zip archive.
|
||||
* @param {Number} level The compression-level between 0-9.
|
||||
* @param {String} pathPrefix The path of the directory within the
|
||||
* Zip archive where the file should be added (optional).
|
||||
* @private
|
||||
*/
|
||||
var addFile = function(zOutStream, f, level, pathPrefix) {
|
||||
var fInStream = new java.io.BufferedInputStream(new java.io.FileInputStream(f));
|
||||
buf = new java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, f.length());
|
||||
fInStream.read(buf, 0, f.length());
|
||||
|
||||
var name = new java.lang.StringBuffer();
|
||||
if (pathPrefix) {
|
||||
// append clean pathPrefix to name buffer
|
||||
var st = new java.util.StringTokenizer(pathPrefix, "\\/");
|
||||
while (st.hasMoreTokens()) {
|
||||
name.append(st.nextToken());
|
||||
name.append("/");
|
||||
}
|
||||
}
|
||||
name.append(f.getName());
|
||||
var entry = new java.util.zip.ZipEntry(name.toString());
|
||||
entry.setSize(f.length());
|
||||
entry.setTime(f.lastModified());
|
||||
zOutStream.setLevel(level);
|
||||
zOutStream.putNextEntry(entry);
|
||||
zOutStream.write(buf, 0, buf.length);
|
||||
zOutStream.closeEntry();
|
||||
fInStream.close();
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Private helper method that converts the argument into
|
||||
* an instance of java.io.File.
|
||||
* @param {helma.File|java.io.File} f Either a file object or
|
||||
* the path to a file as string
|
||||
* @return The argument converted into a file object
|
||||
* @type java.io.File
|
||||
* @private
|
||||
*/
|
||||
var evalFile = function(f) {
|
||||
var result;
|
||||
if (f instanceof java.io.File) {
|
||||
result = f;
|
||||
} else if (f instanceof helma.File || typeof(f) == "string") {
|
||||
result = new java.io.File(f);
|
||||
}
|
||||
if (!result.exists()) {
|
||||
throw "Error creating Zip Object: File '" + f + "' doesn't exist.";
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an array containing the entries of the archive
|
||||
* represented by this helma.Zip instance.
|
||||
* @returns The entries stored in the zip archive
|
||||
* @type helma.Zip.Content
|
||||
*/
|
||||
this.list = function() {
|
||||
var result = new helma.Zip.Content();
|
||||
var zFile = new java.util.zip.ZipFile(file);
|
||||
var entries = zFile.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
result.add(new helma.Zip.Entry(entries.nextElement()));
|
||||
}
|
||||
zFile.close();
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Extracts a single file from the zip archive represented
|
||||
* by this helma.Zip instance. If a destination path is given it
|
||||
* writes the extracted data directly to disk using the
|
||||
* name of the zip entry, otherwise the resulting entry object
|
||||
* contains the extracted data in the property <code>data</code>.
|
||||
* @param {String} name The name of the file to extract
|
||||
* @param {String} destPath An optional destination path where
|
||||
* the extracted file should be stored.
|
||||
* @returns An object containing the entry's properties
|
||||
* @type helma.Zip.Entry
|
||||
* @see helma.Zip.Entry
|
||||
*/
|
||||
this.extract = function(name, destPath) {
|
||||
var zFile = new java.util.zip.ZipFile(file);
|
||||
var entry = zFile.getEntry(name);
|
||||
if (!entry)
|
||||
return null;
|
||||
var result = new helma.Zip.Entry(entry);
|
||||
result.data = extractEntry(zFile, entry, destPath);
|
||||
zFile.close();
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Extracts all files within the zip archive represented by
|
||||
* this helma.Zip instance. If a destination path is given it
|
||||
* stores the files directly on disk, while preserving any directory
|
||||
* structure within the archive. If no destination path is given,
|
||||
* the resulting entry objects will contain the extracted data
|
||||
* in their property <code>data</code>.
|
||||
* @param {String} destPath An optional destination path where the
|
||||
* files in the zip archive should be stored.
|
||||
* @returns An object containing the extracted entries.
|
||||
* @type helma.Zip.Content
|
||||
* @see helma.Zip.Entry
|
||||
*/
|
||||
this.extractAll = function(destPath) {
|
||||
var result = new helma.Zip.Content();
|
||||
var zFile = new java.util.zip.ZipFile(file);
|
||||
var entries = zFile.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
var entry = entries.nextElement();
|
||||
var e = new helma.Zip.Entry(entry);
|
||||
e.data = extractEntry(zFile, entry, destPath);
|
||||
result.add(e);
|
||||
}
|
||||
zFile.close();
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a single file or a whole directory (recursive!) to the zip archive
|
||||
* @param {helma.File|java.io.File|String} f Either a file object
|
||||
* or the path to a file or directory on disk that should be added to the
|
||||
* archive. If the argument represents a directory, its contents will be added
|
||||
* <em>recursively</em> to the archive.
|
||||
* @param {Number} level An optional compression level to use. The argument
|
||||
* must be between zero and 9 (default: 9 = best compression).
|
||||
* @param {String} pathPrefix An optional path prefix to use within the archive.
|
||||
*/
|
||||
this.add = function (f, level, pathPrefix) {
|
||||
var f = evalFile(f);
|
||||
|
||||
// evaluate arguments
|
||||
if (arguments.length == 2) {
|
||||
if (typeof arguments[1] == "string") {
|
||||
pathPrefix = arguments[1];
|
||||
level = 9;
|
||||
} else {
|
||||
level = parseInt(arguments[1], 10);
|
||||
pathPrefix = null;
|
||||
}
|
||||
} else if (level == null || isNaN(level)) {
|
||||
level = 9;
|
||||
}
|
||||
// only levels between 0 and 9 are allowed
|
||||
level = Math.max(0, Math.min(9, level));
|
||||
|
||||
if (f.isDirectory()) {
|
||||
// add a whole directory to the zip file (recursive!)
|
||||
var files = (new helma.File(f.getAbsolutePath())).listRecursive();
|
||||
for (var i in files) {
|
||||
var fAdd = new java.io.File(files[i]);
|
||||
if (!fAdd.isDirectory()) {
|
||||
var p = fAdd.getPath().substring(f.getAbsolutePath().length, fAdd.getParent().length);
|
||||
if (pathPrefix)
|
||||
p = pathPrefix + p;
|
||||
addFile(zOutStream, fAdd, level, p);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addFile(zOutStream, f, level, pathPrefix);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a new entry to the zip file.
|
||||
* @param {ByteArray} buf A byte array containing the data to add
|
||||
* to the archive.
|
||||
* @param {String} name The name of the file to add, containing
|
||||
* an optional path prefix
|
||||
* @param {Number} level The compression level to use (0-9, defaults to 9).
|
||||
*/
|
||||
this.addData = function(buf, name, level) {
|
||||
var entry = new java.util.zip.ZipEntry(name);
|
||||
entry.setSize(buf.length);
|
||||
entry.setTime(new Date());
|
||||
if (level == null || isNaN(level)) {
|
||||
zOutStream.setLevel(9);
|
||||
} else {
|
||||
zOutStream.setLevel(Math.max(0, Math.min(9, parseInt(level, 10))));
|
||||
}
|
||||
zOutStream.putNextEntry(entry);
|
||||
zOutStream.write(buf, 0, buf.length);
|
||||
zOutStream.closeEntry();
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes the zip archive. This method should be called when
|
||||
* all operations have been finished, to ensure that no open
|
||||
* file handles are left.
|
||||
*/
|
||||
this.close = function() {
|
||||
zOutStream.close();
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the binary data of the zip archive.
|
||||
* @returns A ByteArray containing the binary data of the zip archive
|
||||
* @type ByteArray
|
||||
*/
|
||||
this.getData = function() {
|
||||
zOutStream.close();
|
||||
fOutStream.close();
|
||||
var inputStream = new java.io.FileInputStream(tempFile);
|
||||
var bOutStream = new java.io.ByteArrayOutputStream();
|
||||
var buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 8192);
|
||||
try {
|
||||
var chunk;
|
||||
while ((chunk = inputStream.read(buffer)) !== -1) {
|
||||
bOutStream.write(buffer, 0, chunk);
|
||||
}
|
||||
bOutStream.flush();
|
||||
} catch (ex) {
|
||||
app.log(ex);
|
||||
} finally {
|
||||
if (inputStream) inputStream.close();
|
||||
if (bOutStream) bOutStream.close();
|
||||
}
|
||||
return bOutStream.toByteArray();
|
||||
};
|
||||
|
||||
/**
|
||||
* Saves the archive.
|
||||
* @param {String} dest The full destination path including the name
|
||||
* where the zip archive should be saved.
|
||||
*/
|
||||
this.save = function(dest) {
|
||||
if (!dest)
|
||||
throw new Error("no destination for ZipFile given");
|
||||
// first of all, close the ZipOutputStream
|
||||
zOutStream.close();
|
||||
fOutStream.close();
|
||||
var destFile = new java.io.File(dest);
|
||||
try {
|
||||
if (destFile.exists()) destFile['delete']();
|
||||
java.nio.file.Files.move(tempFile.toPath(), destFile.toPath());
|
||||
} catch (ex) {
|
||||
app.log(ex);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
this.toString = function() {
|
||||
if (file) {
|
||||
return "[helma.Zip " + file.getAbsolutePath() + "]";
|
||||
} else {
|
||||
return "[helma.Zip]";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* constructor body
|
||||
*/
|
||||
var tempFile = new java.io.File.createTempFile('zip-', '');
|
||||
var fOutStream = new java.io.FileOutputStream(tempFile);
|
||||
var zOutStream = new java.util.zip.ZipOutputStream(fOutStream);
|
||||
|
||||
if (file) {
|
||||
file = evalFile(file);
|
||||
}
|
||||
|
||||
for (var i in this)
|
||||
this.dontEnum(i);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new helma.Zip.Content instance
|
||||
* @class Instances of this class represent the content
|
||||
* of a zip archive.
|
||||
* @constructor
|
||||
* @returns A newly created instance of helma.Zip.Content
|
||||
*/
|
||||
helma.Zip.Content = function() {
|
||||
/**
|
||||
* The table of contents of the archive
|
||||
* @type Array
|
||||
*/
|
||||
this.toc = [];
|
||||
|
||||
/**
|
||||
* The files contained in the zip archive, where
|
||||
* each directory level is a separate object containing
|
||||
* the entries (files and directories) as properties.
|
||||
*/
|
||||
this.files = {};
|
||||
|
||||
/**
|
||||
* Adds a zip entry object to the table of contents
|
||||
* and the files collection
|
||||
* @param {helma.Zip.Entry} entry The entry to add to the
|
||||
* zip archive
|
||||
*/
|
||||
this.add = function(entry) {
|
||||
// add the file to the table of contents array
|
||||
this.toc[this.toc.length] = entry;
|
||||
// plus add it to the files tree
|
||||
var arr = entry.name.split(/[\\\/]/);
|
||||
var cnt = 0;
|
||||
var curr = this.files;
|
||||
var propName;
|
||||
while (cnt < arr.length-1) {
|
||||
propName = arr[cnt++];
|
||||
if (!curr[propName]) {
|
||||
curr[propName] = {};
|
||||
}
|
||||
curr = curr[propName];
|
||||
}
|
||||
curr[arr[cnt]] = entry;
|
||||
return;
|
||||
};
|
||||
|
||||
for (var i in this)
|
||||
this.dontEnum(i);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/** @ignore */
|
||||
helma.Zip.Content.prototype.toString = function() {
|
||||
return "[helma.Zip.Content]";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance of helma.Zip.Entry
|
||||
* @class Instances of this class represent a single zip archive entry,
|
||||
* containing the (meta)data of the entry.
|
||||
* @param {java.util.zip.ZipEntry} entry The zip entry object whose metadata
|
||||
* should be stored in this instance
|
||||
* @constructor
|
||||
* @returns A newly created helma.Zip.Entry instance.
|
||||
*/
|
||||
helma.Zip.Entry = function(entry) {
|
||||
/**
|
||||
* The name of the zip archive entry
|
||||
* @type String
|
||||
*/
|
||||
this.name = entry.getName();
|
||||
|
||||
/**
|
||||
* The size of the entry in bytes
|
||||
* @type Number
|
||||
*/
|
||||
this.size = entry.getSize();
|
||||
|
||||
/**
|
||||
* The file date of the entry
|
||||
* @type Date
|
||||
*/
|
||||
this.time = entry.getTime() ? new Date(entry.getTime()) : null;
|
||||
|
||||
/**
|
||||
* True if the entry is a directory, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
this.isDirectory = entry.isDirectory();
|
||||
|
||||
/**
|
||||
* The data of the zip entry
|
||||
* @type ByteArray
|
||||
*/
|
||||
this.data = null;
|
||||
|
||||
for (var i in this)
|
||||
this.dontEnum(i);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/** @ignore */
|
||||
helma.Zip.Entry.prototype.toString = function() {
|
||||
return "[helma.Zip.Entry]";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extracts all files in the zip archive data passed as argument
|
||||
* and returns them.
|
||||
* @param {ByteArray} zipData A ByteArray containing the data of the zip archive
|
||||
* @returns The entries of the zip archive
|
||||
* @type helma.Zip.Content
|
||||
*/
|
||||
helma.Zip.extractData = function(zipData) {
|
||||
var zInStream = new java.util.zip.ZipInputStream(new java.io.ByteArrayInputStream(zipData));
|
||||
var result = new helma.Zip.Content();
|
||||
|
||||
var entry;
|
||||
while ((entry = zInStream.getNextEntry()) != null) {
|
||||
var eParam = new helma.Zip.Entry(entry);
|
||||
if (eParam.isDirectory)
|
||||
continue;
|
||||
if (eParam.size == -1)
|
||||
eParam.size = 16384;
|
||||
var bos = new java.io.ByteArrayOutputStream(eParam.size);
|
||||
var buf = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 8192);
|
||||
var count;
|
||||
while ((count = zInStream.read(buf)) != -1)
|
||||
bos.write(buf, 0, count);
|
||||
eParam.data = bos.toByteArray();
|
||||
eParam.size = bos.size();
|
||||
result.add(eParam);
|
||||
}
|
||||
zInStream.close();
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
helma.lib = "Zip";
|
||||
helma.dontEnum(helma.lib);
|
||||
for (var i in helma[helma.lib])
|
||||
helma[helma.lib].dontEnum(i);
|
||||
for (var i in helma[helma.lib].prototype)
|
||||
helma[helma.lib].prototype.dontEnum(i);
|
||||
delete helma.lib;
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Helma License Notice
|
||||
*
|
||||
* The contents of this file are subject to the Helma License
|
||||
* Version 2.0 (the "License"). You may not use this file except in
|
||||
* compliance with the License. A copy of the License is available at
|
||||
* http://adele.helma.org/download/helma/license.txt
|
||||
*
|
||||
* Copyright 1998-2006 Helma Software. All Rights Reserved.
|
||||
*
|
||||
* $RCSfile: Aspects.js,v $
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// convenience SingleFileRepository to load all the
|
||||
// Javascript library files in ./modules/helma
|
||||
|
||||
/** @namespace helma */
|
||||
|
||||
app.addRepository('modules/helma/Aspects.js');
|
||||
app.addRepository('modules/helma/Chart.js');
|
||||
app.addRepository('modules/helma/Color.js');
|
||||
app.addRepository('modules/helma/Database.js');
|
||||
app.addRepository('modules/helma/File.js');
|
||||
app.addRepository('modules/helma/Ftp.js');
|
||||
app.addRepository('modules/helma/Html.js');
|
||||
app.addRepository('modules/helma/Http.js');
|
||||
app.addRepository('modules/helma/Image.js');
|
||||
app.addRepository('modules/helma/Mail.js');
|
||||
app.addRepository('modules/helma/Search.js');
|
||||
app.addRepository('modules/helma/Skin.js');
|
||||
app.addRepository('modules/helma/Ssh.js');
|
||||
app.addRepository('modules/helma/Url.js');
|
||||
app.addRepository('modules/helma/Zip.js');
|
|
@ -1,18 +0,0 @@
|
|||
dependencies {
|
||||
runtimeOnly 'ch.ethz.ganymed:ganymed-ssh2:build209'
|
||||
runtimeOnly 'net.sourceforge.jexcelapi:jxl:2.5.7'
|
||||
runtimeOnly 'org.apache.lucene:lucene-analyzers:2.2.0'
|
||||
runtimeOnly 'org.apache.lucene:lucene-core:2.2.0'
|
||||
}
|
||||
|
||||
jar.enabled = false
|
||||
compileJava.enabled = false
|
||||
compileTestJava.enabled = false
|
||||
processResources.enabled = false
|
||||
processTestResources.enabled = false
|
||||
test.enabled = false
|
||||
|
||||
tasks.register('deps', Copy) {
|
||||
from sourceSets.main.runtimeClasspath
|
||||
into '.'
|
||||
}
|
Binary file not shown.
Binary file not shown.
|
@ -1,86 +0,0 @@
|
|||
Copyright (c) 2006 - 2011 Christian Plattner. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
a.) Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
b.) 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.
|
||||
c.) Neither the name of Christian Plattner nor the names of its 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.
|
||||
|
||||
|
||||
This software includes work that was released under the following license:
|
||||
|
||||
Copyright (c) 2005 - 2006 Swiss Federal Institute of Technology (ETH Zurich),
|
||||
Department of Computer Science (http://www.inf.ethz.ch),
|
||||
Christian Plattner. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
a.) Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
b.) 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.
|
||||
c.) Neither the name of ETH Zurich nor the names of its 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.
|
||||
|
||||
|
||||
The Java implementations of the AES, Blowfish and 3DES ciphers have been
|
||||
taken (and slightly modified) from the cryptography package released by
|
||||
"The Legion Of The Bouncy Castle".
|
||||
|
||||
Their license states the following:
|
||||
|
||||
Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
|
||||
(http://www.bouncycastle.org)
|
||||
|
||||
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, sublicense, 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 NONINFRINGEMENT. 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.
|
|
@ -1,125 +0,0 @@
|
|||
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 Lesser 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.
|
||||
|
||||
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.
|
||||
|
||||
one line to give the program's name and an idea of what it does.
|
||||
Copyright (C) yyyy name of author
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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) year 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.
|
||||
|
||||
signature of Ty Coon, 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 Lesser General Public License instead of this License.
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -1,202 +0,0 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
Binary file not shown.
Binary file not shown.
|
@ -1,35 +0,0 @@
|
|||
# About Jala
|
||||
|
||||
Jala is an open-source collection of JavaScript modules for Helma Object Publisher. Copyright 2004 ORF Online und Teletext GmbH, Vienna (Austria). You can find more information about each module in the API Documentation located in the `docs` directory.
|
||||
|
||||
## Licensing
|
||||
|
||||
Jala itself is licensed under the Apache 2.0 License, but parts of Jala require third party libraries coming with different licenses. You can find all necessary information in the `licenses` directory.
|
||||
|
||||
## Installation
|
||||
|
||||
Move the Jala folder into the `modules` directory of your Helma installation. To include a certain Jala module simply add the following line to your Helma application's source code (replace `[name]` with the desired module name):
|
||||
|
||||
app.addRepository("./modules/jala/code/[name].js");
|
||||
|
||||
If you want to include the whole Jala package at once, you can use the `all` module for convenience:
|
||||
|
||||
app.addRepository("./modules/jala/code/all.js");
|
||||
|
||||
Alternatively, you can import the Jala module from within Helma's
|
||||
`apps.properties` file (replace `[appName]` with the name of your Helma application, `[n]` with a number between 0 and 9 and `[moduleName]` with the desired module
|
||||
name):
|
||||
|
||||
[appName].respository.[n] = ./modules/jala/code/[moduleName].js
|
||||
|
||||
More information about the `addRepository()` method and generally including repositories in a Helma application is available at
|
||||
http://helma.org/stories/77712/.
|
||||
|
||||
## Contact, Bugs and Feedback
|
||||
|
||||
The Jala Project is hosted at https://dev.orf.at/jala/ providing all necessary information about Subversion access, Ticketing, Releases etc.
|
||||
|
||||
Although we encourage you to post your questions and comments as ticket, we also provide a mailing list for convenience (details at
|
||||
https://dev.orf.at/trac/jala/wiki/MailingList).
|
||||
|
||||
For immediate contact you can reach the developers via jaladev AT gmail.com.
|
|
@ -1,21 +0,0 @@
|
|||
dependencies {
|
||||
runtimeOnly 'dom4j:dom4j:1.1.3'
|
||||
runtimeOnly 'jaxen:jaxen:1.1-beta-8'
|
||||
runtimeOnly 'net.sf.javamusictag:jid3lib:0.5.4'
|
||||
|
||||
// FIXME: Did not find these two or appropriate replacements for them
|
||||
//runtime 'id3:de.ueberdosis.mp3info:1.6.0d9'
|
||||
//runtime 'javadns:org.wonderly:?'
|
||||
}
|
||||
|
||||
jar.enabled = false
|
||||
compileJava.enabled = false
|
||||
compileTestJava.enabled = false
|
||||
processResources.enabled = false
|
||||
processTestResources.enabled = false
|
||||
test.enabled = false
|
||||
|
||||
tasks.register('deps', Copy) {
|
||||
from sourceSets.main.runtimeClasspath
|
||||
into 'lib'
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
## build properties for jsdoc api documentation
|
||||
## all paths *must* be relative to the directory where
|
||||
## this file is located
|
||||
|
||||
docs.source = ./code
|
||||
docs.destination = ./docs
|
||||
docs.projectName = Jala 1.3
|
|
@ -1 +0,0 @@
|
|||
Jala is a <a href="http://helma.org">Helma</a>-based library and utility project initially developed to ease the work at <a href="http://orf.at">ORF.at</a>'s software development department.
|
|
@ -1,175 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the jala.AsyncRequest class.
|
||||
*/
|
||||
|
||||
|
||||
// Define the global namespace for Jala modules
|
||||
if (!global.jala) {
|
||||
global.jala = {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new AsyncRequest instance.
|
||||
* @class This class is used to create requests of type "INTERNAL"
|
||||
* (like cron-jobs) that are processed in a separate thread and
|
||||
* therefor asynchronous.
|
||||
* @param {Object} obj Object in whose context the method should be called
|
||||
* @param {String} funcName Name of the function to call
|
||||
* @param {Array} args Array containing the arguments that should be passed
|
||||
* to the function (optional). This option is <em>deprecated</em>, instead
|
||||
* pass the arguments directly to the {@link #run} method.
|
||||
* @constructor
|
||||
* @returns A new instance of AsyncRequest
|
||||
* @type AsyncRequest
|
||||
* @deprecated Use the {@link http://helma.zumbrunn.net/reference/core/app.html#invokeAsync
|
||||
* app.invokeAsync} method instead (built-in into Helma as
|
||||
* of version 1.6)
|
||||
*/
|
||||
jala.AsyncRequest = function(obj, funcName, args) {
|
||||
app.logger.warn("Use of jala.AsyncRequest is deprecated in this version.");
|
||||
app.logger.warn("This module will probably be removed in a " +
|
||||
"future version of Jala.");
|
||||
|
||||
/**
|
||||
* Contains a reference to the thread started by this AsyncRequest
|
||||
* @type java.lang.Thread
|
||||
* @private
|
||||
*/
|
||||
var thread;
|
||||
|
||||
/**
|
||||
* Contains the timeout defined for this AsyncRequest (in milliseconds)
|
||||
* @type Number
|
||||
* @private
|
||||
*/
|
||||
var timeout;
|
||||
|
||||
/**
|
||||
* Contains the number of milliseconds to wait before starting
|
||||
* the asynchronous request.
|
||||
* @type Number
|
||||
* @private
|
||||
*/
|
||||
var delay;
|
||||
|
||||
/**
|
||||
* Run method necessary to implement java.lang.Runnable.
|
||||
* @private
|
||||
*/
|
||||
var runner = function() {
|
||||
// evaluator that will handle the request
|
||||
var ev = app.__app__.getEvaluator();
|
||||
|
||||
if (delay != null) {
|
||||
java.lang.Thread.sleep(delay);
|
||||
}
|
||||
try {
|
||||
if (args === undefined || args === null || args.constructor != Array) {
|
||||
args = [];
|
||||
}
|
||||
if (timeout != null) {
|
||||
ev.invokeInternal(obj, funcName, args, timeout);
|
||||
} else {
|
||||
ev.invokeInternal(obj, funcName, args);
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore it, but log it
|
||||
app.log("[Runner] Caught Exception: " + e);
|
||||
} finally {
|
||||
// release the ev in any case
|
||||
app.__app__.releaseEvaluator(ev);
|
||||
// remove reference to underlying thread
|
||||
thread = null;
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the timeout of this asynchronous request.
|
||||
* @param {Number} seconds Thread-timeout.
|
||||
*/
|
||||
this.setTimeout = function(seconds) {
|
||||
timeout = seconds * 1000;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines the delay to wait before evaluating this asynchronous request.
|
||||
* @param {Number} millis Milliseconds to wait
|
||||
*/
|
||||
this.setDelay = function(millis) {
|
||||
delay = millis;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Starts this asynchronous request. Any arguments passed to
|
||||
* this method will be passed to the method executed by
|
||||
* this AsyncRequest instance.
|
||||
*/
|
||||
this.run = function() {
|
||||
if (arguments.length > 0) {
|
||||
// convert arguments object into array
|
||||
args = Array.prototype.slice.call(arguments, 0, arguments.length);
|
||||
}
|
||||
thread = (new java.lang.Thread(new java.lang.Runnable({"run": runner})));
|
||||
thread.start();
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Starts this asynchronous request.
|
||||
* @deprecated Use {@link #run} instead
|
||||
*/
|
||||
this.evaluate = function() {
|
||||
this.run.apply(this, arguments);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the underlying thread is alive
|
||||
* @returns True if the underlying thread is alive,
|
||||
* false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.isAlive = function() {
|
||||
return thread != null && thread.isAlive();
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
this.toString = function() {
|
||||
return "[jala.AsyncRequest]";
|
||||
};
|
||||
|
||||
/**
|
||||
* Main constructor body
|
||||
*/
|
||||
if (!obj || !funcName)
|
||||
throw "jala.AsyncRequest: insufficient arguments.";
|
||||
return this;
|
||||
}
|
|
@ -1,429 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the jala.BitTorrent class.
|
||||
*/
|
||||
|
||||
|
||||
// Define the global namespace for Jala modules
|
||||
if (!global.jala) {
|
||||
global.jala = {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
app.addRepository("modules/core/String.js");
|
||||
app.addRepository("modules/helma/File.js");
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new BitTorrent file.
|
||||
* @class This class provides methods to create a BitTorrent
|
||||
* metadata file from any desired file.
|
||||
* @param {String} trackerUrl The URL string of the tracker.
|
||||
* @param {String} filePath The path to the original file.
|
||||
* @returns A new BitTorrent file.
|
||||
* @constructor
|
||||
*/
|
||||
jala.BitTorrent = function(filePath, trackerUrl) {
|
||||
var self = this;
|
||||
self.arguments = arguments;
|
||||
|
||||
// FIXME: Add support for multitracker mode as specified in
|
||||
// http://www.bittornado.com/docs/multitracker-spec.txt
|
||||
|
||||
var torrent, sourceFile, torrentFile;
|
||||
var pieceLength = 256;
|
||||
|
||||
var updateTorrent = function() {
|
||||
if (torrent.info) {
|
||||
return torrent;
|
||||
}
|
||||
|
||||
var file = new java.io.File(filePath);
|
||||
if (!file.exists()) {
|
||||
throw Error("File " + file + " does not exist!");
|
||||
}
|
||||
|
||||
var md5 = java.security.MessageDigest.getInstance("MD5");
|
||||
var sha1 = java.security.MessageDigest.getInstance("SHA-1");
|
||||
|
||||
var fis = new java.io.FileInputStream(file);
|
||||
var bis = new java.io.BufferedInputStream(fis);
|
||||
var cache = new java.io.ByteArrayOutputStream();
|
||||
|
||||
var pieces = [];
|
||||
var length = pieceLength * 1024;
|
||||
var buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, length);
|
||||
|
||||
while (bis.read(buffer, 0, buffer.length) > -1) {
|
||||
app.debug("Updating SHA-1 hash with " + buffer.length + " bytes");
|
||||
sha1.reset();
|
||||
sha1["update(byte[])"](buffer);
|
||||
cache["write(byte[])"](buffer);
|
||||
pieces.push(new java.lang.String(sha1.digest()));
|
||||
}
|
||||
|
||||
bis.close();
|
||||
fis.close();
|
||||
|
||||
torrent.info = {
|
||||
//md5sum: new java.lang.String(md5.digest(cache.toByteArray())),
|
||||
length: cache.size(),
|
||||
name: file.getName(),
|
||||
"piece length": length,
|
||||
pieces: pieces.join("")
|
||||
};
|
||||
|
||||
return torrent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get all available property names.
|
||||
* @returns The list of property names.
|
||||
* @type Array
|
||||
*/
|
||||
this.keys = function() {
|
||||
var keys = [];
|
||||
for (var i in torrent) {
|
||||
keys.push(i);
|
||||
}
|
||||
keys.sort();
|
||||
return keys;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a torrent property.
|
||||
* @param {String} name The name of the property.
|
||||
* @returns The value of the property.
|
||||
*/
|
||||
this.get = function(name) {
|
||||
return torrent[name];
|
||||
};
|
||||
|
||||
/**
|
||||
* Set a torrent property.
|
||||
* @param {String} name The name of the property.
|
||||
* @param {Object} value The property's value.
|
||||
*/
|
||||
this.set = function(name, value) {
|
||||
if (typeof torrent[name] == "undefined") {
|
||||
throw Error("Cannot set torrent property " + name);
|
||||
}
|
||||
torrent[name] = value;
|
||||
delete torrent.info;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the creation date of the torrent.
|
||||
* @returns The torrent's creation date.
|
||||
* @type Date
|
||||
*/
|
||||
this.getCreationDate = function() {
|
||||
return new Date(torrent["creation date"] * 1000);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the creation date of the torrent.
|
||||
* @param {Date} date The desired creation date.
|
||||
*/
|
||||
this.setCreationDate = function(date) {
|
||||
this.set("creation date", Math.round((date || new Date()).getTime() / 1000));
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the piece length of the torrent.
|
||||
* @returns The torrent's piece length.
|
||||
* @type Number
|
||||
*/
|
||||
this.getPieceLength = function() {
|
||||
return pieceLength;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the piece length of the torrent.
|
||||
* @param {Number} length The desired piece length.
|
||||
*/
|
||||
this.setPieceLength = function(length) {
|
||||
pieceLength = length;
|
||||
delete torrent.info;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the underlying torrent file.
|
||||
* @returns The torrent file.
|
||||
* @type helma.File
|
||||
*/
|
||||
this.getTorrentFile = function() {
|
||||
return torrentFile;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the underlying source file.
|
||||
* @returns The source file.
|
||||
* @type helma.File
|
||||
*/
|
||||
this.getSourceFile = function() {
|
||||
return sourceFile;
|
||||
};
|
||||
|
||||
/**
|
||||
* Saves the torrent as file.
|
||||
* @param {String} filename An optional name for the torrent file.
|
||||
* If no name is given it will be composed from name of source
|
||||
* file as defined in the torrent plus the ending ".torrent".
|
||||
*/
|
||||
this.save = function(filename) {
|
||||
updateTorrent();
|
||||
if (!filename) {
|
||||
filename = torrent.info.name + ".torrent";
|
||||
}
|
||||
torrentFile = new helma.File(sourceFile.getParent(), filename);
|
||||
torrentFile.remove();
|
||||
torrentFile.open();
|
||||
torrentFile.write(jala.BitTorrent.bencode(torrent));
|
||||
torrentFile.close();
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a string representation of the torrent.
|
||||
* @returns The torrent as string.
|
||||
* @type String
|
||||
*/
|
||||
this.toString = function() {
|
||||
return "[jala.BitTorrent " + filePath + "]";
|
||||
};
|
||||
|
||||
if (String(filePath).endsWith(".torrent")) {
|
||||
torrentFile = new helma.File(filePath);
|
||||
torrent = jala.BitTorrent.bdecode(torrentFile.readAll());
|
||||
sourceFile = new helma.File(torrent.info.name);
|
||||
} else {
|
||||
torrent = {
|
||||
announce: trackerUrl || null,
|
||||
"announce-list": null,
|
||||
"creation date": null,
|
||||
comment: null,
|
||||
"created by": null,
|
||||
};
|
||||
this.setCreationDate();
|
||||
sourceFile = new helma.File(filePath);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The bencode method. Turns an arbitrary JavaScript
|
||||
* object structure into a corresponding encoded
|
||||
* string.
|
||||
* @param {Object} obj The target JavaScript object.
|
||||
* @returns The encoded string.
|
||||
* @type String
|
||||
*/
|
||||
jala.BitTorrent.bencode = function(obj) {
|
||||
var bencode = arguments.callee;
|
||||
var str = obj.toString();
|
||||
res.push();
|
||||
switch (obj.constructor) {
|
||||
case Array:
|
||||
res.write("l");
|
||||
for (var i in obj) {
|
||||
if (obj[i])
|
||||
res.write(bencode(obj[i]));
|
||||
}
|
||||
res.write("e");
|
||||
break;
|
||||
|
||||
case Number:
|
||||
res.write("i" + str + "e");
|
||||
break;
|
||||
|
||||
case Object:
|
||||
res.write("d");
|
||||
var keys = [];
|
||||
for (var i in obj) {
|
||||
keys.push(i);
|
||||
}
|
||||
keys.sort();
|
||||
var key;
|
||||
for (var i in keys) {
|
||||
key = keys[i];
|
||||
if (obj[key]) {
|
||||
res.write(bencode(key));
|
||||
res.write(bencode(obj[key]));
|
||||
}
|
||||
}
|
||||
res.write("e");
|
||||
break;
|
||||
|
||||
default:
|
||||
res.write(str.length + ":" + str);
|
||||
}
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The bdecode method. Turns an encoded string into
|
||||
* a corresponding JavaScript object structure.
|
||||
* FIXME: Handle with caution...
|
||||
* @param {String} code The encoded string.
|
||||
* @returns The decoded JavaScript structure.
|
||||
* @type Object
|
||||
*/
|
||||
jala.BitTorrent.bdecode = function(code) {
|
||||
var DICTIONARY = "d";
|
||||
var LIST = "l";
|
||||
var INTEGER = "i";
|
||||
var STRING = "s";
|
||||
var END = "e";
|
||||
|
||||
var stack = [];
|
||||
var overflowCounter = 0;
|
||||
|
||||
var position = -1, current;
|
||||
|
||||
function getResult() {
|
||||
update();
|
||||
var result;
|
||||
switch (current) {
|
||||
case DICTIONARY:
|
||||
result = bdecodeDictionary();
|
||||
break;
|
||||
case LIST:
|
||||
result = bdecodeList();
|
||||
break;
|
||||
case INTEGER:
|
||||
result = bdecodeInteger();
|
||||
break;
|
||||
case END:
|
||||
case null:
|
||||
//res.debug("*** end detected in getResult()");
|
||||
result = null;
|
||||
break;
|
||||
default:
|
||||
result = bdecodeString();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function update() {
|
||||
position += 1;
|
||||
current = code.charAt(position);
|
||||
/* res.debug("stack: " + stack);
|
||||
res.debug("position: " + position);
|
||||
res.debug("current: " + current);
|
||||
res.debug("remains: " + code.substr(position)); */
|
||||
return;
|
||||
}
|
||||
|
||||
function overflow() {
|
||||
if (overflowCounter++ > 100)
|
||||
throw Error("Error parsing bdecoded string");
|
||||
return false;
|
||||
}
|
||||
|
||||
function bdecodeDictionary() {
|
||||
stack.push(DICTIONARY);
|
||||
var dictionary = {}, key, value;
|
||||
while (current && !overflow()) {
|
||||
key = getResult();
|
||||
if (key === null)
|
||||
break;
|
||||
value = getResult();
|
||||
if (key && value)
|
||||
dictionary[key] = value;
|
||||
else
|
||||
break;
|
||||
}
|
||||
stack.pop();
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
function bdecodeList() {
|
||||
stack.push(LIST);
|
||||
var list = [], value;
|
||||
while (current && !overflow()) {
|
||||
var value = getResult();
|
||||
if (value)
|
||||
list.push(value);
|
||||
else
|
||||
break;
|
||||
}
|
||||
stack.pop();
|
||||
return list;
|
||||
}
|
||||
|
||||
function bdecodeInteger() {
|
||||
var integer = "";
|
||||
stack.push(integer);
|
||||
while (current && !overflow()) {
|
||||
update();
|
||||
if (current == "e")
|
||||
break;
|
||||
integer += current;
|
||||
}
|
||||
if (isNaN(integer))
|
||||
throw("Error in bdecoded integer: " + integer + " is not a number");
|
||||
//res.debug("integer = " + integer);
|
||||
stack.pop();
|
||||
return parseInt(integer);
|
||||
}
|
||||
|
||||
function bdecodeString() {
|
||||
var length = current, string = "";
|
||||
stack.push(string);
|
||||
update();
|
||||
while (current && current != ":" && !overflow()) {
|
||||
length += current;
|
||||
update();
|
||||
}
|
||||
if (isNaN(length))
|
||||
throw("Error in bdecoded string: invalid length " + length);
|
||||
//res.debug("length = " + length);
|
||||
length = parseInt(length);
|
||||
if (length > code.length - position)
|
||||
throw Error("Error parsing bdecoded string");
|
||||
for (var i=0; i<length; i+=1) {
|
||||
update();
|
||||
string += current;
|
||||
}
|
||||
//res.debug("string = " + string);
|
||||
if (string == "creation date")
|
||||
void(null);
|
||||
stack.pop();
|
||||
return string;
|
||||
}
|
||||
|
||||
return getResult();
|
||||
};
|
|
@ -1,119 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the jala.Captcha class.
|
||||
*/
|
||||
|
||||
|
||||
// Define the global namespace for Jala modules
|
||||
if (!global.jala) {
|
||||
global.jala = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new captcha.
|
||||
* @returns A new captcha.
|
||||
* @class Wrapper class for the
|
||||
* {@link http://jcaptcha.sourceforge.net/ JCaptcha library}.
|
||||
* A captcha (an acronym for "completely automated public
|
||||
* Turing test to tell computers and humans apart") is a
|
||||
* type of challenge-response test used in computing to
|
||||
* determine whether or not the user is human.
|
||||
* @constructor
|
||||
*/
|
||||
jala.Captcha = function() {
|
||||
/**
|
||||
* Jala dependencies
|
||||
*/
|
||||
app.addRepository(getProperty("jala.dir", "modules/jala") +
|
||||
"/lib/jcaptcha-all-1.0-RC3.jar");
|
||||
|
||||
var gimpy;
|
||||
|
||||
try {
|
||||
var ref = Packages.com.octo.captcha.engine.image.gimpy;
|
||||
gimpy = ref.DefaultGimpyEngine();
|
||||
} catch(e) {
|
||||
throw("Cannot instantiate object due to missing java class: " +
|
||||
arguments.callee.toString());
|
||||
}
|
||||
var captcha = gimpy.getNextCaptcha();
|
||||
|
||||
/**
|
||||
* Get a new captcha object.
|
||||
* @returns A new captcha object.
|
||||
* @type com.octo.captcha.Captcha
|
||||
*/
|
||||
this.getCaptcha = function getCaptcha() {
|
||||
return captcha;
|
||||
};
|
||||
|
||||
/**
|
||||
* Render a new captcha image.
|
||||
*/
|
||||
this.renderImage = function renderImage() {
|
||||
var image = captcha.getImageChallenge();
|
||||
var stream = new java.io.ByteArrayOutputStream();
|
||||
var ref = Packages.com.sun.image.codec.jpeg.JPEGCodec;
|
||||
var encoder = ref.createJPEGEncoder(stream);
|
||||
encoder.encode(image);
|
||||
res.contentType = "image/jpeg";
|
||||
res.writeBinary(stream.toByteArray());
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Validate a user's input with the prompted captcha.
|
||||
* @param {String} input The user's input.
|
||||
* @returns True if the user's input matches the captcha.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.validate = function validate(input) {
|
||||
return !input || captcha.validateResponse(input);
|
||||
};
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get a string representation of the captcha class.
|
||||
* @returns A string representation of the capthca class.
|
||||
* @type String
|
||||
* @ignore
|
||||
*/
|
||||
jala.Captcha.toString = function toString() {
|
||||
return "[jala.Captcha http://jcaptcha.sourceforge.net]";
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get a string representation of the captcha object.
|
||||
* @returns A string representation of the captcha object.
|
||||
* @type String
|
||||
*/
|
||||
jala.Captcha.prototype.toString = function toString() {
|
||||
return "[jala.Captcha Object]";
|
||||
};
|
File diff suppressed because it is too large
Load diff
|
@ -1,545 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the jala.Date class.
|
||||
*/
|
||||
|
||||
// Define the global namespace for Jala modules
|
||||
if (!global.jala) {
|
||||
global.jala = {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* HelmaLib dependencies
|
||||
*/
|
||||
app.addRepository("modules/core/Date.js");
|
||||
app.addRepository("modules/helma/Html.js");
|
||||
|
||||
/**
|
||||
* Constructs a new Renderings object.
|
||||
* @class This class provides various convenience
|
||||
* methods for rendering purposes.
|
||||
* @constructor
|
||||
*/
|
||||
jala.Date = function() {
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a timestamp as set of DropDown boxes, following the
|
||||
* format passed as argument. Every <select>
|
||||
* item is prefixed with a string so that it can be retrieved
|
||||
* easily from the values of a submitted POST request.
|
||||
* @param {String} prefix The prefix to use for all dropdown boxes, eg. "postdate"
|
||||
* @param {Date} date A Date object to use as preselection (optional)
|
||||
* @param {Object} fmt Array containing one parameter object for every single
|
||||
* select box that should be rendered, with the following properties set:
|
||||
* <ul>
|
||||
* <li>pattern - The date format pattern that should be rendered. Valid
|
||||
* patterns are: "dd", "MM", "yyyy", "HH", "ss".</li>
|
||||
* <li>firstOption - The string to use as first option, eg.: "choose a day"</li>
|
||||
* </ul>
|
||||
*/
|
||||
jala.Date.prototype.renderEditor = function(prefix, date, fmt) {
|
||||
/**
|
||||
* rendering method
|
||||
* @private
|
||||
*/
|
||||
var render = function(param, date) {
|
||||
switch (param.pattern) {
|
||||
case "dd":
|
||||
param.offset = 1;
|
||||
param.max = 31;
|
||||
param.selected = (date ? date.getDate() : null);
|
||||
break;
|
||||
|
||||
case "MM":
|
||||
param.offset = 1;
|
||||
param.max = 12;
|
||||
param.selected = (date ? date.getMonth() +1 : null);
|
||||
break;
|
||||
|
||||
case "yyyy":
|
||||
param.offset = 2002;
|
||||
param.max = 20;
|
||||
param.selected = (date ? date.getFullYear() : null);
|
||||
break;
|
||||
|
||||
case "HH":
|
||||
param.offset = 0;
|
||||
param.max = 24;
|
||||
param.selected = (date ? date.getHours() : null);
|
||||
break;
|
||||
|
||||
case "mm":
|
||||
param.offset = 0;
|
||||
param.max = 60;
|
||||
param.selected = (date ? date.getMinutes() : null);
|
||||
break;
|
||||
|
||||
case "ss":
|
||||
param.offset = 0;
|
||||
param.max = 60;
|
||||
param.selected = (date ? date.getSeconds() : null);
|
||||
break;
|
||||
}
|
||||
|
||||
var key = prefix + ":" + param.pattern;
|
||||
if (req.data[key])
|
||||
param.selected = req.data[key];
|
||||
var options = [];
|
||||
var opt;
|
||||
for (var i=0;i<param.max;i++) {
|
||||
opt = (param.offset + i).format("00");
|
||||
options[i] = [opt, opt];
|
||||
}
|
||||
var html = new helma.Html();
|
||||
html.dropDown({name: key}, options, param.selected, param.firstOption);
|
||||
}
|
||||
|
||||
if (!fmt)
|
||||
var fmt = [{pattern: "dd", firstOption: "day"},
|
||||
{pattern: "MM", firstOption: "month"},
|
||||
{pattern: "yyyy", firstOption: "year"},
|
||||
{pattern: "HH", firstOption: "hour"},
|
||||
{pattern: "mm", firstOption: "minute"}];
|
||||
|
||||
for (var i in fmt) {
|
||||
render(fmt[i], date);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a timestamp as set of dropdown-boxes
|
||||
* @see #renderEditor
|
||||
* @type String
|
||||
*/
|
||||
jala.Date.prototype.renderEditorAsString = function(prefix, date, pattern) {
|
||||
res.push();
|
||||
this.renderEditor(prefix, date, pattern);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new instance of jala.Data.Calendar
|
||||
* @class This class represents a calendar based based on a grouped
|
||||
* collection of HopObjects. It provides several methods for rendering
|
||||
* the calendar plus defining locale and timezone settings.
|
||||
* @param {HopObject} collection A grouped HopObject collection to work on
|
||||
* @returns A newly created jala.Date.Calendar instance
|
||||
* @constructor
|
||||
*/
|
||||
jala.Date.Calendar = function(collection) {
|
||||
var renderer = null;
|
||||
var locale = java.util.Locale.getDefault();
|
||||
var timezone = java.util.TimeZone.getDefault();
|
||||
var hrefFormat = "yyyyMMdd";
|
||||
var accessNameFormat = "yyyyMMdd";
|
||||
|
||||
/**
|
||||
* Returns the collection this calendar object works on
|
||||
* @returns The HopObject collection of this calendar
|
||||
* @type HopObject
|
||||
*/
|
||||
this.getCollection = function() {
|
||||
return collection;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the renderer to use.
|
||||
* @param {Object} r The renderer to use
|
||||
* @see #getRenderer
|
||||
*/
|
||||
this.setRenderer = function(r) {
|
||||
renderer = r;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the renderer used by this calendar.
|
||||
* @returns The calendar renderer
|
||||
* @type Object
|
||||
* @see #setRenderer
|
||||
*/
|
||||
this.getRenderer = function() {
|
||||
if (!renderer) {
|
||||
renderer = new jala.Date.Calendar.Renderer(this);
|
||||
}
|
||||
return renderer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the locale to use within this calendar object
|
||||
* @param {java.util.Locale} loc The locale to use
|
||||
* @see #getLocale
|
||||
*/
|
||||
this.setLocale = function(loc) {
|
||||
locale = loc;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the locale used within this calendar instance. By default
|
||||
* the locale used by this calendar is the default locale of the
|
||||
* Java Virtual Machine running Helma.
|
||||
* @returns The locale of this calendar
|
||||
* @type java.util.Locale
|
||||
* @see #setLocale
|
||||
*/
|
||||
this.getLocale = function() {
|
||||
return locale;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the locale to use within this calendar object
|
||||
* @param {java.util.Locale} loc The locale to use
|
||||
* @see #getTimeZone
|
||||
*/
|
||||
this.setTimeZone = function(tz) {
|
||||
timezone = tz;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the locale used within this calendar instance. By default
|
||||
* the timezone used by this calendar is the default timezone
|
||||
* of the Java Virtual Machine running Helma.
|
||||
* @returns The locale of this calendar
|
||||
* @type java.util.Locale
|
||||
* @see #setTimeZone
|
||||
*/
|
||||
this.getTimeZone = function() {
|
||||
return timezone;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the format of the hrefs to render by this calendar
|
||||
* to the format pattern passed as argument.
|
||||
* @param {String} fmt The date format pattern to use for
|
||||
* rendering the href
|
||||
* @see #getHrefFormat
|
||||
*/
|
||||
this.setHrefFormat = function(fmt) {
|
||||
hrefFormat = fmt;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the date formatting pattern used to render hrefs. The default
|
||||
* format is "yyyyMMdd".
|
||||
* @returns The date formatting pattern
|
||||
* @type String
|
||||
* @see #setHrefFormat
|
||||
*/
|
||||
this.getHrefFormat = function() {
|
||||
return hrefFormat;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the format of the group name to use when trying to access
|
||||
* child objects of the collection this calendar is operating on.
|
||||
* @param {String} fmt The date format pattern to use for
|
||||
* accessing child objects
|
||||
* @see #getAccessNameFormat
|
||||
*/
|
||||
this.setAccessNameFormat = function(fmt) {
|
||||
accessNameFormat = fmt;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the format of the access name used by this calendar to access
|
||||
* child group objects of the collection this calendar is operating on.
|
||||
* The default format is "yyyyMMdd".
|
||||
* @returns The date formatting pattern used to access child objects
|
||||
* @type String
|
||||
* @see #setAccessNameFormat
|
||||
*/
|
||||
this.getAccessNameFormat = function() {
|
||||
return accessNameFormat;
|
||||
};
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
jala.Date.Calendar.prototype.toString = function() {
|
||||
return "[Jala Calendar]";
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the calendar using either a custom renderer defined
|
||||
* using {@link #setRenderer} or the default one.
|
||||
* @see #setRenderer
|
||||
* @see jala.Date.Calendar.Renderer
|
||||
*/
|
||||
jala.Date.Calendar.prototype.render = function(today) {
|
||||
var renderer = this.getRenderer();
|
||||
var collection = this.getCollection();
|
||||
var hrefFormat = this.getHrefFormat();
|
||||
var accessNameFormat = this.getAccessNameFormat();
|
||||
var locale = this.getLocale();
|
||||
var timezone = this.getTimeZone();
|
||||
var size = collection.size();
|
||||
if (size == null)
|
||||
return;
|
||||
|
||||
/**
|
||||
* private method that creates a date object set
|
||||
* to the last date of the previous month or the
|
||||
* first date of the next month (if available)
|
||||
*/
|
||||
var prevNextMonth = function(which, dayIndex) {
|
||||
var obj;
|
||||
if (which == "prev") {
|
||||
if (size <= dayIndex || !(obj = collection.get(dayIndex +1)))
|
||||
return;
|
||||
} else if (which == "next") {
|
||||
if (dayIndex == 0 || !(obj = collection.get(dayIndex - 1)))
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
return new Date(obj.groupname.substring(0, 4),
|
||||
obj.groupname.substring(4, 6) -1,
|
||||
obj.groupname.substring(6));
|
||||
};
|
||||
|
||||
// create the calendar object used for date calculations
|
||||
var cal = java.util.Calendar.getInstance(timezone, locale);
|
||||
var firstDayOfWeek = cal.getFirstDayOfWeek();
|
||||
var symbols = new java.text.DateFormatSymbols(locale);
|
||||
|
||||
res.push();
|
||||
// render the header-row
|
||||
res.push();
|
||||
var weekdays = symbols.getShortWeekdays();
|
||||
for (var i=0;i<7;i++) {
|
||||
renderer.renderDayHeader(weekdays[(i+firstDayOfWeek-1)%7+1]);
|
||||
}
|
||||
renderer.renderRow(res.pop());
|
||||
|
||||
cal.set(java.util.Calendar.DATE, 1);
|
||||
|
||||
// check whether there's a day in path
|
||||
// if so, use it to determine the month to render
|
||||
if (today) {
|
||||
cal.set(java.util.Calendar.YEAR, today.getFullYear());
|
||||
cal.set(java.util.Calendar.MONTH, today.getMonth());
|
||||
}
|
||||
// nr. of empty days in rendered calendar before the first day of month appears
|
||||
var pre = (7-firstDayOfWeek+cal.get(java.util.Calendar.DAY_OF_WEEK)) % 7;
|
||||
var days = cal.getActualMaximum(java.util.Calendar.DATE);
|
||||
var weeks = Math.ceil((pre + days) / 7);
|
||||
var daycnt = 1;
|
||||
|
||||
var date = new Date(cal.get(java.util.Calendar.YEAR), cal.get(java.util.Calendar.MONTH), 1);
|
||||
// remember the index of the first and last days within this month.
|
||||
// this is needed to optimize previous and next month links.
|
||||
var lastDayIndex = Number.MAX_VALUE;
|
||||
var firstDayIndex = -1;
|
||||
|
||||
var dayObj, idx, selected;
|
||||
for (var i=0;i<weeks;i++) {
|
||||
res.push();
|
||||
for (var j=0;j<7;j++) {
|
||||
if ((i == 0 && j < pre) || daycnt > days) {
|
||||
renderer.renderDay(null);
|
||||
} else {
|
||||
date.setDate(daycnt);
|
||||
if ((dayObj = collection.get(date.format(accessNameFormat))) != null) {
|
||||
idx = collection.contains(dayObj);
|
||||
if (idx > -1) {
|
||||
if (idx > firstDayIndex) {
|
||||
firstDayIndex = idx;
|
||||
}
|
||||
if (idx < lastDayIndex) {
|
||||
lastDayIndex = idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
selected = (today != null) ? date.equals(today) : false;
|
||||
renderer.renderDay(date, dayObj != null, selected);
|
||||
daycnt++;
|
||||
}
|
||||
}
|
||||
renderer.renderRow(res.pop());
|
||||
}
|
||||
var prevMonth = prevNextMonth("prev", firstDayIndex) || null;
|
||||
var nextMonth = prevNextMonth("next", lastDayIndex) || null;
|
||||
renderer.renderCalendar(date, res.pop(), prevMonth, nextMonth);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a rendered calendar
|
||||
* @see #renderCalendar
|
||||
* @type String
|
||||
*/
|
||||
jala.Date.Calendar.prototype.getCalendar = function(today) {
|
||||
res.push();
|
||||
this.render(today);
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a new instance of the default calendar renderer.
|
||||
* @class A default renderer to use in conjunction with jala.Date.Calendar
|
||||
* @param {jala.Date.Calendar} calendar The calendar utilizing this renderer
|
||||
* @returns A newly created instance of jala.Date.Calendar.Renderer
|
||||
* @constructor
|
||||
*/
|
||||
jala.Date.Calendar.Renderer = function(calendar) {
|
||||
|
||||
/**
|
||||
* An instance of helma.Html used for rendering the calendar
|
||||
* @type helma.Html
|
||||
*/
|
||||
this.html = new helma.Html();
|
||||
|
||||
/**
|
||||
* The calendar utilizing this renderer instance
|
||||
* @type jala.Date.Calendar
|
||||
*/
|
||||
this.calendar = calendar;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
jala.Date.Calendar.Renderer.prototype.toString = function() {
|
||||
return "[Jala Calendar Default Renderer]";
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a single cell in the calendar day header row directly to response.
|
||||
* @param {String} text The text to display in the header field.
|
||||
*/
|
||||
jala.Date.Calendar.Renderer.prototype.renderDayHeader = function(text) {
|
||||
this.html.element("th", text);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a single calendar row directly to response.
|
||||
* @param {String} row The body of the calendar row.
|
||||
*/
|
||||
jala.Date.Calendar.Renderer.prototype.renderRow = function(row) {
|
||||
this.html.element("tr", row);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a single day within the calendar directly to response.
|
||||
* @param {Date} date A date instance representing the day within the calendar.
|
||||
* @param {Boolean} isExisting True if there is a child object in the calendar's
|
||||
* collection to which the date cell should link to
|
||||
* @param {Boolean} isSelected True if this calendar day should be rendered
|
||||
* as selected day.
|
||||
*/
|
||||
jala.Date.Calendar.Renderer.prototype.renderDay = function(date, isExisting, isSelected) {
|
||||
var attr = {"class": "jala-calendar-day day"};
|
||||
if (isSelected === true) {
|
||||
attr["class"] += " jala-calendar-selected selected";
|
||||
}
|
||||
this.html.openTag("td", attr);
|
||||
if (date != null) {
|
||||
var text = date.getDate();
|
||||
if (isExisting === true) {
|
||||
attr = {"href": this.calendar.getCollection().href() +
|
||||
date.format(this.calendar.getHrefFormat())};
|
||||
this.html.link(attr, text);
|
||||
} else {
|
||||
res.write(text);
|
||||
}
|
||||
}
|
||||
this.html.closeTag("td");
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders a link to the previous or next month's calendar directly to response.
|
||||
* @param {Date} date A date object set to the previous or next available
|
||||
* month. This can be null in case there is no previous or next month.
|
||||
*/
|
||||
jala.Date.Calendar.Renderer.prototype.renderPrevNextLink = function(date) {
|
||||
if (date != null) {
|
||||
var attr = {"href": this.calendar.getCollection().href() +
|
||||
date.format(this.calendar.getHrefFormat())};
|
||||
this.html.link(attr, date.format("MMMM", this.calendar.getLocale()));
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the calendar directly to response.
|
||||
* @param {Date} date A date object representing this calendar's month and year.
|
||||
* Please mind that the day will be set to the <em>last</em> date in this
|
||||
* month.
|
||||
* @param {String} body The rendered calendar weeks including the day header
|
||||
* (basically the whole kernel of the table).
|
||||
* @param {Date} prevMonth A date object set to the last available date of
|
||||
* the previous month. This can be used to render a navigation link to
|
||||
* the previous month.
|
||||
* @param {Date} nextMonth A date object set to the first available date
|
||||
* of the next month. This can be used to render a navigation link to
|
||||
* the next month.
|
||||
*/
|
||||
jala.Date.Calendar.Renderer.prototype.renderCalendar = function(date, body, prevMonth, nextMonth) {
|
||||
var locale = this.calendar.getLocale();
|
||||
this.html.openTag("table", {"class": "jala-calendar calendar"});
|
||||
this.html.openTag("thead");
|
||||
this.html.openTag("tr");
|
||||
this.html.openTag("th", {"colspan": 7});
|
||||
res.write(date.format("MMMM", locale));
|
||||
res.write(' ');
|
||||
res.write(date.format("yyyy", locale));
|
||||
this.html.closeTag("th");
|
||||
this.html.closeTag("tr");
|
||||
this.html.closeTag("thead");
|
||||
this.html.element("tbody", body);
|
||||
this.html.openTag("tfoot");
|
||||
this.html.openTag("tr");
|
||||
this.html.openTag("td", {"class": "jala-calendar-left left", "colspan": 3});
|
||||
this.renderPrevNextLink(prevMonth);
|
||||
this.html.closeTag("td");
|
||||
this.html.openTag("td");
|
||||
this.html.closeTag("td");
|
||||
this.html.openTag("td", {"class": "jala-calendar-right right", "colspan": 3});
|
||||
this.renderPrevNextLink(nextMonth);
|
||||
this.html.closeTag("td");
|
||||
this.html.closeTag("tr");
|
||||
this.html.closeTag("tfoot");
|
||||
this.html.closeTag("table");
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Default date class instance.
|
||||
* @type jala.Date
|
||||
* @final
|
||||
*/
|
||||
jala.date = new jala.Date();
|
|
@ -1,312 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the jala.DnsClient class.
|
||||
*/
|
||||
|
||||
|
||||
// Define the global namespace for Jala modules
|
||||
if (!global.jala) {
|
||||
global.jala = {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Jala dependencies
|
||||
*/
|
||||
app.addRepository(getProperty("jala.dir", "modules/jala") +
|
||||
"/lib/javadns.jar");
|
||||
|
||||
/**
|
||||
* Constructs a new DnsClient object.
|
||||
* @class This is a wrapper around the Dns Client by wonderly.org
|
||||
* providing methods for querying Dns servers. For more information
|
||||
* about the Java DNS client visit
|
||||
* <a href="https://javadns.dev.java.net/">https://javadns.dev.java.net/</a>.
|
||||
* Please mind that the nameserver specified must accept queries on port
|
||||
* 53 TCP (the Java DNS client used doesn't support UDP nameserver queries),
|
||||
* and that reverse lookups are not supported.
|
||||
* @param {String} nameServer IP-Address or FQDN of nameserver to query
|
||||
* @constructor
|
||||
*/
|
||||
jala.DnsClient = function(nameServer) {
|
||||
/**
|
||||
* Contains the IP Adress/FQDN of the name server to query.
|
||||
* @type String
|
||||
*/
|
||||
this.nameServer = nameServer;
|
||||
|
||||
if (!this.nameServer) {
|
||||
throw "jala.DnsClient: missing nameserver argument";
|
||||
} else {
|
||||
// test if required javadns library is available
|
||||
try {
|
||||
var clazz = java.lang.Class.forName("org.wonderly.net.dns.Query",
|
||||
false, app.getClassLoader())
|
||||
} catch (e) {
|
||||
throw "jala.DnsClient requires JavaDNS.jar"
|
||||
+ " in lib/ext or application directory "
|
||||
+ "[https://javadns.dev.java.net/]";
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
jala.DnsClient.PKG = Packages.org.wonderly.net.dns;
|
||||
|
||||
/**
|
||||
* The "A" record/query type.
|
||||
* @type Number
|
||||
* @final
|
||||
*/
|
||||
jala.DnsClient.TYPE_A = jala.DnsClient.PKG.Question.TYPE_A;
|
||||
|
||||
/**
|
||||
* The "CNAME" record/query type.
|
||||
* @type Number
|
||||
* @final
|
||||
*/
|
||||
jala.DnsClient.TYPE_CNAME = jala.DnsClient.PKG.Question.TYPE_CNAME;
|
||||
|
||||
/**
|
||||
* The "MX" record/query type.
|
||||
* @type Number
|
||||
* @final
|
||||
*/
|
||||
jala.DnsClient.TYPE_MX = jala.DnsClient.PKG.Question.TYPE_MX;
|
||||
|
||||
/**
|
||||
* The "NS" record/query type.
|
||||
* @type Number
|
||||
* @final
|
||||
*/
|
||||
jala.DnsClient.TYPE_NS = jala.DnsClient.PKG.Question.TYPE_NS;
|
||||
|
||||
/**
|
||||
* The "PTR" record/query type.
|
||||
* @type Number
|
||||
* @final
|
||||
*/
|
||||
jala.DnsClient.TYPE_PTR = jala.DnsClient.PKG.Question.TYPE_PTR;
|
||||
|
||||
/**
|
||||
* The "SOA" record/query type.
|
||||
* @type Number
|
||||
* @final
|
||||
*/
|
||||
jala.DnsClient.TYPE_SOA = jala.DnsClient.PKG.Question.TYPE_SOA;
|
||||
|
||||
/**
|
||||
* The "TXT" record/query type.
|
||||
* @type Number
|
||||
* @final
|
||||
*/
|
||||
jala.DnsClient.TYPE_TXT = jala.DnsClient.PKG.Question.TYPE_TXT;
|
||||
|
||||
/**
|
||||
* The "WKS" record/query type.
|
||||
* @type Number
|
||||
* @final
|
||||
*/
|
||||
jala.DnsClient.TYPE_WKS = jala.DnsClient.PKG.Question.TYPE_WKS;
|
||||
|
||||
/**
|
||||
* Queries the nameserver for a specific domain
|
||||
* and the given type of record.
|
||||
* @param {String} dName The domain name to query for
|
||||
* @param {Number} queryType The type of records to retrieve
|
||||
* @returns The records retrieved from the nameserver
|
||||
* @type org.wonderly.net.dns.RR
|
||||
*/
|
||||
jala.DnsClient.prototype.query = function(dName, queryType) {
|
||||
if (dName == null) {
|
||||
throw new Error("no domain-name to query for");
|
||||
}
|
||||
if (queryType == null) {
|
||||
queryType = jala.DnsClient.TYPE_A;
|
||||
}
|
||||
// construct the question for querying the nameserver
|
||||
var question = new jala.DnsClient.PKG.Question(dName,
|
||||
queryType,
|
||||
jala.DnsClient.PKG.Question.CLASS_IN);
|
||||
// construct the query
|
||||
var query = new jala.DnsClient.PKG.Query(question);
|
||||
// run the query
|
||||
query.runQuery(this.nameServer);
|
||||
// wrap the records received in instances of jala.DnsClient.Record
|
||||
var answers = query.getAnswers();
|
||||
var arr = [];
|
||||
for (var i=0;i<answers.length;i++) {
|
||||
arr[i] = new jala.DnsClient.Record(answers[i]);
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convenience method to query for the MX-records
|
||||
* of the domain passed as argument.
|
||||
* @param {String} dName The domain name to query for
|
||||
* @returns The records retrieved from the nameserver
|
||||
* @type org.wonderly.net.dns.RR
|
||||
*/
|
||||
jala.DnsClient.prototype.queryMailHost = function (dName) {
|
||||
return this.query(dName, this.TYPE_MX);
|
||||
};
|
||||
|
||||
|
||||
/** @ignore */
|
||||
jala.DnsClient.toString = function() {
|
||||
return "[jala.DnsClient]";
|
||||
};
|
||||
|
||||
|
||||
/** @ignore */
|
||||
jala.DnsClient.prototype.toString = function() {
|
||||
return "[jala.DnsClient (" + this.nameServer + ")]";
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a new instance of jala.DnsClient.Record.
|
||||
* @class Instances of this class wrap record data as received
|
||||
* from the nameserver.
|
||||
* @param {org.wonderly.net.dns.RR} data The data as received from
|
||||
* the nameserver
|
||||
* @returns A newly constructed Record instance
|
||||
* @constructor
|
||||
*/
|
||||
jala.DnsClient.Record = function(data) {
|
||||
/**
|
||||
* The type of the nameserver record represented by this Answer instance.
|
||||
* @type Number
|
||||
* @see #TYPE_A
|
||||
* @see #TYPE_CNAME
|
||||
* @see #TYPE_HINFO
|
||||
* @see #TYPE_MX
|
||||
* @see #TYPE_NS
|
||||
* @see #TYPE_PTR
|
||||
* @see #TYPE_SOA
|
||||
* @see #TYPE_TXT
|
||||
* @see #TYPE_WKS
|
||||
*/
|
||||
this.type = data.getType();
|
||||
|
||||
/**
|
||||
* The name of the host. This will only be set for records
|
||||
* of type A, AAAA and NS.
|
||||
* @type String
|
||||
* @see #TYPE_A
|
||||
* @see #TYPE_AAAA
|
||||
* @see #TYPE_NS
|
||||
*/
|
||||
this.host = null;
|
||||
|
||||
/**
|
||||
* The IP address of the host. This will only be set for records
|
||||
* of type A and AAAA
|
||||
* @type String
|
||||
* @see #TYPE_A
|
||||
* @see #TYPE_AAAA
|
||||
*/
|
||||
this.ipAddress = null;
|
||||
|
||||
/**
|
||||
* The CNAME of this record. This will only be set for records
|
||||
* of type CNAME
|
||||
* @type String
|
||||
* @see #TYPE_CNAME
|
||||
*/
|
||||
this.cname = null;
|
||||
|
||||
/**
|
||||
* The name of the mail exchanging server. This is only set for
|
||||
* records of type MX
|
||||
* @type String
|
||||
* @see #TYPE_MX
|
||||
*/
|
||||
this.mx = null;
|
||||
|
||||
/**
|
||||
* The email address responsible for a name server. This property
|
||||
* will only be set for records of type SOA
|
||||
* @type String
|
||||
* @see #TYPE_SOA
|
||||
*/
|
||||
this.email = null;
|
||||
|
||||
/**
|
||||
* Descriptive text as received from the nameserver. This is only
|
||||
* set for records of type TXT
|
||||
* @type String
|
||||
* @see #TYPE_TXT
|
||||
*/
|
||||
this.text = null;
|
||||
|
||||
/**
|
||||
* Returns the wrapped nameserver record data
|
||||
* @returns The wrapped data
|
||||
* @type org.wonderly.net.dns.RR
|
||||
*/
|
||||
this.getData = function() {
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Main constructor body
|
||||
*/
|
||||
switch (data.getClass()) {
|
||||
case jala.DnsClient.PKG.ARR:
|
||||
case jala.DnsClient.PKG.AAAARR:
|
||||
this.host = data.getHost();
|
||||
this.ipAddress = data.getIPAddress();
|
||||
break;
|
||||
case jala.DnsClient.PKG.NSRR:
|
||||
this.host = data.getHost();
|
||||
break;
|
||||
case jala.DnsClient.PKG.CNAMERR:
|
||||
this.cname = data.getCName();
|
||||
break;
|
||||
case jala.DnsClient.PKG.MXRR:
|
||||
this.mx = data.getExchanger();
|
||||
break;
|
||||
case jala.DnsClient.PKG.SOARR:
|
||||
this.host = data.getNSHost();
|
||||
this.email = data.getResponsibleEmail();
|
||||
break;
|
||||
case jala.DnsClient.PKG.TXTRR:
|
||||
this.text = data.getText();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
jala.DnsClient.Record.prototype.toString = function() {
|
||||
return "[jala.DnsClient.Record]";
|
||||
};
|
File diff suppressed because it is too large
Load diff
|
@ -1,130 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the Global prototype.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the value passed as argument is either a string literal,
|
||||
* an instance of String or of java.lang.String.
|
||||
* @param {Object} val The value to test
|
||||
* @returns True if the value is a string, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
function isString(val) {
|
||||
return typeof(val) == "string" ||
|
||||
val instanceof java.lang.String ||
|
||||
val instanceof String;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the value passed as argument is either a boolean
|
||||
* literal or an instance of Boolean.
|
||||
* @param {Object} val The value to test
|
||||
* @returns True if the value is a boolean, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
function isBoolean(val) {
|
||||
return typeof(val) == "boolean" ||
|
||||
val instanceof Boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the value passed as argument is either a number,
|
||||
* an instance of Number or of java.lang.Number.
|
||||
* @param {Object} val The value to test
|
||||
* @returns True if the value is a number, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
function isNumber(val) {
|
||||
return typeof(val) == "number" ||
|
||||
val instanceof java.lang.Number ||
|
||||
val instanceof Number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the value passed as argument is null.
|
||||
* @param {Object} val The value to test
|
||||
* @returns True if the value is null, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
function isNull(val) {
|
||||
return val === null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the value passed as argument is undefined.
|
||||
* @param {Object} val The value to test
|
||||
* @returns True if the value is undefined, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
function isUndefined(val) {
|
||||
return val === undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the value passed as argument is an array.
|
||||
* @param {Object} val The value to test
|
||||
* @returns True if the value is an array, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
function isArray(val) {
|
||||
return val instanceof Array;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the value passed as argument is either a Javascript date
|
||||
* or an instance of java.util.Date.
|
||||
* @param {Object} val The value to test
|
||||
* @returns True if the value is a date, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
function isDate(val) {
|
||||
return val instanceof Date ||
|
||||
val instanceof java.util.Date;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the value passed as argument is either a Javascript
|
||||
* object or an instance of java.lang.Object.
|
||||
* @param {Object} val The value to test
|
||||
* @returns True if the value is an object, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
function isObject(val) {
|
||||
return val instanceof Object ||
|
||||
val instanceof java.lang.Object;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the value passed as argument is a function.
|
||||
* @param {Object} val The value to test
|
||||
* @returns True if the argument is a function, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
function isFunction(val) {
|
||||
return val instanceof Function;
|
||||
};
|
|
@ -1,253 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the jala.History class.
|
||||
*/
|
||||
|
||||
|
||||
// Define the global namespace for Jala modules
|
||||
if (!global.jala) {
|
||||
global.jala = {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new History object.
|
||||
* @class This class is an implementation of a Browser-like history
|
||||
* stack suitable to use in any Helma application. The difference
|
||||
* to a Browser's history is that this implementation ignores
|
||||
* POST requests and checks if Urls in the stack are still valid to
|
||||
* prevent eg. redirections to a HopObject's url that has been deleted.
|
||||
* Plus it is capable to create new "intermediate" history-stacks
|
||||
* and this way maintain a "history of histories" which is needed for
|
||||
* eg. editing sessions in a popup window that should use their own
|
||||
* request history without interfering with the history of the
|
||||
* main window.
|
||||
* @constructor
|
||||
*/
|
||||
jala.History = function() {
|
||||
var MAX = 40;
|
||||
|
||||
/**
|
||||
* Stack constructor
|
||||
* @private
|
||||
*/
|
||||
var Stack = function(id) {
|
||||
this.items = [];
|
||||
this.id = id;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the current url including query string
|
||||
* @private
|
||||
*/
|
||||
var getUrl = function() {
|
||||
var query;
|
||||
var url = path.href(req.action);
|
||||
try {
|
||||
if (query = req.getServletRequest().getQueryString())
|
||||
url += "?" + query;
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a request is valid for being added
|
||||
* to the history stack. This method returns false
|
||||
* for all POST-requests or requests whose action name
|
||||
* contains a dot (to prevent requests for external stylesheets
|
||||
* or the like from being recorded).
|
||||
* @private
|
||||
* @type Boolean
|
||||
*/
|
||||
var isValid = function() {
|
||||
// FIXME: we should check for mimetype of response instead
|
||||
// of assuming that requests containing a dot aren't worth
|
||||
// being put into history stack ...
|
||||
if (req.isPost() || (req.action && req.action.contains(".")))
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* returns a single Stack instance
|
||||
* @private
|
||||
*/
|
||||
var getStack = function() {
|
||||
if (history.length < 1)
|
||||
history.push(new Stack(getUrl()));
|
||||
return history[history.length -1];
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable containing the history-stacks
|
||||
* @private
|
||||
*/
|
||||
var history = [];
|
||||
|
||||
/**
|
||||
* Initializes a new history stack, adds
|
||||
* it to the array of stacks (which makes it
|
||||
* the default one to use for further requests)
|
||||
* and records the current request Url.
|
||||
*/
|
||||
this.add = function() {
|
||||
if (!isValid())
|
||||
return;
|
||||
var url = getUrl();
|
||||
if (getStack().id != url) {
|
||||
history.push(new Stack(url));
|
||||
this.push();
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the current history stack
|
||||
*/
|
||||
this.remove = function() {
|
||||
history.pop();
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Records a request Url in the currently active
|
||||
* history stack.
|
||||
*/
|
||||
this.push = function() {
|
||||
if (isValid()) {
|
||||
var obj = path[path.length-1];
|
||||
var url = getUrl();
|
||||
var stack = getStack();
|
||||
if (stack.items.length < 1 || stack.items[stack.items.length -1].url != url) {
|
||||
if (stack.items.length >= MAX)
|
||||
stack.items.shift();
|
||||
stack.items.push({
|
||||
url: url,
|
||||
path: path.href().substring(root.href().length).replace(/\+/g, " ")
|
||||
});
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears the currently active history stack
|
||||
*/
|
||||
this.clear = function() {
|
||||
getStack().items.length = 0;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Redirects the client back to the first valid
|
||||
* request in history. Please mind that searching for
|
||||
* a valid Url starts at <em>history.length - 2</em>.
|
||||
* @param {Number} offset The index position in the stack to start
|
||||
* searching at
|
||||
*/
|
||||
this.redirect = function(offset) {
|
||||
res.redirect(this.pop(offset));
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the first valid request Url in history
|
||||
* stack starting with a given offset. The default offset is 1.
|
||||
* Any valid Url found is removed from the stack, therefor
|
||||
* this method <em>alters the contents of the history stack</em>.
|
||||
* @param {Number} offset The index position in history stack to start
|
||||
* searching at
|
||||
* @return The Url of the request
|
||||
* @type String
|
||||
*/
|
||||
this.pop = function(offset) {
|
||||
/**
|
||||
* checks if a referrer is stil valid
|
||||
* @private
|
||||
*/
|
||||
var isValidPath = function(p) {
|
||||
var arr = p.split("/");
|
||||
var obj = root;
|
||||
for (var i=0;i<arr.length -1;i++) {
|
||||
if (!(obj = obj.get(unescape(arr[i]))) || obj.__node__.getState() == 3)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
var obj;
|
||||
var cut = offset != null ? offset : 1;
|
||||
var stack = getStack();
|
||||
if (stack.items.length > 0) {
|
||||
while (cut-- > 0) {
|
||||
obj = stack.items.pop();
|
||||
}
|
||||
}
|
||||
while (stack.items.length > 0) {
|
||||
obj = stack.items.pop();
|
||||
// check if url is valid
|
||||
if (isValidPath(obj.path)) {
|
||||
return obj.url;
|
||||
}
|
||||
}
|
||||
return path.href();
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the request Url at the given position
|
||||
* in the current history stack. If no offset is given
|
||||
* the last Url in the stack is returned. This method
|
||||
* <em>does not alter the stack contents</em>!
|
||||
* @param {Number} offset The index position in history stack to start
|
||||
* searching at
|
||||
* @return The Url of the request
|
||||
* @type String
|
||||
*/
|
||||
this.peek = function(offset) {
|
||||
var stack = getStack();
|
||||
return stack.items[stack.items.length - (offset != null ? offset : 1)];
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the contents of all history stacks
|
||||
* as string
|
||||
* @return The history stacks as string
|
||||
* @type String
|
||||
*/
|
||||
this.dump = function() {
|
||||
return history.toSource();
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
this.toString = function() {
|
||||
return "[History " + getStack().toSource() + "]";
|
||||
};
|
||||
|
||||
return this;
|
||||
}
|
|
@ -1,177 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
/**
|
||||
* @fileoverview Additional fields and methods of the HopObject class.
|
||||
*/
|
||||
|
||||
/**
|
||||
* HelmaLib dependencies
|
||||
*/
|
||||
app.addRepository("modules/core/String.js");
|
||||
app.addRepository("modules/helma/File.js");
|
||||
|
||||
/**
|
||||
* Constructs a name from an object which
|
||||
* is unique in the underlying HopObject collection.
|
||||
* @param {Object} obj The object representing or containing
|
||||
* the alias name. Possible object types include:
|
||||
* <ul>
|
||||
* <li>File</li>
|
||||
* <li>helma.File</li>
|
||||
* <li>java.io.File</li>
|
||||
* <li>String</li>
|
||||
* <li>java.lang.String</li>
|
||||
* <li>Packages.helma.util.MimePart</li>
|
||||
* </ul>
|
||||
* @param {Number} maxLength The maximum length of the alias
|
||||
* @returns The resulting alias
|
||||
* @type String
|
||||
*/
|
||||
HopObject.prototype.getAccessName = function(obj, maxLength) {
|
||||
/**
|
||||
* Private method checking if the key passed as argument is already
|
||||
* existing in this object
|
||||
* @param {String} key The key string to test
|
||||
* @returns True in case the key is already in use, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
var isReserved = function(obj, key) {
|
||||
return key === "." ||
|
||||
key === ".." ||
|
||||
obj[key] != null ||
|
||||
obj[key + "_action"] != null ||
|
||||
obj.get(key) != null
|
||||
};
|
||||
|
||||
// prepare name depending on argument
|
||||
var name;
|
||||
var clazz = obj.constructor || obj.getClass();
|
||||
switch (clazz) {
|
||||
case File:
|
||||
case helma.File:
|
||||
case java.io.File:
|
||||
case Packages.helma.util.MimePart:
|
||||
// first fix bloody ie/win file paths containing backslashes
|
||||
name = obj.getName().split(/[\\\/]/).pop();
|
||||
if (name.contains("."))
|
||||
name = name.substring(0, name.lastIndexOf("."));
|
||||
break;
|
||||
case String:
|
||||
case java.lang.String:
|
||||
name = obj;
|
||||
break;
|
||||
default:
|
||||
name = obj.toString();
|
||||
}
|
||||
|
||||
// remove all (back)slashes
|
||||
var accessName = name.replace(/[\\\/]/g, "");
|
||||
// remove all plus signs
|
||||
accessName = accessName.replace("+","");
|
||||
if (accessName.length > maxLength) {
|
||||
accessName = accessName.substring(0, maxLength);
|
||||
}
|
||||
var result = accessName;
|
||||
if (isReserved(this, result)) {
|
||||
var len = result.length;
|
||||
var counter = 1;
|
||||
var overflow;
|
||||
while (isReserved(this, result)) {
|
||||
result = accessName + "-" + counter.toString();
|
||||
if ((overflow = result.length - maxLength) > 0) {
|
||||
result = accessName.substring(0, accessName.length - overflow) +
|
||||
"-" + counter.toString();
|
||||
if (result.length > maxLength) {
|
||||
throw "Unable to create accessname due to limit restriction";
|
||||
}
|
||||
}
|
||||
counter += 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the internal state of this HopObject is TRANSIENT.
|
||||
* @returns True if this HopObject is marked as <em>transient</em>, false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
HopObject.prototype.isTransient = function() {
|
||||
return this.__node__.getState() === Packages.helma.objectmodel.INodeState.TRANSIENT;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the internal state of this HopObject is VIRTUAL.
|
||||
* @returns True if this HopObject is marked as <em>virtual</em>, false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
HopObject.prototype.isVirtual = function() {
|
||||
return this.__node__.getState() === Packages.helma.objectmodel.INodeState.VIRTUAL;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the internal state of this HopObject is INVALID.
|
||||
* @returns True if this HopObject is marked as <em>invalid</em>, false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
HopObject.prototype.isInvalid = function() {
|
||||
return this.__node__.getState() === Packages.helma.objectmodel.INodeState.INVALID;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the internal state of this HopObject is CLEAN.
|
||||
* @returns True if this HopObject is marked as <em>clean</em>, false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
HopObject.prototype.isClean = function() {
|
||||
return this.__node__.getState() === Packages.helma.objectmodel.INodeState.CLEAN;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the internal state of this HopObject is NEW.
|
||||
* @returns True if this HopObject is marked as <em>new</em>, false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
HopObject.prototype.isNew = function() {
|
||||
return this.__node__.getState() === Packages.helma.objectmodel.INodeState.NEW;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the internal state of this HopObject is MODIFIED.
|
||||
* @returns True if this HopObject is marked as <em>modified</em>, false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
HopObject.prototype.isModified = function() {
|
||||
return this.__node__.getState() === Packages.helma.objectmodel.INodeState.MODIFIED;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the internal state of this HopObject is DELETED.
|
||||
* @returns True if this HopObject is marked as <em>deleted</em>, false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
HopObject.prototype.isDeleted = function() {
|
||||
return this.__node__.getState() === Packages.helma.objectmodel.INodeState.DELETED;
|
||||
};
|
|
@ -1,156 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the jala.HtmlDocument class.
|
||||
*/
|
||||
|
||||
// Define the global namespace for Jala modules
|
||||
if (!global.jala) {
|
||||
global.jala = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Jala dependencies
|
||||
*/
|
||||
(function() {
|
||||
var jalaDir = getProperty("jala.dir", "modules/jala");
|
||||
app.addRepository(jalaDir + "/lib/dom4j-1.6.1.jar");
|
||||
app.addRepository(jalaDir + "/lib/jaxen-1.1-beta-8.jar");
|
||||
})();
|
||||
|
||||
/**
|
||||
* Construct a new HTML document.
|
||||
* @class This class provides easy access to the elements of
|
||||
* an arbitrary HTML document. By using TagSoup, Dom4J and Jaxen
|
||||
* even invalid HTML can be parsed, turned into an object tree
|
||||
* and easily be processed with XPath expressions.
|
||||
* @param {String} source The HTML source code.
|
||||
* @returns A new HTML document.
|
||||
* @constructor
|
||||
*/
|
||||
jala.HtmlDocument = function(source) {
|
||||
var REQUIREMENTS = {
|
||||
"dom4j-1.6.1": "http://www.dom4j.org",
|
||||
"jaxen-1.1-beta-8": "http://www.jaxen.org"
|
||||
};
|
||||
|
||||
var reader = new java.io.StringReader(source);
|
||||
var dom4j = Packages.org.dom4j;
|
||||
var tagsoup = "org.ccil.cowan.tagsoup.Parser";
|
||||
|
||||
try {
|
||||
var saxReader = new dom4j.io.SAXReader(tagsoup);
|
||||
var document = saxReader.read(reader);
|
||||
document.normalize();
|
||||
} catch(e) {
|
||||
res.push();
|
||||
res.write("\njala.HtmlDocument requires the following Java ");
|
||||
res.write("packages in ext/lib or application directory:\n");
|
||||
for (var i in REQUIREMENTS) {
|
||||
res.write(i);
|
||||
res.write(".jar");
|
||||
res.write(" [");
|
||||
res.write(REQUIREMENTS[i]);
|
||||
res.write("]\n");
|
||||
}
|
||||
throw (e + res.pop());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all document nodes from an XPath expression.
|
||||
* @param {String} xpathExpr An XPath expression.
|
||||
* @returns A list of HTML elements.
|
||||
* @type org.dom4j.tree.DefaultElement
|
||||
*/
|
||||
this.scrape = function(xpathExpr) {
|
||||
return document.selectNodes(xpathExpr);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get all link elements of the HTML document.
|
||||
* @returns A list of link elements.
|
||||
* @type Array
|
||||
*/
|
||||
this.getLinks = function() {
|
||||
var result = [];
|
||||
var list = this.scrape("//html:a");
|
||||
for (var i=0; i<list.size(); i+=1) {
|
||||
var element = list.get(i);
|
||||
var text = element.getText();
|
||||
var href = element.attribute("href");
|
||||
if (text && href) {
|
||||
result.push({
|
||||
text: text,
|
||||
url: href.getText()
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves all elements by name from the document.
|
||||
* The returned object structure is compatible for usage
|
||||
* in {@link jala.XmlWriter}.
|
||||
* @param {String} elementName The name of the desired element
|
||||
* @returns The list of available elements in the document
|
||||
* @type Array
|
||||
*/
|
||||
this.getAll = function(elementName) {
|
||||
var result = [], object;
|
||||
var list = this.scrape("//html:" + elementName);
|
||||
var i, n, element, text, attributes, attr, size;
|
||||
for (i=0; i<list.size(); i+=1) {
|
||||
element = list.get(i);
|
||||
object = {
|
||||
name: element.getName(),
|
||||
value: element.getText() || null
|
||||
};
|
||||
attributes = element.attributes();
|
||||
if ((size = attributes.size()) > 0) {
|
||||
object.attributes = new Array;
|
||||
for (n=0; n<size; n+=1) {
|
||||
attr = attributes.get(n);
|
||||
object.attributes.push({
|
||||
name: attr.getName(),
|
||||
value: attr.getData() || null
|
||||
});
|
||||
}
|
||||
}
|
||||
result.push(object);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a string representation of the HTML document.
|
||||
* @returns A string representation of the HTML document.
|
||||
* @type String
|
||||
*/
|
||||
this.toString = function() {
|
||||
return "[jala.HtmlDocument " + source.length + " Bytes]";
|
||||
};
|
||||
|
||||
return this;
|
||||
};
|
|
@ -1,403 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
/**
|
||||
* @fileoverview Methods and macros for internationalization
|
||||
* of Helma applications.
|
||||
*/
|
||||
|
||||
// Define the global namespace for Jala modules
|
||||
if (!global.jala) {
|
||||
global.jala = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of jala.I18n
|
||||
* @class This class provides various functions and macros for
|
||||
* internationalization of Helma applications.
|
||||
* @constructor
|
||||
* @type jala.I18n
|
||||
*/
|
||||
jala.I18n = function() {
|
||||
/**
|
||||
* The default object containing the messages.
|
||||
* @ignore
|
||||
*/
|
||||
var messages = global.messages;
|
||||
|
||||
/**
|
||||
* The default method for retrieving the locale.
|
||||
* @ignore
|
||||
*/
|
||||
var localeGetter = function() {
|
||||
return java.util.Locale.getDefault();
|
||||
};
|
||||
|
||||
/**
|
||||
* Overwrite the default object containing
|
||||
* the messages (ie. a vanilla EcmaScript object).
|
||||
* @param {Object} msgObject The object containing the messages
|
||||
*/
|
||||
this.setMessages = function(msgObject) {
|
||||
messages = msgObject;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the message object.
|
||||
* @returns The object containing the messages
|
||||
* @type Object
|
||||
*/
|
||||
this.getMessages = function() {
|
||||
return messages;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the method for retrieving the locale.
|
||||
* @param {Function} func The getter method
|
||||
*/
|
||||
this.setLocaleGetter = function(func) {
|
||||
if (func && func.constructor == Function) {
|
||||
localeGetter = func;
|
||||
} else {
|
||||
throw Error("Getter method to retrieve locale must be a function");
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the method for retrieving the locale.
|
||||
* @returns The getter method
|
||||
* @type Function
|
||||
*/
|
||||
this.getLocaleGetter = function() {
|
||||
return localeGetter;
|
||||
};
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* The default handler containing the messages.
|
||||
* @ignore
|
||||
*/
|
||||
jala.I18n.HANDLER = global;
|
||||
|
||||
/** @ignore */
|
||||
jala.I18n.prototype.toString = function() {
|
||||
return "[Jala i18n]";
|
||||
};
|
||||
|
||||
/**
|
||||
* Set (overwrite) the default handler containing
|
||||
* the messages (ie. a vanilla EcmaScript object).
|
||||
* @param {Object} handler The handler containing the message object
|
||||
* @deprecated Use {@link #setMessages} instead
|
||||
*/
|
||||
jala.I18n.prototype.setHandler = function(handler) {
|
||||
this.setMessages(handler.messages);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the locale for the given id, which is expected to follow
|
||||
* the form <code>language[_COUNTRY][_variant]</code>, where <code>language</code>
|
||||
* is a valid ISO Language Code (eg. "de"), <code>COUNTRY</code> a valid ISO
|
||||
* Country Code (eg. "AT"), and variant an identifier for the variant to use.
|
||||
* @returns The locale for the given id
|
||||
* @type java.util.Locale
|
||||
*/
|
||||
jala.I18n.prototype.getLocale = function(localeId) {
|
||||
if (localeId) {
|
||||
if (localeId.indexOf("_") > -1) {
|
||||
var arr = localeId.split("_");
|
||||
if (arr.length == 3) {
|
||||
return new java.util.Locale(arr[0], arr[1], arr[2]);
|
||||
} else {
|
||||
return new java.util.Locale(arr[0], arr[1]);
|
||||
}
|
||||
} else {
|
||||
return new java.util.Locale(localeId);
|
||||
}
|
||||
}
|
||||
return java.util.Locale.getDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to "translate" the given message key into a localized
|
||||
* message.
|
||||
* @param {String} key The message to translate (required)
|
||||
* @param {String} plural The plural form of the message to translate
|
||||
* @param {Number} amount A number to determine whether to use the
|
||||
* singular or plural form of the message
|
||||
* @returns The localized message or the appropriate key if no
|
||||
* localized message was found
|
||||
* @type String
|
||||
*/
|
||||
jala.I18n.prototype.translate = function(singularKey, pluralKey, amount) {
|
||||
var translation = null;
|
||||
if (singularKey) {
|
||||
// use the getter method for retrieving the locale
|
||||
var locale = this.getLocaleGetter()();
|
||||
var catalog, key;
|
||||
if ((catalog = jala.i18n.getCatalog(locale))) {
|
||||
if (arguments.length == 3 && amount != 1) { // is plural
|
||||
key = pluralKey;
|
||||
} else {
|
||||
key = singularKey;
|
||||
}
|
||||
if (!(translation = catalog[key])) {
|
||||
translation = key;
|
||||
app.logger.debug("jala.i18n.translate(): Can't find message '" +
|
||||
key + "' for locale '" + locale + "'");
|
||||
}
|
||||
} else {
|
||||
app.logger.debug("jala.i18n.translate(): Can't find message catalog for locale '" + locale + "'");
|
||||
if (!pluralKey || amount == 1) {
|
||||
translation = singularKey;
|
||||
} else {
|
||||
translation = pluralKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
return translation;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper method to get the message catalog
|
||||
* corresponding to the actual locale.
|
||||
* @params {java.util.Locale} locale
|
||||
* @returns The message catalog.
|
||||
*/
|
||||
jala.I18n.prototype.getCatalog = function(locale) {
|
||||
if (!jala.I18n.catalogs) {
|
||||
jala.I18n.catalogs = {};
|
||||
}
|
||||
|
||||
var catalog = jala.I18n.catalogs[locale];
|
||||
|
||||
if (catalog) return catalog;
|
||||
|
||||
var messages = this.getMessages();
|
||||
|
||||
if (locale && messages) {
|
||||
catalog = messages[locale.toLanguageTag()];
|
||||
jala.I18n.catalogs[locale] = catalog;
|
||||
}
|
||||
|
||||
return catalog;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts the message passed as argument into an instance
|
||||
* of java.text.MessageFormat, and formats it using the
|
||||
* replacement values passed.
|
||||
* @param {String} message The message to format
|
||||
* @param {Array} values An optional array containing replacement values
|
||||
* @returns The formatted message or, if the formatting fails, the
|
||||
* message passed as argument.
|
||||
* @type String
|
||||
* @see http://java.sun.com/j2se/1.5.0/docs/api/java/text/MessageFormat.html
|
||||
*/
|
||||
jala.I18n.prototype.formatMessage = function(message, values) {
|
||||
if (message) {
|
||||
var args = null;
|
||||
if (values != null && values.length > 0) {
|
||||
args = java.lang.reflect.Array.newInstance(java.lang.Object, values.length);
|
||||
var arg;
|
||||
for (var i=0;i<values.length;i++) {
|
||||
if ((arg = values[i]) != null) {
|
||||
// MessageFormat can't deal with javascript date objects
|
||||
// so we need to convert them into java.util.Date instances
|
||||
if (arg instanceof Date) {
|
||||
args[i] = new java.util.Date(arg.getTime());
|
||||
} else {
|
||||
args[i] = arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// use the getter method for retrieving the locale
|
||||
var locale = this.getLocaleGetter()();
|
||||
// format the message
|
||||
try {
|
||||
var msgFormat = new java.text.MessageFormat(message, locale);
|
||||
return msgFormat.format(args);
|
||||
} catch (e) {
|
||||
app.logger.warn("jala.i18n.formatMessage(): Unable to format message '"
|
||||
+ message + "', reason: " + e, e.javaException);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a localized message for the message key passed as
|
||||
* argument. If no localization is found, the message key
|
||||
* is returned. Any additional arguments passed to this function
|
||||
* will be used as replacement values during message rendering.
|
||||
* To reference these values the message can contain placeholders
|
||||
* following "{number}" notation, where <code>number</code> must
|
||||
* match the number of the additional argument (starting with zero).
|
||||
* @param {String} key The message to localize
|
||||
* @returns The translated message
|
||||
* @type String
|
||||
* @see #translate
|
||||
* @see #formatMessage
|
||||
*/
|
||||
jala.I18n.prototype.gettext = function(key /** [value 0][, value 1][, ...] */) {
|
||||
return this.formatMessage(this.translate(key),
|
||||
Array.prototype.splice.call(arguments, 1));
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a localized message for the message key passed as
|
||||
* argument. In contrast to gettext() this method
|
||||
* can handle plural forms based on the amount passed as argument.
|
||||
* If no localization is found, the appropriate message key is
|
||||
* returned. Any additional arguments passed to this function
|
||||
* will be used as replacement values during message rendering.
|
||||
* To reference these values the message can contain placeholders
|
||||
* following "{number}" notation, where <code>number</code> must
|
||||
* match the number of the additional argument (starting with zero).
|
||||
* @param {String} singularKey The singular message to localize
|
||||
* @param {String} pluralKey The plural form of the message to localize
|
||||
* @param {Number} amount The amount which is used to determine
|
||||
* whether the singular or plural form of the message should be returned.
|
||||
* @returns The translated message
|
||||
* @type String
|
||||
* @see #translate
|
||||
* @see #formatMessage
|
||||
*/
|
||||
jala.I18n.prototype.ngettext = function(singularKey, pluralKey, amount /** [value 0][, value 1][, ...] */) {
|
||||
return this.formatMessage(this.translate(singularKey, pluralKey, amount || 0),
|
||||
Array.prototype.splice.call(arguments, 2));
|
||||
};
|
||||
|
||||
/**
|
||||
* A simple proxy method which is used to mark a message string
|
||||
* for the i18n parser as to be translated.
|
||||
* @param {String} key The message that should be seen by the
|
||||
* i18n parser as to be translated.
|
||||
* @returns The message in unmodified form
|
||||
* @type String
|
||||
*/
|
||||
jala.I18n.prototype.markgettext = function(key) {
|
||||
return key;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a translated message. The following macro attributes
|
||||
* are accepted:
|
||||
* <ul>
|
||||
* <li>text: The message to translate (required)</li>
|
||||
* <li>plural: The plural form of the message</li>
|
||||
* <li>values: A list of replacement values. Use a comma to separate more
|
||||
* than one value. Each value is either interpreted as a global property
|
||||
* (if it doesn't containg a dot) or as a property name of the given macro
|
||||
* handler object (eg. "user.name"). If the value of the property is a
|
||||
* HopObject or an Array this macro uses the size() resp. length of the
|
||||
* object, otherwise the string representation of the object will be used.</li>
|
||||
* </ul>
|
||||
* @returns The translated message
|
||||
* @type String
|
||||
* @see #gettext
|
||||
* @see #ngettext
|
||||
*/
|
||||
jala.I18n.prototype.message_macro = function(param) {
|
||||
if (param.text) {
|
||||
var args = [param.text];
|
||||
if (param.plural) {
|
||||
args[args.length] = param.plural;
|
||||
}
|
||||
if (param.values != null) {
|
||||
var arr = param.values.split(/\s*,\s*/g);
|
||||
// convert replacement values: if the value name doesn't contain
|
||||
// a dot, look for a global property with that name, otherwise
|
||||
// for a property of the specified macro handler object.
|
||||
var propName, dotIdx, handlerName, handler;
|
||||
for (var i=0;i<arr.length;i++) {
|
||||
if ((propName = arr[i]) != null) {
|
||||
var value = null;
|
||||
if ((dotIdx = propName.indexOf(".")) > 0) {
|
||||
var handlerName = propName.substring(0, dotIdx);
|
||||
if (handlerName == "request") {
|
||||
handler = req.data;
|
||||
} else if (handlerName == "response") {
|
||||
handler = res.data;
|
||||
} else if (!(handler = res.handlers[handlerName])) {
|
||||
continue;
|
||||
}
|
||||
propName = propName.substring(dotIdx + 1);
|
||||
// primitive security: don't allow access to internal properties
|
||||
// and a property named "password"
|
||||
if (propName.charAt(0) != "_" && propName.toLowerCase() != "password") {
|
||||
value = handler[propName];
|
||||
}
|
||||
} else {
|
||||
value = global[propName];
|
||||
}
|
||||
if (value != null) {
|
||||
// if its a HopObject collection or Array, use its size/length
|
||||
// as value
|
||||
if (value instanceof HopObject) {
|
||||
value = value.size();
|
||||
} else if (value instanceof Array) {
|
||||
value = value.length;
|
||||
}
|
||||
}
|
||||
args[args.length] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (param.plural) {
|
||||
return this.ngettext.apply(this, args);
|
||||
} else {
|
||||
return this.gettext.apply(this, args);
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Default i18n class instance.
|
||||
* @type jala.I18n
|
||||
* @final
|
||||
*/
|
||||
jala.i18n = new jala.I18n();
|
||||
|
||||
/**
|
||||
* For convenience reasons the public methods and macros are
|
||||
* put into global scope too
|
||||
*/
|
||||
var gettext = function() {
|
||||
return jala.i18n.gettext.apply(jala.i18n, arguments);
|
||||
};
|
||||
var ngettext = function() {
|
||||
return jala.i18n.ngettext.apply(jala.i18n, arguments);
|
||||
};
|
||||
var markgettext = function() {
|
||||
return jala.i18n.markgettext.apply(jala.i18n, arguments);
|
||||
};
|
||||
var message_macro = function() {
|
||||
return jala.i18n.message_macro.apply(jala.i18n, arguments);
|
||||
};
|
|
@ -1,362 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the jala.ImageFilter class.
|
||||
*/
|
||||
|
||||
|
||||
// Define the global namespace for Jala modules
|
||||
if (!global.jala) {
|
||||
global.jala = {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new ImageFilter object
|
||||
* @class This class provides several image manipulating
|
||||
* methods. Most of this filter library is based on filters created
|
||||
* by Janne Kipinä for JAlbum. For more information have a look
|
||||
* at http://www.ratol.fi/~jakipina/java/
|
||||
* @param {Object} img Either
|
||||
<ul>
|
||||
<li>an instance of helma.image.ImageWrapper</li>
|
||||
<li>the path to the image file as String</li>
|
||||
<li>an instance of helma.File representing the image file</li>
|
||||
<li>an instance of java.io.File representing the image file</li>
|
||||
</ul>
|
||||
* @constructor
|
||||
*/
|
||||
jala.ImageFilter = function(img) {
|
||||
/**
|
||||
* The buffered image to work on
|
||||
* @type java.awt.image.BufferedImage
|
||||
* @private
|
||||
*/
|
||||
var bi;
|
||||
|
||||
/**
|
||||
* Perfoms a gaussian operation (unsharp masking or blurring)
|
||||
* on the image using the kernelFactory passed as argument
|
||||
* @param {Number} radius The radius
|
||||
* @param {Number} amount The amount
|
||||
* @param {Function} kernelFactory Factory method to call for building the kernel
|
||||
* @private
|
||||
*/
|
||||
var gaussianOp = function(radius, amount, kernelFactory) {
|
||||
var DEFAULT_RADIUS = 2;
|
||||
var MINIMUM_RADIUS = 1;
|
||||
var MAXIMUM_RADIUS = 10;
|
||||
var DEFAULT_AMOUNT = 15;
|
||||
var MINIMUM_AMOUNT = 1;
|
||||
var MAXIMUM_AMOUNT = 100;
|
||||
|
||||
// correct arguments if necessary
|
||||
if (isNaN(radius = Math.min(Math.max(radius, MINIMUM_RADIUS), MAXIMUM_RADIUS)))
|
||||
radius = DEFAULT_RADIUS;
|
||||
if (isNaN(amount = Math.min(Math.max(amount, MINIMUM_AMOUNT), MAXIMUM_AMOUNT)))
|
||||
amount = DEFAULT_AMOUNT;
|
||||
|
||||
if ((bi.getWidth() < bi.getHeight()) && (radius > bi.getWidth())) {
|
||||
radius = bi.getWidth();
|
||||
} else if ((bi.getHeight() < bi.getWidth()) && (radius > bi.getHeight())) {
|
||||
radius = bi.getHeight();
|
||||
}
|
||||
|
||||
var size = (radius * 2) + 1;
|
||||
var deviation = amount / 20;
|
||||
var elements = kernelFactory(size, deviation);
|
||||
var large = jala.ImageFilter.getEnlargedImageWithMirroring(bi, radius);
|
||||
var resultImg = new java.awt.image.BufferedImage(large.getWidth(), large.getHeight(), large.getType());
|
||||
var kernel = new java.awt.image.Kernel(size, size, elements);
|
||||
var cop = new java.awt.image.ConvolveOp(kernel, java.awt.image.ConvolveOp.EDGE_NO_OP, null);
|
||||
cop.filter(large, resultImg);
|
||||
// replace the wrapped buffered image with the modified one
|
||||
bi = resultImg.getSubimage(radius, radius, bi.getWidth(), bi.getHeight());
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sharpens the image using a plain sharpening kernel.
|
||||
* @param {Number} amount The amount of sharpening to apply
|
||||
*/
|
||||
this.sharpen = function(amount) {
|
||||
var DEFAULT = 20;
|
||||
var MINIMUM = 1;
|
||||
var MAXIMUM = 100;
|
||||
// correct argument if necessary
|
||||
if (isNaN(Math.min(Math.max(amount, MINIMUM), MAXIMUM)))
|
||||
amount = DEFAULT;
|
||||
var sharpened = new java.awt.image.BufferedImage(bi.getWidth(), bi.getHeight(), bi.getType());
|
||||
var kernel = new java.awt.image.Kernel(3, 3, jala.ImageFilter.getSharpeningKernel(amount));
|
||||
var cop = new java.awt.image.ConvolveOp(kernel, java.awt.image.ConvolveOp.EDGE_NO_OP, null);
|
||||
cop.filter(bi, sharpened);
|
||||
bi = sharpened;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Performs an unsharp mask operation on the image
|
||||
* @param {Number} radius The radius
|
||||
* @param {Number} amount The amount
|
||||
*/
|
||||
this.unsharpMask = function(radius, amount) {
|
||||
gaussianOp(radius, amount, jala.ImageFilter.getUnsharpMaskKernel);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Performs a gaussian blur operation on the image
|
||||
* @param {Number} radius The radius
|
||||
* @param {Number} amount The amount
|
||||
*/
|
||||
this.gaussianBlur = function(radius, amount) {
|
||||
gaussianOp(radius, amount, jala.ImageFilter.getGaussianBlurKernel);
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the image that has been worked on
|
||||
* @return An instance of helma.image.ImageWrapper
|
||||
* @type helma.image.ImageWrapper
|
||||
*/
|
||||
this.getImage = function() {
|
||||
var generator = Packages.helma.image.ImageGenerator.getInstance();
|
||||
return new Packages.helma.image.ImageWrapper(bi,
|
||||
bi.getWidth(),
|
||||
bi.getHeight(),
|
||||
generator);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the wrapped image as byte array, to use eg. in conjunction
|
||||
* with res.writeBinary()
|
||||
* @returns The wrapped image as byte array
|
||||
* @type byte[]
|
||||
*/
|
||||
this.getBytes = function() {
|
||||
var outStream = new java.io.ByteArrayOutputStream();
|
||||
Packages.javax.imageio.ImageIO.write(bi, "jpeg", outStream);
|
||||
var bytes = outStream.toByteArray();
|
||||
outStream.close();
|
||||
return bytes;
|
||||
};
|
||||
|
||||
/**
|
||||
* constructor body
|
||||
* @ignore
|
||||
*/
|
||||
if (arguments.length == 0 || img == null) {
|
||||
throw "jala.ImageFilter: insufficient arguments";
|
||||
} else if (img instanceof Packages.helma.image.ImageWrapper) {
|
||||
bi = img.getBufferedImage();
|
||||
} else {
|
||||
if (typeof(img) == "string") {
|
||||
var inStream = new java.io.FileInputStream(new java.io.File(img));
|
||||
} else {
|
||||
var inStream = new java.io.FileInputStream(img);
|
||||
}
|
||||
var decoder = Packages.com.sun.image.codec.jpeg.JPEGCodec.createJPEGDecoder(inStream);
|
||||
bi = decoder.decodeAsBufferedImage();
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
jala.ImageFilter.prototype.toString = function() {
|
||||
return "[jala.ImageFilter]";
|
||||
};
|
||||
|
||||
/**
|
||||
* Transforms an image into a bigger one while mirroring the edges
|
||||
* This method is used to apply the filtering up to the edges
|
||||
* of an image (otherwise the image would keep an unmodified
|
||||
* border).
|
||||
* @param {java.awt.image.BufferedImage} bi The buffered image to transform
|
||||
* @param {Number} size The size of the border area
|
||||
* @returns The transformed image
|
||||
* @type java.awt.image.BufferedImage
|
||||
* @private
|
||||
*/
|
||||
jala.ImageFilter.getEnlargedImageWithMirroring = function(bi, size) {
|
||||
|
||||
var doFlip = function(bi, sx, sy, dist) {
|
||||
var out = new java.awt.image.BufferedImage(bi.getWidth(), bi.getHeight(), bi.getType());
|
||||
var transform = java.awt.geom.AffineTransform.getScaleInstance(sx, sy);
|
||||
(sx < sy) ? transform.translate(-dist, 0) : transform.translate(0, -dist);
|
||||
var atop = new java.awt.image.AffineTransformOp(transform,
|
||||
java.awt.image.AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
|
||||
out = atop["filter(java.awt.image.BufferedImage,java.awt.image.BufferedImage)"](bi, null);
|
||||
return out;
|
||||
}
|
||||
|
||||
var doHorizontalFlip = function(bi) {
|
||||
return doFlip(bi, -1, 1, bi.getWidth());
|
||||
}
|
||||
|
||||
var doVerticalFlip = function(bi) {
|
||||
return doFlip(bi, 1, -1, bi.getHeight());
|
||||
}
|
||||
|
||||
var width = bi.getWidth() + 2 * size;
|
||||
var height = bi.getHeight() + 2 * size;
|
||||
var out = new java.awt.image.BufferedImage(width, height, bi.getType());
|
||||
var g = out.createGraphics();
|
||||
// due to method overloading exactly define the method to be called
|
||||
var func = "drawImage(java.awt.Image,int,int,java.awt.image.ImageObserver)";
|
||||
g[func](bi, size, size, null);
|
||||
|
||||
var part;
|
||||
//top-left corner
|
||||
part = bi.getSubimage(0, 0, size, size);
|
||||
part = doHorizontalFlip(part);
|
||||
part = doVerticalFlip(part);
|
||||
g[func](part, 0, 0, null);
|
||||
//top-right corner
|
||||
part = bi.getSubimage(bi.getWidth()-size, 0, size, size);
|
||||
part = doHorizontalFlip(part);
|
||||
part = doVerticalFlip(part);
|
||||
g[func](part, width-size, 0, null);
|
||||
//bottom-left corner
|
||||
part = bi.getSubimage(0, bi.getHeight()-size, size, size);
|
||||
part = doHorizontalFlip(part);
|
||||
part = doVerticalFlip(part);
|
||||
g[func](part, 0, height-size, null);
|
||||
//bottom-right corner
|
||||
part = bi.getSubimage(bi.getWidth()-size, bi.getHeight()-size, size, size);
|
||||
part = doHorizontalFlip(part);
|
||||
part = doVerticalFlip(part);
|
||||
g[func](part, width-size, height-size, null);
|
||||
//left border
|
||||
part = bi.getSubimage(0, 0, size, bi.getHeight());
|
||||
part = doHorizontalFlip(part);
|
||||
g[func](part, 0, size, null);
|
||||
//right border
|
||||
part = bi.getSubimage(bi.getWidth()-size, 0, size, bi.getHeight());
|
||||
part = doHorizontalFlip(part);
|
||||
g[func](part, width-size, size, null);
|
||||
//top border
|
||||
part = bi.getSubimage(0, 0, bi.getWidth(), size);
|
||||
part = doVerticalFlip(part);
|
||||
g[func](part, size, 0, null);
|
||||
//bottom border
|
||||
part = bi.getSubimage(0, bi.getHeight()-size, bi.getWidth(), size);
|
||||
part = doVerticalFlip(part);
|
||||
g[func](part, size, height-size, null);
|
||||
return out;
|
||||
};
|
||||
|
||||
/**
|
||||
* Factory method for a gaussian blur kernel
|
||||
* @returns The gaussian blur kernel
|
||||
* @param {Number} size The size of the kernel
|
||||
* @param {Number} deviation The deviation to use
|
||||
* @returns The gaussian blur kernel
|
||||
* @type float[]
|
||||
* @private
|
||||
*/
|
||||
jala.ImageFilter.getGaussianBlurKernel = function(size, deviation) {
|
||||
var nominator = 2 * deviation * deviation;
|
||||
var kernel = java.lang.reflect.Array.newInstance(java.lang.Float.TYPE, size*size);
|
||||
var center = (size - 1) / 2;
|
||||
var limit = size - 1;
|
||||
var xx, yy;
|
||||
var sum = 0;
|
||||
var value = 0;
|
||||
for (var y=0; y<size; y++) {
|
||||
for (var x=0; x<size; x++) {
|
||||
if ((y <= center) && (x <= center)) {
|
||||
if (x >= y) {
|
||||
//calculate new value
|
||||
xx = center - x;
|
||||
yy = center - y;
|
||||
value = Math.exp(-(xx*xx + yy*yy) / nominator);
|
||||
kernel[(y*size)+x] = value;
|
||||
sum += value;
|
||||
} else {
|
||||
//copy existing value
|
||||
value = kernel[(x*size)+y];
|
||||
kernel[(y*size)+x] = value;
|
||||
sum += value;
|
||||
}
|
||||
} else {
|
||||
xx = x;
|
||||
yy = y;
|
||||
if (yy > center)
|
||||
yy = limit - yy;
|
||||
if (xx > center)
|
||||
xx = limit - xx;
|
||||
value = kernel[(yy*size)+xx];
|
||||
kernel[(y*size)+x] = value;
|
||||
sum += value;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (var i=0; i<kernel.length; i++) {
|
||||
kernel[i] = kernel[i] / sum;
|
||||
}
|
||||
return kernel;
|
||||
};
|
||||
|
||||
/**
|
||||
* Factory method for an unsharp mask kernel
|
||||
* @param {Number} size The size of the kernel
|
||||
* @param {Number} deviation The deviation to use
|
||||
* @returns The unsharp mask kernel
|
||||
* @type float[]
|
||||
* @private
|
||||
*/
|
||||
jala.ImageFilter.getUnsharpMaskKernel = function(size, deviation) {
|
||||
var elements = jala.ImageFilter.getGaussianBlurKernel(size, deviation);
|
||||
var center = ((size * size) - 1) / 2;
|
||||
elements[center] = 0;
|
||||
var sum = 0;
|
||||
for (var i=0; i<elements.length; i++) {
|
||||
sum += elements[i];
|
||||
elements[i] = -elements[i];
|
||||
}
|
||||
elements[center] = sum + 1;
|
||||
return elements;
|
||||
};
|
||||
|
||||
/**
|
||||
* Factory method for a sharpening kernel
|
||||
* @param {Number} amount The amount of sharpening to use
|
||||
* @return The sharpening kernel
|
||||
* @type float[]
|
||||
* @private
|
||||
*/
|
||||
jala.ImageFilter.getSharpeningKernel = function(amount) {
|
||||
var kernel = java.lang.reflect.Array.newInstance(java.lang.Float.TYPE, 9);
|
||||
var corner = 0;
|
||||
var side = amount / -50;
|
||||
var center = (side * -4.0) + (corner * -4.0) + 1.0;
|
||||
kernel[0] = kernel[2] = kernel[6] = kernel[8] = corner;
|
||||
kernel[1] = kernel[3] = kernel[5] = kernel[7] = side;
|
||||
kernel[4] = center;
|
||||
return kernel;
|
||||
};
|
||||
|
|
@ -1,765 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the jala.IndexManager class.
|
||||
*/
|
||||
|
||||
|
||||
// Define the global namespace for Jala modules
|
||||
if (!global.jala) {
|
||||
global.jala = {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* HelmaLib dependencies
|
||||
*/
|
||||
app.addRepository("modules/helma/Search.js");
|
||||
app.addRepository("modules/helma/File.js");
|
||||
|
||||
/**
|
||||
* Constructs a new IndexManager object.
|
||||
* @class This class basically sits on top of a helma.Search.Index instance
|
||||
* and provides methods for adding, removing and optimizing the underlying index.
|
||||
* All methods generate jobs that are put into an internal queue which is
|
||||
* processed asynchronously by a separate worker thread. This means all calls
|
||||
* to add(), remove() and optimize() will return immediately, but the changes to
|
||||
* the index will be done within a short delay. Please keep in mind to change the
|
||||
* status of this IndexManager instance to REBUILDING before starting to rebuild
|
||||
* the index, as this ensures that all add/remove/optimize jobs will stay in the
|
||||
* queue and will only be processed after switching the status back to NORMAL.
|
||||
* This ensures that objects that have been modified during a rebuilding process
|
||||
* are re-indexed properly afterwards.
|
||||
* @param {String} name The name of the index, which is the name of the directory
|
||||
* the index already resides or will be created in.
|
||||
* @param {helma.File} dir The base directory where this index's directory
|
||||
* is already existing or will be created in. If not specified a RAM directory
|
||||
* is used.
|
||||
* @param {String} lang The language of the documents in this index. This leads
|
||||
* to the proper Lucene analyzer being used for indexing documents.
|
||||
* @constructor
|
||||
* @see helma.Search.createIndex
|
||||
*/
|
||||
jala.IndexManager = function IndexManager(name, dir, lang) {
|
||||
|
||||
/**
|
||||
* Private variable containing the worker thread
|
||||
* @private
|
||||
*/
|
||||
var thread = null;
|
||||
|
||||
/**
|
||||
* Private flag indicating that the worker thread should stop
|
||||
* @type Boolean
|
||||
* @private
|
||||
*/
|
||||
var interrupted = false;
|
||||
|
||||
/**
|
||||
* Private variable containing the index managed by
|
||||
* this IndexManager instance.
|
||||
* @private
|
||||
*/
|
||||
var index = null;
|
||||
|
||||
/**
|
||||
* Private variable containing a status indicator.
|
||||
* @type Number
|
||||
* @private
|
||||
*/
|
||||
var status = jala.IndexManager.NORMAL;
|
||||
|
||||
/**
|
||||
* Synchronized linked list that functions as a queue for
|
||||
* asynchronous processing of index manipulation jobs.
|
||||
* @type java.util.LinkedList
|
||||
* @private
|
||||
* @see jala.IndexManager.Job
|
||||
*/
|
||||
var queue = java.util.Collections.synchronizedList(new java.util.LinkedList());
|
||||
|
||||
/**
|
||||
* The name of the unique identifier field in the index. Defaults to "id".
|
||||
* @type String
|
||||
* @private
|
||||
*/
|
||||
var idFieldname = "id";
|
||||
|
||||
/**
|
||||
* The index directory
|
||||
* @type Packages.org.apache.lucene.store.Directory
|
||||
* @private
|
||||
*/
|
||||
var indexDirectory = null;
|
||||
|
||||
/**
|
||||
* The searcher utilized by {@link #search}
|
||||
* @type jala.IndexManager.Searcher
|
||||
* @private
|
||||
*/
|
||||
var searcher = null;
|
||||
|
||||
/**
|
||||
* Returns the directory of the underlying index
|
||||
* @returns The directory of the underlying index
|
||||
* @type Packages.org.apache.lucene.store.Directory
|
||||
*/
|
||||
this.getDirectory = function() {
|
||||
return indexDirectory;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the underlying index.
|
||||
* @returns The index this queue is working on.
|
||||
* @type helma.Search.Index
|
||||
*/
|
||||
this.getIndex = function() {
|
||||
return index;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the status of this manager.
|
||||
* @returns The status of this index manager.
|
||||
* @type Number
|
||||
* @see #NORMAL
|
||||
* @see #REBUILDING
|
||||
*/
|
||||
this.getStatus = function() {
|
||||
return status;
|
||||
};
|
||||
|
||||
/**
|
||||
* Modifies the status of this manager, which has implications
|
||||
* on how index modifying jobs are handled. If the status
|
||||
* is {@link #REBUILDING}, all jobs are queued until the status
|
||||
* is set back to {@link #NORMAL}.
|
||||
* @param {Number} s The new status of this manager.
|
||||
* @see #NORMAL
|
||||
* @see #REBUILDING
|
||||
*/
|
||||
this.setStatus = function(s) {
|
||||
status = s;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the queue this index manager is using.
|
||||
* @returns The queue.
|
||||
* @type java.util.LinkedList
|
||||
*/
|
||||
this.getQueue = function() {
|
||||
return queue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the name of the index manger, which
|
||||
* is equal to the name of the underlying index
|
||||
* @returns The name of the index manager
|
||||
* @type String
|
||||
*/
|
||||
this.getName = function() {
|
||||
return name;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the name of the field containing the unique identifier
|
||||
* of document objects in the index wrapped by this IndexManager.
|
||||
* Defaults to "id".
|
||||
* @returns The name of the id field in the index
|
||||
* @type String
|
||||
* @see #setIdFieldname
|
||||
*/
|
||||
this.getIdFieldname = function() {
|
||||
return idFieldname;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the name of the field containing the unique identifier
|
||||
* of document objects in the index wrapped by this IndexManager.
|
||||
* @see #getIdFieldname
|
||||
*/
|
||||
this.setIdFieldname = function(name) {
|
||||
idFieldname = name;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the underlying index is currently optimized.
|
||||
* @returns True in case the index is optimized, false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.hasOptimizingJob = function() {
|
||||
for (var i=0; i<queue.size(); i++) {
|
||||
if (queue.get(i).type == jala.IndexManager.Job.OPTIMIZE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the underlying index is currently rebuilding.
|
||||
* @returns True in case the index is rebuilding, false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.isRebuilding = function() {
|
||||
return status == jala.IndexManager.REBUILDING;
|
||||
};
|
||||
|
||||
/**
|
||||
* Starts the IndexManager worker thread that processes the job queue
|
||||
*/
|
||||
this.start = function() {
|
||||
if (!this.isRunning()) {
|
||||
interrupted = false;
|
||||
thread = app.invokeAsync(this, function() {
|
||||
while (interrupted === false) {
|
||||
if (this.getStatus() != jala.IndexManager.REBUILDING && !queue.isEmpty()) {
|
||||
var job = queue.remove(0);
|
||||
if (this.processJob(job) === false) {
|
||||
// processing job failed, check if we should re-add
|
||||
if (job.errors < jala.IndexManager.MAXTRIES) {
|
||||
// increment error counter and put back into queue
|
||||
job.errors += 1;
|
||||
queue.add(job);
|
||||
} else {
|
||||
this.log("error", "error during queue flush: tried " +
|
||||
jala.IndexManager.MAXTRIES + " times to handle " +
|
||||
job.type + " job " + ", giving up.");
|
||||
}
|
||||
}
|
||||
this.log("debug", "remaining jobs " + queue.size());
|
||||
// if no more jobs are waiting, optimize the index and re-open
|
||||
// the index searcher to make changes visible
|
||||
if (queue.isEmpty()) {
|
||||
var start = java.lang.System.currentTimeMillis();
|
||||
try {
|
||||
this.getIndex().optimize();
|
||||
this.log("optimized index in " + jala.IndexManager.getRuntime(start) + " ms");
|
||||
this.initSearcher();
|
||||
} catch (e) {
|
||||
this.log("error", "Unable to optimize index or re-open searcher, reason: " + e.toString());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// wait for 100ms before checking again
|
||||
java.lang.Thread.sleep(100);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}, [], -1);
|
||||
this.log("started successfully");
|
||||
} else {
|
||||
this.log("already running");
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stops this IndexManager instance. This function waits for 10 seconds
|
||||
* maximum for the worker thread to stop.
|
||||
* @returns True if the worker thread stopped successfully, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
this.stop = function() {
|
||||
interrupted = true;
|
||||
var result;
|
||||
if ((result = this.isRunning()) === true) {
|
||||
if ((result = thread.waitForResult(10000)) === true) {
|
||||
thread = null;
|
||||
this.log("stopped successfully");
|
||||
} else {
|
||||
result = false;
|
||||
this.log("error", "unable to stop");
|
||||
}
|
||||
} else {
|
||||
this.log("info", "already stopped");
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if this IndexManager instance is running
|
||||
* @returns True if this IndexManager instance is running, false otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.isRunning = function() {
|
||||
if (thread != null) {
|
||||
return thread.running;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Read only reference containing the running status of this IndexManager
|
||||
* @type Boolean
|
||||
*/
|
||||
this.running; // for api documentation only, is overwritten by getter below
|
||||
this.__defineGetter__("running", function() {
|
||||
return this.isRunning()
|
||||
});
|
||||
|
||||
/**
|
||||
* Read only reference containing the number of pending jobs
|
||||
* @type Number
|
||||
*/
|
||||
this.pending; // for api documentation only, is overwritten by getter below
|
||||
this.__defineGetter__("pending", function() {
|
||||
return queue.size()
|
||||
});
|
||||
|
||||
/**
|
||||
* Initializes the searcher
|
||||
* @private
|
||||
*/
|
||||
this.initSearcher = function() {
|
||||
searcher = new Packages.org.apache.lucene.search.IndexSearcher(indexDirectory);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the searcher of this index manager
|
||||
* @returns The searcher of this index manager
|
||||
* @type org.apache.lucene.search.IndexSearcher
|
||||
* @private
|
||||
*/
|
||||
this.getSearcher = function() {
|
||||
if (searcher === null) {
|
||||
this.initSearcher();
|
||||
}
|
||||
return searcher;
|
||||
};
|
||||
|
||||
/**
|
||||
* Main constructor body. Initializes the underlying index.
|
||||
*/
|
||||
var search = new helma.Search();
|
||||
var analyzer = helma.Search.getAnalyzer(lang);
|
||||
if (dir != null) {
|
||||
indexDirectory = search.getDirectory(new helma.File(dir, name));
|
||||
this.log("created/mounted " + indexDirectory);
|
||||
} else {
|
||||
indexDirectory = search.getRAMDirectory();
|
||||
this.log("created new RAM directory");
|
||||
}
|
||||
index = search.createIndex(indexDirectory, analyzer);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constant defining the maximum number of tries to add/remove
|
||||
* an object to/from the underlying index.
|
||||
* @type Number
|
||||
* @final
|
||||
*/
|
||||
jala.IndexManager.MAXTRIES = 10;
|
||||
|
||||
/**
|
||||
* Constant defining normal mode of this index manager.
|
||||
* @type Number
|
||||
* @final
|
||||
*/
|
||||
jala.IndexManager.NORMAL = 1;
|
||||
|
||||
/**
|
||||
* Constant defining rebuilding mode of this index manager.
|
||||
* @type Number
|
||||
* @final
|
||||
*/
|
||||
jala.IndexManager.REBUILDING = 2;
|
||||
|
||||
/**
|
||||
* Returns the milliseconds elapsed between the current timestamp
|
||||
* and the one passed as argument.
|
||||
* @returns The elapsed time in millis.
|
||||
* @type Number
|
||||
* @private
|
||||
*/
|
||||
jala.IndexManager.getRuntime = function(millis) {
|
||||
return java.lang.System.currentTimeMillis() - millis;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
jala.IndexManager.prototype.toString = function() {
|
||||
return "[" + this.constructor.name + " '" + this.getName() + "' (" +
|
||||
this.pending + " objects queued)]";
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function that prefixes every log message with
|
||||
* the name of the IndexManager.
|
||||
* @param {String} level An optional logging level. Accepted values
|
||||
* @param {String} msg The log message
|
||||
* are "debug", "info", "warn" and "error".
|
||||
*/
|
||||
jala.IndexManager.prototype.log = function(/* msg, level */) {
|
||||
var level = "info", message;
|
||||
if (arguments.length == 2) {
|
||||
level = arguments[0];
|
||||
message = arguments[1];
|
||||
} else {
|
||||
message = arguments[0];
|
||||
}
|
||||
app.logger[level]("[" + this.constructor.name + " '" +
|
||||
this.getName() + "'] " + message);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Static helper method that returns the value of the "id"
|
||||
* field of a document object.
|
||||
* @param {helma.Search.Document} doc The document whose id
|
||||
* should be returned.
|
||||
* @private
|
||||
*/
|
||||
jala.IndexManager.prototype.getDocumentId = function(doc) {
|
||||
try {
|
||||
return doc.getField(this.getIdFieldname()).value;
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Queues the document object passed as argument for addition to the underlying
|
||||
* index. This includes that all existing documents with the same identifier will
|
||||
* be removed before the object passed as argument is added.
|
||||
* @param {helma.Search.Document} doc The document object that should be
|
||||
* added to the underlying index.
|
||||
* @returns True if the job was added successfully to the internal queue,
|
||||
* false otherwise.
|
||||
* @type Boolean
|
||||
* @see helma.Search.Document
|
||||
*/
|
||||
jala.IndexManager.prototype.add = function(doc) {
|
||||
var id;
|
||||
if (!doc) {
|
||||
this.log("error", "missing document object to add");
|
||||
return false;
|
||||
} else if ((id = this.getDocumentId(doc)) == null) {
|
||||
this.log("error", "document doesn't contain an Id field '" +
|
||||
this.getIdFieldname() + "'");
|
||||
return false;
|
||||
}
|
||||
// the job's callback function which actually adds the document to the index
|
||||
var callback = function() {
|
||||
var start = java.lang.System.currentTimeMillis();
|
||||
this.getIndex().updateDocument(doc, this.getIdFieldname());
|
||||
this.log("debug", "added document with Id " + id +
|
||||
" to index in " + jala.IndexManager.getRuntime(start) + " ms");
|
||||
return;
|
||||
}
|
||||
var job = new jala.IndexManager.Job(jala.IndexManager.Job.ADD, callback);
|
||||
this.getQueue().add(job);
|
||||
this.log("debug", "queued adding document " + id + " to index");
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Queues the removal of all index documents whose identifier value ("id" by default)
|
||||
* matches the number passed as argument.
|
||||
* @param {Number} id The identifier value
|
||||
* @returns True if the removal job was added successfully to the queue, false
|
||||
* otherwise.
|
||||
* @type Boolean
|
||||
*/
|
||||
jala.IndexManager.prototype.remove = function(id) {
|
||||
if (id === null || isNaN(id)) {
|
||||
this.log("error", "missing or invalid document id to remove");
|
||||
return false;
|
||||
}
|
||||
// the job's callback function which actually removes all documents
|
||||
// with the given id from the index
|
||||
var callback = function() {
|
||||
var start = java.lang.System.currentTimeMillis();
|
||||
this.getIndex().removeDocument(this.getIdFieldname(), parseInt(id, 10));
|
||||
this.log("debug", "removed document with Id " + id +
|
||||
" from index in " + jala.IndexManager.getRuntime(start) + " ms");
|
||||
};
|
||||
var job = new jala.IndexManager.Job(jala.IndexManager.Job.REMOVE, callback);
|
||||
this.getQueue().add(job);
|
||||
this.log("debug", "queued removal of document with Id " + id);
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Queues the optimization of the underlying index. Normally there is no need
|
||||
* to call this method explicitly, as the index will be optimized after all
|
||||
* queued jobs have been processed.
|
||||
* @returns True if the optimizing job was added, false otherwise, which means
|
||||
* that there is already an optimizing job waiting in the queue.
|
||||
* @type Boolean
|
||||
*/
|
||||
jala.IndexManager.prototype.optimize = function() {
|
||||
if (this.hasOptimizingJob()) {
|
||||
return false;
|
||||
}
|
||||
var callback = function() {
|
||||
var start = java.lang.System.currentTimeMillis();
|
||||
this.getIndex().optimize();
|
||||
this.log("optimized index in " + jala.IndexManager.getRuntime(start) + " ms");
|
||||
// re-open index searcher, so that changes are seen
|
||||
this.initSearcher();
|
||||
return;
|
||||
};
|
||||
var job = new jala.IndexManager.Job(jala.IndexManager.Job.OPTIMIZE, callback);
|
||||
this.getQueue().add(job);
|
||||
this.log("debug", "queued index optimization");
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Processes a single queued job
|
||||
* @param {Object} job
|
||||
* @private
|
||||
*/
|
||||
jala.IndexManager.prototype.processJob = function(job) {
|
||||
this.log("debug", job.type + " job has been in queue for " +
|
||||
jala.IndexManager.getRuntime(job.createtime.getTime()) +
|
||||
" ms, processing now...");
|
||||
try {
|
||||
job.callback.call(this);
|
||||
} catch (e) {
|
||||
this.log("error", "Exception while processing job " + job.type + ": " + e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Searches the underlying index using the searcher of this index manager
|
||||
* @param {helma.Search.Query|org.apache.lucene.search.Query} query The query
|
||||
* to execute. Can be either an instance of helma.Search.Query, or an instance
|
||||
* of org.apache.lucene.search.Query
|
||||
* @param {helma.Search.QueryFilter|org.apache.lucene.search.Filter} filter
|
||||
* An optional query filter
|
||||
* @param {Array} sortFields An optional array containing
|
||||
* org.apache.lucene.search.SortField instances to use for sorting the result
|
||||
* @returns A HitCollection containing the search results
|
||||
* @type helma.Search.HitCollection
|
||||
*/
|
||||
jala.IndexManager.prototype.search = function(query, filter, sortFields) {
|
||||
var pkg = Packages.org.apache.lucene;
|
||||
if (query == null || (!(query instanceof helma.Search.Query) &&
|
||||
!(query instanceof pkg.search.Query))) {
|
||||
throw "jala.IndexManager search(): missing or invalid query";
|
||||
} else if (query instanceof helma.Search.Query) {
|
||||
// unwrap query
|
||||
query = query.getQuery();
|
||||
}
|
||||
if (filter != null && filter instanceof helma.Search.QueryFilter) {
|
||||
// unwrap filter
|
||||
filter = filter.getFilter();
|
||||
}
|
||||
|
||||
var searcher = this.getSearcher();
|
||||
var analyzer = this.getIndex().getAnalyzer();
|
||||
var hits;
|
||||
if (sortFields != null && sortFields.length > 0) {
|
||||
// convert the array with sortfields to a java array
|
||||
var arr = java.lang.reflect.Array.newInstance(pkg.search.SortField, sortFields.length);
|
||||
sortFields.forEach(function(sortField, idx) {
|
||||
arr[idx] = sortField;
|
||||
});
|
||||
var sort = pkg.search.Sort(arr);
|
||||
if (filter) {
|
||||
hits = searcher.search(query, filter, sort);
|
||||
} else {
|
||||
hits = searcher.search(query, sort);
|
||||
}
|
||||
} else if (filter) {
|
||||
hits = searcher.search(query, filter);
|
||||
} else {
|
||||
hits = searcher.search(query);
|
||||
}
|
||||
this.log("debug", "Query: " + query.toString());
|
||||
return new helma.Search.HitCollection(hits);
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses the query string passed as argument into a lucene Query instance
|
||||
* @param {String} queryStr The query string to parse
|
||||
* @param {Array} fields An array containing the names of the files to search in
|
||||
* @param {Object} boostMap An optional object containing properties whose name denotes
|
||||
* the name of the field to boost in the query, and the value the boost value.
|
||||
* @returns The query
|
||||
* @type org.apache.lucene.search.Query
|
||||
*/
|
||||
jala.IndexManager.prototype.parseQuery = function(queryStr, fields, boostMap) {
|
||||
if (queryStr == null || typeof(queryStr) !== "string") {
|
||||
throw "IndexManager.parseQuery(): missing or invalid query string";
|
||||
}
|
||||
if (fields == null || fields.constructor !== Array || fields.length < 1) {
|
||||
throw "IndexManager.parseQuery(): missing fields argument";
|
||||
}
|
||||
var query = null;
|
||||
var analyzer = this.getIndex().getAnalyzer();
|
||||
var pkg = Packages.org.apache.lucene;
|
||||
var map = null;
|
||||
if (boostMap != null) {
|
||||
// convert the javascript object into a HashMap
|
||||
map = new java.util.HashMap();
|
||||
for (var name in boostMap) {
|
||||
map.put(name, new java.lang.Float(boostMap[name]));
|
||||
}
|
||||
}
|
||||
var parser;
|
||||
try {
|
||||
if (fields.length > 1) {
|
||||
parser = new pkg.queryParser.MultiFieldQueryParser(fields, analyzer, map);
|
||||
} else {
|
||||
parser = new pkg.queryParser.QueryParser(fields, analyzer);
|
||||
}
|
||||
query = parser.parse(queryStr);
|
||||
} catch (e) {
|
||||
// ignore, but write a message to debug log
|
||||
app.logger.debug("Unable to construct search query '" + queryStr +
|
||||
"', reason: " + e);
|
||||
}
|
||||
return query;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses the query passed as argument and returns a caching filter. If an array
|
||||
* with more than one query strings is passed as argument, this method constructs
|
||||
* a boolean query filter where all queries in the array must match.
|
||||
* @param {String|Array} query Either a query string, or an array containing
|
||||
* one or more query strings
|
||||
* @param {org.apache.lucene.analysis.Analyzer} analyzer Optional analyzer
|
||||
* to use when parsing the filter query
|
||||
* @returns A caching query filter
|
||||
* @type org.apache.lucene.search.CachingWrapperFilter
|
||||
*/
|
||||
jala.IndexManager.prototype.parseQueryFilter = function(query, analyzer) {
|
||||
var filter = null;
|
||||
if (query != null) {
|
||||
var pkg = Packages.org.apache.lucene;
|
||||
// use the index' analyzer if none has been specified
|
||||
if (analyzer == null) {
|
||||
analyzer = this.getIndex().getAnalyzer();
|
||||
}
|
||||
var parser = new pkg.queryParser.QueryParser("", analyzer);
|
||||
var filterQuery;
|
||||
try {
|
||||
if (query.constructor === Array) {
|
||||
if (query.length > 1) {
|
||||
filterQuery = new pkg.search.BooleanQuery();
|
||||
query.forEach(function(queryStr){
|
||||
filterQuery.add(parser.parse(queryStr), pkg.search.BooleanClause.Occur.MUST);
|
||||
}, this);
|
||||
} else {
|
||||
filterQuery = parser.parse(query[0]);
|
||||
}
|
||||
} else {
|
||||
filterQuery = parser.parse(query);
|
||||
}
|
||||
filter = new pkg.search.CachingWrapperFilter(new pkg.search.QueryWrapperFilter(filterQuery));
|
||||
} catch (e) {
|
||||
app.logger.debug("Unable to parse query filter '" + query + "', reason: " + e);
|
||||
}
|
||||
}
|
||||
return filter;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*********************
|
||||
***** J O B *****
|
||||
*********************/
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new Job instance.
|
||||
* @class Instances of this class represent a single index
|
||||
* manipulation job to be processed by the index manager.
|
||||
* @param {Number} id The Id of the job
|
||||
* @param {Number} type The type of job, which can be either
|
||||
* jala.IndexManager.Job.ADD, jala.IndexManager.Job.REMOVE
|
||||
* or jala.IndexManager.Job.OPTIMIZE.
|
||||
* @param {Object} data The data needed to process the job.
|
||||
* @returns A newly created Job instance.
|
||||
* @constructor
|
||||
* @see jala.IndexManager.Job
|
||||
*/
|
||||
jala.IndexManager.Job = function(type, callback) {
|
||||
/**
|
||||
* The type of the job
|
||||
* @type Number
|
||||
*/
|
||||
this.type = type;
|
||||
|
||||
/**
|
||||
* The data needed to process this job. For adding jobs this property
|
||||
* must contain the {@link helma.Search.Document} instance to add to
|
||||
* the index. For removal job this property must contain the unique identifier
|
||||
* of the document that should be removed from the index. For optimizing
|
||||
* jobs this property is null.
|
||||
*/
|
||||
this.callback = callback;
|
||||
|
||||
/**
|
||||
* An internal error counter which is increased whenever processing
|
||||
* the job failed.
|
||||
* @type Number
|
||||
* @see jala.IndexManager.MAXTRIES
|
||||
*/
|
||||
this.errors = 0;
|
||||
|
||||
/**
|
||||
* The date and time at which this job was created.
|
||||
* @type Date
|
||||
*/
|
||||
this.createtime = new Date();
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
jala.IndexManager.Job.prototype.toString = function() {
|
||||
return "[Job (type: " + this.type + ")]";
|
||||
};
|
||||
|
||||
/**
|
||||
* Constant defining an add job
|
||||
* @type Number
|
||||
* @final
|
||||
*/
|
||||
jala.IndexManager.Job.ADD = "add";
|
||||
|
||||
/**
|
||||
* Constant defining a removal job
|
||||
* @type Number
|
||||
* @final
|
||||
*/
|
||||
jala.IndexManager.Job.REMOVE = "remove";
|
||||
|
||||
/**
|
||||
* Constant defining an optimizing job
|
||||
* @type Number
|
||||
* @final
|
||||
*/
|
||||
jala.IndexManager.Job.OPTIMIZE = "optimize";
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,130 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the jala.PodcastWriter class.
|
||||
*/
|
||||
|
||||
|
||||
// Define the global namespace for Jala modules
|
||||
if (!global.jala) {
|
||||
global.jala = {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Jala dependencies
|
||||
*/
|
||||
app.addRepository(getProperty("jala.dir", "modules/jala") +
|
||||
"/code/Rss20Writer.js");
|
||||
|
||||
/**
|
||||
* @class Class to create, modify and render standard-compliant
|
||||
* RSS 2.0 feeds including support for Apple's Podcast specification.
|
||||
* @constructor
|
||||
* @extends jala.Rss20Writer
|
||||
* @param {String} header Optional XML header.
|
||||
*/
|
||||
jala.PodcastWriter = function(header) {
|
||||
jala.Rss20Writer.apply(this, arguments);
|
||||
|
||||
var CATEGORY = {
|
||||
name: "itunes:category",
|
||||
attributes: {
|
||||
name: "text"
|
||||
}
|
||||
};
|
||||
|
||||
var OWNER = {
|
||||
name: "itunes:owner",
|
||||
value: [{
|
||||
name: "itunes:name"
|
||||
}, {
|
||||
name: "itunes:email"
|
||||
}]
|
||||
};
|
||||
|
||||
this.addNamespace("itunes", "http://www.itunes.com/dtds/podcast-1.0.dtd");
|
||||
|
||||
this.extendChannel([{
|
||||
name: "itunes:author"
|
||||
}, {
|
||||
name: "itunes:subtitle"
|
||||
}, {
|
||||
name: "itunes:summary"
|
||||
}, {
|
||||
name: "itunes:new-feed-url"
|
||||
}, {
|
||||
name: "itunes:image",
|
||||
attributes: [{
|
||||
name: "href"
|
||||
}]
|
||||
}, {
|
||||
name: "itunes:link",
|
||||
attributes: [{
|
||||
name: "rel"
|
||||
}, {
|
||||
name: "type"
|
||||
}, {
|
||||
name: "href"
|
||||
}]
|
||||
}]);
|
||||
|
||||
this.getChannel().setValue(this.createElement(OWNER));
|
||||
|
||||
this.extendItem([{
|
||||
name: "itunes:duration"
|
||||
}, {
|
||||
name: "itunes:subtitle"
|
||||
}]);
|
||||
|
||||
/**
|
||||
* Add an iTunes Podcast category.
|
||||
* @param {String} name The category's name.
|
||||
* @param {String} subName The (optional) sub-category's name.
|
||||
* @param {jala.XmlWriter.XmlElement} parent Optional parent
|
||||
* element to add the category to.
|
||||
*/
|
||||
this.addItunesCategory = function(name, subName, parent) {
|
||||
if (!parent)
|
||||
parent = this.getChannel();
|
||||
var cat = this.createElement(CATEGORY);
|
||||
cat.populate({attributes: {text: name}});
|
||||
if (subName) {
|
||||
var subCat = this.createElement(CATEGORY);
|
||||
subCat.populate({attributes: {text: subName}});
|
||||
cat.addValue(subCat);
|
||||
}
|
||||
parent.addValue(cat);
|
||||
return;
|
||||
};
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/** A typical XML header as default.
|
||||
@type {String}
|
||||
@final */
|
||||
jala.PodcastWriter.XMLHEADER = '<?xml version="1.0" encoding="UTF-8"?>';
|
|
@ -1,307 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the jala.RemoteContent class.
|
||||
*/
|
||||
|
||||
// HelmaLib dependencies
|
||||
app.addRepository("modules/core/String.js");
|
||||
app.addRepository("modules/core/Object.js");
|
||||
app.addRepository("modules/core/Date.js");
|
||||
app.addRepository("modules/helma/Http.js");
|
||||
|
||||
// Define the global namespace for Jala modules
|
||||
if (!global.jala) {
|
||||
global.jala = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new remote content handler.
|
||||
* @class API to define, fetch and update content
|
||||
* from a remote site.
|
||||
* @param {String} url The URL string of the remote site.
|
||||
* @param {Integer} method The method to retrieve the remote content.
|
||||
* @param {File} storage The cache directory.
|
||||
* @returns A new remote content handler.
|
||||
* @extends helma.Http
|
||||
* @constructor
|
||||
*/
|
||||
jala.RemoteContent = function(url, method, storage) {
|
||||
if (typeof PropertyMgr == "undefined")
|
||||
var PropertyMgr = {};
|
||||
|
||||
var NULLSTR = "";
|
||||
var key = url.md5();
|
||||
var fname = key + jala.RemoteContent.SUFFIX;
|
||||
var cache;
|
||||
method = (method != null ? method.toLowerCase() : null);
|
||||
|
||||
// depending on the method argument the instance
|
||||
// becomes extent of the appropriate remote client
|
||||
switch (method) {
|
||||
case jala.RemoteContent.XMLRPC:
|
||||
break;
|
||||
default:
|
||||
helma.Http.call(this);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!storage) {
|
||||
storage = jala.RemoteContent.CACHEDIR;
|
||||
if (!storage.exists() || !storage.isDirectory())
|
||||
storage.mkdir(storage.getAbsolutePath());
|
||||
}
|
||||
|
||||
var getCache = function() {
|
||||
switch (storage.constructor) {
|
||||
case HopObject:
|
||||
cache = storage;
|
||||
break;
|
||||
|
||||
case PropertyMgr:
|
||||
cache = storage.getAll();
|
||||
break;
|
||||
|
||||
default:
|
||||
var f = new File(storage, fname);
|
||||
cache = f.exists() ? Xml.read(f) : new HopObject();
|
||||
}
|
||||
return cache;
|
||||
};
|
||||
|
||||
var setCache = function() {
|
||||
cache.url = url;
|
||||
cache.method = method;
|
||||
if (!cache.interval) {
|
||||
cache.interval = Date.ONEHOUR;
|
||||
}
|
||||
cache.lastUpdate = new Date();
|
||||
cache = cache.clone(new HopObject());
|
||||
|
||||
switch (storage.constructor) {
|
||||
case HopObject:
|
||||
for (var i in cache)
|
||||
storage[i] = cache[i];
|
||||
break;
|
||||
|
||||
case PropertyMgr:
|
||||
storage.setAll(cache);
|
||||
break;
|
||||
|
||||
default:
|
||||
var f = new File(storage, fname);
|
||||
Xml.write(cache, f);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
cache = getCache();
|
||||
|
||||
/**
|
||||
* Set the interval the remote content's
|
||||
* cache is bound to be updated.
|
||||
* @param {Number} interval The interval value in milliseconds.
|
||||
*/
|
||||
this.setInterval = function(interval) {
|
||||
cache.interval = parseInt(interval, 10);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an arbitrary property of the remote content.
|
||||
* @param {String} key The name of the property.
|
||||
* @returns The value of the property.
|
||||
*/
|
||||
this.get = function(key) {
|
||||
return cache[key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available property names.
|
||||
* @returns The list of property names.
|
||||
* @type Array
|
||||
*/
|
||||
this.getKeys = function() {
|
||||
var keys = [];
|
||||
for (var i in cache) {
|
||||
keys.push(i);
|
||||
}
|
||||
return keys.sort();
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests whether the remote content needs to be updated.
|
||||
* @returns True if the remote content needs to be updated.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.needsUpdate = function() {
|
||||
if (!cache.lastUpdate) {
|
||||
return true;
|
||||
} else {
|
||||
var max = new Date() - cache.interval;
|
||||
if (max - cache.lastUpdate > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the updated and cached remote content.
|
||||
* @returns The content as retrieved from the remote site.
|
||||
* @type String
|
||||
*/
|
||||
this.update = function() {
|
||||
app.debug("[jala.RemoteContent] Retrieving " + url);
|
||||
var result;
|
||||
switch (method) {
|
||||
case jala.RemoteContent.XMLRPC:
|
||||
break;
|
||||
default:
|
||||
result = this.getUrl(url, cache.lastModified || cache.eTag);
|
||||
if (result.code != 200 && cache.content) {
|
||||
// preserve the content received before
|
||||
result.content = cache.content;
|
||||
}
|
||||
result.interval = cache.interval;
|
||||
cache = result;
|
||||
}
|
||||
setCache();
|
||||
return cache.content;
|
||||
};
|
||||
|
||||
/**
|
||||
* Flushes (empties) the cached remote content.
|
||||
*/
|
||||
this.clear = function() {
|
||||
switch (storage.constructor) {
|
||||
case HopObject:
|
||||
for (var i in storage)
|
||||
delete storage[i];
|
||||
break;
|
||||
|
||||
case PropertyMgr:
|
||||
storage.reset();
|
||||
break;
|
||||
|
||||
default:
|
||||
var f = new File(storage, fname);
|
||||
f.remove();
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a string representation of the remote content.
|
||||
* @returns The remote content as string.
|
||||
* @type String
|
||||
*/
|
||||
this.toString = function() {
|
||||
return cache.content || NULLSTR;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the value of the remote content.
|
||||
* @returns The remote content including response header data.
|
||||
* @type Object
|
||||
*/
|
||||
this.valueOf = function() {
|
||||
return cache;
|
||||
};
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* A constant representing the HTTP retrieval method.
|
||||
* @type int
|
||||
* @final
|
||||
*/
|
||||
jala.RemoteContent.HTTP = 1;
|
||||
|
||||
/**
|
||||
* A constant representing the XML-RPC retrieval method.
|
||||
* @type int
|
||||
* @final
|
||||
*/
|
||||
jala.RemoteContent.XMLRPC = 2;
|
||||
|
||||
/**
|
||||
* The default name of the cache directory.
|
||||
* @type String
|
||||
* @final
|
||||
*/
|
||||
jala.RemoteContent.SUFFIX = ".cache";
|
||||
|
||||
/**
|
||||
* The default cache directory.
|
||||
* @type File
|
||||
* @final
|
||||
*/
|
||||
jala.RemoteContent.CACHEDIR = new File(app.dir, jala.RemoteContent.SUFFIX);
|
||||
|
||||
/**
|
||||
* Remove all remote content from a file-based cache.
|
||||
* @param {File} cache An optional target directory.
|
||||
*/
|
||||
jala.RemoteContent.flush = function(cache) {
|
||||
jala.RemoteContent.forEach(function(rc) {
|
||||
rc.clear();
|
||||
return;
|
||||
});
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply a custom method on all remote content in a file-based cache.
|
||||
* @param {Function} callback The callback method to be executed
|
||||
* for each remote content file.
|
||||
* @param {File} cache An optional target directory.
|
||||
*/
|
||||
jala.RemoteContent.forEach = function(callback, cache) {
|
||||
if (!cache)
|
||||
cache = jala.RemoteContent.CACHEDIR;
|
||||
var f, rc;
|
||||
var files = cache.list();
|
||||
for (var i in files) {
|
||||
f = new File(cache, files[i]);
|
||||
if (!files[i].endsWith(jala.RemoteContent.SUFFIX))
|
||||
continue;
|
||||
rc = new jala.RemoteContent(Xml.read(f).url);
|
||||
if (callback && callback.constructor == Function)
|
||||
callback(rc);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply a custom method on all remote content in a file-based cache.
|
||||
* @param {Function} callback The callback method to be executed
|
||||
* for each remote content file.
|
||||
* @param {File} cache An optional target directory.
|
||||
* @deprecated Use {@link #forEach} instead.
|
||||
*/
|
||||
jala.RemoteContent.exec = function() {
|
||||
jala.RemoteContent.forEach.apply(this, arguments);
|
||||
};
|
|
@ -1,334 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the jala.Rss20Writer class.
|
||||
*/
|
||||
|
||||
|
||||
// Define the global namespace for Jala modules
|
||||
if (!global.jala) {
|
||||
global.jala = {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Jala dependencies
|
||||
*/
|
||||
app.addRepository(getProperty("jala.dir", "modules/jala") +
|
||||
"/code/XmlWriter.js");
|
||||
|
||||
/**
|
||||
* @class Class to create, modify and render standard-compliant
|
||||
* RSS 2.0 feeds.
|
||||
* @constructor
|
||||
* @extends jala.XmlWriter
|
||||
* @param {String} header Optional XML header.
|
||||
*/
|
||||
jala.Rss20Writer = function(header) {
|
||||
// defines the prototype of this constructor
|
||||
jala.XmlWriter.apply(this, arguments);
|
||||
|
||||
// this should do the same but alas, helma throws
|
||||
// an error the very first time it is executed:
|
||||
//arguments.callee.prototype = new jala.XmlWriterInterface();
|
||||
|
||||
var DATEFMT = "EEE, dd MMM yyyy HH:mm:ss Z";
|
||||
|
||||
var CATEGORY = {
|
||||
name: "category",
|
||||
amount: Infinity,
|
||||
attributes: {
|
||||
name: "domain",
|
||||
}
|
||||
};
|
||||
|
||||
var ITEM = {
|
||||
name: "item",
|
||||
amount: Infinity,
|
||||
value: [{
|
||||
name: "title",
|
||||
required: true
|
||||
}, {
|
||||
name: "link",
|
||||
}, {
|
||||
name: "description",
|
||||
}, {
|
||||
name: "author",
|
||||
}, {
|
||||
name: "comments",
|
||||
}, {
|
||||
name: "enclosure",
|
||||
attributes: [{
|
||||
name: "url",
|
||||
required: true
|
||||
}, {
|
||||
name: "length",
|
||||
required: true
|
||||
}, {
|
||||
name: "type",
|
||||
required: true
|
||||
}]
|
||||
}, {
|
||||
name: "guid",
|
||||
attributes: [{
|
||||
name: "isPermaLink",
|
||||
type: Boolean
|
||||
}]
|
||||
}, {
|
||||
name: "pubDate",
|
||||
type: Date,
|
||||
format: DATEFMT
|
||||
}, {
|
||||
name: "source",
|
||||
attributes: [{
|
||||
name: "url",
|
||||
required: true
|
||||
}]
|
||||
}]
|
||||
};
|
||||
|
||||
var CHANNEL = {
|
||||
name: "channel",
|
||||
value: [{
|
||||
name: "title",
|
||||
required: true
|
||||
}, {
|
||||
name: "link",
|
||||
required: true
|
||||
}, {
|
||||
name: "description",
|
||||
required: true
|
||||
}, {
|
||||
name: "language",
|
||||
}, {
|
||||
name: "copyright",
|
||||
}, {
|
||||
name: "managingEditor",
|
||||
}, {
|
||||
name: "webMaster",
|
||||
}, {
|
||||
name: "pubDate",
|
||||
type: Date,
|
||||
format: DATEFMT
|
||||
}, {
|
||||
name: "lastBuildDate",
|
||||
type: Date,
|
||||
format: DATEFMT
|
||||
}, {
|
||||
name: "generator",
|
||||
}, {
|
||||
name: "docs",
|
||||
}, {
|
||||
name: "cloud",
|
||||
attributes: [{
|
||||
name: "domain",
|
||||
}, {
|
||||
name: "port",
|
||||
type: Number,
|
||||
format: "#"
|
||||
}, {
|
||||
name: "path",
|
||||
}, {
|
||||
name: "registerProcedure",
|
||||
}, {
|
||||
name: "protocol",
|
||||
}]
|
||||
}, {
|
||||
name: "ttl",
|
||||
type: Number,
|
||||
format: "#"
|
||||
}, {
|
||||
name: "rating",
|
||||
}, {
|
||||
name: "skipHours",
|
||||
}, {
|
||||
name: "skipDays",
|
||||
}]
|
||||
};
|
||||
|
||||
var IMAGE = {
|
||||
name: "image",
|
||||
value: [{
|
||||
name: "url",
|
||||
required: true
|
||||
}, {
|
||||
name: "title",
|
||||
required: true
|
||||
}, {
|
||||
name: "link",
|
||||
required: true
|
||||
}, {
|
||||
name: "width",
|
||||
type: Number,
|
||||
format: "#"
|
||||
}, {
|
||||
name: "height",
|
||||
type: Number,
|
||||
format: "#"
|
||||
}, {
|
||||
name: "description",
|
||||
}]
|
||||
};
|
||||
|
||||
var TEXTINPUT = {
|
||||
name: "textinput",
|
||||
value: [{
|
||||
name: "title",
|
||||
required: true
|
||||
}, {
|
||||
name: "description",
|
||||
required: true
|
||||
}, {
|
||||
name: "name",
|
||||
required: true
|
||||
}, {
|
||||
name: "link",
|
||||
required: true
|
||||
}]
|
||||
};
|
||||
|
||||
var ROOT = {
|
||||
name: "rss",
|
||||
attributes: [{
|
||||
name: "version",
|
||||
value: "2.0"
|
||||
}]
|
||||
};
|
||||
|
||||
var xmlroot = this.createElement(ROOT);
|
||||
var channel = this.createElement(CHANNEL);
|
||||
xmlroot.setValue(channel);
|
||||
|
||||
/**
|
||||
* Get the writer's root element.
|
||||
* @returns The writer's root element.
|
||||
* @type jala.XmlWriter.XmlElement
|
||||
*/
|
||||
this.getRoot = function() {
|
||||
return xmlroot;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add child elements to the channel template.
|
||||
* @param {Array} ext List of additional child elements.
|
||||
*/
|
||||
this.extendChannel = function(ext) {
|
||||
this.extend(CHANNEL, ext);
|
||||
channel = this.createElement(CHANNEL);
|
||||
xmlroot.setValue(channel);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the writer's channel element.
|
||||
* @returns The writer's channel element.
|
||||
* @type jala.XmlWriter.XmlElement
|
||||
*/
|
||||
this.getChannel = function() {
|
||||
return channel;
|
||||
};
|
||||
|
||||
/**
|
||||
* Populate the channel element with data.
|
||||
* @param {Object} data An XmlWriter-compliant object structure.
|
||||
* @returns The populated channel element.
|
||||
* @type jala.XmlWriter.XmlElement
|
||||
*/
|
||||
this.setChannel = function(data) {
|
||||
return channel.populate(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add child elements to the item template.
|
||||
* @param {Array} ext List of additional child elements.
|
||||
*/
|
||||
this.extendItem = function(ext) {
|
||||
this.extend(ITEM, ext);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a new and innocent item element.
|
||||
* @param {Object} data An XmlWriter-compliant object structure.
|
||||
* @returns A new and innocent item element.
|
||||
* @type jala.XmlWriter.XmlElement
|
||||
*/
|
||||
this.createItem = function(data) {
|
||||
var item = this.createElement(ITEM);
|
||||
item.populate(data);
|
||||
return item;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add an item element to the channel element.
|
||||
* @param {jala.XmlWriter.XmlElement} item The item element to add.
|
||||
*/
|
||||
this.addItem = function(item) {
|
||||
channel.addValue(item);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a category element to an arbitrary element.
|
||||
* @param {String} name The name of the category.
|
||||
* @param {String} domain The domain of the category.
|
||||
* @param {jala.XmlWriter.XmlElement} parent The optional parent element.
|
||||
*/
|
||||
this.addCategory = function(name, domain, parent) {
|
||||
if (!parent)
|
||||
parent = channel;
|
||||
var cat = this.createElement(CATEGORY);
|
||||
cat.populate({
|
||||
value: name,
|
||||
attributes: {domain: domain}
|
||||
});
|
||||
parent.addValue(cat);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Populate the image element with data.
|
||||
* @param {Object} data An XmlWriter-compliant object structure.
|
||||
*/
|
||||
this.setImage = function(data) {
|
||||
var image = this.createElement(IMAGE);
|
||||
image.populate(data);
|
||||
channel.setValue(image);
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Populate the textInput element with data.
|
||||
* @param {Object} data An XmlWriter-compliant object structure.
|
||||
*/
|
||||
this.setTextInput = function(data) {
|
||||
var textInput = this.createElement(TEXTINPUT);
|
||||
textInput.populate(data);
|
||||
channel.setValue(textInput);
|
||||
return;
|
||||
};
|
||||
|
||||
return this;
|
||||
};
|
|
@ -1,246 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the jala.Utilities class.
|
||||
*/
|
||||
|
||||
// Define the global namespace for Jala modules
|
||||
if (!global.jala) {
|
||||
global.jala = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* HelmaLib dependencies
|
||||
*/
|
||||
app.addRepository("modules/core/Number.js");
|
||||
|
||||
/**
|
||||
* Construct a utility object.
|
||||
* @class This class contains various convenience methods
|
||||
* which do not fit in any other class.
|
||||
* @returns A new utitilty object.
|
||||
* @constructor
|
||||
*/
|
||||
jala.Utilities = function() {
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a string representation of the utitility class.
|
||||
* @returns [jala.Utilities]
|
||||
* @type String
|
||||
*/
|
||||
jala.Utilities.toString = function() {
|
||||
return "[jala.Utilities]";
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a string representation of the utitility object.
|
||||
* @returns [jala.Utilities Object]
|
||||
* @type String
|
||||
*/
|
||||
jala.Utilities.prototype.toString = function() {
|
||||
return "[jala.Utilities Object]";
|
||||
};
|
||||
|
||||
/**
|
||||
* Default utility class instance.
|
||||
* @type jala.Utilities
|
||||
* @final
|
||||
*/
|
||||
jala.util = new jala.Utilities();
|
||||
|
||||
/**
|
||||
* Creates a random password with different levels of security.
|
||||
* @param {Number} len The length of the password (default: 8)
|
||||
* @param {Number} level The security level
|
||||
* <ul>
|
||||
* <li>0 - containing only vowels or consonants (default)</li>
|
||||
* <li>1 - throws in a number at random position</li>
|
||||
* <li>2 - throws in a number and a special character at random position</li>
|
||||
* </ul>
|
||||
* @returns The resulting password
|
||||
* @type String
|
||||
*/
|
||||
jala.Utilities.prototype.createPassword = function(len, level) {
|
||||
len = len || 8;
|
||||
level = level || 0;
|
||||
|
||||
var LETTERSONLY = 0;
|
||||
var WITHNUMBERS = 1;
|
||||
var WITHSPECIALS = 2;
|
||||
|
||||
var vowels = ['a', 'e', 'i', 'o', 'u'];
|
||||
var consonants = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z'];
|
||||
var specials = ['.', '#', '!', '$', '%', '&', '?'];
|
||||
|
||||
var posNum = level > LETTERSONLY ? Math.floor(Math.random() * (len - 2)) : -1;
|
||||
var posSpecial = level > WITHNUMBERS ? Math.floor(Math.random() * (len - 3)) : -2;
|
||||
if (posNum == posSpecial) {
|
||||
posSpecial += 1;
|
||||
}
|
||||
|
||||
res.push();
|
||||
// loop to create characters:
|
||||
var i, rnd;
|
||||
for (i=0; i<(len-level); i+=1) {
|
||||
if(i % 2 == 0) {
|
||||
// every 2nd one is a vowel
|
||||
rnd = Math.floor(Math.random() * vowels.length);
|
||||
res.write(vowels[rnd]);
|
||||
} else {
|
||||
// every 2nd one is a consonant
|
||||
rnd = Math.floor(Math.random() * consonants.length);
|
||||
res.write(consonants[rnd]);
|
||||
}
|
||||
if (i == posNum) {
|
||||
// increased password security:
|
||||
// throw in a number at random
|
||||
rnd = Math.floor(Math.random() * specials.length);
|
||||
res.write(String(rnd + 1));
|
||||
}
|
||||
if (i == posSpecial) {
|
||||
// increased password security:
|
||||
// throw in a number at random
|
||||
rnd = Math.floor(Math.random() * specials.length);
|
||||
res.write(specials[rnd]);
|
||||
}
|
||||
}
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Static field indicating a removed object property.
|
||||
* @type Number
|
||||
* @final
|
||||
*/
|
||||
jala.Utilities.VALUE_REMOVED = -1;
|
||||
|
||||
/**
|
||||
* Static field indicating ad added object property.
|
||||
* @type Number
|
||||
* @final
|
||||
*/
|
||||
jala.Utilities.VALUE_ADDED = 1;
|
||||
|
||||
/**
|
||||
* Static field indicating a modified object property.
|
||||
* @type Number
|
||||
* @final
|
||||
*/
|
||||
jala.Utilities.VALUE_MODIFIED = 2;
|
||||
|
||||
/**
|
||||
* Returns an array containing the properties that are
|
||||
* added, removed or modified in one object compared to another.
|
||||
* @param {Object} obj1 The first of two objects which should be compared
|
||||
* @param {Object} obj2 The second of two objects which should be compared
|
||||
* @returns An Object containing all properties that are added, removed
|
||||
* or modified in the second object compared to the first.
|
||||
* Each property contains a status field with an integer value
|
||||
* which can be checked against the static jala.Utility fields
|
||||
* VALUE_ADDED, VALUE_MODIFIED and VALUE_REMOVED.
|
||||
* @type Object
|
||||
*/
|
||||
jala.Utilities.prototype.diffObjects = function(obj1, obj2) {
|
||||
var childDiff, value1, value2;
|
||||
var diff = {};
|
||||
var foundDiff = false;
|
||||
|
||||
for (var propName in obj1) {
|
||||
if (obj2[propName] === undefined || obj2[propName] === "" || obj2[propName] === null) {
|
||||
diff[propName] = {status: jala.Utilities.VALUE_REMOVED};
|
||||
foundDiff = true;
|
||||
}
|
||||
}
|
||||
for (var propName in obj2) {
|
||||
value1 = obj1[propName];
|
||||
value2 = obj2[propName];
|
||||
if (value1 == null) {
|
||||
diff[propName] = {status: jala.Utilities.VALUE_ADDED,
|
||||
value: value2};
|
||||
foundDiff = true;
|
||||
} else {
|
||||
switch (value2.constructor) {
|
||||
case HopObject:
|
||||
case Object:
|
||||
if (childDiff = this.diffObjects(value1, value2)) {
|
||||
diff[propName] = childDiff;
|
||||
foundDiff = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (value2 != null && value2 !== "") {
|
||||
if (value1 === null || value1 === undefined || value1 === "") {
|
||||
diff[propName] = {status: jala.Utilities.VALUE_ADDED,
|
||||
value: value2};
|
||||
foundDiff = true;
|
||||
} else if (value1 != value2) {
|
||||
diff[propName] = {status: jala.Utilities.VALUE_MODIFIED,
|
||||
value: value2};
|
||||
foundDiff = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return foundDiff ? diff : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Patches an object with a "diff" object created by the
|
||||
* {@link #diffObjects} method.
|
||||
* Please mind that this method is recursive, it descends
|
||||
* along the "diff" object structure.
|
||||
* @param {Object} obj The Object the diff should be applied to
|
||||
* @param {Object} diff A "diff" object created by the {@link #diffObjects} method
|
||||
* @returns The patched Object with all differences applied
|
||||
* @type Object
|
||||
*/
|
||||
jala.Utilities.prototype.patchObject = function(obj, diff) {
|
||||
var propDiff, value1;
|
||||
for (var propName in diff) {
|
||||
propDiff = diff[propName];
|
||||
value1 = obj[propName];
|
||||
if (propDiff.status != null) {
|
||||
switch (propDiff.status) {
|
||||
case jala.Utilities.VALUE_REMOVED:
|
||||
// app.debug("applyDiff(): removing property " + propName);
|
||||
delete obj[propName];
|
||||
break;
|
||||
case jala.Utilities.VALUE_ADDED:
|
||||
case jala.Utilities.VALUE_MODIFIED:
|
||||
default:
|
||||
// app.debug("applyDiff(): changing property " + propName + " to " + propDiff.value);
|
||||
obj[propName] = propDiff.value;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// app.debug("applyDiff(): descending to child object " + propName);
|
||||
this.patchObject(value1, propDiff);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
};
|
|
@ -1,461 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the jala.XmlRpcRequest class.
|
||||
*/
|
||||
|
||||
|
||||
// Define the global namespace for Jala modules
|
||||
if (!global.jala) {
|
||||
global.jala = {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A constructor for XmlRpc request objects
|
||||
* @class Instances of this class provide the necessary functionality
|
||||
* for issueing XmlRpc requests to a remote service.
|
||||
* @param {String} url The url of the XmlRpc entry point
|
||||
* @param {String} methodName The name of the method to call
|
||||
* @returns A newly created jala.XmlRpcRequest instance
|
||||
* @constructor
|
||||
*/
|
||||
jala.XmlRpcRequest = function(url, methodName) {
|
||||
/** @ignore */
|
||||
var proxy = null;
|
||||
/** @ignore */
|
||||
var timeout = {
|
||||
"connect": 0,
|
||||
"socket": 0
|
||||
};
|
||||
/** @ignore */
|
||||
var debug = false;
|
||||
/** @ignore */
|
||||
var credentials = null;
|
||||
// default input and output encoding
|
||||
/** @ignore */
|
||||
var inputEncoding = "UTF-8";
|
||||
/** @ignore */
|
||||
var outputEncoding = "UTF-8";
|
||||
|
||||
/**
|
||||
* Returns the URL of this request
|
||||
* @returns The URL of this request
|
||||
* @type java.net.URL
|
||||
*/
|
||||
this.getUrl = function() {
|
||||
return new java.net.URL(url);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the proxy host and port. For Java runtimes < 1.5 this method
|
||||
* sets the appropriate system properties (so this has an effect on
|
||||
* all requests based on java.net.URL), for all others the proxy
|
||||
* is only set for this request.
|
||||
* @param {String} proxyString The proxy string in the form 'fqdn:port'
|
||||
* (eg. my.proxy.com:3128)
|
||||
*/
|
||||
this.setProxy = function(proxyString) {
|
||||
if (proxyString && proxyString.trim()) {
|
||||
var idx = proxyString.indexOf(":");
|
||||
if (idx > 0) {
|
||||
var host = proxyString.substring(0, idx);
|
||||
var port = proxyString.substring(idx+1);
|
||||
if (host != null && port != null) {
|
||||
if (java.lang.Class.forName("java.net.Proxy") != null) {
|
||||
// construct a proxy instance
|
||||
var socket = new java.net.InetSocketAddress(host, port);
|
||||
proxy = new java.net.Proxy(java.net.Proxy.Type.HTTP, socket);
|
||||
} else {
|
||||
// the pre jdk1.5 way: set the system properties
|
||||
var sys = java.lang.System.getProperties();
|
||||
if (host) {
|
||||
app.log("[Jala XmlRpc Client] WARNING: setting system http proxy to "
|
||||
+ host + ":" + port);
|
||||
sys.put("http.proxySet", "true");
|
||||
sys.put("http.proxyHost", host);
|
||||
sys.put("http.proxyPort", port);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the proxy object. This method will only return
|
||||
* a value if using a java runtime > 1.5
|
||||
* @returns The proxy to use for this request
|
||||
* @type java.net.Proxy
|
||||
* @see #setProxy
|
||||
*/
|
||||
this.getProxy = function() {
|
||||
return proxy;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the credentials for basic http authentication to
|
||||
* use with this request.
|
||||
* @param {String} username The username
|
||||
* @param {String} password The password
|
||||
*/
|
||||
this.setCredentials = function(username, password) {
|
||||
var str = username + ":" + password;
|
||||
credentials = str.enbase64();
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the credentials of this request
|
||||
* @returns The base46 encoded credentials of this request
|
||||
* @type String
|
||||
*/
|
||||
this.getCredentials = function() {
|
||||
return credentials;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the connection timeout to the specified milliseconds.
|
||||
* @param {Number} millis The timeout to use as connection timeout
|
||||
*/
|
||||
this.setTimeout = function(millis) {
|
||||
timeout.connect = millis;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the socket timeout to the specified milliseconds.
|
||||
* @param {Number} millis The timeout to use as socket timeout
|
||||
*/
|
||||
this.setReadTimeout = function(millis) {
|
||||
timeout.socket = millis;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the connection timeout of this request
|
||||
* @returns The connection timeout value in milliseconds
|
||||
* @type Number
|
||||
*/
|
||||
this.getTimeout = function() {
|
||||
return timeout.connect;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the socket timeout of this request
|
||||
* @returns The socket timeout value in milliseconds
|
||||
* @type Number
|
||||
*/
|
||||
this.getReadTimeout = function() {
|
||||
return timeout.socket;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the name of the remote function to call
|
||||
* @returns The name of the remote function
|
||||
* @type String
|
||||
*/
|
||||
this.getMethodName = function() {
|
||||
return methodName;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets both input and output encoding to the
|
||||
* specified encoding string
|
||||
* @param {String} enc The encoding to use for
|
||||
* both input and output. This must be a valid
|
||||
* java encoding string.
|
||||
*/
|
||||
this.setEncoding = function(enc) {
|
||||
inputEncoding = enc;
|
||||
outputEncoding = enc;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the input encoding to the specified encoding string
|
||||
* @param {String} enc The encoding to use for input. This must be a valid
|
||||
* java encoding string.
|
||||
*/
|
||||
this.setInputEncoding = function(enc) {
|
||||
inputEncoding = enc;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the output encoding to the specified encoding string
|
||||
* @param {String} enc The encoding to use for output. This must be a valid
|
||||
* java encoding string.
|
||||
*/
|
||||
this.setOutputEncoding = function(enc) {
|
||||
outputEncoding = enc;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the input encoding
|
||||
* @returns The input encoding used by this request
|
||||
* @type String
|
||||
*/
|
||||
this.getInputEncoding = function() {
|
||||
return inputEncoding;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the output encoding
|
||||
* @returns The output encoding used by this request
|
||||
* @type String
|
||||
*/
|
||||
this.getOutputEncoding = function() {
|
||||
return outputEncoding;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enables or disables the debug mode. If enabled the xml source
|
||||
* of both request and response is included in the result properties
|
||||
* 'requestXml' and 'responseXml'
|
||||
* @param {Boolean} flag True or false.
|
||||
*/
|
||||
this.setDebug = function(flag) {
|
||||
debug = flag;
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if debug is enabled for this request, false otherwise
|
||||
* @returns True if debugging is enabled, false otherwise
|
||||
* @type Boolean
|
||||
*/
|
||||
this.debug = function() {
|
||||
return debug == true;
|
||||
};
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
jala.XmlRpcRequest.prototype.toString = function() {
|
||||
return "[Jala XmlRpc Request]";
|
||||
};
|
||||
|
||||
/**
|
||||
* Calling this method executes the remote method using
|
||||
* the arguments specified.
|
||||
* @returns The result of this XmlRpc request
|
||||
* @type Object
|
||||
*/
|
||||
jala.XmlRpcRequest.prototype.execute = function(/** [arg1][, arg2][, ...] */) {
|
||||
// if in debug mode, log the time the request took to event log
|
||||
if (app.__app__.debug() == true) {
|
||||
var start = new Date();
|
||||
}
|
||||
|
||||
var tz = java.util.TimeZone.getDefault();
|
||||
var reqProcessor = new Packages.org.apache.xmlrpc.XmlRpcClientRequestProcessor(tz);
|
||||
var resProcessor = new Packages.org.apache.xmlrpc.XmlRpcClientResponseProcessor(tz);
|
||||
// create the result object
|
||||
var result = {
|
||||
error: null,
|
||||
result: null,
|
||||
requestXml: null,
|
||||
responseXml: null
|
||||
};
|
||||
|
||||
// convert arguments into their appropriate java representations
|
||||
var params = new java.util.Vector();
|
||||
for (var i=0;i<arguments.length;i++) {
|
||||
params.add(jala.XmlRpcRequest.convertArgument(arguments[i]));
|
||||
}
|
||||
|
||||
var r = new Packages.org.apache.xmlrpc.XmlRpcRequest(this.getMethodName(), params);
|
||||
var requestBytes = reqProcessor.encodeRequestBytes(r, this.getOutputEncoding());
|
||||
if (this.debug() == true) {
|
||||
result.requestXml = String(new java.lang.String(requestBytes));
|
||||
}
|
||||
// open the connection
|
||||
var proxy = this.getProxy();
|
||||
var url = this.getUrl();
|
||||
var conn = proxy ? url.openConnection(proxy) : url.openConnection();
|
||||
conn.setAllowUserInteraction(false);
|
||||
conn.setRequestMethod("POST");
|
||||
conn.setRequestProperty("User-Agent", "Jala XmlRpc Client");
|
||||
conn.setRequestProperty("Content-Type", "text/xml");
|
||||
conn.setRequestProperty("Content-Length", requestBytes.length);
|
||||
// set timeouts if defined and possible
|
||||
if (parseFloat(java.lang.System.getProperty("java.specification.version"), 10) >= 1.5) {
|
||||
conn.setConnectTimeout(this.getTimeout());
|
||||
conn.setReadTimeout(this.getReadTimeout());
|
||||
} else {
|
||||
app.logger.debug("WARNING: timeouts can only be using a Java runtime >= 1.5");
|
||||
}
|
||||
// set authentication credentials if defined
|
||||
if (this.getCredentials() != null) {
|
||||
conn.setRequestProperty("Authorization", "Basic " + this.getCredentials());
|
||||
}
|
||||
|
||||
try {
|
||||
conn.setDoOutput(true);
|
||||
var outStream = conn.getOutputStream();
|
||||
outStream["write(byte[])"](requestBytes);
|
||||
outStream.flush();
|
||||
outStream.close();
|
||||
|
||||
if (conn.getContentLength() > 0) {
|
||||
var inStream = conn.getInputStream();
|
||||
if (this.debug() == true) {
|
||||
inStream = new java.io.BufferedInputStream(conn.getInputStream());
|
||||
var outStream = new java.io.ByteArrayOutputStream();
|
||||
var buf = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 1024);
|
||||
var bytes;
|
||||
while ((bytes = inStream.read(buf)) > -1) {
|
||||
outStream.write(buf, 0, bytes);
|
||||
}
|
||||
result.responseXml = outStream.toString(this.getInputEncoding());
|
||||
inStream.close();
|
||||
// change the inStream and don't set the input encoding of
|
||||
// the response processor, since the conversion already happened above
|
||||
inStream = new java.io.ByteArrayInputStream(outStream.toByteArray());
|
||||
}
|
||||
resProcessor.setInputEncoding(this.getInputEncoding());
|
||||
var parsedResult = resProcessor.decodeResponse(inStream);
|
||||
if (parsedResult instanceof java.lang.Exception) {
|
||||
result.error = parsedResult;
|
||||
} else {
|
||||
result.result = jala.XmlRpcRequest.convertResult(parsedResult);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
result.error = "[Jala XmlRpc Request] Error executing " + this.getMethodName()
|
||||
+ " with arguments " + jala.XmlRpcRequest.argumentsToString(arguments)
|
||||
+ ", the error is: " + e.toString();
|
||||
}
|
||||
if (app.__app__.debug() == true) {
|
||||
app.logger.debug("[Jala XmlRpc Request] (" + ((new Date()) - start) + " ms): executed '"
|
||||
+ this.getMethodName() + "' with arguments: "
|
||||
+ jala.XmlRpcRequest.argumentsToString(arguments));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper method for converting a Javascript object into
|
||||
* its appropriate Java object.
|
||||
* @param {Object} obj The Javascript object to convert
|
||||
* @returns The appropriate Java representation of the object
|
||||
* @type java.lang.Object
|
||||
*/
|
||||
jala.XmlRpcRequest.convertArgument = function(obj) {
|
||||
var result;
|
||||
if (obj instanceof Array) {
|
||||
// convert into Vector
|
||||
result = new java.util.Vector(obj.length);
|
||||
for (var i=0;i<obj.length;i++) {
|
||||
result.add(i, jala.XmlRpcRequest.convertArgument(obj[i]));
|
||||
}
|
||||
} else if (obj instanceof Date) {
|
||||
// convert into java.util.Date
|
||||
result = new java.util.Date(obj.getTime());
|
||||
} else if (typeof(obj) == "boolean" || obj instanceof Boolean) {
|
||||
result = obj;
|
||||
} else if (typeof(obj) == "string" || obj instanceof String) {
|
||||
result = obj;
|
||||
} else if (isNaN(obj) == false) {
|
||||
// convert into Integer or Double
|
||||
if (obj - obj.toFixed() > 0) {
|
||||
result = new java.lang.Double(obj);
|
||||
} else {
|
||||
result = new java.lang.Integer(obj);
|
||||
}
|
||||
} else if (obj instanceof Object) {
|
||||
// convert into Hashtable
|
||||
result = new java.util.Hashtable();
|
||||
for (var key in obj) {
|
||||
if (obj[key] != null) {
|
||||
result.put(key, jala.XmlRpcRequest.convertArgument(obj[key]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result = obj;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a Java object into its appropriate Javascript representation.
|
||||
* @param {java.lang.Object} obj The Java object to convert
|
||||
* @returns The appropriate Javascript representation of the Java object
|
||||
* @type Object
|
||||
*/
|
||||
jala.XmlRpcRequest.convertResult = function(obj) {
|
||||
var result;
|
||||
if (obj instanceof java.util.Vector) {
|
||||
// convert into Array
|
||||
result = [];
|
||||
var e = obj.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
result.push(jala.XmlRpcRequest.convertResult(e.nextElement()));
|
||||
}
|
||||
} else if (obj instanceof java.util.Hashtable) {
|
||||
// convert into Object
|
||||
result = {};
|
||||
var e = obj.keys();
|
||||
var key;
|
||||
while (e.hasMoreElements()) {
|
||||
key = e.nextElement();
|
||||
result[key] = jala.XmlRpcRequest.convertResult(obj.get(key));
|
||||
}
|
||||
} else if (obj instanceof java.lang.String) {
|
||||
result = String(obj);
|
||||
} else if (obj instanceof java.lang.Number) {
|
||||
result = Number(obj);
|
||||
} else if (obj instanceof java.lang.Boolean) {
|
||||
result = Boolean(obj);
|
||||
} else if (obj instanceof java.lang.Date) {
|
||||
result = new Date(obj.getTime());
|
||||
} else {
|
||||
result = obj;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper method to format an arguments array into
|
||||
* a string useable for debugging output.
|
||||
* @param {Object} args An arguments array
|
||||
* @returns The arguments array formatted as string
|
||||
* @type String
|
||||
*/
|
||||
jala.XmlRpcRequest.argumentsToString = function(args) {
|
||||
var arr = [];
|
||||
for (var i=0;i<args.length;i++) {
|
||||
if (typeof(args[i]) == "string") {
|
||||
arr.push('"' + args[i] + '"');
|
||||
} else {
|
||||
arr.push(args[i]);
|
||||
}
|
||||
}
|
||||
return arr.join(", ");
|
||||
};
|
|
@ -1,365 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Fields and methods of the jala.XmlWriter class.
|
||||
*/
|
||||
|
||||
|
||||
// Define the global namespace for Jala modules
|
||||
if (!global.jala) {
|
||||
global.jala = {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new XML writer.
|
||||
* @class This class defines a generic interface to write
|
||||
* arbitrary and validating XML source code. This is done
|
||||
* by first applying data objects onto template objects,
|
||||
* both in a specified format. Then, the resulting object
|
||||
* tree is transformed into XML. Moreover, template objects
|
||||
* can be extended with other template objects to provide
|
||||
* full flexibility in inheriting subclasses.
|
||||
* @param {String} header An optional XML header.
|
||||
* @returns A new XML writer.
|
||||
* @constructor
|
||||
*/
|
||||
jala.XmlWriter = function(header) {
|
||||
var self = this;
|
||||
var XMLHEADER = header ||
|
||||
'<?xml version="1.0" encoding="iso-8859-15"?>';
|
||||
var LOCALE = java.util.Locale.ENGLISH;
|
||||
|
||||
var write = function(str) {
|
||||
return res.write(str);
|
||||
};
|
||||
|
||||
var writeln = function(str) {
|
||||
res.write(str);
|
||||
res.write("\n");
|
||||
return;
|
||||
};
|
||||
|
||||
var getString = function(data, format) {
|
||||
if (data == null)
|
||||
return;
|
||||
switch (data.constructor) {
|
||||
case String:
|
||||
return encodeXml(data);
|
||||
case Number:
|
||||
case Date:
|
||||
if (format && data.format)
|
||||
return encodeXml(data.format(format, LOCALE));
|
||||
else if (data.toUTCString)
|
||||
return encodeXml(data.toUTCString());
|
||||
else
|
||||
return encodeXml(data.toString());
|
||||
break;
|
||||
case Object:
|
||||
return null;
|
||||
}
|
||||
return encodeXml(data.toString());
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
var XmlElement = function(data) {
|
||||
if (!data)
|
||||
throw Error("Insufficient arguments to create XmlElement");
|
||||
|
||||
var children = {};
|
||||
var properties = [
|
||||
"name",
|
||||
"attributes",
|
||||
"type",
|
||||
"required",
|
||||
"format",
|
||||
"readonly"
|
||||
];
|
||||
|
||||
if (data.value) {
|
||||
if (data.value.constructor == Object) {
|
||||
this.value = [new XmlElement(data.value)];
|
||||
} else if (data.value.constructor == Array) {
|
||||
this.value = [];
|
||||
for (var i in data.value) {
|
||||
this.value[i] = new XmlElement(data.value[i]);
|
||||
}
|
||||
} else
|
||||
throw Error("Cannot handle unknown type of template value");
|
||||
}
|
||||
|
||||
for (var i in properties) {
|
||||
var key = properties[i];
|
||||
this[key] = data[key] || null;
|
||||
}
|
||||
|
||||
if (this.attributes) {
|
||||
this.attributes = self.clone(this.attributes);
|
||||
if (this.attributes.constructor == Object)
|
||||
this.attributes = [this.attributes];
|
||||
} else {
|
||||
this.attributes = [];
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
XmlElement.toString = function() {
|
||||
return "[XmlElement constructor]";
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
XmlElement.prototype.setValue = function(element) {
|
||||
if (element.constructor != this.constructor)
|
||||
throw Error("Invalid type for XmlElement addition");
|
||||
if (!this.value)
|
||||
this.value = [];
|
||||
else {
|
||||
var pos = this.contains(element);
|
||||
if (pos > -1)
|
||||
this.value.splice(pos, 1);
|
||||
}
|
||||
this.addValue(element);
|
||||
return this;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
XmlElement.prototype.addValue = function(element) {
|
||||
if (element.constructor != this.constructor)
|
||||
throw Error("Invalid type for XmlElement addition");
|
||||
if (!this.value)
|
||||
this.value = [];
|
||||
this.value.push(element);
|
||||
return this;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
XmlElement.prototype.contains = function(element) {
|
||||
if (!this.value || !element)
|
||||
return -1;
|
||||
for (var i in this.value) {
|
||||
if (this.value[i].name == element.name)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
XmlElement.prototype.populate = function(data) {
|
||||
if (this.attributes) {
|
||||
var value;
|
||||
for (var i in this.attributes) {
|
||||
var attr = this.attributes[i];
|
||||
if (!attr.name)
|
||||
throw Error("Cannot populate unnamed attribute entry");
|
||||
if (data && data.attributes)
|
||||
value = data.attributes[attr.name];
|
||||
if (data && (data.value || data.attributes) && !value && attr.required) {
|
||||
throw Error('Missing required ' + (attr.type || Object).name + ' attribute "' +
|
||||
attr.name + '" in element <' + this.name + '> (' + value + ")");
|
||||
}
|
||||
if (value && attr.type && attr.type != value.constructor) {
|
||||
throw Error('Type mismatch in attribute "' +
|
||||
this.name + ":" + attr.name + '"');
|
||||
}
|
||||
if (value) {
|
||||
app.debug("populating attribute " + attr.name +
|
||||
" with " + value.constructor.name + ": " + value.toSource());
|
||||
}
|
||||
if (!attr.readonly) {
|
||||
attr.value = getString(value, attr.format) || attr.value ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data && data.value) // && data.value.constructor == Object)
|
||||
data = data.value;
|
||||
|
||||
if (this.value && data) {
|
||||
for (var i in this.value) {
|
||||
var element = this.value[i];
|
||||
element.populate(data[element.name]);
|
||||
}
|
||||
} else {
|
||||
if (!data && this.required)
|
||||
throw Error('Missing required element "' + this.name + '"');
|
||||
if (data && this.type && this.type != data.constructor) {
|
||||
throw Error('Type mismatch in element "' + this.name + '"');
|
||||
}
|
||||
if (data) {
|
||||
app.debug("populating element <" + this.name + "> with " +
|
||||
(this.type || Object).name + ": " + data.toSource());
|
||||
}
|
||||
if (!this.readonly)
|
||||
this.value = getString(data, this.format) || this.value;
|
||||
}
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
XmlElement.prototype.write = function(path) {
|
||||
if (!path)
|
||||
path = "";
|
||||
|
||||
if (!this.value && !this.attributes)
|
||||
return;
|
||||
|
||||
var attrBuffer = new java.lang.StringBuffer();
|
||||
if (this.attributes) {
|
||||
for (var a in this.attributes) {
|
||||
var attr = this.attributes[a];
|
||||
if (attr.value) {
|
||||
attrBuffer.append(" " + attr.name + '="');
|
||||
attrBuffer.append(attr.value);
|
||||
attrBuffer.append('"');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var attrSize = attrBuffer.length();
|
||||
if (!this.value && attrSize < 1)
|
||||
return;
|
||||
|
||||
write("<" + this.name);
|
||||
if (attrSize > 0) {
|
||||
display = true;
|
||||
write(attrBuffer.toString());
|
||||
}
|
||||
if (this.value) {
|
||||
write(">");
|
||||
if (this.value && this.value.constructor == Array) {
|
||||
for (var i in this.value)
|
||||
this.value[i].write(path+"/"+this.name);
|
||||
} else
|
||||
write(this.value);
|
||||
write("</" + this.name + ">\n");
|
||||
} else
|
||||
write("/>\n");
|
||||
return;
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
XmlElement.prototype.toString = function() {
|
||||
return "[XmlElement: " + this.toSource() + "]";
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a newly created XML element.
|
||||
* @param {Object} data The XML data as object tree.
|
||||
* @returns The resulting XML element.
|
||||
* @type jala.XmlWriter.XmlElement
|
||||
*/
|
||||
this.createElement = function(data) {
|
||||
return new XmlElement(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the root XML element of this writer.
|
||||
* @returns The root XML element.
|
||||
* @type jala.XmlWriter.XmlElement
|
||||
*/
|
||||
this.getRoot = function() {
|
||||
return new XmlElement({});
|
||||
};
|
||||
|
||||
/**
|
||||
* Extend a template object.
|
||||
* @param {Object} template The template object.
|
||||
* @param {Object} ext The extension object.
|
||||
* @returns The XML writer.
|
||||
* @type jala.XmlWriter
|
||||
*/
|
||||
this.extend = function(template, ext) {
|
||||
if (ext.constructor == Object)
|
||||
ext = [ext];
|
||||
if (ext.constructor == Array) {
|
||||
for (var i in ext)
|
||||
template.value.push(ext[i]);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a namespace to this writer.
|
||||
* @param {String} name The name of the namespace.
|
||||
* @param {String} url The URL string of the namespace.
|
||||
* @returns The XML root element.
|
||||
* @type jala.XmlWriter.XmlElement
|
||||
*/
|
||||
this.addNamespace = function(name, url) {
|
||||
var ref = this.getRoot();
|
||||
ref.attributes.push({
|
||||
name: "xmlns:" + name,
|
||||
value: url
|
||||
});
|
||||
return ref;
|
||||
};
|
||||
|
||||
/**
|
||||
* Write the XML to the response buffer.
|
||||
*/
|
||||
this.write = function() {
|
||||
res.contentType = "text/xml";
|
||||
writeln(XMLHEADER);
|
||||
this.getRoot().write();
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the XML output as string.
|
||||
* @returns The XML output.
|
||||
* @type String
|
||||
*/
|
||||
this.toString = function() {
|
||||
res.push();
|
||||
this.write();
|
||||
return res.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Clone this XML writer.
|
||||
* @param {Object} The clone templare.
|
||||
* @returns The cloned XML writer.
|
||||
* @type jala.XmlWriter
|
||||
*/
|
||||
this.clone = function(obj) {
|
||||
if (!obj || typeof obj != "object")
|
||||
return obj;
|
||||
var copy = new obj.constructor;
|
||||
for (var i in obj) {
|
||||
if (obj[i].constructor == Object ||
|
||||
obj[i].constructor == Array)
|
||||
copy[i]= this.clone(obj[i]);
|
||||
else
|
||||
copy[i] = obj[i];
|
||||
}
|
||||
return copy;
|
||||
};
|
||||
|
||||
return this;
|
||||
};
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
//
|
||||
// Jala Project [http://opensvn.csie.org/traccgi/jala]
|
||||
//
|
||||
// Copyright 2004 ORF Online und Teletext GmbH
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// $Revision$
|
||||
// $LastChangedBy$
|
||||
// $LastChangedDate$
|
||||
// $HeadURL$
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Wrapper for automatic inclusion of all Jala modules.
|
||||
*/
|
||||
|
||||
|
||||
// Define the global namespace for Jala modules
|
||||
if (!global.jala) {
|
||||
/** @namespace jala */
|
||||
global.jala = {};
|
||||
}
|
||||
|
||||
|
||||
(function() {
|
||||
var packages = [
|
||||
"AsyncRequest",
|
||||
"BitTorrent",
|
||||
"Date",
|
||||
"DnsClient",
|
||||
"Captcha",
|
||||
"Form",
|
||||
"History",
|
||||
"HtmlDocument",
|
||||
"HopObject",
|
||||
"I18n",
|
||||
"ImageFilter",
|
||||
"IndexManager",
|
||||
"ListRenderer",
|
||||
"Mp3",
|
||||
"PodcastWriter",
|
||||
"RemoteContent",
|
||||
"Rss20Writer",
|
||||
"Utilities",
|
||||
"XmlRpcRequest",
|
||||
"XmlWriter"
|
||||
];
|
||||
var jalaDir = getProperty("jala.dir", "modules/jala");
|
||||
for (var i in packages) {
|
||||
app.addRepository(jalaDir + "/code/" + packages[i] + ".js");
|
||||
}
|
||||
return;
|
||||
})();
|
||||
|
||||
|
||||
/**
|
||||
* Get a string representation of the Jala library.
|
||||
* @returns [Jala JavaScript Application Library]
|
||||
* @type String
|
||||
*/
|
||||
jala.toString = function() {
|
||||
return "[Jala JavaScript Application Library]";
|
||||
};
|
|
@ -1,692 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<!--NewPage-->
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>
|
||||
Global
|
||||
</TITLE>
|
||||
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
|
||||
</HEAD>
|
||||
<SCRIPT>
|
||||
function asd()
|
||||
{
|
||||
parent.document.title="Global";
|
||||
}
|
||||
</SCRIPT>
|
||||
<BODY BGCOLOR="white" onload="asd();">
|
||||
|
||||
<!-- ========== START OF NAVBAR ========== -->
|
||||
<A NAME="navbar_bottom"><!-- --></A>
|
||||
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
|
||||
<TR>
|
||||
<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
|
||||
<A NAME="navbar_bottom_firstrow"><!-- --></A>
|
||||
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
|
||||
<TR ALIGN="center" VALIGN="top">
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">File</FONT> </TD>
|
||||
<TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
|
||||
<!--TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"--> <!--A HREF="deprecated-list.html"--><!--FONT CLASS="NavBarFont1">Deprecated</FONT--><!--/A--><!-- </TD-->
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"--><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</TD>
|
||||
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
|
||||
<B>Jala 1.3</B>
|
||||
</EM>
|
||||
</TD
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
|
||||
<B>PREV CLASS</B><!--
|
||||
NEXT CLASS
|
||||
-->
|
||||
<A HREF="helma.Http.html"><B>NEXT CLASS</B></A></FONT></TD>
|
||||
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
|
||||
<A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
|
||||
<A HREF="Global.html" TARGET="_top"><B>NO FRAMES</B></A>
|
||||
|
||||
<SCRIPT>
|
||||
<!--
|
||||
if(window==top) {
|
||||
document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
|
||||
}
|
||||
//-->
|
||||
</SCRIPT>
|
||||
<NOSCRIPT>
|
||||
<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
|
||||
</NOSCRIPT>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
|
||||
SUMMARY: <A HREF="#field_summary">FIELD</A> | <A HREF="#constructor_summary">CONSTR</A> | <A HREF="#method_summary">METHOD</A></FONT></TD>
|
||||
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
|
||||
DETAIL: <A HREF="#field_detail">FIELD</A> | <A HREF="#constructor_detail">CONSTR</A> | <A HREF="#method_detail">METHOD</A></FONT></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<!-- =========== END OF NAVBAR =========== -->
|
||||
<HR>
|
||||
|
||||
<!-- ======== START OF CLASS DATA ======== -->
|
||||
<H2>Class Global</H2>
|
||||
<PRE>Object
|
||||
|
|
||||
+--<b>Global</b>
|
||||
</PRE>
|
||||
|
||||
|
||||
<HR>
|
||||
<DL>
|
||||
<!-- Class definition -->
|
||||
<DT>class
|
||||
<B>Global</B>
|
||||
|
||||
|
||||
</DL>
|
||||
|
||||
<HR>
|
||||
|
||||
<!-- ======== NESTED CLASS SUMMARY ======== -->
|
||||
|
||||
<!-- ======== END NESTED CLASS SUMMARY ======== -->
|
||||
|
||||
|
||||
<!-- =========== FIELD SUMMARY =========== -->
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- =========== END FIELD SUMMARY =========== -->
|
||||
|
||||
|
||||
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
|
||||
|
||||
<!-- ======== END CONSTRUCTOR SUMMARY ======== -->
|
||||
|
||||
|
||||
|
||||
<!-- ========== METHOD SUMMARY =========== -->
|
||||
|
||||
<A NAME="method_summary"><!-- --></A>
|
||||
<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
|
||||
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
|
||||
<TD COLSPAN=2><FONT SIZE="+2">
|
||||
<B>Method Summary</B></FONT></TD>
|
||||
</TR>
|
||||
|
||||
|
||||
<TR BGCOLOR="white" CLASS="TableRowColor">
|
||||
<TD ALIGN="right" VALIGN="top" WIDTH="1%">
|
||||
<FONT SIZE="-1">
|
||||
<CODE><static> Boolean</CODE>
|
||||
</FONT>
|
||||
</TD>
|
||||
<TD>
|
||||
<CODE>
|
||||
<B>
|
||||
<A HREF="#!s!isArray">isArray</A></B>(<Object> val)
|
||||
</CODE>
|
||||
<BR>
|
||||
|
||||
Returns true if the value passed as argument is an array.
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR BGCOLOR="white" CLASS="TableRowColor">
|
||||
<TD ALIGN="right" VALIGN="top" WIDTH="1%">
|
||||
<FONT SIZE="-1">
|
||||
<CODE><static> Boolean</CODE>
|
||||
</FONT>
|
||||
</TD>
|
||||
<TD>
|
||||
<CODE>
|
||||
<B>
|
||||
<A HREF="#!s!isBoolean">isBoolean</A></B>(<Object> val)
|
||||
</CODE>
|
||||
<BR>
|
||||
|
||||
Returns true if the value passed as argument is either a boolean
|
||||
literal or an instance of Boolean.
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR BGCOLOR="white" CLASS="TableRowColor">
|
||||
<TD ALIGN="right" VALIGN="top" WIDTH="1%">
|
||||
<FONT SIZE="-1">
|
||||
<CODE><static> Boolean</CODE>
|
||||
</FONT>
|
||||
</TD>
|
||||
<TD>
|
||||
<CODE>
|
||||
<B>
|
||||
<A HREF="#!s!isDate">isDate</A></B>(<Object> val)
|
||||
</CODE>
|
||||
<BR>
|
||||
|
||||
Returns true if the value passed as argument is either a Javascript date
|
||||
or an instance of java.util.Date.
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR BGCOLOR="white" CLASS="TableRowColor">
|
||||
<TD ALIGN="right" VALIGN="top" WIDTH="1%">
|
||||
<FONT SIZE="-1">
|
||||
<CODE><static> Boolean</CODE>
|
||||
</FONT>
|
||||
</TD>
|
||||
<TD>
|
||||
<CODE>
|
||||
<B>
|
||||
<A HREF="#!s!isFunction">isFunction</A></B>(<Object> val)
|
||||
</CODE>
|
||||
<BR>
|
||||
|
||||
Returns true if the value passed as argument is a function.
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR BGCOLOR="white" CLASS="TableRowColor">
|
||||
<TD ALIGN="right" VALIGN="top" WIDTH="1%">
|
||||
<FONT SIZE="-1">
|
||||
<CODE><static> Boolean</CODE>
|
||||
</FONT>
|
||||
</TD>
|
||||
<TD>
|
||||
<CODE>
|
||||
<B>
|
||||
<A HREF="#!s!isNull">isNull</A></B>(<Object> val)
|
||||
</CODE>
|
||||
<BR>
|
||||
|
||||
Returns true if the value passed as argument is null.
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR BGCOLOR="white" CLASS="TableRowColor">
|
||||
<TD ALIGN="right" VALIGN="top" WIDTH="1%">
|
||||
<FONT SIZE="-1">
|
||||
<CODE><static> Boolean</CODE>
|
||||
</FONT>
|
||||
</TD>
|
||||
<TD>
|
||||
<CODE>
|
||||
<B>
|
||||
<A HREF="#!s!isNumber">isNumber</A></B>(<Object> val)
|
||||
</CODE>
|
||||
<BR>
|
||||
|
||||
Returns true if the value passed as argument is either a number,
|
||||
an instance of Number or of java.lang.Number.
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR BGCOLOR="white" CLASS="TableRowColor">
|
||||
<TD ALIGN="right" VALIGN="top" WIDTH="1%">
|
||||
<FONT SIZE="-1">
|
||||
<CODE><static> Boolean</CODE>
|
||||
</FONT>
|
||||
</TD>
|
||||
<TD>
|
||||
<CODE>
|
||||
<B>
|
||||
<A HREF="#!s!isObject">isObject</A></B>(<Object> val)
|
||||
</CODE>
|
||||
<BR>
|
||||
|
||||
Returns true if the value passed as argument is either a Javascript
|
||||
object or an instance of java.lang.Object.
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR BGCOLOR="white" CLASS="TableRowColor">
|
||||
<TD ALIGN="right" VALIGN="top" WIDTH="1%">
|
||||
<FONT SIZE="-1">
|
||||
<CODE><static> Boolean</CODE>
|
||||
</FONT>
|
||||
</TD>
|
||||
<TD>
|
||||
<CODE>
|
||||
<B>
|
||||
<A HREF="#!s!isString">isString</A></B>(<Object> val)
|
||||
</CODE>
|
||||
<BR>
|
||||
|
||||
Returns true if the value passed as argument is either a string literal,
|
||||
an instance of String or of java.lang.String.
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR BGCOLOR="white" CLASS="TableRowColor">
|
||||
<TD ALIGN="right" VALIGN="top" WIDTH="1%">
|
||||
<FONT SIZE="-1">
|
||||
<CODE><static> Boolean</CODE>
|
||||
</FONT>
|
||||
</TD>
|
||||
<TD>
|
||||
<CODE>
|
||||
<B>
|
||||
<A HREF="#!s!isUndefined">isUndefined</A></B>(<Object> val)
|
||||
</CODE>
|
||||
<BR>
|
||||
|
||||
Returns true if the value passed as argument is undefined.
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
|
||||
</TABLE>
|
||||
|
||||
|
||||
|
||||
<P>
|
||||
<!-- ========== END METHOD SUMMARY =========== -->
|
||||
|
||||
|
||||
<!-- ============ FIELD DETAIL START =========== -->
|
||||
|
||||
|
||||
<!-- ============ FIELD DETAIL END =========== -->
|
||||
|
||||
<!-- ========= CONSTRUCTOR DETAIL START ======== -->
|
||||
|
||||
|
||||
<!-- Constructor return value(s) -->
|
||||
|
||||
<!-- End constructor return value(s) -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES -->
|
||||
|
||||
<HR/>
|
||||
<!-- END ADDITIONAL ATTRIBUTES -->
|
||||
|
||||
<!-- ========= CONSTRUCTOR DETAIL END ======== -->
|
||||
|
||||
|
||||
<!-- ============ METHOD DETAIL START ========== -->
|
||||
|
||||
<A NAME="method_detail"><!-- --></A>
|
||||
<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
|
||||
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
|
||||
<TD COLSPAN=1><FONT SIZE="+2">
|
||||
<B>Method Detail</B></FONT>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
|
||||
<!-- One single method detail entry -->
|
||||
|
||||
<A NAME="!s!isArray"><!-- --></A>
|
||||
<H3>isArray</H3>
|
||||
<PRE><static> Boolean <B>isArray</B>(<Object> val)</PRE>
|
||||
|
||||
<UL>Returns true if the value passed as argument is an array.</UL>
|
||||
|
||||
|
||||
<!-- METHOD PARAMETERS START -->
|
||||
|
||||
<UL>
|
||||
<B>Parameters:</B>
|
||||
|
||||
<UL><CODE>val</CODE> - The value to test
|
||||
</UL>
|
||||
|
||||
</UL>
|
||||
|
||||
<!-- METHOD PARAMETERS END -->
|
||||
|
||||
|
||||
<UL>
|
||||
<B>Returns:</B>
|
||||
<UL>
|
||||
True if the value is an array, false otherwise
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES START -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES END -->
|
||||
<HR>
|
||||
|
||||
<A NAME="!s!isBoolean"><!-- --></A>
|
||||
<H3>isBoolean</H3>
|
||||
<PRE><static> Boolean <B>isBoolean</B>(<Object> val)</PRE>
|
||||
|
||||
<UL>Returns true if the value passed as argument is either a boolean
|
||||
literal or an instance of Boolean.</UL>
|
||||
|
||||
|
||||
<!-- METHOD PARAMETERS START -->
|
||||
|
||||
<UL>
|
||||
<B>Parameters:</B>
|
||||
|
||||
<UL><CODE>val</CODE> - The value to test
|
||||
</UL>
|
||||
|
||||
</UL>
|
||||
|
||||
<!-- METHOD PARAMETERS END -->
|
||||
|
||||
|
||||
<UL>
|
||||
<B>Returns:</B>
|
||||
<UL>
|
||||
True if the value is a boolean, false otherwise
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES START -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES END -->
|
||||
<HR>
|
||||
|
||||
<A NAME="!s!isDate"><!-- --></A>
|
||||
<H3>isDate</H3>
|
||||
<PRE><static> Boolean <B>isDate</B>(<Object> val)</PRE>
|
||||
|
||||
<UL>Returns true if the value passed as argument is either a Javascript date
|
||||
or an instance of java.util.Date.</UL>
|
||||
|
||||
|
||||
<!-- METHOD PARAMETERS START -->
|
||||
|
||||
<UL>
|
||||
<B>Parameters:</B>
|
||||
|
||||
<UL><CODE>val</CODE> - The value to test
|
||||
</UL>
|
||||
|
||||
</UL>
|
||||
|
||||
<!-- METHOD PARAMETERS END -->
|
||||
|
||||
|
||||
<UL>
|
||||
<B>Returns:</B>
|
||||
<UL>
|
||||
True if the value is a date, false otherwise
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES START -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES END -->
|
||||
<HR>
|
||||
|
||||
<A NAME="!s!isFunction"><!-- --></A>
|
||||
<H3>isFunction</H3>
|
||||
<PRE><static> Boolean <B>isFunction</B>(<Object> val)</PRE>
|
||||
|
||||
<UL>Returns true if the value passed as argument is a function.</UL>
|
||||
|
||||
|
||||
<!-- METHOD PARAMETERS START -->
|
||||
|
||||
<UL>
|
||||
<B>Parameters:</B>
|
||||
|
||||
<UL><CODE>val</CODE> - The value to test
|
||||
</UL>
|
||||
|
||||
</UL>
|
||||
|
||||
<!-- METHOD PARAMETERS END -->
|
||||
|
||||
|
||||
<UL>
|
||||
<B>Returns:</B>
|
||||
<UL>
|
||||
True if the argument is a function, false otherwise
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES START -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES END -->
|
||||
<HR>
|
||||
|
||||
<A NAME="!s!isNull"><!-- --></A>
|
||||
<H3>isNull</H3>
|
||||
<PRE><static> Boolean <B>isNull</B>(<Object> val)</PRE>
|
||||
|
||||
<UL>Returns true if the value passed as argument is null.</UL>
|
||||
|
||||
|
||||
<!-- METHOD PARAMETERS START -->
|
||||
|
||||
<UL>
|
||||
<B>Parameters:</B>
|
||||
|
||||
<UL><CODE>val</CODE> - The value to test
|
||||
</UL>
|
||||
|
||||
</UL>
|
||||
|
||||
<!-- METHOD PARAMETERS END -->
|
||||
|
||||
|
||||
<UL>
|
||||
<B>Returns:</B>
|
||||
<UL>
|
||||
True if the value is null, false otherwise
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES START -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES END -->
|
||||
<HR>
|
||||
|
||||
<A NAME="!s!isNumber"><!-- --></A>
|
||||
<H3>isNumber</H3>
|
||||
<PRE><static> Boolean <B>isNumber</B>(<Object> val)</PRE>
|
||||
|
||||
<UL>Returns true if the value passed as argument is either a number,
|
||||
an instance of Number or of java.lang.Number.</UL>
|
||||
|
||||
|
||||
<!-- METHOD PARAMETERS START -->
|
||||
|
||||
<UL>
|
||||
<B>Parameters:</B>
|
||||
|
||||
<UL><CODE>val</CODE> - The value to test
|
||||
</UL>
|
||||
|
||||
</UL>
|
||||
|
||||
<!-- METHOD PARAMETERS END -->
|
||||
|
||||
|
||||
<UL>
|
||||
<B>Returns:</B>
|
||||
<UL>
|
||||
True if the value is a number, false otherwise
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES START -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES END -->
|
||||
<HR>
|
||||
|
||||
<A NAME="!s!isObject"><!-- --></A>
|
||||
<H3>isObject</H3>
|
||||
<PRE><static> Boolean <B>isObject</B>(<Object> val)</PRE>
|
||||
|
||||
<UL>Returns true if the value passed as argument is either a Javascript
|
||||
object or an instance of java.lang.Object.</UL>
|
||||
|
||||
|
||||
<!-- METHOD PARAMETERS START -->
|
||||
|
||||
<UL>
|
||||
<B>Parameters:</B>
|
||||
|
||||
<UL><CODE>val</CODE> - The value to test
|
||||
</UL>
|
||||
|
||||
</UL>
|
||||
|
||||
<!-- METHOD PARAMETERS END -->
|
||||
|
||||
|
||||
<UL>
|
||||
<B>Returns:</B>
|
||||
<UL>
|
||||
True if the value is an object, false otherwise
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES START -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES END -->
|
||||
<HR>
|
||||
|
||||
<A NAME="!s!isString"><!-- --></A>
|
||||
<H3>isString</H3>
|
||||
<PRE><static> Boolean <B>isString</B>(<Object> val)</PRE>
|
||||
|
||||
<UL>Returns true if the value passed as argument is either a string literal,
|
||||
an instance of String or of java.lang.String.</UL>
|
||||
|
||||
|
||||
<!-- METHOD PARAMETERS START -->
|
||||
|
||||
<UL>
|
||||
<B>Parameters:</B>
|
||||
|
||||
<UL><CODE>val</CODE> - The value to test
|
||||
</UL>
|
||||
|
||||
</UL>
|
||||
|
||||
<!-- METHOD PARAMETERS END -->
|
||||
|
||||
|
||||
<UL>
|
||||
<B>Returns:</B>
|
||||
<UL>
|
||||
True if the value is a string, false otherwise
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES START -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES END -->
|
||||
<HR>
|
||||
|
||||
<A NAME="!s!isUndefined"><!-- --></A>
|
||||
<H3>isUndefined</H3>
|
||||
<PRE><static> Boolean <B>isUndefined</B>(<Object> val)</PRE>
|
||||
|
||||
<UL>Returns true if the value passed as argument is undefined.</UL>
|
||||
|
||||
|
||||
<!-- METHOD PARAMETERS START -->
|
||||
|
||||
<UL>
|
||||
<B>Parameters:</B>
|
||||
|
||||
<UL><CODE>val</CODE> - The value to test
|
||||
</UL>
|
||||
|
||||
</UL>
|
||||
|
||||
<!-- METHOD PARAMETERS END -->
|
||||
|
||||
|
||||
<UL>
|
||||
<B>Returns:</B>
|
||||
<UL>
|
||||
True if the value is undefined, false otherwise
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES START -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES END -->
|
||||
<HR>
|
||||
|
||||
|
||||
|
||||
<!-- ============ METHOD DETAIL END ========== -->
|
||||
|
||||
<!-- ========= END OF CLASS DATA ========= -->
|
||||
|
||||
<!-- ========== START OF NAVBAR ========== -->
|
||||
<A NAME="navbar_bottom"><!-- --></A>
|
||||
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
|
||||
<TR>
|
||||
<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
|
||||
<A NAME="navbar_bottom_firstrow"><!-- --></A>
|
||||
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
|
||||
<TR ALIGN="center" VALIGN="top">
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">File</FONT> </TD>
|
||||
<TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><b>Tree</b></FONT></A> </TD>
|
||||
<!--TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"--> <!--A HREF="deprecated-list.html"--><!--FONT CLASS="NavBarFont1">Deprecated</FONT--><!--/A--><!-- </TD-->
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</TD>
|
||||
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
|
||||
<B>Jala 1.3</B>
|
||||
</EM>
|
||||
</TD
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
|
||||
<B>PREV CLASS</B><!--
|
||||
NEXT CLASS
|
||||
-->
|
||||
<A HREF="helma.Http.html"><B>NEXT CLASS</B></A></FONT></TD>
|
||||
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
|
||||
<A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
|
||||
<A HREF="Global.html" TARGET="_top"><B>NO FRAMES</B></A>
|
||||
|
||||
<SCRIPT>
|
||||
<!--
|
||||
if(window==top) {
|
||||
document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
|
||||
}
|
||||
//-->
|
||||
</SCRIPT>
|
||||
<NOSCRIPT>
|
||||
<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
|
||||
</NOSCRIPT>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
|
||||
SUMMARY: <A HREF="#field_summary">FIELD</A> | <A HREF="#constructor_summary">CONSTR</A> | <A HREF="#method_summary">METHOD</A></FONT></TD>
|
||||
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
|
||||
DETAIL: <A HREF="#field_detail">FIELD</A> | <A HREF="#constructor_detail">CONSTR</A> | <A HREF="#method_detail">METHOD</A></FONT></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
|
||||
<!-- =========== END OF NAVBAR =========== -->
|
||||
|
||||
<HR>
|
||||
<FONT SIZE="-1">
|
||||
|
||||
</FONT>
|
||||
<div class="jsdoc_ctime">Documentation generated by <a href="http://jsdoc.sourceforge.net/" target="_parent">JSDoc</a> on Tue Jan 8 15:45:31 2008</div>
|
||||
</BODY>
|
||||
</HTML>
|
|
@ -1,581 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<!--NewPage-->
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>
|
||||
HopObject
|
||||
</TITLE>
|
||||
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
|
||||
</HEAD>
|
||||
<SCRIPT>
|
||||
function asd()
|
||||
{
|
||||
parent.document.title="HopObject";
|
||||
}
|
||||
</SCRIPT>
|
||||
<BODY BGCOLOR="white" onload="asd();">
|
||||
|
||||
<!-- ========== START OF NAVBAR ========== -->
|
||||
<A NAME="navbar_bottom"><!-- --></A>
|
||||
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
|
||||
<TR>
|
||||
<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
|
||||
<A NAME="navbar_bottom_firstrow"><!-- --></A>
|
||||
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
|
||||
<TR ALIGN="center" VALIGN="top">
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">File</FONT> </TD>
|
||||
<TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
|
||||
<!--TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"--> <!--A HREF="deprecated-list.html"--><!--FONT CLASS="NavBarFont1">Deprecated</FONT--><!--/A--><!-- </TD-->
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"--><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</TD>
|
||||
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
|
||||
<B>Jala 1.3</B>
|
||||
</EM>
|
||||
</TD
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
|
||||
<A HREF="helma.Http.html"><B>PREV CLASS</B></A><!--
|
||||
NEXT CLASS
|
||||
-->
|
||||
<A HREF="jala.html"><B>NEXT CLASS</B></A></FONT></TD>
|
||||
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
|
||||
<A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
|
||||
<A HREF="HopObject.html" TARGET="_top"><B>NO FRAMES</B></A>
|
||||
|
||||
<SCRIPT>
|
||||
<!--
|
||||
if(window==top) {
|
||||
document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
|
||||
}
|
||||
//-->
|
||||
</SCRIPT>
|
||||
<NOSCRIPT>
|
||||
<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
|
||||
</NOSCRIPT>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
|
||||
SUMMARY: <A HREF="#field_summary">FIELD</A> | <A HREF="#constructor_summary">CONSTR</A> | <A HREF="#method_summary">METHOD</A></FONT></TD>
|
||||
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
|
||||
DETAIL: <A HREF="#field_detail">FIELD</A> | <A HREF="#constructor_detail">CONSTR</A> | <A HREF="#method_detail">METHOD</A></FONT></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<!-- =========== END OF NAVBAR =========== -->
|
||||
<HR>
|
||||
|
||||
<!-- ======== START OF CLASS DATA ======== -->
|
||||
<H2>Class HopObject</H2>
|
||||
<PRE>Object
|
||||
|
|
||||
+--<b>HopObject</b>
|
||||
</PRE>
|
||||
|
||||
|
||||
<HR>
|
||||
<DL>
|
||||
<!-- Class definition -->
|
||||
<DT>class
|
||||
<B>HopObject</B>
|
||||
|
||||
|
||||
</DL>
|
||||
|
||||
<HR>
|
||||
|
||||
<!-- ======== NESTED CLASS SUMMARY ======== -->
|
||||
|
||||
<!-- ======== END NESTED CLASS SUMMARY ======== -->
|
||||
|
||||
|
||||
<!-- =========== FIELD SUMMARY =========== -->
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- =========== END FIELD SUMMARY =========== -->
|
||||
|
||||
|
||||
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
|
||||
|
||||
<!-- ======== END CONSTRUCTOR SUMMARY ======== -->
|
||||
|
||||
|
||||
|
||||
<!-- ========== METHOD SUMMARY =========== -->
|
||||
|
||||
<A NAME="method_summary"><!-- --></A>
|
||||
<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
|
||||
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
|
||||
<TD COLSPAN=2><FONT SIZE="+2">
|
||||
<B>Method Summary</B></FONT></TD>
|
||||
</TR>
|
||||
|
||||
|
||||
<TR BGCOLOR="white" CLASS="TableRowColor">
|
||||
<TD ALIGN="right" VALIGN="top" WIDTH="1%">
|
||||
<FONT SIZE="-1">
|
||||
<CODE> String</CODE>
|
||||
</FONT>
|
||||
</TD>
|
||||
<TD>
|
||||
<CODE>
|
||||
<B>
|
||||
<A HREF="#getAccessName">getAccessName</A></B>(<Object> obj, <Number> maxLength)
|
||||
</CODE>
|
||||
<BR>
|
||||
|
||||
Constructs a name from an object which
|
||||
is unique in the underlying HopObject collection.
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR BGCOLOR="white" CLASS="TableRowColor">
|
||||
<TD ALIGN="right" VALIGN="top" WIDTH="1%">
|
||||
<FONT SIZE="-1">
|
||||
<CODE> Boolean</CODE>
|
||||
</FONT>
|
||||
</TD>
|
||||
<TD>
|
||||
<CODE>
|
||||
<B>
|
||||
<A HREF="#isClean">isClean</A></B>()
|
||||
</CODE>
|
||||
<BR>
|
||||
|
||||
Returns true if the internal state of this HopObject is CLEAN.
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR BGCOLOR="white" CLASS="TableRowColor">
|
||||
<TD ALIGN="right" VALIGN="top" WIDTH="1%">
|
||||
<FONT SIZE="-1">
|
||||
<CODE> Boolean</CODE>
|
||||
</FONT>
|
||||
</TD>
|
||||
<TD>
|
||||
<CODE>
|
||||
<B>
|
||||
<A HREF="#isDeleted">isDeleted</A></B>()
|
||||
</CODE>
|
||||
<BR>
|
||||
|
||||
Returns true if the internal state of this HopObject is DELETED.
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR BGCOLOR="white" CLASS="TableRowColor">
|
||||
<TD ALIGN="right" VALIGN="top" WIDTH="1%">
|
||||
<FONT SIZE="-1">
|
||||
<CODE> Boolean</CODE>
|
||||
</FONT>
|
||||
</TD>
|
||||
<TD>
|
||||
<CODE>
|
||||
<B>
|
||||
<A HREF="#isInvalid">isInvalid</A></B>()
|
||||
</CODE>
|
||||
<BR>
|
||||
|
||||
Returns true if the internal state of this HopObject is INVALID.
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR BGCOLOR="white" CLASS="TableRowColor">
|
||||
<TD ALIGN="right" VALIGN="top" WIDTH="1%">
|
||||
<FONT SIZE="-1">
|
||||
<CODE> Boolean</CODE>
|
||||
</FONT>
|
||||
</TD>
|
||||
<TD>
|
||||
<CODE>
|
||||
<B>
|
||||
<A HREF="#isModified">isModified</A></B>()
|
||||
</CODE>
|
||||
<BR>
|
||||
|
||||
Returns true if the internal state of this HopObject is MODIFIED.
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR BGCOLOR="white" CLASS="TableRowColor">
|
||||
<TD ALIGN="right" VALIGN="top" WIDTH="1%">
|
||||
<FONT SIZE="-1">
|
||||
<CODE> Boolean</CODE>
|
||||
</FONT>
|
||||
</TD>
|
||||
<TD>
|
||||
<CODE>
|
||||
<B>
|
||||
<A HREF="#isNew">isNew</A></B>()
|
||||
</CODE>
|
||||
<BR>
|
||||
|
||||
Returns true if the internal state of this HopObject is NEW.
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR BGCOLOR="white" CLASS="TableRowColor">
|
||||
<TD ALIGN="right" VALIGN="top" WIDTH="1%">
|
||||
<FONT SIZE="-1">
|
||||
<CODE> Boolean</CODE>
|
||||
</FONT>
|
||||
</TD>
|
||||
<TD>
|
||||
<CODE>
|
||||
<B>
|
||||
<A HREF="#isTransient">isTransient</A></B>()
|
||||
</CODE>
|
||||
<BR>
|
||||
|
||||
Returns true if the internal state of this HopObject is TRANSIENT.
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR BGCOLOR="white" CLASS="TableRowColor">
|
||||
<TD ALIGN="right" VALIGN="top" WIDTH="1%">
|
||||
<FONT SIZE="-1">
|
||||
<CODE> Boolean</CODE>
|
||||
</FONT>
|
||||
</TD>
|
||||
<TD>
|
||||
<CODE>
|
||||
<B>
|
||||
<A HREF="#isVirtual">isVirtual</A></B>()
|
||||
</CODE>
|
||||
<BR>
|
||||
|
||||
Returns true if the internal state of this HopObject is VIRTUAL.
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
|
||||
</TABLE>
|
||||
|
||||
|
||||
|
||||
<P>
|
||||
<!-- ========== END METHOD SUMMARY =========== -->
|
||||
|
||||
|
||||
<!-- ============ FIELD DETAIL START =========== -->
|
||||
|
||||
|
||||
<!-- ============ FIELD DETAIL END =========== -->
|
||||
|
||||
<!-- ========= CONSTRUCTOR DETAIL START ======== -->
|
||||
|
||||
|
||||
<!-- Constructor return value(s) -->
|
||||
|
||||
<!-- End constructor return value(s) -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES -->
|
||||
|
||||
<HR/>
|
||||
<!-- END ADDITIONAL ATTRIBUTES -->
|
||||
|
||||
<!-- ========= CONSTRUCTOR DETAIL END ======== -->
|
||||
|
||||
|
||||
<!-- ============ METHOD DETAIL START ========== -->
|
||||
|
||||
<A NAME="method_detail"><!-- --></A>
|
||||
<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
|
||||
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
|
||||
<TD COLSPAN=1><FONT SIZE="+2">
|
||||
<B>Method Detail</B></FONT>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
|
||||
<!-- One single method detail entry -->
|
||||
|
||||
<A NAME="getAccessName"><!-- --></A>
|
||||
<H3>getAccessName</H3>
|
||||
<PRE>String <B>getAccessName</B>(<Object> obj, <Number> maxLength)</PRE>
|
||||
|
||||
<UL>Constructs a name from an object which
|
||||
is unique in the underlying HopObject collection.</UL>
|
||||
|
||||
|
||||
<!-- METHOD PARAMETERS START -->
|
||||
|
||||
<UL>
|
||||
<B>Parameters:</B>
|
||||
|
||||
<UL><CODE>obj</CODE> - The object representing or containing the alias name. Possible object types include: <ul> <li>File</li> <li>helma.File</li> <li>java.io.File</li> <li>String</li> <li>java.lang.String</li> <li>Packages.helma.util.MimePart</li> </ul>
|
||||
</UL>
|
||||
|
||||
<UL><CODE>maxLength</CODE> - The maximum length of the alias
|
||||
</UL>
|
||||
|
||||
</UL>
|
||||
|
||||
<!-- METHOD PARAMETERS END -->
|
||||
|
||||
|
||||
<UL>
|
||||
<B>Returns:</B>
|
||||
<UL>
|
||||
The resulting alias
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES START -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES END -->
|
||||
<HR>
|
||||
|
||||
<A NAME="isClean"><!-- --></A>
|
||||
<H3>isClean</H3>
|
||||
<PRE>Boolean <B>isClean</B>()</PRE>
|
||||
|
||||
<UL>Returns true if the internal state of this HopObject is CLEAN.</UL>
|
||||
|
||||
|
||||
<!-- METHOD PARAMETERS START -->
|
||||
|
||||
<!-- METHOD PARAMETERS END -->
|
||||
|
||||
|
||||
<UL>
|
||||
<B>Returns:</B>
|
||||
<UL>
|
||||
True if this HopObject is marked as <em>clean</em>, false otherwise.
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES START -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES END -->
|
||||
<HR>
|
||||
|
||||
<A NAME="isDeleted"><!-- --></A>
|
||||
<H3>isDeleted</H3>
|
||||
<PRE>Boolean <B>isDeleted</B>()</PRE>
|
||||
|
||||
<UL>Returns true if the internal state of this HopObject is DELETED.</UL>
|
||||
|
||||
|
||||
<!-- METHOD PARAMETERS START -->
|
||||
|
||||
<!-- METHOD PARAMETERS END -->
|
||||
|
||||
|
||||
<UL>
|
||||
<B>Returns:</B>
|
||||
<UL>
|
||||
True if this HopObject is marked as <em>deleted</em>, false otherwise.
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES START -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES END -->
|
||||
<HR>
|
||||
|
||||
<A NAME="isInvalid"><!-- --></A>
|
||||
<H3>isInvalid</H3>
|
||||
<PRE>Boolean <B>isInvalid</B>()</PRE>
|
||||
|
||||
<UL>Returns true if the internal state of this HopObject is INVALID.</UL>
|
||||
|
||||
|
||||
<!-- METHOD PARAMETERS START -->
|
||||
|
||||
<!-- METHOD PARAMETERS END -->
|
||||
|
||||
|
||||
<UL>
|
||||
<B>Returns:</B>
|
||||
<UL>
|
||||
True if this HopObject is marked as <em>invalid</em>, false otherwise.
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES START -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES END -->
|
||||
<HR>
|
||||
|
||||
<A NAME="isModified"><!-- --></A>
|
||||
<H3>isModified</H3>
|
||||
<PRE>Boolean <B>isModified</B>()</PRE>
|
||||
|
||||
<UL>Returns true if the internal state of this HopObject is MODIFIED.</UL>
|
||||
|
||||
|
||||
<!-- METHOD PARAMETERS START -->
|
||||
|
||||
<!-- METHOD PARAMETERS END -->
|
||||
|
||||
|
||||
<UL>
|
||||
<B>Returns:</B>
|
||||
<UL>
|
||||
True if this HopObject is marked as <em>modified</em>, false otherwise.
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES START -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES END -->
|
||||
<HR>
|
||||
|
||||
<A NAME="isNew"><!-- --></A>
|
||||
<H3>isNew</H3>
|
||||
<PRE>Boolean <B>isNew</B>()</PRE>
|
||||
|
||||
<UL>Returns true if the internal state of this HopObject is NEW.</UL>
|
||||
|
||||
|
||||
<!-- METHOD PARAMETERS START -->
|
||||
|
||||
<!-- METHOD PARAMETERS END -->
|
||||
|
||||
|
||||
<UL>
|
||||
<B>Returns:</B>
|
||||
<UL>
|
||||
True if this HopObject is marked as <em>new</em>, false otherwise.
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES START -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES END -->
|
||||
<HR>
|
||||
|
||||
<A NAME="isTransient"><!-- --></A>
|
||||
<H3>isTransient</H3>
|
||||
<PRE>Boolean <B>isTransient</B>()</PRE>
|
||||
|
||||
<UL>Returns true if the internal state of this HopObject is TRANSIENT.</UL>
|
||||
|
||||
|
||||
<!-- METHOD PARAMETERS START -->
|
||||
|
||||
<!-- METHOD PARAMETERS END -->
|
||||
|
||||
|
||||
<UL>
|
||||
<B>Returns:</B>
|
||||
<UL>
|
||||
True if this HopObject is marked as <em>transient</em>, false otherwise.
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES START -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES END -->
|
||||
<HR>
|
||||
|
||||
<A NAME="isVirtual"><!-- --></A>
|
||||
<H3>isVirtual</H3>
|
||||
<PRE>Boolean <B>isVirtual</B>()</PRE>
|
||||
|
||||
<UL>Returns true if the internal state of this HopObject is VIRTUAL.</UL>
|
||||
|
||||
|
||||
<!-- METHOD PARAMETERS START -->
|
||||
|
||||
<!-- METHOD PARAMETERS END -->
|
||||
|
||||
|
||||
<UL>
|
||||
<B>Returns:</B>
|
||||
<UL>
|
||||
True if this HopObject is marked as <em>virtual</em>, false otherwise.
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES START -->
|
||||
|
||||
<!-- ADDITIONAL ATTRIBUTES END -->
|
||||
<HR>
|
||||
|
||||
|
||||
|
||||
<!-- ============ METHOD DETAIL END ========== -->
|
||||
|
||||
<!-- ========= END OF CLASS DATA ========= -->
|
||||
|
||||
<!-- ========== START OF NAVBAR ========== -->
|
||||
<A NAME="navbar_bottom"><!-- --></A>
|
||||
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
|
||||
<TR>
|
||||
<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
|
||||
<A NAME="navbar_bottom_firstrow"><!-- --></A>
|
||||
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
|
||||
<TR ALIGN="center" VALIGN="top">
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">File</FONT> </TD>
|
||||
<TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><b>Tree</b></FONT></A> </TD>
|
||||
<!--TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"--> <!--A HREF="deprecated-list.html"--><!--FONT CLASS="NavBarFont1">Deprecated</FONT--><!--/A--><!-- </TD-->
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</TD>
|
||||
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
|
||||
<B>Jala 1.3</B>
|
||||
</EM>
|
||||
</TD
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
|
||||
<A HREF="helma.Http.html"><B>PREV CLASS</B></A><!--
|
||||
NEXT CLASS
|
||||
-->
|
||||
<A HREF="jala.html"><B>NEXT CLASS</B></A></FONT></TD>
|
||||
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
|
||||
<A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
|
||||
<A HREF="HopObject.html" TARGET="_top"><B>NO FRAMES</B></A>
|
||||
|
||||
<SCRIPT>
|
||||
<!--
|
||||
if(window==top) {
|
||||
document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
|
||||
}
|
||||
//-->
|
||||
</SCRIPT>
|
||||
<NOSCRIPT>
|
||||
<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
|
||||
</NOSCRIPT>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
|
||||
SUMMARY: <A HREF="#field_summary">FIELD</A> | <A HREF="#constructor_summary">CONSTR</A> | <A HREF="#method_summary">METHOD</A></FONT></TD>
|
||||
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
|
||||
DETAIL: <A HREF="#field_detail">FIELD</A> | <A HREF="#constructor_detail">CONSTR</A> | <A HREF="#method_detail">METHOD</A></FONT></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
|
||||
<!-- =========== END OF NAVBAR =========== -->
|
||||
|
||||
<HR>
|
||||
<FONT SIZE="-1">
|
||||
|
||||
</FONT>
|
||||
<div class="jsdoc_ctime">Documentation generated by <a href="http://jsdoc.sourceforge.net/" target="_parent">JSDoc</a> on Tue Jan 8 15:45:31 2008</div>
|
||||
</BODY>
|
||||
</HTML>
|
|
@ -1,323 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<!--NewPage-->
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>
|
||||
All Classes
|
||||
</TITLE>
|
||||
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
|
||||
</HEAD>
|
||||
<SCRIPT>
|
||||
function asd()
|
||||
{
|
||||
parent.document.title=" All Classes";
|
||||
}
|
||||
</SCRIPT>
|
||||
<BODY BGCOLOR="white" onload="asd();">
|
||||
|
||||
<H3 class="FrameHeadingFont"><B></B></H3>
|
||||
<FONT size="+1" CLASS="FrameHeadingFont">
|
||||
<B><a href="overview-summary.html" target="classFrame">All Classes</a></B></FONT>
|
||||
<BR>
|
||||
|
||||
<TABLE BORDER="0" WIDTH="100%">
|
||||
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="Global.html" TARGET="classFrame">Global</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="HopObject.html" TARGET="classFrame">HopObject</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.html" TARGET="classFrame">jala</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.AsyncRequest.html" TARGET="classFrame">jala.AsyncRequest</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.BitTorrent.html" TARGET="classFrame">jala.BitTorrent</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Captcha.html" TARGET="classFrame">jala.Captcha</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Date.html" TARGET="classFrame">jala.Date</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Date.Calendar.html" TARGET="classFrame">jala.Date.Calendar</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Date.Calendar.Renderer.html" TARGET="classFrame">jala.Date.Calendar.Renderer</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.db.html" TARGET="classFrame">jala.db</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.db.FileDatabase.html" TARGET="classFrame">jala.db.FileDatabase</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.db.RamDatabase.html" TARGET="classFrame">jala.db.RamDatabase</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.db.Server.html" TARGET="classFrame">jala.db.Server</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.DnsClient.html" TARGET="classFrame">jala.DnsClient</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.DnsClient.Record.html" TARGET="classFrame">jala.DnsClient.Record</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.html" TARGET="classFrame">jala.Form</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.html" TARGET="classFrame">jala.Form.Component</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Button.html" TARGET="classFrame">jala.Form.Component.Button</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Checkbox.html" TARGET="classFrame">jala.Form.Component.Checkbox</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Date.html" TARGET="classFrame">jala.Form.Component.Date</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Fieldset.html" TARGET="classFrame">jala.Form.Component.Fieldset</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.File.html" TARGET="classFrame">jala.Form.Component.File</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Hidden.html" TARGET="classFrame">jala.Form.Component.Hidden</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Image.html" TARGET="classFrame">jala.Form.Component.Image</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Input.html" TARGET="classFrame">jala.Form.Component.Input</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Password.html" TARGET="classFrame">jala.Form.Component.Password</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Radio.html" TARGET="classFrame">jala.Form.Component.Radio</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Select.html" TARGET="classFrame">jala.Form.Component.Select</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Skin.html" TARGET="classFrame">jala.Form.Component.Skin</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Submit.html" TARGET="classFrame">jala.Form.Component.Submit</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Textarea.html" TARGET="classFrame">jala.Form.Component.Textarea</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Tracker.html" TARGET="classFrame">jala.Form.Tracker</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.History.html" TARGET="classFrame">jala.History</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.HtmlDocument.html" TARGET="classFrame">jala.HtmlDocument</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.I18n.html" TARGET="classFrame">jala.I18n</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.ImageFilter.html" TARGET="classFrame">jala.ImageFilter</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.IndexManager.html" TARGET="classFrame">jala.IndexManager</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.IndexManager.Job.html" TARGET="classFrame">jala.IndexManager.Job</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.ListRenderer.html" TARGET="classFrame">jala.ListRenderer</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.ListRenderer.ArrayList.html" TARGET="classFrame">jala.ListRenderer.ArrayList</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Mp3.html" TARGET="classFrame">jala.Mp3</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Mp3.Id3v1.html" TARGET="classFrame">jala.Mp3.Id3v1</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Mp3.Id3v2.html" TARGET="classFrame">jala.Mp3.Id3v2</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.PodcastWriter.html" TARGET="classFrame">jala.PodcastWriter</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.RemoteContent.html" TARGET="classFrame">jala.RemoteContent</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Rss20Writer.html" TARGET="classFrame">jala.Rss20Writer</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Utilities.html" TARGET="classFrame">jala.Utilities</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.XmlRpcRequest.html" TARGET="classFrame">jala.XmlRpcRequest</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.XmlWriter.html" TARGET="classFrame">jala.XmlWriter</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
</TABLE>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
|
@ -1,322 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>
|
||||
Jala 1.3 All Classes
|
||||
</TITLE>
|
||||
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
|
||||
</HEAD>
|
||||
<SCRIPT>
|
||||
function asd()
|
||||
{
|
||||
parent.document.title="Jala 1.3 All Classes";
|
||||
}
|
||||
</SCRIPT>
|
||||
<BODY BGCOLOR="white" onload="asd();">
|
||||
|
||||
<H3 CLASS="FrameHeadingFont">Jala 1.3</H3>
|
||||
<FONT size="+1" CLASS="FrameHeadingFont">
|
||||
<B><a href="overview-summary.html">All Classes</a></B></FONT>
|
||||
<BR>
|
||||
|
||||
<TABLE BORDER="0" WIDTH="100%">
|
||||
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="Global.html" >Global</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="HopObject.html" >HopObject</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.html" >jala</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.AsyncRequest.html" >jala.AsyncRequest</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.BitTorrent.html" >jala.BitTorrent</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Captcha.html" >jala.Captcha</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Date.html" >jala.Date</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Date.Calendar.html" >jala.Date.Calendar</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Date.Calendar.Renderer.html" >jala.Date.Calendar.Renderer</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.db.html" >jala.db</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.db.FileDatabase.html" >jala.db.FileDatabase</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.db.RamDatabase.html" >jala.db.RamDatabase</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.db.Server.html" >jala.db.Server</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.DnsClient.html" >jala.DnsClient</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.DnsClient.Record.html" >jala.DnsClient.Record</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.html" >jala.Form</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.html" >jala.Form.Component</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Button.html" >jala.Form.Component.Button</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Checkbox.html" >jala.Form.Component.Checkbox</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Date.html" >jala.Form.Component.Date</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Fieldset.html" >jala.Form.Component.Fieldset</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.File.html" >jala.Form.Component.File</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Hidden.html" >jala.Form.Component.Hidden</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Image.html" >jala.Form.Component.Image</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Input.html" >jala.Form.Component.Input</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Password.html" >jala.Form.Component.Password</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Radio.html" >jala.Form.Component.Radio</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Select.html" >jala.Form.Component.Select</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Skin.html" >jala.Form.Component.Skin</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Submit.html" >jala.Form.Component.Submit</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Component.Textarea.html" >jala.Form.Component.Textarea</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Form.Tracker.html" >jala.Form.Tracker</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.History.html" >jala.History</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.HtmlDocument.html" >jala.HtmlDocument</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.I18n.html" >jala.I18n</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.ImageFilter.html" >jala.ImageFilter</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.IndexManager.html" >jala.IndexManager</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.IndexManager.Job.html" >jala.IndexManager.Job</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.ListRenderer.html" >jala.ListRenderer</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.ListRenderer.ArrayList.html" >jala.ListRenderer.ArrayList</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Mp3.html" >jala.Mp3</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Mp3.Id3v1.html" >jala.Mp3.Id3v1</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Mp3.Id3v2.html" >jala.Mp3.Id3v2</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.PodcastWriter.html" >jala.PodcastWriter</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.RemoteContent.html" >jala.RemoteContent</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Rss20Writer.html" >jala.Rss20Writer</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.Utilities.html" >jala.Utilities</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.XmlRpcRequest.html" >jala.XmlRpcRequest</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="jala.XmlWriter.html" >jala.XmlWriter</A>
|
||||
<BR>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
|
||||
</TABLE>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
|
@ -1,331 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>
|
||||
Jala 1.3 Constant Values
|
||||
</TITLE>
|
||||
<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
|
||||
</HEAD>
|
||||
<SCRIPT>
|
||||
function asd()
|
||||
{
|
||||
parent.document.title=" Constant Values";
|
||||
}
|
||||
</SCRIPT>
|
||||
<BODY BGCOLOR="white" onload="asd();">
|
||||
|
||||
<!-- ========== START OF NAVBAR ========== -->
|
||||
<A NAME="navbar_top"><!-- --></A>
|
||||
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
|
||||
<TR>
|
||||
<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
|
||||
<A NAME="navbar_top_firstrow"><!-- --></A>
|
||||
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
|
||||
<TR ALIGN="center" VALIGN="top">
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">File</FONT> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
|
||||
<!--TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD-->
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</TD>
|
||||
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
|
||||
<B>Jala 1.3</B>
|
||||
</EM>
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
|
||||
PREV
|
||||
NEXT</FONT></TD>
|
||||
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
|
||||
<A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
|
||||
<A HREF="help-doc.html" TARGET="_top"><B>NO FRAMES</B></A>
|
||||
|
||||
<SCRIPT>
|
||||
<!--
|
||||
if(window==top) {
|
||||
document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
|
||||
}
|
||||
//-->
|
||||
</SCRIPT>
|
||||
<NOSCRIPT>
|
||||
<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
|
||||
</NOSCRIPT>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<!-- =========== END OF NAVBAR =========== -->
|
||||
|
||||
<HR>
|
||||
<CENTER> <H1>Constant Field Values</H1> </CENTER>
|
||||
<HR>
|
||||
<UL>
|
||||
|
||||
<LI><A HREF="#jala.Form">jala.Form</A></LI>
|
||||
|
||||
<LI><A HREF="#jala.IndexManager">jala.IndexManager</A></LI>
|
||||
|
||||
<LI><A HREF="#jala.IndexManager.Job">jala.IndexManager.Job</A></LI>
|
||||
|
||||
<LI><A HREF="#jala.PodcastWriter">jala.PodcastWriter</A></LI>
|
||||
|
||||
<LI><A HREF="#jala.RemoteContent">jala.RemoteContent</A></LI>
|
||||
|
||||
<LI><A HREF="#jala.Utilities">jala.Utilities</A></LI>
|
||||
|
||||
</UL>
|
||||
|
||||
<HR>
|
||||
|
||||
|
||||
<A NAME="jala.Form"></A>
|
||||
<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0">
|
||||
<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
|
||||
<TD colspan="2">
|
||||
<B><A HREF="jala.Form.html">jala.Form</A></B>
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.Form.html#MINLENGTH">MINLENGTH</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>"minlength"</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.Form.html#MAXLENGTH">MAXLENGTH</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>"maxlength"</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.Form.html#REQUIRE">REQUIRE</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>"require"</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.Form.html#CHECKOPTIONS">CHECKOPTIONS</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>"checkoptions"</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.Form.html#CONTENTTYPE">CONTENTTYPE</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>"contenttype"</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.Form.html#MAXWIDTH">MAXWIDTH</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>"maxwidth"</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.Form.html#MINWIDTH">MINWIDTH</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>"minwidth"</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.Form.html#MAXHEIGHT">MAXHEIGHT</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>"maxheight"</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.Form.html#MINHEIGHT">MINHEIGHT</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>"minheight"</CODE></TD>
|
||||
</TR>
|
||||
|
||||
</TABLE>
|
||||
<P>
|
||||
|
||||
<P>
|
||||
|
||||
<A NAME="jala.IndexManager"></A>
|
||||
<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0">
|
||||
<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
|
||||
<TD colspan="2">
|
||||
<B><A HREF="jala.IndexManager.html">jala.IndexManager</A></B>
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.IndexManager.html#MAXTRIES">MAXTRIES</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>10</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.IndexManager.html#NORMAL">NORMAL</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>1</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.IndexManager.html#REBUILDING">REBUILDING</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>2</CODE></TD>
|
||||
</TR>
|
||||
|
||||
</TABLE>
|
||||
<P>
|
||||
|
||||
<P>
|
||||
|
||||
<A NAME="jala.IndexManager.Job"></A>
|
||||
<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0">
|
||||
<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
|
||||
<TD colspan="2">
|
||||
<B><A HREF="jala.IndexManager.Job.html">jala.IndexManager.Job</A></B>
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.IndexManager.Job.html#ADD">ADD</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>"add"</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.IndexManager.Job.html#REMOVE">REMOVE</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>"remove"</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.IndexManager.Job.html#OPTIMIZE">OPTIMIZE</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>"optimize"</CODE></TD>
|
||||
</TR>
|
||||
|
||||
</TABLE>
|
||||
<P>
|
||||
|
||||
<P>
|
||||
|
||||
<A NAME="jala.PodcastWriter"></A>
|
||||
<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0">
|
||||
<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
|
||||
<TD colspan="2">
|
||||
<B><A HREF="jala.PodcastWriter.html">jala.PodcastWriter</A></B>
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.PodcastWriter.html#XMLHEADER">XMLHEADER</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>'<?xml version="1.0" encoding="UTF-8"?>'</CODE></TD>
|
||||
</TR>
|
||||
|
||||
</TABLE>
|
||||
<P>
|
||||
|
||||
<P>
|
||||
|
||||
<A NAME="jala.RemoteContent"></A>
|
||||
<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0">
|
||||
<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
|
||||
<TD colspan="2">
|
||||
<B><A HREF="jala.RemoteContent.html">jala.RemoteContent</A></B>
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.RemoteContent.html#HTTP">HTTP</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>1</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.RemoteContent.html#XMLRPC">XMLRPC</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>2</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.RemoteContent.html#SUFFIX">SUFFIX</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>".cache"</CODE></TD>
|
||||
</TR>
|
||||
|
||||
</TABLE>
|
||||
<P>
|
||||
|
||||
<P>
|
||||
|
||||
<A NAME="jala.Utilities"></A>
|
||||
<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0">
|
||||
<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
|
||||
<TD colspan="2">
|
||||
<B><A HREF="jala.Utilities.html">jala.Utilities</A></B>
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.Utilities.html#VALUE_ADDED">VALUE_ADDED</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>1</CODE></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><CODE><A HREF="jala.Utilities.html#VALUE_MODIFIED">VALUE_MODIFIED</A></CODE></TD>
|
||||
<TD ALIGN="right"><CODE>2</CODE></TD>
|
||||
</TR>
|
||||
|
||||
</TABLE>
|
||||
<P>
|
||||
|
||||
<P>
|
||||
|
||||
|
||||
<HR>
|
||||
|
||||
<!-- ========== START OF NAVBAR ========== -->
|
||||
<A NAME="navbar_bottom"><!-- --></A>
|
||||
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
|
||||
<TR>
|
||||
<TD COLSPAN=3 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
|
||||
<A NAME="navbar_bottom_firstrow"><!-- --></A>
|
||||
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
|
||||
<TR ALIGN="center" VALIGN="top">
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">File</FONT> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><b>Tree</b></FONT></A> </TD>
|
||||
<!--TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD-->
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
|
||||
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</TD>
|
||||
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
|
||||
<B>Jala 1.3</B>
|
||||
</EM>
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
|
||||
PREV
|
||||
NEXT</FONT></TD>
|
||||
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
|
||||
<A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
|
||||
<A HREF="help-doc.html" TARGET="_top"><B>NO FRAMES</B></A>
|
||||
|
||||
<SCRIPT>
|
||||
<!--
|
||||
if(window==top) {
|
||||
document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>');
|
||||
}
|
||||
//-->
|
||||
</SCRIPT>
|
||||
<NOSCRIPT>
|
||||
<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>
|
||||
</NOSCRIPT>
|
||||
</FONT></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<!-- =========== END OF NAVBAR =========== -->
|
||||
|
||||
<HR>
|
||||
<FONT SIZE="-1">
|
||||
|
||||
</FONT>
|
||||
<div class="jsdoc_ctime">Documentation generated by <a href="http://jsdoc.sourceforge.net/" target="_parent">JSDoc</a> on Tue Jan 8 15:45:31 2008</div>
|
||||
</BODY>
|
||||
</HTML>
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue