| Author | Operation | Description |
|---|---|---|
| mgshow | 2014-02-22 | Starts to deploy Bonsai Guide |
This guide is NOT a complete tutorial on XLEWS framework
and is addressed to new developers and provides a quick and (we hope) clean approach to .xlem philosophy.
If you're an expertise web developer, this framework will speed up your
development time with provided set of prepared components and a less complex syntax than
other languages.
This guide is "under construction": we do apologize for mistakes and partial descriptions
and we'll be delighted to receive any suggestion.
Copyright (c) 2012-2014 Lemansys S.r.l - ITALY, Inc. All rights reserved. XLEWS is a free framework; you can redistribute it and/or modify it under the terms of the Apache 2 License (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. XLEWS may interact with other software such as Python, MySQL and MongoDB with licenses provided by related owners.
XLEWS is an acronym of eXtraordinary Lightweight Extensible Web and application Server.
XLEWS is a lightweight framework developed with Python 3.x,
very quick, smart and easy and addressed also to web developers with no big experience.
XLEWS is absolutely free and open source and released under Apache 2 license.
As development side XLEWS is fully integrable with Eclipse IDEs via "ad hoc" plugins.
XLEWS can be combined with Apache Web Server via proxy pass.
You can free download source and binaries XLEWS versions in GIT HUB site.
Other important provided features:
XLEWS is running under as Python program and for this reason you must download and configure it in your environment.
XLEM Server Pages are text files saved into your web application with .xlem suffix and let you to generate dynamic behaviors,
rather than simply provide dynamic content (html, images ...) to final users.
This pages are tag based, case sensitive, identified by sequence <@ … @> (and “closure” sequence where needed <@/ … @> ) and can be mixed with html (or xml) tags.
Every XLEM Page is usually composed by 2 (two) sections:
@content
section !!!
<@page version="1.0"@>
<@// put your computational code here... @>
<@dim name as string@>
<@set name=”mgshow”@>
<@/page@>
<@content type=”text/html” encoding=”UTF-8”@>

<title>Hello World!

Hello Mr. <@=name@> !!!

<@/content@>
You've to create necessarly a XLEWS project to run your set of .xlem pages.
A XLEWS Project is a JSP/Servlet application: any XLEWS application is "simply" deployed as JSP/Servlet application.
You can import, export and deploy XLEWS application such as .WAR
files.
XLEM is already providing an Eclipse plugin suite to better and quick development of your applications.
To deploy and undeploy applications you so can use Tomcat console manager or (at development phase)
related embedded test server (ex: Eclipse WTP)
XLEM Variables
Any .xlem page lets you define variables.
You can define variables both in page and content sections.
You cannot define an already declared variable.
Any declared "base"variable must not be necessarly initialized: XLEWS will do it!!!
To declare XLEWS variables you must use the @dim
tag
<@dim varname as vartype@>
@set
tag
<@set varname = value or expression@>
| VarType | Related Java class/primitive | Notes |
|---|---|---|
| boolean | boolean | boolean values (default = false) |
| cookie | com.xXLEM.http.XLEMCookie | new cookie instance |
| date | com.xXLEM.datatype.XLEMDate | date(/time) values (default is "now") |
| double | double | double values (default = 0.0d) |
| float | float | float values (default = 0.0f) |
| integer | int | integer values (default = 0) |
| long | long | long values (default = 0L) |
| string | java.lang.String | String values (default = "" [empty string]) |
| VarType | Related Java class/primitive | Notes |
|---|---|---|
| booleanarray | boolean[] | boolean array |
| cookiearray | com.xXLEM.http.XLEMCookie[] | cookie arrays |
| datearray | com.xXLEM.datatype.XLEMDate[] | date arrays |
| doublearray | double[] | double arrays |
| floatarray | float[] | float arrays |
| integerarray | int[] | integer arrays |
| longarray | long[] | long arrays |
| stringarray | java.lang.String[] | String arrays |
@dim
statement and will be discussed later in this guide.| ObjectType | Related Java class/primitive | Notes |
|---|---|---|
| genericdatabase | com.xXLEM.datatype.XLEMGenericDatabase | Very useful when connecting with a "sql" database |
| localizer | com.xXLEM.datatype.XLEMLocalizer | Useful when localizing application (same scope of Resource Bundle) |
| option | com.xXLEM.datatype.XLEMOption | Useful to manage list options and automatically binding values into "select" html tag |
| rssnews | com.xXLEM.xml.XLEMRSSNews | Manage a single RSS Item |
| rssnewsreader | com.xXLEM.xml.XLEMRSSNewsReader | Lets you to connect with a RSS channel and retrive results as "rssnews" |
| sqlform | com.xXLEM.datatype.XLEMSQLForm | Easy (and simple mapper) between a SQL Table and Form. Under development: for testing purpose only |
| sqlview | com.xXLEM.datatype.XLEMSQLView | Easy (and simple mapper) between a SQL Query and Form. Under development: for testing purpose only |
| textfilereader | com.xXLEM.datatype.XLEMTextFileReader | Manage Text File Input Streams |
| textfilewriter | com.xXLEM.datatype.XLEMTextFileWriter | Manage Text File Output Streams |
| xmlbuilder | com.xXLEM.xml.XLEMXMLBuilder | Used to quickly compose XML streaming in memory |
| xmldocument | com.xXLEM.xml.XLEMXMLDocument | XML DOM parser from multiple source (StringBuffer, URL, File and generic input stream) |
| xmlparser | com.xXLEM.xml.XLEMXMLParser | This is a very quick and easy version of XML SAX from multiple source (StringBuffer, URL, File and generic input stream): you can parse a lot of MB in a few seconds!!! |
| xmlvalidator | com.xXLEM.xml.XLEMXMLValidator/td> | Validate an XML source using specified xsd |
| xsltransformer | com.xXLEM.xml.XLEMXSLTranformer | Use this component when transforming an XML streaming with a XSL stylesheet: usually HTML markup is returned. |
javatype @dim
tag attribute
<@dim varname as javatype vartype@>
in this case you must initialize your variable
<@dim extDate as javatype java.util.Date@>
<@set extDate= new java.util.Date()@>
newjavatype
statement !!!
<@dim myBuffer as javatype StringBuffer@>
<@set myBuffer= new StringBuffer()@>
is equivalent to:
<@dim myBuffer as newjavatype StringBuffer@>
<@page version="1.0"@>
<@// Some variable declaration...@>
<@dim k as integer@>
<@dim i,j as integer@>
<@set i=100@>
<@set j=i*2@>
<@set k=j+3@>
<@dim firstName as string@>
<@set firstName="John"@>
<@dim lastName as string@>
<@set lastName="Doe"@>
<@dim items as integerarray@>
<@set items=new int[] {1,2}@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>
<@//HTML (dynamic) code goes here...@>

<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
<title>Variables & Expressions</title>

i= <@=i@> , j= <@=j@> , k = <@=k@>
<@dim fullname as string@>
<@set fullname=(firstName+" "+lastName).toUpperCase()@>

Full name is <@=fullname@>

Sum is <@=items[0]+items[1]@>

<@/content@>
... this page returni= 100 , j= 200 , k = 203 Full name is JOHN DOE Sum is 3
XLEWS allows you to manage conditional statements using the following tags:
<@if expression @>
<@elseif expression @>
(zero or more occurencies...)<@else@>
(zero or just one occurency)<@endif@> [or <@/if@>]
expression
follows the rules of Java™ syntax: for better understanding we
suggest to view related topic
@if
statement conditional expression
and you must not use brackets in sequences. But remember that in the Java™ sections that can be embedded in Lem pages you,
of course, must follow Java™ rules.
@endif
and @/if
are equivalents.
<@page version="1.0"@>
<@// How to use conditional statements...@>
<@dim connectionDate as date@>
<@dim MORNING_HELLO,AFTERNOON_HELLO,EVENING_HELLO as string@>
<@set MORNING_HELLO="Good Morning"@>
<@set AFTERNOON_HELLO="It's Afternoon"@>
<@set EVENING_HELLO="Good Evening"@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
<title>Conditional Statements with XLEWS 4.1</title>

<@dim hour as integer@>
<@set hour=connectionDate.gethour()@>
<@if hour<14@>
<@=MORNING_HELLO@>
<@elseif hour<18@>
<@=AFTERNOON_HELLO@>
<@else@>
<@=EVENING_HELLO@>
<@endif@>
dear user...

<@/content@>
and a possible return message should be...
Good Evening dear user...
XLEWS allows you to manage loops using the following tag sequences:
<@for variable = startValue to endValue [step incrementValue] @> ... <@next@>
<@while expression @> ... <@wend@>
<@forall javaType variable in ARRAY @> ... <@endforall@>
@for variable
must be declared before and outside loop sequence.
@forall variable
must be declared inside tag with specified Java™ type
and must have the same javaType
of ARRAY
item!
@next
, @endfor
and @/for
are equivalents.
@wend
, @endwhile
and @/while
are equivalents.
@endforall
and @/forall
are equivalents.
<@page version="1.0"@>
<@// Running Loops on XLEWS platform...@>
<@dim i as integer@>
<@dim bestFriends as stringarray@>
<@set bestFriends=new String[] {"Mark","Paul","Mattew","Gino"}@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
<title>XLEWS Loops</title>

<@dim base as integer@>
<@set base=4@>
<@for i=1 to 11 step 3@>
<@=base@>*<@=i@> = <@=base*i@> |
<@endfor@>

<@set i=10@>Wild sequence:
<@while i<100@>
<@=i@>
<@set i*=2@> <@// equals to i=i*2 @>
<@wend@>

My best Friends are
<@forall String friend in bestFriends@>
<@=friend@>
<@endforall@>

<@/content@>
and the output is...
4*1 = 4 | 4*4 = 16 | 4*7 = 28 | 4*10 = 40 |
Wild sequence: 10 20 40 80
My best Friends are Mark Paul Mattew Gino
Sometime should be very useful to share content between pages or split content management
of very long pages in multiple sub entities.
XLEWS provides a @external
tag wich you can import "shared" code from one
or more module(s)
<@external src="[[$root/]path/]module-name.xlmh" @>
.xlmh
.xlem
page and may
not contains lem tags
but, for example, only markup tags such as html
or static text.
.xlmh
module the main page will be refreshed and recompiled!
.xlmh
module can include another module: in this case the
path
will be referred to main including .xlem
page path, or
if your specify $root
prefix XLEWS will search module from Application Root (Web)Content.
> main file: modules.xlem
>> modules: modules/header.xlmh, modules/footer.xlmh, modules/menu.xlmh
modules.xlem - source:
<@page version="1.0"@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
<title>XLEWS Modules (.xlmh)</title>

<@external src="modules/header.xlmh"@>
!!!  I'm in body section !!!
POWERED by XLEM XLEWS
XLEWS provides a quick way to read/parse text file streaming
using textfilereader
component (
com.xXLEM.datatype.XLEMTextFileReader
) and to write
using textfilewriter
component (
com.xXLEM.datatype.XLEMTextFileWriter
).
You can read or write "line by line" from and to multiple streaming sources.
Let us to show just some example about opening read methods of
textfilewriter
:
| Method | Description |
|---|---|
openfromfile(string filename, string encoding) |
tries to open a text streaming from filename source path with
specified encoding returning true if operation was successfully
accomplished, otherwise false . |
openfromfile(string filename) |
tries to open a text streaming from filename source path without specified encoding.
Returns true if operation was successfully
accomplished, otherwise false . |
openfromurl(string url, string encoding) |
tries to open a text streaming from url address with
specified encoding returning true if operation was successfully
accomplished, otherwise false . |
openfromurl(string url) |
tries to open a text streaming from url address without specified encoding.
Returns true if operation was successfully
accomplished, otherwise false . |
openfromstream(InputStream stream, string encoding) |
tries to open a text streaming from stream generic inputstream with
specified encoding returning true if operation was successfully
accomplished, otherwise false . |
openfromstream(InputStream stream) |
tries to open a text streaming from stream generic inputstream without specified encoding.
Returns true if operation was successfully
accomplished, otherwise false . |
textfilewriter
:
| Method | Description |
|---|---|
opentofile(string filename, string encoding) |
tries to open a text streaming to filename source path with
specified encoding returning true if operation was successfully
accomplished, otherwise false . |
opentofile(string filename) |
tries to open a text streaming to filename source path without specified encoding.
Returns true if operation was successfully
accomplished, otherwise false . |
opentostream(OutputStream stream, string encoding) |
tries to send a text streaming to stream outputstream with
specified encoding returning true if operation was successfully
accomplished, otherwise false . |
opentostream(OutputStream stream) |
tries to send a text streaming to stream outputstream without specified encoding.
Returns true if operation was successfully
accomplished, otherwise false . |
.csv
file and display
splitted data row at video such as HTML table.
resources/users.csv
file:
# User list
# Username; First Name; Last Name; Email
<EMAIL_ADDRESS><EMAIL_ADDRESS># End of file
textfilereader.xlem
source code:
<@page version="1.0"@>
<@dim reader as textfilereader@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type"
CONTENT="text/html; charset=UTF-8"/>
<title>XLEWS Text I/O - Reader</title>

XLEWS - Reading Text File

<@if reader.openfromfile(toURI("resources/users.csv"))@>

User Name	First Name
	Last Name
Email

<@dim line as string@>
<@dim items as stringarray@>
<@dim i as integer@>
<@while reader.hasline()@>
<@set line=reader.nextline()@>
<@if !isblank(line) && !line.startsWith("#")@>
<@set items=line.split(";")@>
<@if items.length==4@>

<@for i=0 to 3@>
<@=items[i]@>
<@endfor@>

<@endif@>
<@/if@>
<@wend @>

<@call reader.close()@>
<@else@>
ERROR= <@=reader.geterror()@>
<@endif@>

<@/content@>
XLEWS - Reading Text File
User Name First Name Last Name Email
a.scott
Alfred
Scott
<EMAIL_ADDRESS>p.green
Paul
Green
<EMAIL_ADDRESS>textfilewriter.xlem
source code:
<@page version="1.0"@>
<@dim newFile as string@>
<@set newFile=System.getProperty("java.io.tmpdir")+
"lews-test-out.txt"@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type"
CONTENT="text/html; charset=UTF-8"/>
<title>XLEWS Text I/O - Writer</title>

File to save should be located at Server Path :

 <@=newFile@>
<@dim outF as textfilewriter@>
<@if outF.opentofile(newFile)@>
<@call outF.writeline("FIRST LINE!")@>
<@call outF.writeline("SECOND LINE ...")@>
<@call outF.write("... and CONTINUE!")@>
<@call outF.writeline("LAST LINE!")@>
<@call outF.close()@>

File successfully saved and closed!!!
<@else@>
ERROR:
<@=outF.geterror()@>
<@endif@>

<@/content@>
File to save should be located at Server Path :
/TEMPORARY-SPECIFIC-PAT .../lews-test-out.txt
File was successfully saved and closed!!!
lews-test-out.txt
file looks like:
FIRST LINE!
SECOND LINE ...... and CONTINUE!
LAST LINE!
As you'll se multiple time on this tutorial, XLEWS "anticipate" developers in ERROR management.
Usually XLEWS tags and components do not "trows" exceptions, but give back true
if operation was successfully performed or false
otherwise; in addition developer
can retrieve error message details by calling .geterror()
method of related component.
In any case XLEWS is extensible and integrable with every Java™ component,
bean and library: sometime developers should directly manage exceptions and errors.
To do it, XLEWS provides a "simple" error management based on tags:
<@try@>
Trowable sequence code<@/try@>
<@catch@>
Java™ exception type<@/catch@>
<@finally@>
Optionally sequence code to be in any case executed<@/finally@>
<@/try@>
and <@endtry@>
tags are equivalent.
<@/catch@>
and <@endcatch@>
tags are equivalent.
<@/finally@>
and <@endfinally@>
tags are equivalent.
@try
and @catch
sequence tag are mandatory,
@finally
section is optional!!!
<@catch@>
and
<@/catch@>
in sequence.
<@catch;@>...</@catch@>
sequence you'll have back
a pre instantiated exception
of
java.lang.Throwable
class type. This exception
instance will be available only inside related @catch
section!!!
error-management.xlem
) show a few simple
lines of code for error management :
<@page version="1.0"@>
<@dim filename as string@>
<@set filename="non-existent-file.ext"@>
<@dim fis as javatype java.io.FileInputStream@>
<@set fis=null@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type"
CONTENT="text/html; charset=UTF-8"/>
<title>Error Management with XLEWS</title>

