Javascript is a loosely typed language. That means a variable x may now hold a number, two lines down a string and another ten lines down an HTML element. What might be confusing is that Javascript often converts types automatically. The rules behind automatic type convertion sometimes are – well, surprisingly abnormal. Did you know that
"0" == false
evaluates to true and why?
Programmers from other languages such as Java often find dynamic typing challenging, and therefore try to twist Javascript to help avoid typing problems like that:
function isString(obj) { return typeof(obj) == 'string'; }
function isNumber(obj) { return typeof(obj) == 'number'; }
function isBoolean(obj) { return typeof(obj) == 'boolean'; }
function isFunction(obj) { return typeof(obj) == 'function'; }
function isObject(obj) { return typeof(obj) == 'object' || isFunction(obj); }
function isArray(obj) { return isObject(obj) && obj instanceof Array; }
function isDate(obj) { return isObject(obj) && obj instanceof Date; }
function isError(obj) { return isObject(obj) && obj instanceof Error; }
function isUndefined(obj) { return typeof(obj) == 'undefined'; }
function isNull(obj) { return obj === null; }
function isNone(obj) { return isUndefined(obj) || isNull(obj); }
function isSet(obj) { return !isNone(obj); }
function isTrue(obj) { return isSet(obj) && !!obj; }
function isFalse(obj) { return isSet(obj) && !obj; }
That’s a real life example. I think it’s a pity. Though it might help in the first hand, it hinders the developer to truely master the language and the benefits that come with dynamic typing.
There are four important aspects involved with dynamic typing, which I will cover in a series of articles.
The first (the one you are reading) includes the basics: What types does Javascript have and what are the general rules of type convertion.
The second is about automatic type convertion. When and how does automatic type convertion occur?
Sometimes you need to explicitly convert a type to another. The third part will cover the most suitable ways to do so.
Finally we consider ways of type detection. For some types that’s easy, for others it spells disaster.
Types in Javascript – The basics
There are five primitive types in Javascript and there are objects. The primitive types are undefined, null, boolean, number, and string. Objects include (but are not limited to) Array, Function, and Date.
The type undefined has exactly one value: undefined. It is used when a variable has not been assigned a value.
var a; // typeof a is "undefined"
The type null has exactly one value as well: null. It is mostly used to represent a non-existent reference.
var b = document.getElementById("thisIdIsNotWithinTheDocument");
// b is null
We slowly increase the number of values. The type boolean has to values: true and false.
var c = true; var d = !c; // false
Now there is a huge step in values. There are 18437736874454810627 possible values for the number type. Numbers in Javascript are represented by double-precision 64-bits according to IEEE 754.
Take a moment and think about it. You know what I mean? There are no integers in javascript! Though integers between -231 and 231 – 1 are represented exactly in Javascript they still are floating point numbers, not integers.
In addition, there are three special values: NaN, which stands for “not a number” (though still it is a number), positive Infinity and negative Infinity.
var e = 42; var f = e / 0; // f now is Infinity
As a footnote I want to add that there are two zeros in Javascript. You rarely will encounter a situation where that matters. I have yet to make that experience.
A string in Javascript is a primitive in contrast to e.g. Java. Thus you compare two strings by the equality operator ===, you do not need an equals function. Every character is represented by a 16-bit unsigned integer value, therefore unicode characters with codepoint 65536 and above cannot be used in Javascript.
var g = "hello world";
Everything else is an object. For type convertion it does not matter which kind of an object you have. Mostly. I will cover the details in the coming sections.
Conversion
Some statements in javascript and many operators expect values of a specific type. The if statement for example expects a boolean and if you call it with any other type it has to be converted.
Conversion to boolean
Convertion to boolean is quite easy. Null and undefined are converted to false, any object is converted to true. Numbers are converted to true except for 0 and NaN which are converted to false. The empty string is converted to false, any other to true.
| value | to string | comment |
|---|---|---|
| undefined | "undefined" | |
| null | "null" | |
| true | "true" | |
| false | "false" | |
| NaNl | "NaN" | |
| 0 | "0" | |
| 1 | "1" | |
| Object | result of the object's toString method |
Summary
That covers the basics of types in Javascript and the general rules on conversion.
I know I have been quite inprecise when dealing with objects. The standard talks about methods called [[DefaultValue]] having an optional hint, of [[ToPrimitive]] and something called [[ToInt32]] and [[ToUint32]] and so on. I thought this too technical for the average advanced developper, so I skipped the details.
For further reading I recommend either chapter 8 and 9 of ECMA-262 (if you don't mind technical stuff) or chapter 3 of David Flanagan's JavaScript - The Definitive Guide, 5th Edition.
Free IP to Geo Location script
We offer a simple IP geolocation javascript for free!
After including you will able to access to the geo position (lat/long) of your visitor, get his hometown and country. The only precondition is to include a link to http://unitedcoderscom.appspot.com/.
If you want to include it on high traffic sites it could make problems because there are limits with the used webservices. We have build some caching strategies so it wont cause in the most cases. If you want to do more requests read limits in the article of making a ip2location mashup and deploy your instance directly.
Play with it and use some free Proxyserver to change your own IP!
How to include?
<script type="text/javascript" src="http://pyunitedcoders.appspot.com/geo_data.js?key=#google_key#"></script> <script type="text/javascript"> document.write(com.unitedCoders.geo.generate_map(500, 400)); </script>
The google key parameter is optional. You need it if you want to use the google ip location api and/or the static google map to show all found locations. After printing the generate_map function it will the following map and the found location displayed.
You are near these cities:
We using more then one IP2geo API for an fault-tolerant script and more detailed position. Intern we call ipinfodb and hostip and after including our geo location javascript there will added more javascripts (for more locations):
- maxwind.com
- the google ajax api – if the key parameter is set
- WIPmedia.com
Our javascript “ip-geolocation and data aggregator” include all these scripts – the initial loading could take a while. A second request (after reload or from a second page) of the same visitor will be cached. After all a global object with all data will generated based on the calling ip. In the javascript context all data are available and/or you can use the javascript html generator function to generate simple html code.
The com.unitedCoders.geo object
com.unitedCoders.geo = {
ll : [ { country: 'Germany', city: 'Esslingen', long: 9.3, lat:48.75, name:'iplocationtools'},
{ country: 'Germany', city: 'Waldenbuch', long: 9.1333, lat:48.6333, name:'maxwind'},
{ country: 'GERMANY (DE)', city: 'Karlsruhe', long: 8.4, lat: 49.05, name: 'hostip' }],
getLat: function(), // this is computed with the ll-coordinates
getLong: function(), // this is computed with the ll-coordinates
generate_map: function(width, height),
}
the generated html-code
First you have to add to your page using our geo location script some css-styles if you want to design the following pure html lines. For simple usage there exists the id “local_map”.
<div id="local_map"> <img src="http://maps.google.com/staticmap?size=320x240&key=your_google_key&markers=48.75,9.3,midblue1%7C49.05,8.4,midgreen2%7C48.6333,9.1333,midred3%7C48.8111,8.94444,black"/> <ol> <li>iplocationtools: Esslingen, Germany</li> <li>hostip: Karlsruhe, GERMANY (DE)</li> <li>maxmind: Waldenbuch, Germany</li> </ol> </div>
The google map example use the google static map api so there is only one large url with the geo location parameters and the text lines below with the geo location service provider data. Feel free to use the javascript data directly or build better html widgets. But dont forget to include a link to unitedcoderscom.appspot.com for free usage!
Java persistence with Hibernate and Annotations
Hibernate is a well known object-relational mapping library (ORM) for Java. It allows you to map entries in your relational database to objects in your Java classes.
Usually this is done by a mapping file written in XML. As this approach is a bit more expensive we will use annotations to map a class to the relating database table.
Based on the Maven tutorial by my colleague Phillip, we will begin with a quickstart archetype and include Hibernate and a MySQL connection. Then we will write a simple data access object (DAO) which maps to the database table we will create. After that we use a class to set up the connection and fill the database with some of our objects.
Note: This is just a superficial glance at Hibernate to get in touch with the framework.
Setting up the project
After generating the quickstart archetype we will extend the pom.xml. Add the following dependencies:
<!-- hibernate with annotations for persistence -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.3.2.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.3.1.GA</version>
</dependency>
<!-- connector to mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
The first two extensions add hibernate support and annotation support. The third one provides the the connection to MySQL.
The Database Parts
Now we will create a simple database table to store our data and add a corresponding class. Let’s pretend we want to store interesting coordinates. We just use a description, the longitude and latitude. Additionally we use an id as our primary key which will autoincrement.
CREATE TABLE `hibernateexample`.`coordinatestorage` ( `id` INT NOT NULL AUTO_INCREMENT, `description` VARCHAR(100) NOT NULL, `longitude` FLOAT NOT NULL, `latitude` FLOAT NOT NULL, PRIMARY KEY (`id`) )
The Java class looks according, using annotations for the mapping.
package com.unitedcoders.dao;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "coordinatestorage")
public class CoordinateStorage {
@Id
@GeneratedValue
Integer id;
@Column
String description;
@Column
Float longitude;
@Column
Float latitude;
// ... following Getter and Setter, cut out for brevity
That’s about all we need to store the data but we’re still lacking the connection to the database. Create a hibernate.properties file in you classpath and fill it with the appropriate values.
hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.connection.driver_class=com.mysql.jdbc.Driver hibernate.connection.url=jdbc:mysql://localhost/hibernateexample hibernate.connection.username=root hibernate.connection.password=root
The Application
To test the persistence classes we will set up a simple Java class, get a session, create some objects and save them into the database.
package com.unitedcoders;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.classic.Session;
import com.unitedcoders.dao.CoordinateStorage;
public class FillDatabase {
public static void main(String[] args) {
AnnotationConfiguration configuration = new AnnotationConfiguration();
configuration.addAnnotatedClass(CoordinateStorage.class);
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
for (Float i = 0.0F; i < 10.0F; i++) {
CoordinateStorage coStorage = new CoordinateStorage();
coStorage.setDescription("Location " + i);
coStorage.setLatitude((i * i * 12) % 360);
coStorage.setLongitude((i * i * 55) % 360);
session.save(coStorage);
}
session.close();
sessionFactory.close();
}
}
Final Words
As you can see it's fairly simple to get Hibernate integration in your project. We just looked a very minimal feature set here and integrated Hibernate manually. For a real application you would configure the project differently.
For more information refer to the Hibernate documentation and especially to the available annotations.
In-depth guide to javascript functions
You already know how to define or assign functions directly, use multi parameter arguments in anonymous calls and know all the different variants of the function-constructor? Then you won’t find anything new about the subtle differences in using functions in JavaScript.
The work title of this article was “Different ways to define JavaScript functions”. Some code examples look quite similar but the differences can be important. While I am explaining the different ways to define JavaScript functions, you can test the code directly: install the firebug plugin and use the JavaScript console to play interactively below the article.
Function Statement
In the first example here I define a function to wrap the “window.alert”-function to open the default javascript popup-Message box:
function hello(msg) {
alert(msg);
}
It defines a function object in the relative namespace, named hello with one parameter msg. If you define it directly in a script-part of an html-document the function name is available in the global namespace of the document.
function fib(n) {
return (n<2)?n:fib(n-1)+fib(n-2);
}
Here you can see a example with recursion - the classic Fibonacci function. While using the function statement you can use the function name in the function directly because the function name is defined before the function is interpreted. Dont try start the function with more than 50 - its very expensive.
function two(n) {
return one(n) * 2;
}
document.write(two(4));
function one(n) {
return n;
}
A special case is to call a function before (JavaScript is based on an interpreter, not a compiler) it's defined: function two calls function one. The JavaScript parser works bottom up but all names of functions statements are known at start. The example can not used with function literals - it will produce an "one is not defined"-Error.
Function constructor
Functions in JavaScript can be used as variables and passed as arguments to other functions: they are objects like String or Object. They can also be created by using the Function constructor.
var product = new Function("a", "b", "return x*y;");
The last string argument is the function body with the JavaScript code, all arguments before it define the argument names. This variant can be used to generate new function with generated JavaScript code.
But the function body has to be parsed on every run, so performance is rather bad and the function is almost impossible to be precompiled. But be careful:
var msg = "global";
function test() {
var msg = "local";
var intern = new Function("return msg;");
return intern();
}
test(); // -> "global"
The local function intern runs in global scope and returns "global" instead of "local" like expected!
Function literals
var hello = function(msg) {
alert(msg);
}
The difference to the first function statement example is that the anonymous function can be assigned directly to the variable hello (typeof(hello)=="function"). With a function literal you can assign function into a defined namespace instead the relative scope like the function statement. The problem namespacing in JavaScript is an other interesting thing you can find by fotiweb.com or phpied.com more. In JavaScript you use simple objects with the default syntax "{}" to define namespace holder. This is the first step to write clean JavaScript without having namespace problems if an other JavaScript lib defines the same global variable (There exists more than one popular lib with defining the variable "$" global).
var com = com||{};
com.unitedCoders = com.unitedCoders||{};
com.unitedCoders.hello = function(msg) { alert(msg); };
//Using this function with name-space:
com.unitedCoders.hello("Calling with name-space!");
But back to the function literal and how we can write the example "fib" - the above example show that this wont work.
var fib = function(n) { return (n<2)?n:fib(n-1) + fib(n-2); }
var fib2 = fib;
fib = undefined;
You can assign a function value to another variable or overwrite variables (for example with undefined). In the example the first line will be correct, but after deleting fib the inner part in the function fib2 will produce a "TypeError: fib is not a function". The first, but rarely seen solution is the usage of the local function name.
var fib = function myfib(n) { return (n<2)?n:myfib(n-1) + myfib(n-2); }
The function name myfib is only available in the function - say the local scope. You can assign the variable fib to any other name the local name myfib will always available. If you assign the function to a variable myfib the local scope will exist.
The other solution is using the callee - object who is available with the special identifier arguments (a list of all arguments) when calling the function. There is also no need to define the parameter names in the function header.
var sum = function() {
var sum = 0;
for (var i=0; i<arguments.length; i++) {
sum += arguments[i];
}
return sum;
};
The identifier arguments offer the callee-property and it's a reference to the local function itself. With this reference there is the clean solution for recursion without a local function name:
var fib = function(n) {
return (n<2)?n:arguments.callee(n-1)+arguments.callee(n-2);
};
See on the next page what anonymous functions are and more examples for eval.
Anonymous functions
Sometimes you need a simple function without the need of assigning it to a name. This is called a anonymous function and I will give some examples of the usage.
var nums = [1, 4, 3, 2, 6, 2, 0];
nums.sort( function(a,b){ return a-b; } );
To sort a list of integers the sort-method expects a function as a parameter. This function can be defined directly within the parameter section of the sort-method by using the function literal.
var calculator = {
'add': function(a, b) { return a + b}, 'sub': function(a, b) { return a - b},
'mul': function(a, b) { return a * b}, 'div': function(a, b) { return a / b}
};
calculator.sub(3, 3); // 0
calculator.add(3, 3); // 6
calculator.mul(3, 3); // 9
In this example I created directly an object with some function properties. It looks like a simple calculator, the feature is to assign functions directly to object properties.
(function (){
var max = 20;
function square(a) { return a*a; };
for (var i=0; i<max; i++) {
document.write("The square of "+i+" is "+square(i)+"<br/>");
}
})();
If you offer scriptlets to include a function directly in other peoples html-code it would be great to define no new variables in the global namespace. A common solution is to put your code in a anonymous function, work with local variables and execute this function directly. Remember: the return value of a function definition is the function himself, and the parentheses after a function will execute it: syntax is (function(){;})() .
function sequence() {
return arguments.callee.internal++;
}
sequence.internal = 0;
sequence(); // -> 0
sequence(); // -> 1
sequence(); // -> 2
sequence(); // -> 3
How to build a simple singleton - a function who produce a sequence. We don't need to define a new prototype or a global variable. First we define a function. Because its a Object we can set a property named internal and assign it with 0. When calling the function with the callee-reference we can access to the property internal (Yes, its not internal - it is public accessible for everyone).
eval is evil
eval("function square(n){return n*n;}")
eval is a global function! It evaluate the JavaScript given as the first parameter string and return the last statement (if more included). Don't use the second parameter (JS 1.5 Definition) or try to use the eval property of window or this (Rakesh Blogpost)!
Now eval works like expected:
var test = function(){return eval("var i1 = 5; i2 = 7;");};
var i1 = 1;
var i2 = 2;
var i3 = test();
var i4 = eval(test());
First the function test will filled with to assignments in the function body and returning the result of eval. After executing i1 is not changed, because in test there is a new local i1 defined. After this the global variable i2 is overwritten with 7. And the result of test() is 7. The end test returns only the result of test because if eval don't get a string as argument it does nothing and returning the argument[0] !
Use eval only if you really need it. For example don't use it for accessing object properties like this:
ob = {"a1": "yeah", "a2": "other", "a3": "more");
//Accessing via eval
for (i=1;i<4;i++) { document.write(i + " = " + eval("ob.a"+i)); }
//Accessing via [name]
for (i=1;i<4; i++) { document.write(i + ": " + ob["a"+i]); }
conclusion
After reading this very detailed article about the different possibilities in which a JavaScript function can be defined, hopefully you won't ever again stumble upon a specimen without recognizing it as such.
Running a Java Wicket Application in the Google App Engine
The Google App Engine (GAE) is a wonderful playground for your apps, especially when you have no server at hand. It gives you everything you need for free, up to a certain limit. As I happened to be a Java developer it became really interesting when the GAE started supporting Java. You have to register for a GAE account and then apply for Java to be activated. There is a small waiting time but there still seem to be open slots.
As I’m working with Apache Wicket at the moment I thought it would be a nice idea to give you everything you need to get started with development with the GAE and Wicket as your frontend. So in the following lines we will set up a minimal Java / Wicket application and deploy it into the GAE.
Download and install the Google App Engine Java
You’ll find everything you need to know on Google’s page: http://code.google.com/appengine/
Make sure to select the Java SDK and not the Python one. While downloading you can register and get a GAE account. After you are locked in apply for the Java environment. The developer kit brings along an application server, so that you can test your application locally. It might take some time till you get the confirmation link which will be telling that you’re free to use Java. Until then you have to limit your experiments to your local machine.
Creating the Wicket Project with Maven
As build tool we will be using Maven, so if you’re new to that you might want to read the Maven tutorial of my colleague Phillip. It gives a good introduction of maven and how it will aid you in software development.
For the impatient, here’s the quickstart, as found on the Wicket homepage:
mvn archetype:create -DarchetypeGroupId=org.apache.wicket \ -DarchetypeArtifactId=wicket-archetype-quickstart \ -DarchetypeVersion=1.4-rc2 \ -DgroupId=com.united-coders -DartifactId=gae-minimal
I’ll be using the second release candidate of Wicket 1.4. Running the command will leave you with the project structure we’ll be working with. You can run and deploy this in you local servlet containter, but to deploy it into the GAE we need to make some changes.
Google App Engine specific changes
As mentioned on Alastair Maw’s blog, we need to make a few changes to the project so that it will be running, once deployed. This is due to the special environment (the sandbox) the application will be running in. For our example we have to change the application so that it does not spawn any extra threads. Alastair Maw already mentioned what we have to do, so we take his advice and then import the GAE settings into our project, so that we can deploy it.
Changes in the Wicket project
When building the project for deployment make sure to enable the deployment mode. In deployment mode Wicket does not try to spawn any processes for monitoring changes in resource files. This can be done in the configuration file or in the command line when building the project. Because this is a setting only used before deployment I prefer to use the command line option and leave the configuration untouched.
So when you’re ready to deploy use the following command: (not yet, we need to make some more changes. but it should compile)
mvn -Dwicket.configuration=deployment clean package
Additionally we need to override the creation of the newSessionStore(), so that it does not run in a separate thread in the background.
So edit your WicketApplication.java as shown below.
public class WicketApplication extends WebApplication
{
/**
* Constructor
*/
public WicketApplication()
{
}
/**
* @see org.apache.wicket.Application#getHomePage()
*/
public Class<HomePage> getHomePage()
{
return HomePage.class;
}
@Override
public HttpSessionStore newSessionStore(){
return new HttpSessionStore(this);
}
}
GAE specific settings
Take the appengine-web.xml file from the new_project_template in the demo folder and copy it to your projects src/main/webapp/WEB-INF/ folder.
Enable session support and enter the name of your project (as shown in the GAE). After that your appengine-web.xml file should look similar to this:
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0"> <!-- Replace this with your application id from http://appengine.google.com --> <application>nameOfYourProject</application> <version>1</version> <sessions-enabled>true</sessions-enabled> </appengine-web-app>
Deploy your application into the Google App Engine
After building your project with maven you can upload the project files with the script supplied with the SDK.
./bin/appcfg.sh update projects/wickethelloworld/target/wickethelloworld-1.0-SNAPSHOT
That’s it. Sources are attached. The deployed app can be found here: http://wickethelloworld.appspot.com/
UPDATE
* The limit of available accounts has been abolished.
And there two articles I’d recommend reading when you want to get a bit more detail before you start:
* Google App Engine for Java – 3 Tips for Getting Started
* Google App Engine For Java – Microblogging Case Study
Maven 2 (Part 1): Setting up a simple Apache Maven 2 project
Java software development is often associated with repetitive tasks like building project’s java classes, generating documentation and reporting. Doing this repetitive tasks manually costs a lot of time and tend to be error-prone. In addition to that it is extremely boring to do the same tasks again and again. These tasks should get automated, because they are often equal. To automate these tasks a build tool that could do this work is needed. Today, many java projects are using the Maven as a build tool to manage these objectives. The Maven project reached big popularity by making repetitive tasks automatable.
Another advantage when using Maven is that all dependencies referenced by the project are resolved automatically. This is extremely helpful for bigger java projects that use a huge set of dependencies. To explain how to use Maven and to help you to get into it we start a new tutorial-series about Maven 2 at unitedcoderscom.appspot.com. The initial part of this tutorial describes how to set up a Maven 2 project structure. Further parts of this tutorial-series will describe the main functionality of Maven (e.g. plugins, archetypes, the dependency mechanism, profiles, repositories, scopes…) stepwise.
First of all Maven 2 needs to be installed, which can be downloaded at http://maven.apache.org/download.html. A good help on installing Maven can be found here. Having a Debian-based Linux (e.g. Ubuntu) you are able to install everything automatically by executing:
sudo apt-get install maven2
After you’ve installed Maven 2 on your system you can run a litte test by executing “mvn –version” on your console. The result should be an information about the installed Maven version.
To start a simple new Maven 2 project please run “mvn archetype:generate”. This will help you generating a specific Maven 2 project by using a Maven 2 archetype. Archetype are patterns for Maven 2 projects. We’ll take a closer view on archetype in the third part of this tutorial-series.
After running “mvn archetype:generate” you’ll see a bunch of Maven 2 archetypes:
phil@scarface:/home/phil/experiments$ mvn archetype:generate [INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'archetype'. [INFO] ------------------------------------------------------------------------ [INFO] Building Maven Default Project [INFO] task-segment: [archetype:generate] (aggregator-style) [INFO] ------------------------------------------------------------------------ [INFO] Preparing archetype:generate [INFO] No goals needed for project - skipping [INFO] Setting property: classpath.resource.loader.class => 'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'. [INFO] Setting property: velocimacro.messages.on => 'false'. [INFO] Setting property: resource.loader => 'classpath'. [INFO] Setting property: resource.manager.logwhenfound => 'false'. [INFO] [archetype:generate] [INFO] Generating project in Interactive mode [INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0) Choose archetype: 1: internal -> appfuse-basic-jsf (AppFuse archetype for creating a web application with Hibernate, Spring and JSF) 2: internal -> appfuse-basic-spring (AppFuse archetype for creating a web application with Hibernate, Spring and Spring MVC) 3: internal -> appfuse-basic-struts (AppFuse archetype for creating a web application with Hibernate, Spring and Struts 2) 4: internal -> appfuse-basic-tapestry (AppFuse archetype for creating a web application with Hibernate, Spring and Tapestry 4) 5: internal -> appfuse-core (AppFuse archetype for creating a jar application with Hibernate and Spring and XFire) 6: internal -> appfuse-modular-jsf (AppFuse archetype for creating a modular application with Hibernate, Spring and JSF) 7: internal -> appfuse-modular-spring (AppFuse archetype for creating a modular application with Hibernate, Spring and Spring MVC) 8: internal -> appfuse-modular-struts (AppFuse archetype for creating a modular application with Hibernate, Spring and Struts 2) 9: internal -> appfuse-modular-tapestry (AppFuse archetype for creating a modular application with Hibernate, Spring and Tapestry 4) 10: internal -> maven-archetype-j2ee-simple (A simple J2EE Java application) 11: internal -> maven-archetype-marmalade-mojo (A Maven plugin development project using marmalade) 12: internal -> maven-archetype-mojo (A Maven Java plugin development project) 13: internal -> maven-archetype-portlet (A simple portlet application) 14: internal -> maven-archetype-profiles () 15: internal -> maven-archetype-quickstart () 16: internal -> maven-archetype-site-simple (A simple site generation project) 17: internal -> maven-archetype-site (A more complex site project) 18: internal -> maven-archetype-webapp (A simple Java web application) 19: internal -> jini-service-archetype (Archetype for Jini service project creation) 20: internal -> softeu-archetype-seam (JSF+Facelets+Seam Archetype) 21: internal -> softeu-archetype-seam-simple (JSF+Facelets+Seam (no persistence) Archetype) 22: internal -> softeu-archetype-jsf (JSF+Facelets Archetype) 23: internal -> jpa-maven-archetype (JPA application) 24: internal -> spring-osgi-bundle-archetype (Spring-OSGi archetype) 25: internal -> confluence-plugin-archetype (Atlassian Confluence plugin archetype) 26: internal -> jira-plugin-archetype (Atlassian JIRA plugin archetype) 27: internal -> maven-archetype-har (Hibernate Archive) 28: internal -> maven-archetype-sar (JBoss Service Archive) 29: internal -> wicket-archetype-quickstart (A simple Apache Wicket project) 30: internal -> scala-archetype-simple (A simple scala project) 31: internal -> lift-archetype-blank (A blank/empty liftweb project) 32: internal -> lift-archetype-basic (The basic (liftweb) project) 33: internal -> cocoon-22-archetype-block-plain ([http://cocoon.apache.org/2.2/maven-plugins/]) 34: internal -> cocoon-22-archetype-block ([http://cocoon.apache.org/2.2/maven-plugins/]) 35: internal -> cocoon-22-archetype-webapp ([http://cocoon.apache.org/2.2/maven-plugins/]) 36: internal -> myfaces-archetype-helloworld (A simple archetype using MyFaces) 37: internal -> myfaces-archetype-helloworld-facelets (A simple archetype using MyFaces and facelets) 38: internal -> myfaces-archetype-trinidad (A simple archetype using Myfaces and Trinidad) 39: internal -> myfaces-archetype-jsfcomponents (A simple archetype for create custom JSF components using MyFaces) 40: internal -> gmaven-archetype-basic (Groovy basic archetype) 41: internal -> gmaven-archetype-mojo (Groovy mojo archetype) Choose a number: (1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/28/29/30/31/32/33/34/35/36/37/38/39/40/41) 15: :
Now it’s up to you to choose. In this example we’ll use the archetype 15 “maven-archetype-quickstart”. Type “15” and press [Return]. After you choosed your archetype you’ll be asked for project-specific settings:
Define value for groupId: : com.unitedcoders Define value for artifactId: : MyExampleApp Define value for version: 1.0-SNAPSHOT: : 0.0.1-SNAPSHOT Define value for package: com.unitedcoders: : com.unitedcoders.examples
The artifactId defines how the project and accordingly our java artifact will be called. The groupId defines to which group the artifact should belong. At the version prompt you should place the initial version number for your project (In this case: 0.0.1-SNAPSHOT). At least we’ll define the main package for our java code. If you have entered everything right, you’ll be asked to confirm your informations.
Confirm properties configuration: groupId: com.united-coders artifactId: MyExampleApp version: 0.0.1-SNAPSHOT package: com.united-coders.examples Y: : y
If everything looks like you expected ist please go on by entering “y” for YES.
[INFO] ---------------------------------------------------------------------------- [INFO] Using following parameters for creating OldArchetype: maven-archetype-quickstart:RELEASE [INFO] ---------------------------------------------------------------------------- [INFO] Parameter: groupId, Value: com.united-coders [INFO] Parameter: packageName, Value: com.united-coders.examples [INFO] Parameter: package, Value: com.united-coders.examples [INFO] Parameter: artifactId, Value: MyExampleApp [INFO] Parameter: basedir, Value: /home/phil/experiments [INFO] Parameter: version, Value: 0.0.1-SNAPSHOT [INFO] ********************* End of debug info from resources from generated POM *********************** [INFO] OldArchetype created in dir: /home/phil/experiments/MyExampleApp [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3 minutes 28 seconds [INFO] Finished at: Fri Apr 17 12:05:44 CEST 2009 [INFO] Final Memory: 9M/124M [INFO] ------------------------------------------------------------------------ phil@scarface:/home/phil/experiments$
Congratulations! You’ve created a simple Maven 2 project structure. Let’s take a look what happened. Navigate to your projects rootfolder and take a look on the contents:
<img src="http://www.unitedcoderscom.appspot.com/sites/default/files/imagepicker/p/Phillip%20Steffensen/shell2_1.png" alt="Maven 2 project structure" /></center>
You'll see that your project contains 3 files: pom.xml, App.java and AppTest.java. The pom.xml contains your projects Maven 2 configuration. Please take a look on the Maven website for further informations on how the pom configures your project and how to manage your applications dependencies and dpendency versions. The class App.java is a really simple example class and - as you certainly expected - the class AppTest.java contains associated JUnit testcase. Now you are able to run some Maven targets on your project. Run the following targets on your project and take a look on what will happen:
<ul>
<li>mvn test (runs the projects testcases)</li>
<li>mvn clean (removes the projects "target"-folder)</li>
<li>mvn package (build the artifact)</li>
<li>mvn eclipse:eclipse (create a .project-File to make the project eclipse-importable)</li>
</ul>
Let's take a closer look at the <a href="http://maven.apache.org/ref/current/maven-model/maven.html#class_project">pom.xml</a>'s (POM - project object model) contents:
<pre class="prettyprint"><project xmlns="http://maven.apache.org/POM/4.0.0" [...] >
<modelVersion>4.0.0</modelVersion>
<groupId>com.unitedcoders</groupId>
<artifactId>MyExampleApp</artifactId>
<packaging>jar</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>MyExampleApp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
The groupId, the artifactId and the version we've entered during the project generation process can now be found in the pom.xml. The artifactId is also used as the projects name. The xml-node "modelVersion" declares to which version of project descriptor this pom.xml conforms. "packaging" defines the type of artifact this project produces (jar, war,...). In this case the default "jar" is used. So our project will create a jar-file on the "package" target. At the xml-node "url" the projects url is defined. The default url is "http://maven.apache.org". You can edit this entry and insert the URL of this project at a continous integration tool or the projects SVN url. Underneath these project configurations you can see the xml-node "dependencies". This node contains all of the projects dependencies (in this case only junit 3.8.1). In the next part of this tutorial series we will focus on those dependencies and scopes.
Further Maven 2 articles:
Maven 2 (Part 2): Dependencies, properties and scopes
Maven 2 (Part 3): Configuring eclipse for Apache Maven 2 projects
How to access the manager servlet of Apache Tomcat
If you set up a brand new tomcat with the default configuration, you are unable to access the manager servlet. All requests on http://[YourHost]:[TomcatPort]/manager/html are responded by a HTTP Status 403 (“Access to the requested resource has been denied”). If you use your tomcat for a productive system the manager servlet should always be deactivated. The tomcat’s default configuration hides the manager servlet for some security reasons. If you want to access the manager servlet you should add some lines to your tomcat-users.xml at $CATALINA_HOME/conf/tomcat-users.xml and restart your tomcat.
The default content of tomcat-users.xml is:
<?xml version='1.0' encoding='utf-8'>
<tomcat-users>
<role rolename="tomcat" />
<role rolename="role1" />
<role rolename="admin" />
<user username="tomcat" password="tomcat" roles="tomcat" />
<user username="role1" password="tomcat" roles="role1" />
<user username="both" password="tomcat" roles="tomcat,role1" />
</tomcat-users>
To make the manager servlet reachable you should modify your tomcat-users.xml like that:
<?xml version='1.0' encoding='utf-8'>
<tomcat-users>
<role rolename="tomcat" />
<role rolename="role1" />
<role rolename="manager" />
<role rolename="admin" />
<user username="tomcat" password="tomcat" roles="tomcat" />
<user username="role1" password="tomcat" roles="role1" />
<user username="both" password="tomcat" roles="tomcat,role1" />
<user username="YOUR_USERNAME" password="YOUR_PASSWORD" roles="manager,admin" />
</tomcat-users>
After restarting tomcat you are now able to access http://[YourHost]:[TomcatPort]/manager/html by entering YOUR_USERNAME and YOUR_PASSWORD on the htaccess-prompt. Some might think that it is safe enough to add a strong password to the manager/admin-account. But is it really safe enough to hide the manager servlet behind a simple htaccess login? No! You may not want that somebody accesses your tomcat servers manager servlet and drops all your applications, if he/she knows the login. Maybe somebody does it in the malicious way or maybe it is only a mistake. To protect the tomcat and applications from such faults, you should not modify the default tomcat-users.xml for productive systems.
Functional programming with Python
To work with lists many c/c++ programmer use a simple for-loop. I will try to explain how this can be made a little bit easier. For that I use the self-explaining script language python.
Here is a simple example to filter all odd integers from a list in simple python 2.x syntax.
def filter_odd(myList):
result = [] # initialize the result list
for num in myList: # iterate over the list
if num % 2 == 1: # modulo 2 return 1 for odd integers
result.append(num) # add to the result
return result
The function call will return a list containing only odd integers (you can use the result of the modulo operation directly without comparing with 1). Try it directly on a interactive python console (as an applet on secapps.com).
>> print filter_odd([1,2,3,4,5]) [1, 3, 5]
try it functional
The function filter_odd could be a more generic method, if the condition could be a variable or used as a parameter:
def condition_odd(num): # the condition as separate function
return num % 2 == 1
#condition_odd
def generic_filter(condition, myList):
result = []
for num in myList:
if condition(num): # the same condition like the first example, only as parameter
result.append(num)
return result
#generic_filter
We can define a condition as a function and use it as a parameter in the generic_filter implementation to filter the values of list myList. Ok, you don’t have to define a generic filter function, python offers the filter function in the standard language.
>> print filter_generic(condition_odd, [1,2,3,4,5]) [1, 3, 5] >>print filter(condition_odd, [1,2,3,4,5]) [1, 3, 5]
The new implementation does not say what to do, it say how to use the condition on a list and has much less code compared to first example.
Passing a function as a parameter is a key aspect of functional programming. But the condition_odd function will only be used for the line with the filter call. The next step will show you, how to use this function parameter without defining it separately.
>> print filter(lambda x: x % 2 == 1, [1,2,3,4,5]) [1, 3, 5]
The first parameter is the lambda construct: Create a temporary, anonymous function with x as parameter and return the result of the term “x % 2 == 1“. I don’t have to define a function and I can use the filter in one line. Save namespace with one-time functions and code lines.
list comprehension
One-line solutions are fine to write short code, but it also has to be readable. If the reader doesn’t know what filter and lambda means, it can be confusing.
An other alternative for the one-line filter solution, and more confusing in python, is
list comprehension</cite>. You can write the above example: <pre class="prettyprint">>> print [x for x in [1,2,3,4,5] if x % 2 == 1] [1, 3, 5]
The result contains items from the constant list, filtered with the term in the if-condition. [Updated] You have to use the exact syntax, not the simple variant like filter.
more functional helper: map and reduce
There are some other list functions. First the map function with calls for every item in the list a function. In a example we will double every integer from the list. This could also be written as a list comprehension.
>>print map(lambda x: x*2, [1,2,3,4,5]) [2, 4, 6, 8, 10] >>print [x**2 for x in [1,2,3,4,5]] [2, 4, 6, 8, 10]
Second function is reduce. It get a function and a list as parameter and will call the function with the first two items from the list. Then the result and the next item will be computed and so on. A simple exapmle will calculate the sum of a number list:
>>print reduce(lambda a, b: a + b, [1,2,3,4,5]) 15
This simple example can also resolved with the build-in sum function.
two examples
Now we will try some real world examples - project eulers first problem: Find the sum of all the multiples of 3 or 5 below 1000. Simply to resolve with a for-loop:
- the condition term is x%3==0 or x%5==0
- filter the values beetween 0 and 1000
- calculate the sum
def eulerOne(myList):
mySum = 0
for num in range(1000):
if num%3==0 or num%5==0:
mySum += num
return mySum
But we want to do it with an one-liner, with functional programming or a list comprehension:
>>print reduce(lambda a,b:a + b, [x for x in range(1000) if x % 3 == 0 or x % 5 == 0]) 233168 >>print sum([x for x in range(1000) if not (x%3 and x%5)]) 233168
The second line show a shorter version with sum and a little bit boolean algebra but it will not so clear readable.
As a second example filter all persons who older than 18:
>>persons = [{'age': 5, 'name': 'peter'}, {'age': 20, 'name': 'paul'}]
>>print [x['name'] for x in persons if x['age'] > 18]
['paul']
>>print map(lambda x:x['name'], filter(lambda x: x['age']>19, persons))
['paul']
summary
Here the summary with the python doc-strings to the new learned functions:
- filter(function or None, sequence) -> list, tuple, or string
- Return those items of sequence for which function(item) is true. If
function is None, return the items that are true. If sequence is a tuple
or string, return the same type, else return a list. - map(function, sequence[, sequence, ...]) -> list
- Return a list of the results of applying the function to the items of
the argument sequence(s). If more than one sequence is given, the
function is called with an argument list consisting of the corresponding
item of each sequence, substituting None for missing values when not all
sequences have the same length. If the function is None, return a list of
the items of the sequence (or a list of tuples if more than one sequence). - reduce(function, sequence[, initial]) -> value
- Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5). If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty. - lambda - syntax
- normal function definition:
def name(arguments): return expression
anonymous lambda function definition:
lambda arguments: expression
[Updated]: filter and map are still in python 3000 in the iterator variant, the reduce-function is moved in the functools module.
By continuing to use the site, you agree to the use of cookies. more information
The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.