JPALIO:Home
From Jpaliowiki EN
Contents |
Introduction
The jPALIO (JAVA based Portal All In One) is a tool for the management of a company's internal processes, devised to operate both in the Intranet and the Internet. The jPALIO as an universal databus, can also be used in the personalized distributed multivendor database-based internet portals with extreme ease of updating information vital for operations of big organizations, companies or corporations. With its significant number of implemented communication connectors (SQL, TCP/IP, XML, LDAP, SMTP, SNMP, JAVA components, WebServices) the system can be easily integrated with other systems and solutions.
The jPALIO is a modular system based entirely on the technologies and products such as: JAVA, Tomcat, Apache and any SQL database with JDBC or ODBC interface (ORACLE, DB2, Sybase, SQLServer, PostgreSQL, HypersonicSQL, Access, etc.). The jPALIO's structure enables easy introduction of new elements and their remote control.
Designing the jPALIO, significant focus was put on proper security strategy, so SSL protocol is used to ensure security of transferred data. Additionally, user authentication may incorporate tokens or chip cards with Public Key Infrastructure.
System features
jPALIO offers the following features:
- content management as a separate module (Newser)
- protection against attempts to modify the content of the browser's address bar (it is not possible to change the values of variables sent in the address bar by using checksums)
- no need to use cookies (cookies are a potential threat), which allows a system built based on jPALIO to work with all browsers
- the ability to build cluster configurations with load-balancing
- the ability to build a hierarchical and distributed structure with automatic propagation of new version of the application code to subordinate servers (propagation is restricted to new versions of individual objects, without the need for sending the whole code every time) and with automatic propagation of new versions of jPALIO application servers themselves.
- roles based access (where roles are built from privileges), the roles are assigned to users in the context of regions/organizational units (the ability to have different roles assigned depending on a region/organizational unit).
- the client's interface is limited to a web browser (no need to install anything at client PCs, easiness of operations using mobile computers, standardized user interface, independence of the operating system, no need to maintain applications on hundreds of client PCs)
- easy creation of a user-friendly and fully standardized user interface, full usage of the tips mechanism (selection of data from a list, dialog boxes, etc.) and the data input control mechanism (automatically built forms with data input control logic)
- user passwords are stored in a database in the undisclosed, encrypted form
- the ability to activate gzip compression for transferred data, which is especially important in case of low bandwidth links (e.g. dial-up)
- the ability to use the SSL protocol in communication between jPALIO servers and between jPALIO and a client (a web browser)
- database connections pooling management, ensuring a high level of efficiency and reliability of data exchange and with automatic restoration of broken connections
- the ability to authenticate users using tokens and chip cards
jPALIO functional diagram
jPALIO architecture
Session control
Session control can be implemented in 2 ways:
- by storing session information in operating memory
- by writing session information to the database (an option to implement session sharing by several jPALIO installations
Configuration files
Configuration files describe instances or their parameters. There is a separate configuration file for each instance. Locations of configuration files for all instances are saved in the config.xml file located in the webapps/palio/WEB-INF sub folder of the Tomcat container server's root folder. An example of the config.xml file's contents
<?xml version="1.0" encoding="UTF-8"?>
<palio>
<config>
<locale language="pl" timezone="Europe/Warsaw" charset="utf-8"/>
<!-- Optional port for jDesigner – default 5465 -->
<designer port="5465"/>
<instances dir="instances"/>
<!-- Specification of jPALIO logs folder and the pattern of log file names -->
<logs dir="/var/log/jpalio" pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c - %m%n" level="DEBUG"/>
<!-- UProxy server settings -->
<proxy host="myproxy.com" port="8080"/>
</config>
</palio>
The dir attribute of the instances tag defines a folder, where configuration files of all instances are located. The access path to this folder defines its location in respect to the folder, where the config.xml file is located. Lack of the instances tag will force the server to search for the instance definition in the sub folder webapps/palio/WEB-INF/instances of the Tomcat container server's root folder, by default. A configuration file for a specific instance should have the name instance_name.xml (jPALIO retrieves the instance name from the file name, disregarding its extension) and contain a definition of a single instance. An example of the instance configuration file
<instance>
<admin user="administrator login" password="administrator password"/>
<locale language="pl" timezone="Europe/Warsaw"/>
<preload all="true" code="true" media="true"/>
<shared/>
<cache all="true" media="true" source="false"/>
<URL runSecure="{ -1 (unSecure), 0 (neutral), 1 (secure) }" runHost="10.2.1.1" mediaSecure="-1" mediaHost="10.2.1.2"/>
<session timeout="0" cookies="false" staticIP="false"/>
<secure sid="1234567" hash="MD5"/>
<page statistic="false" default="1"/>
<date presentation="dd-MM-yyyy"/>
<currency thousand=" " decimal="," scale="2"/>
<connector name="palio" url="jdbc:oracle:thin:@serwer:port:sid" refresh="0" traceRead="true" traceWrite="true" traceExecute="true">
<user>login</user>
<password>****</password>
<dedicatedRefresh>5</dedicatedRefresh>
</connector>
<connector name="palio" url="torn.netobjects@serwer:port:jpalio" refresh="0" traceRead="true" traceWrite="true" traceExecute="true">
<user>login</user>
<password>****</password>
<timeout>0</timeout>
<resetCounter>2000</resetCounter>
</connector>
<connector name="data" class="GenericSQLConnector" url="jdbc:oracle:thin:@host:port:sid" refresh="0" traceRead="true" traceWrite="true" traceExecute="true">
<user>login</user>
<password>****</password>
<driver>oracle.jdbc.driver.OracleDriver</driver>
<initSQL>select sysdate from dual</initSQL>
<refreshSQL>select sysdate from dual</refreshSQL>
<reconnectExceptions>17002 17009 1012 28 17410</reconnectExceptions>
</connector>
<connector name="informix" class="GenericSQLConnector" url="jdbc:informix-sqli://host:port[/dbname]:INFORMIXSERVER=server_name;user=login;password=****" refresh="0" traceRead="true" traceWrite="true" traceExecute="true">
<driver>com.informix.jdbc.IfxDriver</driver>
<reconnectExceptions>201</reconnectExceptions>
</connector>
<connector name="remote" url="remote@serwer:port:jpalio" refresh="0" traceRead="true">
<user>login</user>
<password>****</password>
<timeout>0</timeout>
<resetCounter>2000</resetCounter>
</connector>
<connector name="sybase" class="GenericSQLConnector" url="jdbc:sybase:Tds:host:port" refresh="0" traceRead="true" traceWrite="true" traceExecute="true">
<user>login</user>
<password>****</password>
<driver>com.sybase.jdbc.SybDriver</driver>
<initSQL>use gtc</initSQL>
<refreshSQL>select sysdate from dual</refreshSQL>
<reconnectExceptions></reconnectExceptions>
</connector>
<connector name="tcp" url="tcp:@host:port" refresh="0" traceWrite="true">
<charset>iso-8859-2</charset>
</connector>
<connector name="ftp" url="ftp://ftp.serwer.pl:21">
<user>login</user>
<password>****</password>
</connector>
<connector name="ldap" url="ldap://localhost:389/dc=xxx">
<principal>cn=Manager,dc=xxx</principal>
<credentials>secret</credentials>
</connector>
<listener name="palio">
<class>palio.listeners.GenericPalioListener</class>
<port>port</port>
<user>login</user>
<password>****</password>
</listener>
<listener name="remote">
<class>palio.listeners.RemoteListener</class>
<port>port</port>
<user>login</user>
<password>****</password>
<modules>user palio logic mth sql</modules>
</listener>
<listener name="metadata">
<class>palio.listeners.MetaDataListener</class>
<port>port</port>
</listener>
<!-- Optional port for jDesigner - default 5465 -->
<designer port="5465"/>
<module name="Ezop">
<client_conn>st</client_conn>
<client_table>clients</client_table>
<client_sequence>clients_s</client_sequence>
</module>
<module name="AdServer">
<refresh_rate>10</refresh_rate>
</module>
<module name="Mapper"/>
<module name="Mail">
<smtp_server>IP serwera SMTP</smtp_server>
<pop3_server>IP serwera POP3</pop3_server>
<charset>ISO-8859-2</charset>
</module>
<module name="Scheduler"/>
</instance>
The admin tag defines the administrator's login and password that enable the management of users, who have access to that specific instance's application code. The page tag specifies the portal's home page identifier for a specific instance. The secure tag defines and initializes the checksum calculation algorithm for URL addresses. With connector tags you can define connectors for various types of systems (e.g. databases), including definition of user login and password with user and password tags, respectively. The connector named palio must be defined in the configuration file. With listener tags you can define listeners to listen on various types of ports, including specification of a port number with the port tag and user login and password with user and password tags, respectively. The module tag is used to attach jPALIO modules (sets of functions) that are not available as standard, by providing a module's name as a value of the name attribute and the module's parameters by means of tags embedded in the module tag.
Listeners
Listeners are used to receive calls from a client and to pass them on for execution to the application code. An example of such a listener is the Web server (for calls sent over the HTTP protocol). Listeners can also provide certain services to specific instances. This applies e.g. to the SNMP listener, which collects information on the network status (by first querying the devices) and writes it to a specific instance's table for future analysis.
Connectors
Connectors are used to connect jPALIO with various types of systems.
Instance types
There are three types of instances in jPALIO distinguished by different levels of code's security. Instance type can be set in instance configuration XML file, e.g.
<instance type="master"> (case in-sensitive)
There are three allowed types:
- MASTER
- Default bacause of backward compatibility (warnings are logged in case of type's definition lack in configuration). No security restrictions. Full access to all features, packages or libraries.
- STANDARD
- This will be default instance type in future releases. Restricted access to critical Java classes allowing to stop server or access environment parameters of VM, etc., Java security management or container's classes. No access also to other instances beyond your own.
- RESTRICTED
- Restricted access level, suitable for untrusted users not allowing them to threat jPALIO server as whole Dostępna funkcjonalność jest bardzo ograniczona. Access only to one instance and classes from few packages: palio.modules, palio.api, java.lang (except of few criticals), java.util and java.io (for general stream handling, not access to system files).
All restrictions mentioned above accords to jPalio Classic/Super Palio as well as Java/Groovy classes or scripts.
Components
You can distinguish the following components in jPALIO
pages objects privileges roles regions media tasks
Pages are elements called from the user interface (a web browser) - they portal is composed of them. Each of the pages contains a link to an object that forms its content. When a page is called the system checks if the user has adequate access rights to access it (in case of pages protected with privileges) and if the verification is successful the application control is passed on to the object associated with the page.
Objects are elements, where the application code is saved. Objects form the contents of pages. Each object can call any number of other objects and also - recurrently - itself. The source code that is the contents of a specific object is compiled and cached in the system on the first launch of this object.
Privileges are elements that define access rights to pages. Using privileges you can also restrict access to various parts of the portal.
Roles are groups of privileges. Using roles you can restrict access to various parts of the portal. Depending on the assigned roles users have the guaranteed access only to selected parts of the portal.
Regions are areas, where users' access rights to various parts of the portal are valid. A user can have different roles in each of the regions.
Media are multimedia and binary files (images, animations, movies, sounds, documents, etc.) placed and presented on the pages.
Tasks are definitions of operations performed by jPALIO periodically and automatically. Tasks can be divided into groups. Each group is associated with a separate thread that is dedicated to it. It is especially useful when certain tasks take long time to execute and block execution of other tasks.
Objects, pages and media are placed in a hierarchical types structure that reflects functional modules of the portal.
Syntax of the jPALIO language
Basic features of the created language
- the server-side executed scripting language
- distinguishing between small and capital letters
- no need to define variables
- variables are treated as arrays indexed from 0
- arrays can store values of various types at the same time
- expression values and results returned by functions are added to the HTML code
Data types
Dependencies between data types available in the system are hierarchical in accordance with the diagram
List of data types
String - a data type that corresponds to the java.lang.String type; String-type variables are strings of characters placed in double quotation marks (for simple texts, i.e. texts that consist of a single word, usage of quotation marks is not obligatory); in order to place a double quotation mark or a backslash in the string of characters one has to precede it with a backslash
"text text text" abcdefghijklmnopqrstuvwxyz "" "description \"quotation\" description"
Long - a data type that corresponds to the java.lang.Long type; Long-type variables are integral numbers with or without a mark
879 -52322 0
Boolean - a data type that corresponds to the java.lang.Boolean type; Boolean-type variables can take logical values of true or false
true false
BigDecimal - a data type that corresponds to the java.lang.BigDecimal type; BigDecimal-type variables are floating point numbers with or without a mark
-0.75982 11.034 3.14159265358979
Date - a data type that corresponds to the java.util.Date type; Date-type variables are dates, which in application code can be written down in any of the three formats d-M-y, d-M-y H:m, d-M-y H:m:s, where d is day in a month, M is month, y is year, H is hour, m are minutes, s are seconds; the current date can be retrieved with the SYSDATE keyword (letter size is irrelevant)
14-04-966 1-1-2005 15:45 sysdate
LinkedList - a data type that corresponds to the java.util.LinkedList type; LinkedList-type variables are lists of Object[]-type elements; these variables cannot be written directly in the application code but are used to suitably control the application code; LinkedList-type values are typically the results of SQL queries of the SELECT type, which can be used as parameters when calling the for function and instruction
HashMap - a data type that corresponds to the java.util.HashMap type; HashMap-type variables are sets of element pairs of the Object type, where one of them is the key and the other one is the value; these variables cannot be written directly in the application code, HashMap-type values can be used as function call parameters
TreeMap - a data type that corresponds to the java.util.TreeMap type; TreeMap-type variables are sets of element pairs of the Object type, where one of them is the key and the other one is the value; these variables cannot be written directly in the application code, TreeMap-type values can be used as function call parameters
PalioCode - jPALIO code placed in the application code as a string of jPALIO instructions in curly brackets; PalioCode-type variables cannot be defined in the application code - jPALIO code can only be used directly as function call parameters for functions that expect arguments of the PalioCode type
{ $=(var, 7) $var }
Object[] – Object[]-type variables are value arrays of any type; in the application code an array is placed in square brackets as a string of values separated by comas
[19, false, -0.142857, "XYZ"] [] ["A", [4, 5, 6], [7, 8], sysdate]
byte[] – byte[]-type variables are strings of bytes; these variables cannot be placed directly in the application code; byte[]-type values are typically the contents of binary files placed on the server using upload forms
It is possible to dynamically change data types through casting - preceding calls to a variable's value with a type name in brackets or through conversion - calling an appropriate function.
Variables
Variables are available during a single call of a page but can be passed on by page call parameters in the URL address. All page calls with passing on parameters relate to passing on parameters of the String type. In order to receive parameters of a particular type one has to perform the type conversion using special functions.
Assigning a value to a variable
$=(variable_name, value)
Call to the variable's value
$variable_name
Assigning a value array to a variable
$=(variable_name, [value1, value, value3, ...])
A call to a value array saved in a variable
$variable_name[]
A call to the second element of such array (array elements are indexed from 0)
$variable_name[1]
All variables are treated as arrays and a call to the variable's value is synonymous with a call to the first element of the array (element of the index 0). So, a call
$variable_name
is equivalent to
$variable_name[0]
A change of the variable's value through casting
(type_name)$variable_name
A variable that does not exist or has no value assigned to it has a null value defined by the null constant of the Object-type. A variable can be assigned the null value as well
$=(variable_name, null)
In order to assign null values to all array elements one can use the null constant type casting
$=(variable_name, (Object[])null)
Each variable in the program's application code is treated as an Object-type variable. That's why passing on a variable's value as a function call parameter requires type casting or conversion (as long as that function expects an argument type other than Object). This requirements also applies to passing on the null value.
In order to place the $ character in the application code you have to enter
$$
Starting from version 6.2.10 of jPALIO special characters can be entered using the format
$\SPECIAL_CHARACTER
so, the dollar sign can be entered as
$\$
Comments
There are 2 types of comments. A comment that starts with the string of characters $// and ends at the end of a line of text
$// comment
A comment that is placed between the string of characters $/* and the string of characters $*/ and which can cover any number of text lines
$/* comment $*/
Operators
There are many different operators defined in the jPALIO system
- arithmetic operators
+ add operator (dyadic) – subtract operator (dyadic) * multiple operator (dyadic) / divide operator (dyadic) % division remainder operator (dyadic) ++ increment operator (unary) –– decrement operator (unary)
- logical operators
&& logical AND (dyadic) || logical OR (dyadic) ! logical NOT (unary) == logical Equal To (dyadic) != logical Not Equal To (dyadic) <> logical Not Equal To (dyadic) < logical Less Than (dyadic) <= logical Less Than or Equal To (dyadic) > logical Greater Than (dyadic) >= logical Greater Than or Equal To (dyadic)
- bit operators
& bitwise AND (dyadic) | bitwise OR (dyadic) ^ bitwise XOR (dyadic) ~ bitwise NOT (unary)
- other
= assignment operator (dyadic) + character strings concatenation operator (dyadic) ? conditional expression operator (ternary)
Methods of usage of operators
$operator(arguments)
Apart from its dyadic version the character strings concatenation operator also has the unary version, where the argument is a character string array and the result of operation is concatenation of all characters from this array.
$+([string1, string2, string3, ... ])
Apart from their dyadic versions logical AND and OR operators also have their unary versions, where the argument is a logical expressions array and the result of operation is the logical product and logical sum of all expressions from the array, respectively.
Apart from its dyadic version the divide operator also has its ternary version, where the third argument defines required precision of the operation (number of digits after the point).
Operators are short notations of calls to particular functions and during compiling they are replaced by calls to specific functions
+ add function – subtract function * multiply function / divide function % remainder function ++ increment function –– decrement function && and function || or function ! not function == equals function != notEquals function <> notEquals function < lesser function <= lesserOrEquals function > bigger function >= biggerOrEquals function & bitwiseAnd function | bitwiseOr function ^ bitwiseXor function ~ bitwiseNot function = setParam function ? condition function
So, for example, a call
$+(2, 7)
is equivalent to
$add(2, 7)
Examples
$// Set variable z to value 5 $=(z, 5) $// Increase z variable's value by 1 $++(z) $// Collect variable's value z and place it in HTML code $z
$// Calculate expression ((24 + 76) * 8.99) and place in HTML code
$*($+(24, 76), 8.99)
$// Set variable x to value 7 $=(x, 7) $// Set variable y to value of variable x divided by 14 $// with precision up to 1 place after the point $=(y, $/((Long)$x, 14, 1))
$// Assign character string "def" to variable t $=(t, "def") $// Concatenation of character strings "abc" and "def" and placing the result in HTML code $+("abc", "def") $// Concatenation of character string "abc" and character strong saved in variable t and $// writing the result again to variable t $=(t, $+("abc", (String)$t)) $// Assign variable s with character string that is the result of concatenation $// of character strings "abc", "def" and "ghi" $=(s, $+(["abc", "def", "ghi"]))
$// Set variable b to value true $=(b, true) $// Calculate logical expression (~b) and place it in HTML code $!((Boolean)$b) $// Calculate logical expression (b || (true && ~b)) and place it in HTML code $||((Boolean)$b, $&&(true, $!((Boolean)$b)))
$// Set variable i to value 3 $=(i, 3) $// Place letter P in HTML code if variable i has even value $// or letter N if variable i has odd value $?($==($%((Long)$i, 2), 0), "P", "N")
$// Set variable today to current date $=(today, sysdate) $// Set variable s to the number of seconds that passed since the beginning of 2005 until now $=(s, $-((Date)$today, 01-01-2005 00:00:00)) $// Place in HTML code the number of seconds that passed since the beginning of 2005 until now $toLong($/((Long)$s, 86400))
$// Set variable tab2D to the value array [[1,2,3], ["A","B"]] $=(tab2D, [[1, 2, 3], ["A", "B"]]) $// Set variable tab1D to the second of arrays of array tab2D $=(tab1D, (Object[])$tab2D[1]) $// Place in HTML code the first element of array tab1D $tab1D[0]
Control instructions
3 types of control instruction have been defined
if – execution of an operation if a particular condition is met for – execution of an operation a number of times in a loop try – execution of an operation with exception handling
If instruction
The if instruction can be used in two ways
$if(condition, {
codeOnTrue
})
where
condition – Boolean type condition codeOnTrue – a set of instructions executed, when condition is true
or
$if(condition, {
codeOnTrue
}, {
codeOnFalse
})
where
condition – Boolean type condition codeOnTrue – a set of instructions executed, when condition is true codeOnFalse – a set of instructions executed, when condition is false
Examples
$// Set variable condition to value true $=(condition, true) $if((Boolean)$condition, { $// Place header in HTML code if variable condition has value true <h3>Header's content</h3> })
$// Set variable x to value 5 $=(x, 5) $if($==((Long)$x, 7), { $// Set variable y to value 0 if variable x has value 7 $=(y, 0) }, { $// Set variable y to value 3 if variable x has value other than 7 $=(y, 3) }) $// Place value of variable y in HTML code $y
For instruction
The for instruction has 4 structures
$for(loopCount, {
loopCode
})
where
loopCount – number of iterations loopCode – a set of instruction executed in each of the loopCount iterations of the loop
or
$for(conditionParamName, {
loopCode
})
where
conditionParamName – variable's name loopCode – a set of instructions executed in a loop until the conditionParamName variable
has value true
or
$for(paramName, loopTable, {
loopCode
})
where
paramName – variable's name loopTable – Object[]-type array loopCode – a set of instructions executed for each element of the loopTable array; at each loop iteration a single element of the loopTable array will be assigned to the paramName variable
or
$for(paramName, loopList, {
loopCode
})
where
paramName – variable's name loopList – LinkedList-type list loopCode – a set of instructions executed for each element from the loopList list; at each loop iteration a single row of the loopList list will be assigned to the paramName variable; a single row of the loopList list is the Object[]-type array
Examples
$// Set variable Cnt to value 1 $=(Cnt, 1) $// Execute the instruction set 7 times $for(7, { $// Place value of variable Cnt in HTML code $Cnt $// Increase Cnt variable's value by 1 $++(Cnt) })
$// Set variable Ctr to value 1 $=(Ctr, 1) $// Set variable loop to value true $=(loop, true) $// Execute a set of instruction if variable loop is true $for(loop, { $// Place value of variable Ctr in HTML code $Ctr $// Increase Ctr variable's value by 1 $++(Ctr) $// Set variable loop to value false if variable Ctr takes value bigger than 4 $if($>((Long)$Ctr, 4), { $=(loop, false) }) })
$// Assign value array ["html","xml","txt"] to variable extensions $=(extensions, ["html","xml","txt"]) $// Execute a set of instructions for each of the elements from the extensions array $for(i, $extensions[], { $// Place value of current element of table extensions in HTML code $i })
$// Set variable users to the result of execution of SQL query, $// that collects the list of rows from table p_users $=(users, $sql.read("select id, login from p_users order by login")) $// Execute a set of instructions for each row of list users $for(i, (LinkedList)$users, { $// Place values of elements of the current row of list users in HTML code $// (the first of elements is id, and the second is login) $i[0] $i[1] })
Try instruction
The try instruction has 2 structures
$try({
tryCode
}, {
catchCode
})
where
tryCode – a set of instruction, which when attempted to execute can trigger an exception catchCode – a set of instructions that handle an exception
or
$try({
tryCode
}, {
catchCode
}, {
finallyCode
})
where
tryCode – a set of instruction, which when attempted to execute can trigger an exception catchCode – a set of instructions that handle an exception finallyCode – a set of instructions executed at the end, regardless of whether in the try block there was an exception and regardless of whether it was handled
Examples
$try({
$// Divide by zero instruction causes an exception
$// and transfer of control to exception handling block
$/(7, 0)
}, {
$// Place information about attempt to divide by zero in HTML code
Attempt to divide by zero!
})
$try({
$// Attempt to open file for writing
$=(WRITER, $pipe.openWriter("/tmp/text.txt", "FILE", "ISO-8859-2"))
$// Attempt to write to file
$pipe.write((java.io.Writer)$WRITER, "TEXT")
}, {
$// Display error message
$error.getMessage()
}, {
$// Attempt to close file
$try({ $pipe.closeWriter((java.io.Writer)$WRITER) }, {})
})
jPALIO instruction sets
Instruction sets (SuperPALIO language) have been introduced in order to speed up and facilitate creation of instruction call sequences. An instruction set looks like this
${
a string of SuperPALIO instructions
}
where each instruction within a string of instructions (except for the last one) must end with a semicolon. Any number of white characters can be placed between all instructions and operators.
Inside an instruction set (written in SuperPALIO) one can also put jPALIO instructions. The structure for this purpose looks like this
$( jPALIO instruction string );
Formats of expressions in the instruction string
- assigning the expression's value to a variable
variable_name = expression;
- inputting the expression's value into a specific position of an array
variable_name [index] = expression;
- placing the expression's value in HTML code
expression;
Components of expressions
- values of constants
null false true -19 0.001 "text"
- values of variables
(type_name)variable_name variable_name[] or (Object[])variable_name (type_name)variable_name[index]
- values of functions
(type_name)module_name.function_name(arguments) (type_name)function_name(arguments)
- expression arrays
[expression1, expression2, ... ] []
- arithmetic operators
expression1 + expression2 expression1 - expression2 expression1 * expression2 expression1 / expression2
- relational operators
expression1 || expression2 expression1 && expression2 ! expression
- logical operators
expression1 == expression2 expression1 != expression2 expression1 <> expression2 expression1 < expression2 expression1 <= expression2 expression1 > expression2 expression1 >= expression2
- concatenation operator
expression1 + expression2
- conditional expression operator
condition ? expression1 : expression2
- parenthesis to determine the sequence of operations
(expression)
In case of logical operations all component types are automatically converted into Boolean. Any errors are then returned dynamically - not at compilation time.
Argument types of add and subtract operators are matched one by one according to particular conditions. If one of the matches works, the subsequent ones are not checked. Matching conditions
- if an operation involves exactly two components and there is no negation operator with the first component, then the complier will convert the expression into add or subtract function; users have to match component types and argument types of those functions themselves
- if the operation involves more than two components or there is a negation operator with the first component and all arguments are of the Long type, the returned value will of the Long type; jPALIO's internal function is used
- if all arguments are of the Long or BigDecimal type, the returned value will be of the BigDecimal type; jPALIO's internal function is used
- if all components are added then arguments can be of any type; all arguments are cast to the String type and concatenated using the add function
- the no match error is returned
Argument types of multiply and divide operators are matched one by one according to particular conditions. If one of the matches works, the subsequent ones are not checked. Matching conditions
- if an operation involves exactly two components, then the complier will convert the expression into multiple or divide function; users have to match component types and argument types of those functions themselves
- if all components are multiplied and are of the Long type, the returned value is also of the Long type; jPALIO's internal functions is used
- if all arguments are of the Long or BigDecimal type, the returned value is also of the BigDecimal type; jPALIO's internal function is used
- the no match error is returned
In case of the array read operator, the index role can be played by any expression - there is automatic conversion of the index type to the Long type. Left-side expression is automatically converted into the Object[] type.
The term component used above means an expression with higher priority level.
Examples
${
$($/* Assign expression value(5 + 1) to variable a $*/);
a = 5 + 1;
$($/* Place value of variable a in HTML code $*/);
a;
$($/* Place the string of characters <br> in HTML code $*/);
"<br>";
$($/* Assign expression value(19 - 6 * 2) to variable b $*/);
b = 19 – (Long)a * 2;
$($/* Place the record b - 4 = 3 that ends with the <br> tag in HTML code $*/);
"b – 4 = " + ((Long)b – 4) + "<br>"
}
$// Place value of variable b in HTML code
$// if it is called from outside of the instruction set
$b
${
$($/* Assign value array [1, 1, 2, 3, 5]) to variable t $*/);
t = [1, 1, 2, 3, 5];
$($/* Assign the number of elements in the array t to variable i $*/);
i = tableLen(t[]);
$($/* Add to the table t an element that is the sum of two last elements from this table $*/);
addParam("t", (Long)t[(Long)i – 1] + (Long)t[(Long)i – 2]);
$($/* Place the array of all values from the table t in HTML code $*/);
t[];
}
${
$($/* Assign value 0 to variable sum $*/);
sum = 0;
$($/* Calculate the sum of absolute values of numbers from the array [4, -7, 2] $*/);
for("i", [4, –7, 2], {
if((Long)i < 0, {
sum = (Long)sum – (Long)i;
}, {
sum = (Long)sum + (Long)i;
});
});
$($/* Place the record |4| + |–7| + |2| = 13 in HTML code $*/);
"|4| + |–7| + |2| = " + sum;
}
JAVA instruction sets
jPALIO platform also enables creation of instruction sets in the JAVA language. An instruction set will look like this
$[ a set of instruction in the JAVA language ]
Example
$[ // Reference to the current object Current current = Instance.getCurrent(); // Write to the page's source current.getWriter().println("<h3>Hello, World!</h3>"); // Set jPALIO parameter current.setParam("_TestParam", Long.valueOf(200)); // Retrieve external jPALIO parameter Long _TestParam = (Long)current.getParam("_TestParam")[0]; current.getWriter().println("_TestParam = " + _TestParam + "<br>"); // Loop for (int i = 0; i < 10; i++) { current.getWriter().println(i +"<br>"); } // Class definition class SpecialFunction { public double sinh(double x) { return ((java.lang.Math.exp(x) - java.lang.Math.exp(-x))/2.0); } } SpecialFunction f = new SpecialFunction(); current.getWriter().println("sinh(2.5) = " + f.sinh(2.5) + "<br>"); ] $// Call outside of the instruction set to the parameter value set inside this instruction set _TestParam = $_TestParam
From JAVA instruction sets You can call jPALIO objects:
palio.Groovy.object(ID_OBIEKTU)
palio.Groovy.object(ID_OBIEKTU, new Object[] {PARAMETR1, PARAMETR2, PARAMETR3, ...})
palio.Groovy.object(KOD_OBIEKTU)
palio.Groovy.object(KOD_OBIEKTU, new Object[] {PARAMETR1, PARAMETR2, PARAMETR3, ...})
Objects
Objects contain application control code. Once an object is created it can be used multiple times. Invoking an object from inside of another object or from inside of the same object (recurrently) will look like this
$*object_identifier
or
$*object_code
in case of no parameter objects, and
$*object_identifier(parameter1, parameter2, ... )
lub
$*object_code(parameter1, parameter2, ... )
for objects invoked with parameters, where object_identifier is a unique number assigned automatically to each object when it is created, and object_code is a unique string of characters assigned to each object by users. The object code's first character must be a letter or the underscore character, subsequent characters can be digits or a point, after the point there must be a letter or the underscore character. The same rule applies to creating of page codes, media and elements of hierarchical type structure.
A call within an object to the value of any parameter of its invoking will look like this
$parameter_no
or (in case of parameters that are value arrays)
$parameter_no[]
whereas, parameters are numbered from 0, so $0 means the value of the first parameter ($0[] if the first parameter is an array), $1 - the value of the second parameter ($1[] if the second parameter is an array), etc.
Object call parameters exist only while this object is being executed and are not visible outside of this object.
Variables set before invoking the object are visible inside this object and can be modified by it.
Variables set inside the object remain visible in the application code also after invoking this object.
For example, let an object with the identifier 1 have the following contents
Call to object 1<br>
$=(z1, 11)
Set value of variable z1 in object 1 to $z1<br>
$*2("PAR112", "PAR212")
<br>Return to object 1<br>
Variable z1 in object 1 has value $z1<br>
Variable z2 in object 1 has value $z2<br>
Variable z3 in object 1 has value $z3<br>
and an object with the identifier 2 have the following content
<br>Call to object 2<br>
$try({ $=(p1, $+("has value ", (String)$0)) }, { $=(p1, "does not exist") })
$try({ $=(p2, $+("has value ", (String)$1)) }, { $=(p2, "does not exist") })
$try({ $=(p3, $+("has value ", (String)$2)) }, { $=(p3, "does not exist") })
The first object 2 call parameter $p1<br>
The second object 2 call parameter $p2<br>
The third object 2 call parameter $p3<br>
Variable z1 in object 2 has value $z1<br>
$=(z1, 21)
$=(z2, 22)
Change of value of variable z1 in object 2 to $z1<br>
Set value of variable z2 in object 2 to $z2<br>
$*3("PAR123")
<br>Return to object 2<br>
Variable z1 in object 2 has value $z1<br>
Variable z2 in object 2 has value $z2<br>
Variable z3 in object 2 has value $z3<br>
and an object with the identifier 3 have the following content
<br>Call to object 3<br>
$try({ $=(p1, $+("has value ", (String)$0)) }, { $=(p1, "does not exist") })
$try({ $=(p2, $+("has value ", (String)$1)) }, { $=(p2, "does not exist") })
$try({ $=(p3, $+("has value ", (String)$2)) }, { $=(p3, "does not exist") })
The first object 3 call parameter $p1<br>
The second object 3 call parameter $p2<br>
The third object 3 call parameter $p3<br>
Variable z1 in object 3 has value $z1<br>
Variable z2 in object 3 has value $z2<br>
$=(z1, 31)
$=(z2, 32)
$=(z3, 33)
Change of value of variable z1 in object 3 to $z1<br>
Change of value of variable z2 in object 3 to $z2<br>
Set value of variable z3 in object 3 to $z3<br>
Invoking the object with the identifier 1 from the above example will generate the following record in HTML code
Call to object 1 Set value of variable z1 in object 1 to 11 Call to object 2 The first object 2 call parameter has value PAR112 The second object 2 call parameter has value PAR212 The third object 2 call parameter does not exist Variable z1 in object 2 has value 11 Change of value of variable z1 in object 2 to 21 Set value of variable z2 in object 2 to 22 Call to object 3 The first object 3 call parameter has value PAR123 The second object 3 call parameter does not exist The third object 3 call parameter does not exist Variable z1 in object 3 has value 21 Variable z2 in object 3 has value 22 Change of value of variable z1 in object 3 to 31 Change of value of variable z2 in object 3 to 32 Set value of variable z3 in object 3 to 33 Return to object 2 Variable z1 in object 2 has value 31 Variable z2 in object 2 has value 32 Variable z3 in object 2 has value 33 Return to object 1 Variable z1 in object 1 has value 31 Variable z2 in object 1 has value 32 Variable z3 in object 1 has value 33
With version 5.0.0 of jPALIO the instruction for returning the value by an object was introduced. The return instruction causes an immediate exit from code / object with the return of a value. Everything that is located after the return instruction will not be executed
$return("VALUE")
The returned value can be retrieved
$@=(RESULT, (String)$*OBJECT_IDENTIFIER_OR_CODE)
It is also possible to exit the code without returning a value
$return()
If the exit instruction is executed inside a loop, iteration is interrupted and the program exits from the object. This behaviour applies to the majority of the embedded code in the object (loops, conditional instructions, etc.). The only exception are all methods of the $palio.execute...() type. Usage of the exit instruction inside this method interrupts execution of this code only (not the whole object). Because of this all of those methods now return a value (usually null, if execution of the code was not interrupted). The method $palio.executeToBuffer returns exit (any value returned inside the code is lost). A method that invokes the code in another thread does not return a value (exit is logged, any returned value is lost).
In version 5.0.0 of jPALIO we have introduced an instruction that imports JAVA types and packages. Import of a specific type for quicker future use
$#import(palio.pelements.PObject)
Import of a whole package (when mapping exact readings are checked first and the packages are checked later)
$#import(palio.pelements.*)
Local variables
With version 5.0.0 of jPALIO we have introduced local variables. Names of local variables are preceded with @ character. Local variables can be used without a threat of being overwritten by another object or by a recurring call of the same object
$@=(text, "She has got a cat") Text: $@text
Local variables have statically stored types based on the first assignment. So, one can re-assign values but only of the same type - the stored type is provided for each usage of the variable (casting is not required)
$@=(value, 2) 2+2 = $+($@value, $@value)
In order for a more detailed type to be stored, one should cast with the first assignment
$=(ID, 7) $@=(ID, (Long)$ID) $@ID
A special instruction allows to quickly assign object call parameters to local variables together with type storage
$#params(Long id, String action, Object[] parameters)
which is equivalent to
$@=(id, (Long)$0) $@=(action, (String)$1) $@=(parameters, $2[])
Methods can be invoked for the benefit of local variables
$@=(text, "She has got a cat")
Text: $@text <br/>
Length: $@text.length() <br/>
Has she got a cat? $@text.contains("cat") <br/>
All errors related to invoking of methods are trapped at compiling time because local variable types are known.
Local variables can also be used in SuperPALIO code
${
@text = "She has got a cat";
"Text: "; $@text; "<br/>";
"Length of text: "; @text.length(); "<br/>";
@value = 2;
"2+2 = "; ($@value + $@value);
}
Starting with version 6.2.10 of jPALIO the @ character became part of the local variable's name. As the result (ensuring compatibility with previous versions) the records
$@=(variable, value) $@=(@variable, value) $=(@variable, value)
became equivalent. However, it is recommended to use the following format
$=(@variable, value)
Invoking $getParam("variable") means calling a global variable, and invoking $getParam("@variable") means calling a local variable.
Modules
Modules are sets of functions invoked from the application code. Each module must be a palio.modules.Module class derivative and must be located in the palio.modules package. Functionality of jPALIO modules is described in the following table
| MODULE | FUNCTIONALITY |
|---|---|
| Admin | a set of functions to manage an instance and a set of information functions |
| Ads* | a set of functions to operate an ads server |
| Bar | a set of functions to generate barcodes |
| Beans* | a set of functions to access class objects written in compliance with the JavaBeans specification |
| BugBase | a set of functions to handle the error database |
| Cache | a set of functions to buffer frequently used data in the system |
| Cert | a set of functions to handle certificates |
| Chart | a set of functions to draw charts |
| CMS* | a set of functions to create CMS |
| Crypto | a set of cryptographic functions |
| Disk | a set of functions to access disk files |
| Editor* | a set of functions to integrate the TinyMCE editor with jPALIO |
| Error | a set of functions to handle exceptions |
| Ezop* | a set of functions used to build internet shops |
| Forum* | a set of functions to create discussion forums |
| FTP | a set of functions to communicate with an FTP server |
| Global | a set of functions to handle global variables |
| Hetman | a set of functions that support creation and implementation of processes (workflow) |
| History | a set of functions to record the history of changes to the contents of database tables |
| HTML | a set of functions that facilitate work with HTML code |
| Imager | a set of functions to perform operations on images |
| IText | a set of functions to generate PDF files |
| Lang | a set of functions that support building of multi-language portals |
| Ldap | a set of functions to communicate with LDAP servers |
| Log | a set of functions to create log records |
| Logic | a set of basic logical operators |
| Mail* | a set of functions to send messages using the electronic mail |
| Mapper | a set of functions to create maps |
| Media | a set of functions to handle multimedia objects |
| Mth | a set of mathematical functions |
| Net | a set of functions to perform network operations |
| Newser | a set of functions to handle news |
| Newsletter* | a set of functions to distribute e-mail messages to subscribers |
| Page | a set of functions to handle pages, build internet addresses and redirections, to perform operations related to the HTTP header |
| Palio | a set of basic functions of the jPALIO system |
| Pipe | a set of functions to perform operations on streams |
| Proc | a set of functions to create and handle business processes |
| Reflect | a set of functions that support programming in the JAVA language |
| Remote | a set of functions to remotely invoke functions |
| Report* | a set of functions that support creation of reports |
| Scheduler* | a set of functions to schedule periodic tasks performed automatically by jPALIO |
| SearchUtils | a set of functions for advanced text searching |
| SNMP | a set of functions that support network management |
| Sql | a set of functions to communicate with databases |
| Std | a set of standard functions that facilitate building of sites |
| Text | a set of functions to perform operations on characters strings |
| Time | a set of functions that support execution of operations related to time and date |
| UrlModule* | a set of functions to generate URLs for PALIO |
| User | a set of functions that enable management of users, roles and sessions |
| Util | a set of utility functions |
| VirtualTable | a specialized applet that builds a virtual table to use by all users for common writing and drawing |
| XLS | a set of functions to generate XLS files |
| Xml | a set of functions to process files in XML format |
For modules marked with * a record in the instance's configuration file is required.
Functions
Call to a function from a specific module
$module_name.function_name(arguments)
Letter size in the module's name is irrelevant.
In case of Logic, Mth, Page, Palio, Std, Text and Util modules it is not required to precede the function's name with the module's name - the record is streamlined into
$function_name(arguments)
The full documentation of all functions is available at the address
http://docs.torn.com.pl/jPalio/modules/
Integration with Groovy
With version 6.0.0. of jPALIO we introduced the ability to create application code using the groovy language.
In a groovy-written object that is associated with a page, the access to HTTP parameters is ensured by the params map.
In a groovy-written object that is called from the other object, the access to call arguments is ensured by the args array.
The groovy language offers the ability to declare classes. In this case the object contains a full class declaration
package PACKAGE_NAME;
class CLASS_NAME
{
...
}
An object, in which the above declaration is written, must have the code PACKAGE_NAME.CLASS_NAME. You can use groovy-written classes in groovy code only. Each class must be defined in a separate jPALIO object.
// Class definition within the object coded toys.balls.Ball
package toys.balls
class Ball
{
public Ball(color, size)
{
this.color = color
this.size = size
}
public printBallData ()
{
return "${color} ball of size ${size}"
}
def color, size
}
A call to the jPALIO object from a groovy object will look like this
import palio.Groovy Groovy.object(OBJECT_IDENTIFIER) Groovy.object(OBJECT_IDENTIFIER, (Object[])[PARAMETER1, PARAMETER2, PARAMETER3, ...]) Groovy.object(OBJECT_CODE) Groovy.object(OBJECT_CODE, (Object[])[PARAMETER1, PARAMETER2, PARAMETER3, ...])
A call to the groovy object from a jPALIO object will look like this
$*OBJECT_IDENTIFIER $*OBJECT_IDENTIFIER(PARAMETER1, PARAMETER2, PARAMETER3, ...) $*OBJECT_CODE $*OBJECT_CODE(PARAMETER1, PARAMETER2, PARAMETER3, ...)
A call in groovy from jPALIO modules to a function will look like this
import palio.Groovy
Groovy.module("MODULE_NAME").FUNCTION_NAME()
Groovy.module("MODULE_NAME").FUNCTION_NAME(ARGUMENT1, ARGUMENT2, ARGUMENT3, ...)
or
import palio.Groovy
MODULE_NAME = Groovy.module("MODULE_NAME")
MODULE_NAME.FUNCTION_NAME()
MODULE_NAME.FUNCTION_NAME(ARGUMENT1, ARGUMENT2, ARGUMENT3, ...)
The following function is used to invoke functions from jPALIO modules in groovy (functions that take arguments of the PalioCode type)
PalioCode palio.Groovy.asPalioCode(Closure closure)
Example
import palio.Groovy
Groovy.module("sql").transaction(palio.Groovy.asPalioCode({
code in the groovy language
}))
Just as jPALIO objects the groovy objects can also return values
return("VALUE")
Examples
Using basic functions
<html> <head> <title>jPALIO</title> $// Place coding declaration in HTML file source $html.contentMeta() </head> <body> $// Assign value to variable VAR $=(VAR, 1234567) $// List value of variable VAR Zmienna <b>VAR</b> ma wartość <b>$VAR</b><br> $// List result of the expression (VAR % 7) The division remainder of variable <b>VAR</b> by <b>7</b> is <b>$%((Long)$VAR, 7)</b><br> $// Assign result of the expression (VAR - 1234456) to variable VAR $=(VAR, $–((Long)$VAR, 1234456)) $// List value of variable VAR After subtracting <b>1234456</b> from the value of variable <b>VAR</b> it has the value <b>$VAR</b><br> $// List result of the expression (VAR / (-2.5)) The result of dividing the variable <b>VAR</b> by <b>-2.5</b> with precision up to 1 place after the point is <b>$/((Long)$VAR, -2.5, 1)</b><br><br> $// Assign current date and time on server to variable NOW $=(NOW, sysdate) $// List date in format day.month.year Date <b>$toString((Date)$NOW, "dd.MM.yyyy")</b><br> $// WList time in format hour:minutes:seconds Time <b>$toString((Date)$NOW, "HH:mm:ss")</b><br> $// List client's IP address Client's IP address <b>$net.getClientIP()</b><br><br> $// Assign value array to a variable TABLE $=(TABLE, ["j", "P", "A", "L", "I", "O"]) Elements of the table <b>TABLE</b>: $// Set counter CTR to start value 0 $=(CTR, 0) $// Set the number of elements of table TABLE to variable TL $=(TL, $tableLen($TABLE[])) $// Loop through all elements of table TABLE $for(i, $TABLE[], { $// Check if the analyzed element of table TABLE is not the last element, $// if yes - list the value of this element and the point, if not - list only the value of this element $if($<((Long)$CTR, $–((Long)$TL, 1)), { <b>$i</b>, }, { <b>$i</b> }) $// Increase CRT counter's value by 1 $++(CTR) }) <br><br> $// Concatenation and processing of character strings The result of concatenation of character strings <b>m</b>, <b>~SS~SS~</b> and <b>ppI</b>, where small letters were replaced by capital letters and the character <b>~</b> with letter <b>i</b> is <b>$replace($toUpper($+(["m", "~SS~SS~", "ppI"])), "~", "i")</b><br><br> $// List the character $ Character <b>$$</b><br><br> $// Create a link to the home page <a href="$pageURL($defaultPageID())">home page</a> </body> </html>
Upload of SWF files (PostgreSQL)
$/* In order for this example to work properly it is necessary to create in the PostgreSQL database the following table and sequence create table flash ( id numeric(12) not null constraint fla_pk primary key, width numeric(3) not null, height numeric(3) not null, file_name varchar(250) not null, file_size numeric(12) not null, file_mime_type varchar(100) not null, file_content bytea, created timestamp not null ); create sequence flash_s start 1; $*/ $// Check if the form was sent, if yes - process data from the form $ifNotNull($flash_add, { $// Check if the file was sent, $// if yes - process data from the form, $// if no - report error $if($&&([$isNotNull($flash_content[1]), $isNotNull($flash_content[2]), $isNotNull($flash_content[3])]), { $// Check if the sent file is in SWF format, $// if yes - try to save data from the form to database, $// if no - report error $if($==($toLower($toString($flash_content[3])), "application/x-shockwave-flash"), { $// Attempt to save data from the form to database with exception handling $// and report error if unsuccessful $try({ $// Start of transaction $sql.transaction({ $// Retrieve next value from the sequence that generates file identifiers $=(flash_id, $sql.getSequence("flash_s")) $// Save file to database $sql.write("insert into flash (id, width, height, file_name, file_size, file_mime_type, file_content, created) values (?, ?, ?, ?, ?, ?, ?, now())", [$flash_id, $flash_width, $flash_height, $flash_content[1], $flash_content[2], $flash_content[3], (byte[])$flash_content]) }) $// Store message on the success of save-to-database operation $=(_Info, "The file was saved in the database") $// Delete values of variables that store data from the form $=(flash_width, null) $=(flash_height, null) }, { $// Store message on the failure of save-to-database operation $=(_Error, "Attempt to save the file to database failed") }) }, { $// Store message on the reason of failure of save-to-database operation $=(_Error, "Improper file format") }) }, { $// Store message on the reason of failure of save-to-database operation $=(_Error, "No file") }) }) $// Display message on the failure of save-to-database operation $ifNotNull($_Error, { <center><b style="color:red">$_Error</b></center> }) $// Display message on the success of save-to-database operation $ifNotNull($_Info, { <center><b>$_Info</b></center> }) $// Create file upload form $html.createUploadForm("flash_form","flash_form", $pageURL($currentPage()), "field", "button", { <table cellspacing=1 cellpadding=1 border=0 align=center> <tr><td colspan=2 align=right><b>Add file</b></td></tr> <tr> <td>width</td> $// Create text field to input width <td>$html.textField("flash_width", (String)$flash_width, 3, false, "WIDTH", "/^[1-9]\d*$/", "size=40") px</td> </tr> <tr> <td>height</td> $// Create text field to input height <td>$html.textField("flash_height", (String)$flash_height, 3, false, "WYSOKOŚĆ", "/^[1-9]\d*$/", "size=40") px</td> </tr> <tr> <td>file</td> $// Create text field to input file <td><input type="file" name="flash_content" size="40"></td> </tr> $// Create button to send form <tr><td colspan=2 align=right>$html.submitButton("flash_add", "Add")</td></tr> </table> }, { $// Form validation code if (form.flash_width.value=="") error+="\n- the WIDTH field cannot be empty"; if (form.flash_height.value=="") error+="\n- the HEIGHT field cannot be empty"; if (form.flash_content.value=="") error+="\n- the FILE field cannot be empty"; })