<@try@>
<@set fis=new java.io.FileInputStream(filename)@>
<@// Do something... @>
<@/try@>
<@catch java.io.FileNotFoundException@>
FILE NOT FOUND "<@=filename@>" :((

<@=exception.toString()@>
<@/catch@>
<@catch Exception@>
GENERIC ERROR opening <@=filename@>

<@=exception.toString()@>
<@/catch@>
<@finally @>
<@if !isnull(fis)@><@call fis.close()@><@/if@>
<@/finally@>

<@/content@>
FILE NOT FOUND "no-existent-file.ext" :((
java.io.FileNotFoundException: no-existent-file.ext (No such file or directory)
XLEWS provides the following components to accomplish xml integration into your dynamic .xlem
applications
Parsing
xmlparser
xmldocument
Building
xmlbuilder
Validation
xmlvalidator
xmlparser
sax
parser that with few tags let you perform "smart" xml parsing.
...
<@dim xml as xmlparser@>
<@if xml.open( something... )@>
<@while xml.getnexttag()@>
<@if xml.istag("someTag")@>
... do something ...
<@elseif xml.istag("anotherTag")@>
... do something ...
<@elseif xml.istag("anotherElseTag")@>
... do something ...
<@endif@>
<@wend@>
<@call xml.close()@>
<@else@>
XML parsing error = <@=xml.geterror()@>
<@endif@>
...
You've to perform these simple steps:
open( source )
where source
can be
string
(ex: "http[s]://yoursite/yourpath/yourxml" or a local file)StringBuffer
containing your XML codeInputStreeam
containing your XML streaminggetnexttag()
this loops for all tags istag( tagName )
check if tagName
has been currently interceptedclose()
close parse and release input stream (very important, don't forget!) com.xXLEM.xml.XLEMXMLParser
javadoc)
currtagname()
return current inspected tag name getcontent()
return current tag content (if not, will return an empty string) getpar(parName)
return parName
tag attribute for the current inspected tag (if not existing attribute, will return an empty string)
Suppose that exist the file "resources/demo.xml" under your application
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book>
<id>498756</id>
<title>Antony and Cleopatra</title>
<price currency="USD">35.00</price>
<author>
<name>William Shakespeare</name>
<id>SKSPX012</id>
</author>
</book>
<book>
<id>591287</id>
<title>Divina Commedia</title>
<price currency="USD">24.50</price>
<author>
<name>Dante Alighieri</name>
<id>ALDNY451</id>
</author>
</book>
</books>
This .xlem will parse previous file providing the book list
and calculating discount for each one.
<@page version="1.0"@>
<@dim xml as xmlparser@>
<@dim bookId as string@>
<@dim bookAuthor as string@>
<@dim bookTitle as string@>
<@dim bookCurrency as string@>
<@dim bookPrice as float@>
<@dim bookRealPrice as string@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
<title>XLEWS Xml Parser</title>

Book online store:

<@if xml.open(toURI("resources/demo.xml"))@>
<@while xml.getnexttag()@>
<@if xml.istag("name")@>
<@set bookAuthor=xml.getcontent()@>
<@elseif xml.istag("title")@>
<@set bookTitle=xml.getcontent()@>
<@elseif xml.isfullpathtag("/books/book/id")@>
<@set bookId=xml.getcontent()@>
<@elseif xml.istag("price")@>
<@set bookCurrency=xml.getpar("currency")@>
<@set bookPrice=(tofloat(xml.getcontent())*80)/100.0f@>
<@set bookRealPrice=xml.getcontent()@>
<@elseif xml.istag("book")@>
<@set bookTitle=bookAuthor=bookId=bookCurrency=""@>
<@elseif xml.istag("/book")@>
Book - <@=bookId@>: <@=bookTitle@> by <@=bookAuthor@>
only for <@=bookCurrency@>
<@=bookRealPrice@> <@=bookPrice@>

<@endif@>
<@wend@>
<@call xml.close()@>
<@else@>
ERROR: <@=xml.geterror()@>
<@endif@>

<@/content@>
Book online store:
Book - 498756: Antony and Cleopatra by William Shakespeare
only for USD
35.00 28.0
Book - 591287: Divina Commedia by Dante Alighieri
only for USD
24.50 19.6
xmldocument
xmldocument
component.xmlparser
xmldocument
for very large XML (ex: more than 1MB) because
this will be very expensive for the server: please consider this overhead!!!
xmldocument
rather than xmlparser
.
<@page version="1.0"@>
<@dim xml as xmldocument@>
<@dim bookPrice as float@>
<@dim i as integer@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
<title>XLEWS XML Document </title>

Book online store:

<@if xml.openfromfile(toURI("resources/demo.xml"))@>
<@dim bookNodes as javatype org.w3c.dom.NodeList@>
<@set bookNodes=xml.getElementsByTagName("book")@>
<@dim tNode as javatype org.w3c.dom.Node@>
<@dim priceNode as javatype org.w3c.dom.Node@>
<@// We're supposing xml well formed ;) @>
<@// Otherwise you must check for missing tags !!!@>
<@for i=0 to bookNodes.getLength()-1 @>
<@set tNode=bookNodes.item(i)@>
Book - <@=xml.getcontent(tNode,"id")@>:
<@=xml.getcontent(tNode,"title")@>
by<EMAIL_ADDRESS>(xml.getFirstElementByTagName(tNode,"author"),
"name")@>
<@set priceNode=xml.getFirstElementByTagName(tNode,"price")@>
<@if notisnull(priceNode)@>
only for <@=xml.getpar(priceNode,"currency")@>
<@set bookPrice=tofloat(xml.getcontent(priceNode))*80/100.0f@>
<@=xml.getcontent(priceNode)@>
 <@=bookPrice@>
<@endif@>

<@endfor@>
<@else@>
ERROR: <@=xml.getErrorCause()@>
<@endif@>

<@/content@>
openfromfile(string path)
openfromfile(File file)
openfrombuffer(string content)
openfrombuffer(StringBuffer content)
openfromstream(InputStream stream)
openfromurl(string address)
openfromurl(URL address)
true
if XML has been opened, otherwise false
.
Document
interface you can check for errors, calling method getErrorCause()
.
xmldocument
.
Document
interface.
Node getFirstElementByTagName(rootNode,nodeName)
nodeName
name and child of
rootNode
node.String getcontent(rootNode,nodeName)
nodeName
name and child of
rootNode
node.
String getpar(rootNode,nodeName,attributeName)
attributeName
attribute into first tag with nodeName
name and child of
rootNode
node.
String getcontent(node)
Node node
String getpar(node,attributeName)
attributeName
attribute into specified Node node
.
String getAllXmlContent()
will return as string
all xml content
of current xmldocument
Node[] getElementsByTagName(rootNode,nodeName)
Node[]
array tags with nodeName
name
and child of rootNode
node.xmldocument
you'll already be enabled to modify
current xml document, but we will not discuss this here.
xmlbuilder
xmlbuilder
component you can quickly create xml
sequences.
com.xXLEM.xml.XLEMXMLBuilder
class.
<@page version="1.0"@>
<@dim books as stringarray@>
<@set books=new String[] {
"498756|Antony and Cleopatra|William Shakespeare|"+
"SKSPX012|USD|35.00",
"591287|Divina Commedia|Dante Alighieri|"+
"ALDNY451|USD|24.50"
}@>
<@dim xml as xmlbuilder@>
<@call xml.init("1.0","UTF-8")@>
<@call xml.newcomment("Automatic generated with xmlbuilder")@>
<@call xml.newtag("books")@>
<@dim bki as stringarray@>
<@forall String book in books@>
<@set bki=book.split("[|]")@>
<@call xml.newtag("book")@>
<@call xml.newtag("id",bki[0])@>
<@call xml.newtag("title",bki[1])@>
<@call xml.opentag("price")@>
<@call xml.setpar("currency",bki[4])@>
<@call xml.endtag(false)@>
<@call xml.setcontent(bki[5])@>
<@call xml.closetag("price")@>
<@call xml.newtag("author")@>
<@call xml.newtag("name",bki[2])@>
<@call xml.newtag("id",bki[3])@>
<@call xml.closetag("author")@>
<@call xml.closetag("book")@>
<@endforall@>
<@call xml.closetag("books")@>
<@/page@>
<@// !!! Please put not space(s) or new line(s) between ...@>
<@// ... "content" tag and "<?xml?>" tag ...@>
<@// ... otherwise with some browser your XML will not work properly!!!!@>
<@content type="text/xml" encoding="UTF-8"@><@=xml.tostring()@>
<@/content@>
init(...)
method if you wan have only xml tags.
tostring()
or toString()
method
you can retrieve xml tag sequence as string
.
"text/xml"
!!!
<?xml version="1.0" encoding="UTF-8"?>

<books>
<book>
<id>498756</id>
<title>Antony and Cleopatra</title>
<price currency="USD">35.00</price>
<author>
<name>William Shakespeare</name>
<id>SKSPX012</id>
</author>
</book>
<book>
<id>591287</id>
<title>Divina Commedia</title>
<price currency="USD">24.50</price>
<author>
<name>Dante Alighieri</name>
<id>ALDNY451</id>
</author>
</book>
</books>
xmlvalidator
xmlvalidator
can be used.javax.xml.validation.Validator
class.xml
source (local file or url)schema
(local file or url)validate()
method of current
xmlvalidator
component.
validator
component more than once re-defining
source
and schema
.
com.xXLEM.xml.XLEMXMLValidator
for more info.
Suppose you've defined schema file "resources/validator.dtd"
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="hello" type="xsd:string"/>
</xsd:schema>
Now we'll show how to validate two xml static files:
"resource/xml_ok.xml"
<?xml version="1.0" encoding="UTF-8"?>
<hello>Hello World</hello>
and "resource/xml_ko.xml"
<?xml version="1.0" encoding="UTF-8"?>
<message>
<hello>Hello World</hello>
</message>
.xlem
validator page:
<@page version="1.0"@>
<@dim xmlSources as stringarray@>
<@set xmlSources=new String[] {
"resources/xml_ok.xml",
"resources/xml_ko.xml"
}@>
<@dim validator as xmlvalidator@>
<@call validator.setschemaasfile(toURI("resources/validator.xsd"))@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
<title>XLEWS XML Validator</title>

Validating xml sources:

<@forall String src in xmlSources@>
Validating <<EMAIL_ADDRESS>
... result is
<@try@>
<@call validator.setsourceasfile(toURI(src))@>
<@call validator.validate()@>
ok
<@/try@>
<@catch Exception@>
<@=exception.getMessage()@>
<@endcatch@>

<@/forall@>

<@/content@>
Validating xml sources:
Validating resources/xml_ok.xml...
... result is ok
Validating resources/xml_ko.xml...
... result is cvc-elt.1: Cannot find the declaration of element 'message'.
XLEWS provides the following component to accomplish xsl integration into your
dynamic .xlem
applications
xsltransformer
XSL transformer
you might better separate data from rendering.
xml source
(from buffer, file or url) and
related xsl
"mask" (buffer, file or url)
xsltransformer
by seeing XLEWS javadoc
and related Java™ class com.xXLEM.xsl.XLEMXSLTransformer
Now we'll show the xml book list (resources/demo.xml) as html
This is the xsl file: (resources/xsl-books.xsl)
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output method="html"
indent="yes"
doctype-public="-//W3C//DTD HTML 4.01//EN"
/>
<xsl:template match="books">

<title>Available books</title>

Available books:

<xsl:apply-templates/>

</xsl:template>
<xsl:template match="book">

<xsl:value-of select="title"/>
author: <xsl:value-of select="author/name"/>

</xsl:template>
</xsl:stylesheet>
<@page version="1.0"@>
<@dim transf as xsltransformer@>
<@dim xsl_error as string@>
<@dim res as string@>
<@try@>
<@call transf.setsourceasfile(toURI("resources/demo.xml"))@>
<@call transf.setstyleasfile(toURI("resources/xsl-books.xsl"))@>
<@set res=transf.transform()@>
<@/try@>
<@catch Exception@>
<@set xsl_error=exception.getMessage()@>
<@/catch@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>
<@if !isblank(res)@>
<@=res@>
<@else@>

<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
<title>XSL Transnformer error</title>

Error transforming XSL=

<@=xsl_error@>

<@=transf.geterror()@>

<@endif@>
<@/content@>
and the ouptput result will be:
Available books:
- Antony and Cleopatra
author: William Shakespeare
- Divina Commedia
author: Dante Alighieri
HTTP protocol is based on http request and response.
XLEM developers can interact with these objects using:
These components are automatically provided as "instances" inside any .xlem
page.
request
component is based on java class
com.xXLEM.http.XLEMHTTPRequest
and implements
javax.servlet.http.HttpServletRequest
.
| Method | Description |
|---|---|
getheaders() |
return a String Array containing name of all current user request http headers |
getheader(String headerName) |
tries to return request header name headerName as string ;
if it does not exist will return "" (empty string) |
toboolean(String rqParam) |
tries to return request parameter rqParam as boolean ;
if does not exist or it is not convertible, will return false |
todouble(String rqParam) |
tries to return request parameter rqParam as double ;
if does not exist or it is not convertible will return 0.0d |
tofloat(String rqParam) |
tries to return request parameter rqParam as float ;
if it does not exist or it is not convertible, will return 0.0f |
tointeger(String rqParam) |
tries to return request parameter rqParam as integer ;
if it does not exist or it is not convertible will return 0 |
tolong(String rqParam) |
tries to return request parameter rqParam as long ;
if it does not exist or it is not convertible will return 0L |
tostring(String rqParam) |
tries to return request parameter rqParam as string ;
if it does not exist or it is not convertible will return "" (empty string) |
decode(String value,String encoding) |
tries to return a value "url-decoded"
with specified encoding
if it is not possible request will return the same value
parameter |
decode(String value) |
= decode(String value,"UTF-8") |
encode(String value,String encoding) |
tries to return a value "url-encoded"
with specified encoding
if it is not possible request will return the same value
parameter |
encode(String value) |
= encode(String value,"UTF-8") |
tobooleanarray(rqParam),todoublearray(...),tofloatarray(...),
tointegerarray(...),tolongarray(...),tostringarray(...)
you can try to retrieve request
parameters as array of related "type"; if rqParam not found null
XLEWS
will return null
querystring
component is based on java class
com.xXLEM.http.XLEMQueryString
and automatically provides
a powerful method to retrieve parameters from query string:
| Method | Description |
|---|---|
toboolean(String query parameter) |
tries to return request parameter qryParam as boolean ;
if it does not exist or it is not convertible will return false |
todouble(String qryParam) |
tries to return query parameter qryParam as double ;
if it does not exist or it is not convertible will return 0.0d |
tofloat(String qryParam) |
tries to return query parameter qryParam as float ;
if it does not exists or it is not convertible will return 0.0f |
tointeger(String qryParam) |
tries to return query parameter qryParam as integer ;
if it does not exist or it is not convertible will return 0 |
tolong(String qryParam) |
tries to return query parameter qryParam as long ;
if it does not exist or it is not convertible will return 0L |
tostring(String qryParam) |
tries to return query parameter qryParam as string ;
if it does not exist or it is not convertible will return "" (empty string) |
request.getQueryString()
and you'll have back a string representing
current user querystring
response
component is based on java class
com.xXLEM.http.XLEMHTTPResponse
and implements
javax.servlet.http.HttpServletResponse
.
response.redirect(stirng url)
(equivalent to
response.sendRedrect(...)
method)
<@page@>...</@page@>
section.
Suppose to have two .xlem pages:
- login.xlem
- login_welcome.xlem
First (login.xlem
)page simply shows a form where user put username (text) and password.
login_welcome.xlem
) will process form data and if is user
is 'mgshow' and password is = '123456' then shows welcome message otherwise will redirect
to login.xlem
page adding user in querystring.
login.xlem
page fill the retrieved user name in querystring inside html
user field.
login.xlem
page source code:
<@page version="1.0"@>
<@dim currentUser as string@>
<@set currentUser=querystring.tostring("usr")@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
<title>XLEWS Login Form example</title>

Login Form

<form name="loginForm" method="post"
action="login_welcome.xlem">

User:

<input type="text" name="username"
value="<@=htmlformat(currentUser)@>"

Password:

<input type="password"
name="userpassword">

<input type="submit" name="btLogin"
value="Login...">

</form>

<@/content@>
login_welcome.xlem
page source code:
<@page version="1.0"@>
<@dim uname,upass as string@>
<@set uname=request.tostring("username")@>
<@set upass=request.tostring("userpassword")@>
<@dim okDisplay as boolean@>
<@set okDisplay=("mgshow".equals(uname) &&
"123456".equals(upass))@>
<@if !okDisplay@>
<@call response.redirect("login.xlem?usr="+
request.encode(uname))@>
<@/if@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>
<@if okDisplay@>

<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
<title>Welcome <@=uname@></title>

Please Welcome <@=uname@>,

Have a nice day !!!!

You've sent this headers:
<@dim headers as stringarray@>
<@set headers=request.getheaders()@>
<@forall String header in headers@>

<@=header@> =
<@=request.getheader(header)@>
<@endforall@>

<@/if@>
<@/content@>
Please Welcome mgshow,
Have a nice day !!!!
You've sent this headers:
host = localhost:8080
user-agent = Mozilla/5.0 (Macintosh;
Intel Mac OS X 10.7; rv:8.0.1)
Gecko/20100101 Firefox/8.0.1
accept = text/html,application/xhtml+xml,
application/xml;q=0.9,*/*;q=0.8
accept-language = en-us,en;q=0.5
accept-encoding = gzip, deflate
accept-charset = ISO-8859-1,utf-8;q=0.7,*;q=0.7
connection = keep-alive
referer = http://localhost:8080/lews41-examples/login.xlem
content-type = application/x-www-form-urlencoded
content-length = 52
XLEWS provides to developers session
component that fully manages
http user session.
XLEWS links one session per current user to a data (or better "attributes") that
developers can read (get
) and write (set
)
to make persistent the info across multiple user requests.
This component is derived from Java™ class
com.xXLEM.http.XLEMHTTPSession
that implements
javax.servlet.http.HttpSession
interface.
Unlike .jsp
, any XLEM, by default, does not activate
user session management !!!!
To activate http user session management you've to specify into
<@page@>
tag the following attributes:
<@page version="1.0"
session="true" [if not present = "false"]
createonfail = "true/false" (if not present ="true")
@>
createonfail="true"
you'll force XLEWS to create session if it does not already exists.
session
instance inside your
.xlem
page. If not, every call over session
instance will return a
null pointer exception
: be careful!!!!
| Method | Description |
|---|---|
getid() |
return the session unique id as string |
exists(String sessionAttribute) |
return true if sessionAttribute exists,
otherwise false |
getboolean(String sAttr) |
tries to return session attribute sAttr as boolean ;
if it does not exist or it is not convertible will return false |
getdate(String sAttr) |
tries to return session attribute sAttr as date
(com.xXLEM.datatype.XLEMDate );
if it does not exist or it is not convertible will return null |
getdouble(String sAttr) |
tries to return session attribute sAttr as double ;
if it does not exist or it is not convertible, will return 0.0d |
getfloat(String sAttr) |
tries to return session attribute sAttr as float ;
if it does not exist or it is not convertible will return 0.0f |
getinteger(String sAttr) |
tries to return session attribute sAttr as integer ;
if it does not exist or it is not convertible, will return 0 |
getlong(String sAttr) |
tries to return session attribute sAttr as long ;
if it does not exist or it is not convertible will return 0L |
getstring(String sAttr) |
tries to return session attribute sAttr as string ;
if it does not exist or it is not convertible will return "" (empty string) |
get(String sAttr) |
returns session attribute sAttr as java.lang.Object ;
if it does not exist or it is not convertible will return null |
setboolean(String sAttr, boolean value) |
assigns boolean
value to session attribute sAttr |
setdouble(String sAttr, double value) |
assigns double
value to session attribute sAttr |
setdate(String sAttr, date value) |
assigns date (com.xXLEM.datatype.XLEMDate )
value to session attribute sAttr |
setfloat(String sAttr, float value) |
assigns float
value to session attribute sAttr |
setinteger(String sAttr, integer value) |
assigns integer
value to session attribute sAttr |
setlong(String sAttr, long value) |
assigns long
value to session attribute sAttr |
setstring(String sAttr, string value) |
assigns string
value to session attribute sAttr |
set(String sAttr, java.lang.Object value) |
assigns "some"
value to session attribute sAttr |
getbooleanarray(sAttr),getdoublearray(...),getfloatarray(...),
getintegerarray(...),getlongarray(...),getstringarray(...)
you can try to retrieve
session attributes as array of related "type"; if sAttr not found null
XLEWS
will return null
<@page version="1.0" session="true" createonfail="true"@>
<@dim hints as integer@>
<@set hints=session.getinteger("MY_HINTS")@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
<title>XLEWS User Session Management</title>

You're visited this page <@=++hints@> times!
<@call session.setinteger("MY_HINTS",hints)@>

<@/content@>
XLEWS provides application
component to developers that fully manage
current web application.
Please consider application
as "shared" session across all users!
XLEWS provides only one application
instance per application.
This application
can store data (or better "attributes") that
developers can read (get
) and write (set
)
to make persistent info across all user requests.
This component is derived from Java™ class
com.xXLEM.http.XLEMServletContext
that implements
javax.servlet.ServletContext
interface.
In addition with all interface provided methods, to speed up your
data checking and retrieving, you can also use:
| Method | Description |
|---|---|
exists(String applicationAttribute) |
return true if applicationAttribute exists,
otherwise false |
getboolean(String appAttr) |
tries to return application attribute appAttr as boolean ;
if it does not exist or it is not convertible will return false |
getdate(String appAttr) |
tries to return application attribute appAttr as date
(com.xXLEM.datatype.XLEMDate );
if it does not exist or it is not convertible will return null |
getdouble(String appAttr) |
tries to return application attribute appAttr as double ;
if it does not exist or it is not convertible will return 0.0d |
getfloat(String appAttr) |
tries to return application attribute appAttr as float ;
if it does not exist or it is not convertible will return 0.0f |
getinteger(String appAttr) |
tries to return application attribute appAttr as integer ;
if it does not exist or it is not convertible will return 0 |
getlong(String appAttr) |
tries to return application attribute appAttr as long ;
if it doesnot exists or it is not convertible will return 0L |
getstring(String appAttr) |
tries to return application attribute appAttr as string ;
if it does not exist or it is not convertible will return "" (empty string) |
get(String appAttr) |
returns application attribute appAttr as java.lang.Object ;
if it does not exist or it is not convertible will return null |
setboolean(String appAttr, boolean value) |
assigns boolean
value to application attribute appAttr |
setdouble(String appAttr, double value) |
assigns double
value to application attribute appAttr |
setdate(String appAttr, date value) |
assigns date (com.xXLEM.datatype.XLEMDate )
value to application attribute appAttr |
setfloat(String appAttr, float value) |
assigns float
value to application attribute appAttr |
setinteger(String appAttr, integer value) |
assigns integer
value to application attribute appAttr |
setlong(String appAttr, long value) |
assigns long
value to application attribute appAttr |
setstring(String appAttr, string value) |
assigns string
value to application attribute appAttr |
set(String appAttr, java.lang.Object value) |
assigns "some"
value to application attribute appAttr |
getbooleanarray(appAttr),getdoublearray(...),getfloatarray(...),
getintegerarray(...),getlongarray(...),getstringarray(...)
you can try to retrieve
application attributes as array of related "type"; if appAttr not found null
XLEWS
will return null
.xlem
application lifeciclye.
<@page version="1.0" session="true" createonfail="true"@>
<@dim hints as integer@>
<@set hints=session.getinteger("MY_HINTS")@>
<@dim globalHints as integer@>
<@set globalHints=1+application.getinteger("GLOBAL_HINTS")@>
<@call application.setinteger("GLOBAL_HINTS",globalHints)@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
<title>XLEWS Application Data Management</title>

You're visited this page <@=++hints@> times.

Total visits <@=globalHints@>.
<@call session.setinteger("MY_HINTS",hints)@>

<@/content@>
XLEM syntax and tags is very easy and powerful.
However you should need to directly put Java™ scripting.
XLEWS allows you to mix and switch from JAVA™ code to XLEM tags simply
calling <@java@>
your script<@/java@>
sequence.
You can share variables, instances and so on... : this make XLEM
very extensible and programmable!!!
You can write output to the final user
using out
provided instance.
Let us to show this brief example:
<@page version="1.0"@>
<@dim i as integer@>
<@set i=4@>
<@dim firstName as string@>
<@set firstName="John"@>
<@java@>
int y=i*10;
String lastName="Doe";
<@/java@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
<title>Putting Java code...</title>

Hello <@=firstName@> <@=lastName@> !

<@java@>
out.write(i+" + "+y+" = "+(i+y));
<@/java@>

<@/content@>
Hello John Doe !
4 + 40 = 44
XLEWS allows you to define custom functions inside any XLEM.
You must use the <@jfun@>
tag.
<@jfun returnJavaType functionName (arguments) [throws ...]{
... Java™ code ...
}@>
To call and use your functions you can use the <@call@>
tag,
assign returned function value to a specified variable using the
<@set@>
tag or directly put result (if available) with
<@=@>
tag.
<@jfun@>
tag in any tag sequence of current
XLEM (in both page
and
content
section). XLEWS parser will reallocate it before compile.
session, application, out, request, response
(and so on...). You
have to pass it as arguments if you need to use someone of this !!!
<@page version="1.0"@>
<@jfun double average(int a,int b) {
return (double) (a+b)/2;
}@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
<title>XLEWS Custom Functions</title>

<@=hello("Mark Twain")@>
<@jfun String hello(String name) {
return "Hello "+name+" !";
}@>
<@dim res as double@>
<@set res=average(2,7)@>

Average between 2 and 7 is <@=res@>
<@call sayGoodbye(out)@>

<@jfun void sayGoodbye(JspWriter writer) throws Exception{
writer.println(
"

Au revoir!

");
}@>
<@/content@>
Hello Mark Twain !
Average between 2 and 7 is 4.5
Au revoir!
Java™ is an Object Programming Language, extensible with standard or custom libraries.
XLEM is a mix result between:
java.io.*
etc...)javax.servlet.*
etc...)com.xXLEM.lews.*
etc...)<@uselibrary@>
tag.
src
" folder of
your current web application (don't forget XLEM XLEWS Application is very similar to
JSP/Servlet application )
<@uselibrary@>
tags in any tag sequence of current
XLEM (in both page
and
content
section) or into a module (.xlmh
).
XLEWS parser will reallocate it on "top" before compile.
src
folder of your web application)
package test.xXLEM.beans;
import java.io.Serializable;
public class TestBean implements Serializable {
private static final long serialVersionUID =
-5351748588779926998L;
public TestBean() {
super();
}
private String firstName;
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String sayHello() {
return "Hello from "+firstName+" "+lastName+"!";
}
}
<@page version="1.0"@>
<@uselibrary java.util.Properties@>
<@dim myProperties as javatype Properties@>
<@call myProperties=new Properties()@>
<@call myProperties.setProperty("first","First Property")@>
<@call myProperties.setProperty("last","Last Property")@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>
<@dim test as javatype TestBean@>
<@set test=new TestBean()@>
<@call test.setFirstName("Paul")@>
<@call test.setLastName("Smith")@>
<@uselibrary test.xXLEM.beans.TestBean@>

<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
<title>Import and Extends Lews</title>

<@=test.sayHello()@>

My properties are:

First:
<@=myProperties.getProperty("first")@>

Last:
<@=myProperties.getProperty("last")@>

<@/content@>
Hello from Paul Smith!
My properties are:
- First: First Property
- Last: Last Property
XLEWS creates only an instance for each XLEM inside Application Server Container.
Usually any .xlem
page runs multiple times (multithreaded) the same
method for each connected user.
You can define "global variables" to share data between instances (such as
application
way, previously discussed).
This is the syntax (very similar to @dim
statement):
<@global
varname as [javatype] vartype
@>
javatype
will be automatically instantiated.
<@global@>
tags in any tag sequence of current
XLEM (in both page
and
content
section) or into a module (.xlmh
).
XLEWS parser will reallocate it outside "run" method, into a "global zone" before compile.
@set
tag used for
local variables.
<@page version="1.0"@>
<@global lastVisit as date@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
<title>XLEWS Global Variables</title>

<@dim now as date@>
This page has been visited <@=++counter@> times!

Now is <@=now.format("yyyy-mm-dd hh:mn:ss")@>,

last visit <@=lastVisit.format("yyyy-mm-dd hh:mn:ss")@>
<@set lastVisit=now@>

<@global counter as integer@>
<@/content@>
.xlmh
),
usually inside $APPLICATION_ROOT/dep/globals.xlmh
..xlem
page that would share these values and functions
simply have to include with @external
tag this module.
/dep/globals.xlmh
module
<@// Define variables here...@>
<@dim maxResults as integer@>
<@set maxResults = 100@>
... other declarations and settings...
<@jfun void connectToDatabase (int results) {
....
}@>
... other functions...
<@// ... end of module@>
/page-name.xlem
page
@page
section (but already into content
)
import module and use variables and funcions...
<@page ... @>
... main declarations
<@external src="dep/globals.xlmh" @>
... other declarations and settings...
<@// implementation example... @>
<@dim results as integer@>
<@set results=querystring.tointeger("res")@>
<@if results>maxResults@>
<@set results=maxResults@>
<@endif@>
<@call connectToDatabase(results)@>
... next code...
Nowadays we cannot limit a web application life cycle inside himself.
Your web application may be connected to a remote site to retrieve
partial html contents such as header of footer section, xml or JSON streams to
build rich Web 2.0 applications and so on.
XLEWS is providing the XLEMHttpClient
component (
com.xXLEM.datatype.XLEMHttpClient
).
Every XLEMHttpClient
call will be performed server side
and not client side!!!
XLEMHttpClient
offers static method to perform http get and post
already using XML streaming.
| Method | Throws | Description |
|---|---|---|
LemasnysHttpClient.get(String url) |
MalformedURLException,
IOException |
Perform a call on specified url assuming "UTF-8" as character econding
and returns html content as string |
XLEMHttpClient.get(String url, String encoding) |
MalformedURLException,
IOException |
Perform a call on specified url assuming encoding as character econding
and returns html content as string |
XLEMHttpClient.get(String url, String encoding, Properties props) |
MalformedURLException,
IOException |
Perform a call on specified url assuming encoding as character econding
and returns html content as string. At request pahse will be added headers contained into
props Properties |
XLEMHttpClient.post(String url, String bodyContent) |
MalformedURLException,
IOException |
Send bodyContent (as sequence of
&field1=value&field2=value... ) to a specified
url and returns html content
remote response as string. |
XLEMHttpClient.post(String url, String bodyContent, Properties props) |
MalformedURLException,
IOException |
Send bodyContent (as sequence of
&field1=value&field2=value... ) to a specified
url and returns html content
remote response as string.
At request pahse will be added headers contained into
props Properties
|
XLEMHttpClient.postXML(String url, String bodyContent) |
MalformedURLException,
IOException |
Send bodyContent (as xml sequence) to a specified
url and returns xml (or html) remote response as string.
|
XLEMHttpClient.postXML(String url, String bodyContent, Properties props) |
MalformedURLException,
IOException |
Send bodyContent (as xml sequence) to a specified
url and returns xml (or html) remote response as string.
At request pahse will be added headers contained into
props Properties
|
spider
that "grabs"
the page title of specified url.
<@page version="1.0"@>
<@dim remoteURL as string@>
<@set remoteURL=querystring.tostring("url")@>
<@dim error as string@>
<@dim START_TAG,END_TAG as string@>
<@set START_TAG="<title>"@>
<@set END_TAG="</title>"@>
<@dim res as string@>
<@if !isblank(remoteURL)@>
<@try@>
<@set res=XLEMHttpClient.get(remoteURL)@>
<@dim indx as integer@>
<@set indx=res.toLowerCase().indexOf(START_TAG)@>
<@if indx<0@>
<@set error="I'm sorrt but... title not present :(( "@>
<@else@>
<@set res=res.substring(indx+START_TAG.length())@>
<@set indx=res.toLowerCase().indexOf(END_TAG)@>
<@if indx<0@>
<@set error="I'm sorry but... title tag is not well formed :(( "@>
<@else@>
<@set res=res.substring(0,indx)@>
<@endif@>
<@endif@>
<@endtry@>
<@catch Exception@>
<@set error=exception.getMessage()@>
<@endcatch@>
<@endif@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8"/>
<title>XLEWS Http Client</title>

Page Title "grab"

<form method="get" action="" name="searchTitle">
Insert URL= <input
type="text" name="url"
value="<@=htmlformat(remoteURL)@>"
size="60"> <input type="submit"
value="Grab title...">
</form>
<@if !isblank(error)@>
ERROR:

<@=error@>

<@else@>
PAGE TITLE at <a href=
"<@=remoteURL@>"><@=remoteURL@> is " <@=res@> "
<@endif@>

<@/content@>
and a response output example
Page Title "grab"
PAGE TITLE at http://www.sourceforge.net
is " SourceForge - Download, Develop and Publish Free Open Source Software "
Nowadays many applications need to interacts with RDBMS database such as MySQL, Postgres,
Oracle, IBM DB2 (...).
In this section we provide a simple overview: you're invited to follow future
technical articles and tutorials and see related class javadoc
!!!
XLEWS provides a component named genericdatabase
(
related to Java™ class com.xXLEM.datatype.XLEMGenericDatabase
)
that interacts with already existing
javax.sql.DataSource
or lets you to create a "pooled" connection using LDBC
connector (we discuss soon...).
XLEWS is already offering two extra components sqlview
and
sqlform
to automatically bind (just in a primitive manner) SQL query results
and create/modify simple table records. Be careful because this last components
are under "hard" development!!!
Consider genericdatabase
such as very simply and quick way to access
to database. In any case you can retrieve a java.sql.Connection
from current
genericdatabase
using the getconnection()
method.
Any database connection is based on Java JDBC techonology, so be sure to
have the proper JDBC driver related to your preferred database!
Once retrieved driver file (.jar), you should place it inside a libraries folder of your
current application ($WEB_APP_ROOT/WEB-INF/lib)
or, if more apps needs to use the
same database type, you can put this file into $CATALINA_HOME/lib
folder!!!
Once defined a genericdatabase
component, you've to "open"
communication with a specific database.
javax.sql.Datasource
instance (previous retrieved)
<@dim your_db as genericdatabase@>
...
<@if your_db.open( datasource )@>
... perform your sql operations...
<@call your_db.close()@> [release connection]
<@else@>
Error opening database: <@=your_db.lasterror()@>
<@endif@>
Please remember that XLEWS is bundled inside Tomcat 7.0.x, so a right and
standard way is to referrer to official guide
Tomcat 7 - JNDI Datasource HOW-TOLDBC
<@dim your_db as genericdatabase@>
...
<@if your_db.open( application.getLDBC ("ldbc_name") )@>
... perform your sql operations...
<@call your_db.close()@> [release connection]
<@else@>
Error opening database: <@=your_db.lasterror()@>
<@endif@>
XLEWS provides a component driver to RDBMS named ldbc
(XLEM DataBase Connector) powered by
com.xXLEM.lews.runtime.XLEMLDBC
Java™ class and defined at
"application" level (ServletContext attribute ...).
LDBC
looks like a DataSource and you must define it inside
an xml file (lews.xml
) inside your WEB-INF
path
$APPLICATION_ROOT/WEB-INF/lews.xml
.
LDBC
settings lews.xml
file:
<?xml version="1.0" encoding="UTF-8"?>
<lews>
...
<ldbcs>
<ldbc>
<name>my_ecommerce</name> [required]
<user>XLEM</user> [rq]
<password>4Eq21xYt</password> [rq]
<driver>org.postgresql.Driver</driver> [rq]
<url>jdbc:postgresql://localhost/myecommercedb</url> [rq]
<autocommit>true</autocommit> [opt: default=true]
<maxconnections>15</maxconnections> [opt: default=30]
<timeout>60</timeout> [in seconds!!!] [opt:def. =120]
</ldbc>
<ldbc>
<name>other_db</name>
...
</ldbc>
</ldbcs>
...
</lews>
genericdatabase
instance,
you can perform SQL queries
(and manage result set) operations or execute
SQL statements
.
t_users
.
This example will perform a SQL query returning login and age of all users sorted by login name.
<@if db.query("select * from t_users order by c_login")@>
<@while db.nextrecord()@>
<@=db.getstring("c_login")@>
with age= <@=db.getinteger("c_age")@>

<@wend@>
<@else@>
QUERY ERROR: <@=db.lasterror()@>
<@endif@>
<@if db.query("select * from t_users order by c_login")@>
RECORDS= <@=db.records()@>
<@call db.beforefirstrecord()@>

<@while db.nextrecord()@>
<@=db.getstring("c_login")@>
with age= <@=db.getinteger("c_age")@>

<@wend@>
<@else@>
QUERY ERROR: <@=db.lasterror()@>
<@endif@>
Database: acme_demo [postgres]
User: test
Password: XLEM
TABLE t_users:
id login age
---------------------------------
1 mgshow 28
2 goofy 32
3 arthur 48
4 mildred 56
$APP_ROOT_PATH/WEB-INF/lews.xml [LDBC section]
<ldbcs>
<ldbc>
<name>demo</name>
<user>test</user>
<password>XLEM</password>
<driver>org.postgresql.Driver</driver>
<url>jdbc:postgresql://localhost/acme_users</url>
<autocommit>true</autocommit>
<maxconnections>5</maxconnections>
<timeout>60</timeout>
</ldbc>
<ldbcs>
genericdatabase.xlem
<@page version="1.0"@>
<@dim db as genericdatabase@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type"
CONTENT="text/html; charset=UTF-8"/>
<title>XLEWS Database Connection with LDBC</title>

<@if db.open(application.getLDBC("demo"))@>

DB RESULTS

<@if db.query("select * from t_users order by c_login")@>
RECORDS : <@=db.records()@>

<@call db.beforefirstrecord()@>
<@while db.nextrecord()@>
<@=db.getstring("c_login")@>
with age =<@=db.getinteger("c_age")@>

<@wend@>
<@else@>
QUERY ERROR: <@=db.lasterror()@>
<@endif@>
<@call db.close()@>

LDBC Status Monitor:

<@=application.getLDBC("demo").
printStatus()@>

<@else@>
ERROR: <@=db.lasterror()@>
<@endif@>

<@/content@>
DB RESULTS
RECORDS : 4
arthur with age =48
goofy with age =32
mgshow with age =28
mildred with age =56
LDBC Status Monitor:
LDBC demo
----------------------
conn |status
----------------------
0 |RLSD
1 |FREE
2 |FREE
3 |FREE
4 |FREE
newName
(as string) and newAge
as integer:
<@if db.execute(
"update t_users set c_login='"+sqlformat(newName)+
"', c_age="+newAge+" where c_id=4") > 0
@>
User successfully updated!
<@else@>
Unable to update user: <@=db.lasterror()@>
<@endif@>
sqlformat
is a function provided in any .xlem
page and lets you to better
manage sql formatting inside any text field.
Prepared Statement
management
using genericdatabase
, but as previously discussed, you can retrieve from
genericdatabase
the "pure" java.sql.Connection
and
fully to implement Java™ sql API !!!
genericdatabase
instance when
you'll terminate all SQL operations. In any case of LDBC, XLEWS will automatically try to
recycle all opened and expired connections.sqlview
component
sqlview
component (related to Java™ class
com.xXLEM.datatype.XLEMSQLView
).
sqlview.xlem
page source code:
<@page version="1.0"@>
<@dim view as sqlview@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type"
CONTENT="text/html; charset=UTF-8"/>
<title>Page title</title>

Simple SQL Table Binding

<@dim db as genericdatabase@>
<@if db.open(application.getLDBC("demo"))@>
<@call view.setconnection(db)@>
<@call view.settable("t_users")@>
<@dim res as string@>

HTML Basic sql binding

<@set res=view.tohtml()@>
<@if isnull(res)@>
SQL binding error: <@=view.geterror()@>
<@else@>
<@=res@>
<@endif@>

XML Basic sql binding

<@set res=view.toxml()@>
<@if isnull(res)@>
SQL binding error: <@=view.geterror()@>
<@else@>
<@=htmlformat(res)@>
<@endif@>

"Single" selection binding

<form name="form1">
<@call view.setselection("single")@>
<@set res=view.tohtml()@>
<@if isnull(res)@>
SQL binding error: <@=view.geterror()@>
<@else@>
<@=res@>
<@endif@>
</form>

"Multi" selection binding (with some additional settings)

<form name="form2">
<@call view.setfilter("c_id>1")@>
<@call view.setorderby("c_age desc,c_login")@>
<@call view.setselection("multi","fldUserCheck")@>
<@call view.setlink("sqlform.xlem?id=$KEY$")@>
<@call view.sethtmlvar("alternate1"," style='background:#fa0'")@>
<@call view.sethtmlvar("alternate2"," style='background:#f80'")@>
<@set res=view.tohtml()@>
<@if isnull(res)@>
SQL binding error: <@=view.geterror()@>
<@else@>
<@=res@>
<@endif@>
</form>
<@call db.close()@>
<@else@>
ERROR: <@=db.lasterror()@>
<@endif@>

<@/content@>
<@// End of XLEM Web Page Code...@>
Simple SQL Table Binding
HTML Basic sql binding
c_id c_login c_age 1 mgshow 28 2 goofy 32 3 arthur 48 4 mildred 56
XML Basic sql binding
<res><cols><c id="c_id" type="int8">c_id</c>
<c id="c_login" type="varchar">c_login</c>
<c id="c_age" type="int8">c_age</c></cols>
<data><r><f>1</f><f>mgshow</f><f>28</f>
</r><r><f>2</f><f>goofy</f><f>32</f>
</r><r><f>3</f><f>arthur</f><f>48</f>
</r><r><f>4</f><f>mildred</f><f>56</f>
</r></data></res>
"Single" selection binding
"Multi" selection binding (with additional settings)
sqlform
sqlform
component (related to Java™ class
com.xXLEM.datatype.XLEMSQLForm
).
sqlform
component you can update, insert or delete records;
XLEWS will automatically recognize and process (in a basic way) form fields.
sqlform.xlem
page source code:
<@page version="1.0"@>
<@dim form as sqlform@>
<@dim db as genericdatabase@>
<@dim okDb as boolean@>
<@dim error as string@>
<@set okDb=db.open(application.getLDBC("demo"))@>
<@if !okDb@>
<@set error=db.lasterror()@>
<@else@>
<@call form.settable("t_users")@>
<@if form.bind(
db.getconnection(),
"c_id="+querystring.tointeger("id"))
@>
<@call form.setForm(
"frmEditUser", // form name
"POST", // form method
"sqlprocess.xlem", // form action
" id='frmEdt' " // extras
)@>
<@call form.setfield("c_id","hidden","true")@>
<@call form.setfield("c_login","label","User Login")@>
<@call form.setfield("c_age","label","User Age")@>
<@else@>
<@set error=form.geterror()@>
<@endif@>
<@call db.close()@>
<@endif@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>
<@//HTML (dynamic) code goes here...@>

<meta HTTP-EQUIV="content-type"
CONTENT="text/html; charset=UTF-8"/>
<title>SQL FORM</title>

<@if !okDb@>
DB ERROR= "<@=error@>"
<@elseif !isblank(error)@>
CANNOT EDIT USER:
 <@=error@>
<@else@>

Editing <@=form.getfield("c_login").getValue()@>

Back to list...

<@=form.tohtml()@>
<@endif@>

<@/content@>
Editing mildred
Back to list...
sqlprocess.xlem
page of sql update form
<@page version="1.0"@>
<@dim form as sqlform@>
<@dim db as genericdatabase@>
<@dim okDb as boolean@>
<@dim error as string@>
<@if db.open(application.getLDBC("demo"))@>
<@// You must declare table [better security]@>
<@call form.settable("t_users")@>
<@// Required for retrieving table structure@>
<@call form.bind(db.getconnection())@>
<@if form.updaterecord(
request.getParameterMap(), // Request Fields
db.getconnection(), // SQL Connection
new String[] {"c_id"} // Keys
) > 0 @>
<@else@>
<@set error="Unable to update record!"+form.geterror()@>
<@endif@>
<@call db.close()@>
<@else@>
<@set error=db.lasterror()@>
<@endif@>
<@// If ok return to list ...@>
<@if isblank(error)@>
<@call response.redirect("sqlview.xlem")@>
<@endif@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>
<@if !isblank(error)@>>

<meta HTTP-EQUIV="content-type"
CONTENT="text/html; charset=UTF-8"/>
<title>SQL PROCESS ERROR</title>

ERROR PROCESSING SQL FORM:

<@=error@>

<@endif@>
<@/content@>
<@// End of XLEM Web Page Code...@>
setfield
allowed parameters:
"readonly" ==> "true" or "false"
"hidden" ==> "true" or "false"
"password" ==> "true" or "false" for display this field such as password...
"flag" ==> "true" or "false" for display this fiels such as checkbok(flag)...
"textarea" ==> "true" or "false" for display this fiels such as text area...
"html" ==> ex: "size='212' style='calendar2' ... "
"label" ==> new Caption/Label name of this field...
"description" ==> new description for this field...
"value" ==> new value for this field...
"validation" ==> validation allowed:
"notnull","number","integer","range[x,y]" ,"range(x,y)",
"regex: regular expression"...
"order" ==> new order for this field in form fields sequence
[value will be converted in int]...
Developers usually have to maintain the same web application using different languages.
To do it, you can use localizer
component
(com.xXLEM.datatype.XLEMLocalizer
).
The localizer
works like
java.util.ResourceBundle
To localize your .xlem
applications you've to:
localizer
$WEB_APP_PATH/src
we have created this Java™ package
locale.example
.
# Resource Bundle Example - Default Language
welcome.title=Hello!
welcome.message=Welcome to the XLEWS World!
change.language=Select your language:
system=Default System Language
current=Current Browser Language
en=English
fr=French
it=Italian
de=German
# Resource Bundle Example - Italiano
# Please note that "en" key is missing, so bundle will get
# the "default" en key ("English")
welcome.title=Ciao!
welcome.message=Benvenuto nel fantastico mondo di XLEWS!
change.language=Cambia lingua:
system=Linguaggio del tuo sistema operativo
current=Lingua del browser
fr=Francese
it=Italiano
de=Tedesco
# Resource Bundle Example - Français
welcome.title=Bonjour!
welcome.message=Bienvenue dans le merveilleux monde du Lews!
welcome.message=Changez language:
current=Language navigateur actuel
system=Language par défaut du système
en=Anglais
fr=Français
it=Italien
de=Allemande
localizer.xlem
):
<@page version="1.0"@>
<@dim loc as localizer@>
<@dim qKey as string@>
<@set qKey=querystring.tostring("key")@>
<@// Try to localize with current browser language...@>
<@if "current".equals(qKey)@>
<@call loc.open("locale.example.welcome",
request.getLocale().toString())@>
<@// Try to localize with current server OS language...@>
<@elseif "system".equals(qKey)@>
<@call loc.open("locale.example.welcome")@>
<@// Try to localize with current retrieved key language...@>
<@else@>
<@call loc.open("locale.example.welcome", qKey)@>
<@endif@>
<@dim languageBar as stringarray@>
<@set languageBar=new String[] {"system","current","en","it","fr","de"}@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type"
CONTENT="text/html; charset=UTF-8"/>
<title>XLEWS Application Localization</title>

<@=loc.getmessage("welcome.title")@>

<@=loc.getmessage("welcome.message")@>

<@=loc.getmessage("change.language")@>

<@forall String key in languageBar@>
<a href="?key=<@=key@>"><@=loc.getmessage(key)@> |
<@endforall@>

<@/content@>
Ciao!
Benvenuto nel fantastico mondo di XLEWS!
Cambia lingua:
Linguaggio del sistema operativo |
Lingua del browser |
English |
Italiano |
Francese |
Tedesco |
XLEWS il fully compatible with HTML 5 and CSS 3 programming.
Developing with HTML 5 is very easy because you've only to declare the proper doc type.
In addition you can mix html 5 tags and related objects (canvas, video, audio) with XLEM
Server Page tags and Javascript to create unlimited dynamic effects and applications.
Please see this example (html5.xlem
)
<@page version="1.0"@>
<@dim canvasWidth,canvasHeight as integer@>
<@set canvasWidth=180@>
<@set canvasHeight=130@>
<@dim baseImage as string@>
<@set baseImage="resources/backdrop.png"@>
<@dim textRotation as string@>
<@set textRotation="2deg"@>
<@// With "option" you can create dynamic option list@>
<@// to aggregate with a selection html field@>
<@dim choices as option@>
<@call choices.add("0","Draw on canvas")@>
<@call choices.add("1","Show Image")@>
<@call choices.add("2","Image multiply")@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>
<!doctype html>

<meta charset="UTF-8" />
<title>XLEWS & HTML 5 - Canvas</title>

XLEWS & HTML 5 - Canvas

Draw Image

<canvas id="canvasImg" width="<@=canvasWidth@>"
height="<@=canvasHeight@>">This text is displayed if
your browser does not support HTML5 Canvas.</canvas>

<select onchange="javascript:drawImg(this.value)">
<@=choices.tohtml("0")@>
</select>

<@/content@>
Mobile device support is today highly recommended more specifically
when you're creating new web applications.
However mobile devices are very different by producer, display, resolution and
so on...
Developers should be supported to recognize the best solution for current device
navigating any (dynamic) web application.
Any XLEM can provide a set of useful functions to recognize most
popular mobile devices:
| Page Function | Description |
|---|---|
is_android(String userAgent) | Return true if an Android device
is currently connected; otherwise false |
is_blackberry(String userAgent) | Return true if a BlackBerry device
is currently connected; otherwise false |
is_ipad(String userAgent) | Return true if a iPad device
is currently connected; otherwise false |
is_iphone(String userAgent) | Return true if a iPhone device
is currently connected; otherwise false |
is_windows_ce(String userAgent) | Return true if a Windows CE device
is currently connected; otherwise false |
is_windows_mobile(String userAgent) | Return true if a Windows Mobile device
is currently connected; otherwise false |
ismobile(String userAgent) | Return true if a "supposed" device
mobile is currently connected; otherwise false |
is_mobile(String userAgent) | The same of ismobile(...) |
userAgent
can be retrieved by these following ways:
request.getuseragent()
request.getheader("user-agent")
request
is provided current http user request.
mobile.xlem
):
<@page version="1.0"@>
<@dim uag as string@>
<@set uag=request.getuseragent()@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type"
CONTENT="text/html; charset=UTF-8"/>
<title>XLEWS Mobile Device Recognition...</title>

<@if is_iphone(uag)@>
You're connected with I-Phone
<@elseif is_blackberry(uag)@>
You're connected with BlackBerry
<@elseif is_ipad(uag)@>
You're connected with I-Pad
<@elseif is_mobile(uag)@>
I suppose you're connected with a mobile device!
<@else@>
I suppose you're not connected with a mobile device!
<@endif@>

<@/content@>
XLEWS is providing two elementar components rssnewsreader
(
com.xXLEM.xml.XLEMRSSNewsReader
)and rssnews
(com.xXLEM.xml.XLEMRSSNews
) wich developers can use to retrieve
RSS feeds.
The rssnewsreader
component links to specified RSS feed: such as discussed about XLEWS XML Streaming, the RSS news can be retrieved from multiple
stream sources (local files, url, string buffers and generic input stream ).
The rssnews
component is used to manage (reading scope)
any available news.
XLEWS converts reader fields and any news field/info as "properties": you've simply
to retrieve preferred info using [component.]getproperty(propertyName)
.
For more info we suggest to consult related XLEWS javadoc and take a look to this example
were we'll try to connect with
CNN RSS world channel (rss.xlem
).
<@page version="1.0"@>
<@dim rss as rssnewsreader@>
<@dim title as string@>
<@dim image as string@>
<@dim error as string@>
<@if !rss.openfromurl("http://rss.cnn.com/rss/edition_world.rss")@>
<@set error=rss.geterror()@>
<@else@>
<@set title=rss.getproperty("title")@>
<@if !isblank(rss.getproperty("image/url"))@>
<@set image=" "@>
<@endif@>
<@endif@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>

<meta HTTP-EQUIV="content-type"
CONTENT="text/html; charset=UTF-8"/>
<title>RSS NEWS</title>

<@if isblank(error)@>

<@=image@> NEWS CHANNEL : <@=title@>

<@=rss.getproperty("description")@>

Last updated: <@=rss.getproperty("pubdate")@>

Available news: <@=rss.news()@>

<@dim i as integer@>
<@dim news as rssnews@>
<@for i = 1 to rss.news()@>
<@set news=rss.getnews(i-1)@>

<@=news.getproperty("pubdate")@>

#<@=i@>: <@=news.getproperty("title")@>

<@=news.getproperty("description")@>

<@endfor@>
<@else@>
ERROR: <@=error@>
<@endif@>

<@/content@>
[ IMG LOGO] NEWS CHANNEL : CNN.com - WORLD
CNN.com delivers up-to-the-minute news and information on
the latest top stories, weather, entertainment, politics and more.
Last updated: Wed, 04 Jan 2012 02:13:41 EST
Available news: 3
Wed, 04 Jan 2012 01:05:58 EST
#1: Taliban ready to talk, spokesman saysThe Afghan Taliban are prepared to open...
Wed, 04 Jan 2012 00:48:28 EST
#2: Maldives' top court to rule on spa ban
The Supreme Court of the Maldives is expected to...
Tue, 03 Jan 2012 09:42:40 EST
#3: Ex-Tunisia leader faces trial over killingsTunisian ex-President Zine el Abidine Ben Ali, who was...
If you take a look back at previous examples when returning some content via http response, we've used:
out.write([some expression])
at Java™ sections...
@content
section.
@content
section !!!
<@switchout@>
tag you can redirect any subsequent output operation
(except out.write
case) to specified buffer (java.lang.StringBuffer
)
until the <@/switchout@>
is called.
@page@
section and retrieve the "shifted" output whenever you needs.
content
and/or encoding
attributes
of @content
section!!!
switchout.xlem
) where we provide
a different output content type depending on provided "enc" querystring parameter:
<@page version="1.0"@>
<@dim encType as string@>
<@set encType=querystring.tostring("enc")@>
<@// Declare and instantiate a "buffer" @>
<@dim bfr as newjavatype StringBuffer@>
<@dim welcomeMsg as string@>
<@set welcomeMsg="Hello now it's "+
new XLEMDate().format("yyyy-mm-dd hh:mn:ss")@>
<@if encType.equals("xml")@>
<@// Enforce response content type @>
<@// outside @content section !!!!!@>
<@call response.setContentType("text/xml")@>
<@switchout bfr@><?xml version="1.0" encoding="UTF-8"?>
<tags>
<tag><@=htmlformat(welcomeMsg)@></tag>
</tags>
<@/switchout@>
<@else@>
<@switchout bfr@>

<title>HTML RESPONSE</title>

<@=welcomeMsg@>

<@/switchout@>
<@endif@>
<@/page@>
<@// Please forget "content" attribute if you like@>
<@// to make DYNAMIC the content response type!!!!@>
<@// You'll can do also with encoding attribute...@>
<@content encoding="UTF-8"@><@=bfr.toString()@><@/content@>
<@// End of XLEM Web Page Code...@>
XLEWS is fully compliant with Servlet API 3.0 so you can run JSP and servlets in addition to
.xlem
pages: you can mix them all using "including" features!!!
XLEWS provides you the pageContext
instance inside
any .xlem
page.
With include(...)
pageContext
method you can
include (at runtime level) an existing .jsp
, servlet
or
another .xlem
inside the same project!!!
A .jsp
or servlet
can do also calling a .xlem
page (...) [ on a XLEWS context :)) !!!!]
JSPs, servlets, ans LEMs can share data at Application, Session and Request
[as attributes] level.
In this example a lem2jsp.xlem
page will include a
target.jsp
page:
lem2jsp.xlem
source code:
<@page version="1.0" session="true" createonfail="true"@>
<@call session.setstring("session.attribute","lem_123456")@>
<@call application.setstring("application.attribute","lem_35545454")@>
<@call request.setstring("request.attribute","lem_rq12345")@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>
<@//HTML (dynamic) code goes here...@>

<meta HTTP-EQUIV="content-type"
CONTENT="text/html; charset=UTF-8"/>
<title>LEM including JSP</title>

Hello from LEM,
now I'm trying to open a .jsp page ....

<@try@>
<@call pageContext.include("target.jsp")@>
<@/try@>
<@catch Exception@>
ERROR: <@=exception.toString()@>
<@/catch@>

<@/content@>
target.jsp
source code:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Hello from .jsp

Application attribute is
<%=application.getAttribute("application.attribute") %>

Session attribute is
<%=session.getAttribute("session.attribute") %>

Request attribute is
<%=request.getAttribute("request.attribute") %>

Hello from LEM, now I'm trying to open a .jsp page ....
Hello from .jsp
- Application attribute is lem_35545454
- Session attribute is lem_123456
- Request attribute is lem_rq12345
jsp2lem.jsp
page will include a
target.xlem
page:
jsp2lem.jsp
source code:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP including LEM</title>

Hello from JSP,
now I'm trying to open a .xlem page ....

<%
session.setAttribute("session.attribute","jsp_123456");
application.setAttribute("application.attribute","jsp_35545454");
request.setAttribute("request.attribute","jsp_rq12345");
%>
<%try {
pageContext.include("target.xlem");
} catch (Exception ex) {%>
ERROR: <%=ex.toString()%>
<%} %>

target.xlem
source code:
<@page version="1.0" session="true" createonfail="true"@>
<@//Nothing to do...@>
<@/page@>
<@content type="text/html" encoding="UTF-8"@>
Hello from .xlem

Application attribute is
<@=application.getstring("application.attribute") @>

Session attribute is
<@=session.getstring("session.attribute") @>

Request attribute is
<@=request.getstring("request.attribute") @>

<@/content@>
Hello from JSP, now I'm trying to open a .xlem page ....
Hello from .xlem
- Application attribute is jsp_35545454
- Session attribute is jsp_123456
- Request attribute is jsp_rq12345
Eclipse (http://www.eclipse.org) is one of must popular
free and open source Java (and J2EE) IDE.
XLEWS provides this following plugin suite:
.xlem
pages editor with syntax highligthing.xlmh
modules editor with syntax highligthing.xlem
pages creation.xlmh
modules creation


|
Inline Help Text
|
This is sample HTML for inline help text that appears embedded in page content. The page corresponds to 11.1 Inline Help. The help text is of two varieties: Page inline help and Field inline help. Page inline help text appears at the top of a section or content area and is intended to provide help on that entire section or page. Field inline help text pertains to and appears directly beneath a particular field or group of closely related fields.
Both types of help text may include hyperlinks inside the text itself and/or at the end of the text. When the links appear at the end of the text, the following image: should be included in the href preceding the link text. The image itself should have
alt="" and the title for the link should specify that a new window is being opened, e.g., "Help on Projects (Opens New Window) ".
Example: [ HTML ]
- None -


Next: Macro Forms as Places, Previous: APPLY Forms as Places, Up: Kinds of Places
Any compound form for which the operator has a
setf expander
defined can be used as a place.
The operator must refer to the global function definition, rather than a locally defined function or macro.


{% extends "base.html" %} {% block title %}Registration Complete | MROCP {% endblock %} {% block content %}
Thanks for registering! We've sent you an email with instructions on how to finalize your account.
If you haven't received the email within an hour or so, please check your spam folder.
If you find nothing, please contact us at<EMAIL_ADDRESS>, indicating the problem.


FISTA - Fast InfoSet Translator and Attacker
This extension converts incoming Fast Infoset requests and responses to XML, and converts outgoing messages back to Fast Infoset. This allows messages to be analyzed within Burp, and use of Burp tools including Repeater, Intruder and Scanner. The client and server are unaware of the translation and function as normal.


Individual String to Type converters, that PicoContainer may use to convert types where required. Of Note:
- Primitive and boxed equivalent converters
- java.io.File and java.net.URL converters
- Your own implementations of Converter
- An aggregate 'Converters' implementation that's built-in to PicoContainer (but extensible)


There are no audio documents on this item to work with.
Transcription length: {{ this.transcription.annotations.length }}
Synched: {{ !this.transcription.isPendingUpload }}
Last edit: {{ this.transcription.lastEdit | date:'mediumTime' }}
Use audio channel:


#include "copyright.h"
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cstdarg>
#include <new>
#include "new_handler_support.h"
#include "log.h"
#include "config.h"
#include "utils.h"
#include "sample.h"
#include "samples_library.h"
#include "sound.h"
#include "midi.h"
#include "reverb.h"
#include "poly.h"
#include "equalizer.h"
Go to the source code of this file.
| #define BUFFER_FRAME_COUNT 256 |
| #define CFG_PARAMS_COUNT 22 |
Number of parameters in the cfg structure below.
Definition at line 21 of file PIano.h.
| #define FRAME_SIZE (2 * sizeof(sample_t)) |
| #define MAX |
( |
|
a, |
|
|
|
b |
|
) |
| (a > b) ? a : b |
| #define MIN |
( |
|
a, |
|
|
|
b |
|
) |
| (a < b) ? a : b |
True if PIano launched in interactive mode (option -i)
Definition at line 94 of file PIano.h.
| PUBLIC volatile bool keepRunning |
True while the application is running.
Definition at line 97 of file PIano.h.
Overall master volume (gain)
Definition at line 93 of file PIano.h.
Maximum number of voices that have been mixed simultaneously.
Definition at line 101 of file PIano.h.
Maximum gain used un mixing voices.
Definition at line 105 of file PIano.h.
Maximum duration of the mixer function during play (nanoseconds)
Definition at line 102 of file PIano.h.
Enable replaying last 5 seconds played.
Definition at line 96 of file PIano.h.
Maximim duration of the reverb process.
Definition at line 104 of file PIano.h.
Minimum duration of the reverb process.
Definition at line 103 of file PIano.h.
Sampling Rate. Will be initialized to 44100. Not supposed to be modified at thispoint in time.
Definition at line 92 of file PIano.h.
If true, no logging message will be displayed.
Definition at line 95 of file PIano.h.


History
Back in the 19th century, suits were designed for all buttons of a suit to be buttoned. However, in the early 1900s, King Edward VII of Great Britain became too large in diameter to comfortably fit in a fully-buttoned suit. Thus, he began to leave the bottom button of his suit jacket and vest unbuttoned. To make the King feel better, his subjects also started to unbutton the bottom buttons of their suits and vests, and this trend eventually spread to the commoners and continues until today.
Ever since the mid-20th century, men’s suits have been designed so that the bottom button serve only as a decorative purpose – meant to be left unbuttoned.
How to Button
A two-button suit from Brooks Brothers. Notice that the bottom button remains undone.
Currently, the two-button-single-breasted jacket is the most popular style for suit jackets and sport coats. On a two-button jacket, the top button is fastened, while the bottom is often left undone.
A classic three-button three-piece suit from Brooks Brothers.
Taller individuals often prefer a three-button jacket, but it requires a more complex rule. The bottom button is never buttoned, the middle one is always buttoned, and the top button is sometimes buttoned. The buttoning of the top button depends on the cut of the suit. To “test” whether your three-button suit demands the buttoning of the top button, fasten the middle button and see whether the top button “closes” on its own. If the suit does, button the top button; if else, button only the middle button
A Brooks Brothers one-button peak-lapel tuxedo.
For one-button jackets, such as dinner jackets, the only button of the jacket should be always buttoned. However, there is no rule for single-breasted suits with more than three buttons. Button these jackets as you see fit.
A modern double-breasted suit, again from Brooks Brothers.
All buttons of a double-breasted suit are traditionally buttoned. However, in recent years, it has become popular to unfasten the bottom row of buttons on a double-breasted suit with more than two rows of buttons. The latter is more suitable for modern double-breasted jackets.
When to Button
British PM David Cameron and US President Barack Obama wear their suits unbuttoned while sitting (AP Photo/Carolyn Kaster)
Appropriate buttons on a single-breasted jacket are fastened when standing and unfastened when sitting. Some who wear bespoke or otherwise well-fitting jackets keep their jackets buttoned while sitting to “show off” its tailoring. Additionally, many choose to button their jackets while on camera, regardless of posture, because a closed jacket often looks better on camera.
By tradition, a double-breasted suit is always fully-buttoned regardless of posture. However, the bottom row of buttons is sometimes unfastened when sitting to relieve stress on the suit’s buttons.
Vests
A Brooks Brothers vest, worn without a jacket.
Vests are similar to suits in buttoning etiquette – the bottom button is always unbuttoned per British tradition. So, technically, European vests could be buttoned fully, but the difference between British and European-cut vests is so little that it is safe to leave all vests’ bottom buttons undone. For more casual occasions, it might also be appropriate to undo the top button of the vest for symmetry.


Configuration type: {{gitSyncInfo.type}}
Configuration name: {{gitSyncInfo.name}}
Git remote URL: {{gitSyncInfo.remote}}
Automatic indexation: None Every {{gitSyncInfo.indexationInterval}} minutes
| Gets the latest commits from the remote repository. No reset done. The repository might have to be cloned first if not already done. | |
| Resets the repository and clones it from scratch. This can take some time, depending on the size of the repository. | |
| Close | Returns to the project page without doing anything. |
| Branch | Commit | Author | Time | Message |
|---|---|---|---|---|
| {{branch.name}} | {{branch.commit.shortId}} |
{{branch.commit.author.name}} | {{branch.commit.commitTime | date:'mediumDate'}} {{branch.commit.commitTime | date:'shortTime'}} | {{branch.commit.shortMessage}} |


We're sorry!
This account is currently unavailable.
Please check the email address on record for this account for a notification from Lunarpages.
If you are the owner of this account, please contact us by email at<EMAIL_ADDRESS>or via Lunarpages Helpdesk at https://support.lunarpages.com.
Thank you for choosing Lunarpages Internet Solutions.
Support:<PHONE_NUMBER>


Config.ru
Difference between run and use
Run - Takes an argument that is an object that responds to call and returns a Rack response. Use - Specifies middleware to use in a stack.
Run - Takes an argument that is an object that responds to call and returns a Rack response. Use - Specifies middleware to use in a stack.
sudo chown -R $USER /usr/local
Bind and fat arrow result in something similar but with different implementations.
fn = -> console.log @
ctx = {foo: 'bar', fn: -> console.log(@)}
pusher.execute('event_name', ctx.fn.bind(ctx))
In most cases, the context of the function (also known as @
) is based on the receiver. In this contrived example, to execute the function on the pusher object, we might pass in the function name and then the callback function. When we call a function to an outside source, we have no idea in what context it might be executed. In our case, ctx.fn
and @fn
might be the exact same – these are just references to how to call the function, but an important takeaway is that these do not pass determine the context. To ensure the context, one must specify it with the bind function. pusher.execute('event_name', ctx.fn.bind(ctx))
is essentially equal to pusher.execute('event_name', @fn.bind(ctx))
. The receiver in this case doesn’t matter.
JS OOP isn’t a joy ride. Oh well.
This is a neat little validation plugin that passes back error objects.
onBeforeRender
but it wouldn’t execute until it was changed to onRender
.universal.js
so had to use the ga('create', 'UA-XXXX-Y', 'auto');
syntaxA Promise is an object that represents a one-time event, typically the outcome of an async task like an AJAX call.
MyApp.vent.on("foo", function(){ alert("bar"); });
triggered by MyApp.vent.trigger("foo");
App.vent.trigger('user_loaded', true)
or App.vent.trigger('user_loaded', false)
that means that the listener can adjust accordingly (i.e. App.vent.once('user_loaded', (user_loaded) -> $('.change-scene').show() if user_loaded ))
store.enabled
wasn’t true
for ie7. It came down to the fact that ie7 didn’t have JSON.Thought this was a cool little way to store whether a td square had been clicked on…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
racksh
for a rack console. Pretty dandy.DATABASE_URL
env instead of database.yml to configure the postgres DB.rake secret
will generate the new token via.config.assets.precompile += ['print_wishlist.css']
so that it is precompiled separately. Though it was written in sass it needed the print_wishlist.css.sass extensions as sass isn’t recognized in the app.rb as it expect the file after compilation rather than before via.


{% extends "template.html" %} {% block content %}
If you are new user, please click here for sign up.


Hudson understands Checkstyle analysis report XML format. When this option is configured Hudson shows the Checkstyle analysis results in different views: historical result trend, module and package statistics, web UI for viewing analysis reports and warnings, and so on.
You need to set up your build to run Checkstyle in order to use this feature - this Hudson plug-in does not perform the actual analysis! This plug-in is not invoked for failed builds, it is only called for stable or unstable builds (i.e., a build with failed tests).


There isn't one thing that makes a single Pokémon the best attacker in the game. As with all of the elements of the card game, it is about balance and trade-offs. This guide will walk you through how to make decisions about selecting your primary and backup attackers when building a deck. This will also highlight some of the popular attackers in the current Standard format.
There are a couple important tiers of damage for common Pokémon HP. When considering attack damage it's important to keep these in mind as far as how many attacks will it take to reach these tiers:
From these numbers you can see that an attack which does 90 damage can only one-hit KO (OHKO) lower HP non-EX Pokémon but can two hit both high HP non-EX and many EX Pokémon. On the other hand an attack which does 80 damage will miss out on the two hit KO for some basic EX/GX Pokémon. Attaching a {{ 'B01B3LF0WW'|affiliate_link('Fighting Fury Belt', page='detail') }} can help with the math by adding an extra 10 damage to each attack. For hitting the high HP Pokémon EX and GX, you can use {{ 'B071NLXY2C'|affiliate_link('Choice Band', page='detail') }} to do an extra 30 damage with your attacks. This can be used by non-basic Pokémon unlike Fighting Fury Belt but doesn't get additional damage when attacking non EX/GX Pokémon. Specifically the supporters {{ 'B01MSEWOUZ'|affiliate_link('Professor Kukui', page='detail') }} or {{ 'B016VKBYXE'|affiliate_link('Giovanni\'s Scheme', page='detail') }} can help by adding an additional 20 damage, remembering that you can only play a single supporter per turn.
{% set examples = [ ('B01B3LF0WW', 'Fury Belt'), ('B071NLXY2C', 'Choice Band'), ('B01MSEWOUZ', 'Kukui'), ('B016VKBYXE', 'Giovanni'), ] %} {{ display_examples(examples) }}Attacks which can ramp up their damage based on the amount of energy being used, the number or type of benched Pokémon, or the amount of damage on the Pokémon in play. Some great examples of these are {% set examples = [ ('B016VKC294', 'Mega Mewtwo-EX (BREAKhrough)'), ('B00S5LLYK6', 'Mega Gardevoir-EX (Primal Clash)'), ('B01IUAJX0O', 'Mega Gardevoir-EX (Steam Siege)'), ('B00WTGLVFQ', 'Mega Rayquaza-EX (Roaring Skies)'), ('B00IDLSI7K', 'Yveltal-EX (XY)'), ('B01B3LDPTC', 'Darkrai-EX (BREAKPoint)'), ('B016VKAT2Q', 'Xerneas (BREAKhrough)'), ('B071RS1N74', 'Garbodor (Guardians Rising)'), ('B01NAXAIYK', 'Tarous GX (Sun & Moon)'), ('B0128VBP2U', 'Gyarados (Ancient Origins)'), ('B0128V9RCK', 'Vespiquen (Ancient Origins)'), ] %} {{ list_examples(examples) }}.
{{ display_examples(examples) }}You can only attach a single energy per turn so the lower the attack cost the better. Attacks requiring more than two attachments will certainly require playing some form of energy acceleration. Attacks which require two colorless energy, either alone or with another single energy, can take advantage of {{ 'B01M34NW7C'|affiliate_link('Double Colorless Energy', page='detail') }} to reduce the number of turns required to attack. That isn't too say that attacks that cost three or more attachments are completely unusable. Many players have found success playing with {{ 'B01IUAJLEC'|affiliate_link('Volcanion-EX (Steam Siege)', page='detail') }} which has a three energy attack.
{{ display_examples([('B01IUAJLEC', 'Volcanion-EX (Steam Siege)'), ]) }}Lower energy attacks also allow for using powerful healing cards like {{ 'B01B3LF932'|affiliate_link('Max Potion', page='detail') }} which will discard your energy. {{ 'B01B3LF4SC'|affiliate_link('Greninja (BREAKPoint)', page='detail') }} uses this strategy because the attack also allows for bringing the energy back into the hand meaning you can heal without discarding anything.
{{ display_examples([('B01B3LF4SC', 'Greninja (BREAKPoint)'), ('B01B3LF6JO', 'Greninja BREAK (BREAKPoint)'), ]) }}Most lower stage, non-EX Pokémon have less than 100 HP and can be easily knocked out. Also as with the energy cost, each evolution stage requires another turn before you can get your main attacks going. Mega evolutions also will end your turn unless you have a spirit link attached, which is another card that you'll need in your deck and have to find quickly. At the same time, these evolved Pokémon tend to be very strong.
{% set examples = [ ('B06VSRYKJK', 'Rare Candy'), ('B01BZE9SDE', 'Evosoda'), ('B06X8WWHCQ', 'Timer Ball (Sun & Moon)'), ('B00WTGKYS6', 'Wally (Roaring Skies)'), ] %}There are a few cards which can help support using evolved Pokémon such as {{ list_examples(examples) }}.
{{ display_examples(examples) }} {% set examples = [ ('B0128V9RCK', 'Vespiquen (Ancient Origins)'), ('B016VKA4FI', 'Zoroark (BREAKthrough)'), ('B01B3LFL76', 'Zebstrika (BREAKPoint)'), ('B01BZE9GDQ', 'Raichu (Generations)'), ] %}For budget deck builders, a number of decks have been built around stage one attackers like {{ list_examples(examples) }}. Since they aren't ultra rare cards they are cheap and easy to find. In the game since they only give up one prize and only require a single double colorless energy to attach, they are easy to get setup. While they don't all hit for a lot of damage, they can win games if you can keep recycling attackers and energy.
{{ display_examples(examples) }}Basic Pokémon on the other hand can make use of cards like {{ 'B01B3LF0WW'|affiliate_link('Fighting Fury Belt (BREAKPoint)', page='detail') }} to increase their HP and attack. Also they can use {{ 'B01B3LF6TE'|affiliate_link('Max Elixir (BREAKPoint)', page='detail') }} to get energy attached quickly.
Retreat cost isn't necessarily a huge consideration when picking an attacker for your deck but having a free retreat can be a big advantage since it can allow you to switch out attackers to protect Pokémon which have damage counters on them. When playing attackers with high retreat cost you need to be careful when they are put on the bench since your opponent could draw them up to the active and stall you while you have to attach energy to attack. Decks with higher retreat cost Pokémon need to play more switching cards to avoid this problem which leaves less space for other cards.
Obviously more HP is better when it comes to Pokémon. Looking back at those damage numbers, if you are using a Pokémon which is just outside those normal ranges then it can make it more difficult for your opponent to OHKO your attackers. Higher HP EX Pokémon like {{ 'B01EU44NFO'|affiliate_link('Zygarde-EX (Fates Collide)', page='detail') }} with 190 HP or the extreme {{ 'B00S5LMC8O'|affiliate_link('Wailord-EX (Primal Clash)', page='detail') }} with 250 HP are a couple examples outside the normal 170-180 HP range for EX. The recent stage two {{ 'B06W9F63JH'|affiliate_link('Decidueye-GX (Sun & Moon)', page='detail') }} and {{ 'B06VSQSKSQ'|affiliate_link('Solgaleo-GX (Sun & Moon)', page='detail') }} with 250 HP are also outside the HP normally seen even on Mega EX cards.
{% set examples = [ ('B01EU44NFO', 'Zygarde-EX (Fates Collide)'), ('B00S5LMC8O', 'Wailord-EX (Primal Clash)'), ('B06W9F63JH', 'Decidueye-GX (Sun & Moon)'), ('B06VSQSKSQ', 'Solgaleo-GX (Sun & Moon)'), ] %} {{ display_examples(examples) }}Weakness doubles the amount of damage taken which easily turns attacks into OHKOs. Picking an attacker which hits for weakness on popular Pokémon can make some match ups very easy. On the other hand, when trying to decide about using a new Pokémon it's worth considering which popular Pokémon will hit it for weakness. With the popularity of dark decks like Darkrai-EX and Yvental-EX that is not an ideal weakness to have but it's great for cards like Mega Gardevoir-EX which have resistence. {{ 'B01B3LDU0Q'|affiliate_link('Mega Scizor-EX (BREAKPoint)', page='detail') }} and {{ 'B0128VE1I0'|affiliate_link('Mega Sceptile-EX (Ancient Origins)', page='detail') }} are strong Pokémon with efficient attacks but have declined in popularity with the rise of {{ 'B01IUAJLEC'|affiliate_link('Volcanion-EX (Steam Siege)', page='detail') }} which hits them both for weakness.
The popularity of certain Pokémon or certain types of Pokémon ebbs and flows with players trying to counter popular decks and with the release of new sets. Weakness may or may might be a deciding factor on the deck you want to play but it's something that you'll need to think about and account for when you play.
There is a lot to take into consideration when picking an attacking Pokémon for your deck. There is no high HP, single prize basic Pokémon with attacks for 100+ damage for a single energy and has free retreat. You should pick something that matches your play style whether that's setting up consistent two hit KOs or swinging for big OHKOs. Picking your attacker will inform the rest of the cards that you'll need in your deck for setting up its attack and continuing throughout the game.


Shower Power
Based on redflag's and Leif's recommendations, last night I picked up an Oxygenics Shower Head for $20 at Home Depot. It's a lo-flo shower head which aerates the water in a jet-like fashion. It kind feels like you're being hit by round drops instead of a stream, or you're standing in a stream of bubbles. Nicer than most lo-flos I've tried (mostly hostels).
Anywho, I'm excited to save the bunnies (not the killer ones, but the rest, y'know?) and save money on the electricity bill. What's really funny is I'm not sure if it is the 'aerated' action or maybe if I couldn't tell that the water was REALLY hot (which I kinda realized at first) but anyways, I was LOBSTER red after the first shower. The second shower resulted in non-strangeness.
I also installed an electronic thermostat - but I'm not convinced thats not going to cost more money. Heating the space in my apartment is a very weird thing - partially because of the high ceilings and the smoker who opens the windows and so on - so I think we used to always leave the heat off... And now it turns itself on! I'll have to keep turning it down until its unbearable.
About this entry
You"re currently reading "Shower Power," an entry on a crick in the net
- Published:
- 03.01.05 / 1pm
- Category:
- Circular File, Enviroh-oh-Oh!
Nice, I think I remember some of those showerheads while traipsing across Europe. They tend to dribble out little spurts of tepid water as you carefully sidestep the vomit and try not to touch the body shavings from the hirsute Portugese punter who just got out of the shower before you...
Dude! You're alive!
I'm not portugese!?
Alive and well.
I was talking about other people at the hostels. There was always some nasty Portugest guy who left a hair ring in the drain of those places. Shoot me an email. Credit running down at internet cafe. Peace. J


The help topic you are trying to view is located in the {0} module, which is not currently installed. This module might be available as a plugin. To check, choose Tools > Plugins.