Requirement Constraints

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Tuesday, 19 March 2013

ZK + Spring Security Login form–Part 2

Posted on 04:59 by Unknown

Implement custom UserDetailsService for spring security

In the last article, all our user name and password are hard coded in the xml file itself. But this will not useful for the real world application. Most of the time, user name and passwords are stored in the database and we need to validate against the database to give access to our secured pages.

As a first step towards that, this post will explain will explain little bit on that. This is not complete implementation, later we will see how to connect database and check the user name and password, But this will help you how to start on that.

Technologies used in this example:

1. ZK 6.5.1 CE Version.
2. Spring-security-core 3.0.5

Step 1:
Download this document and setup the development environment.

Step 2:
Let us create ZK Maven Project. Follow the below instruction.
In the Eclipse IDE, Select File –> New-> Other-> Maven Project as shown here.
image_thumb

Click Next.
image_thumb1
Uncheck the option “Create a simple Project(skip archetype selection) and Click next.
image_thumb2
Select “ZK” in the catalog and select “ZK-archetype-webapp 6.0” as shown here."
image_thumb3[1]
Click Next after selecting the ZK Archetype.
image
Enter “zkloginexample2” for Group ID, Artifact id and Package. And important, please select “ZK-Version-since” from the bottom list and then select finish.
Now, the following folder structure will be created.
image

Step 3:
Next we will include the spring dependency in the POM File.
Double click the POM.XML file in the project navigator.
image_thumb7

Click on the POM.XML tab. The following modification has been done.
1. Change the ZK Version to latest CE Version.
2. Remove the Maven ZK EE Version Repository.
3. Add the spring security dependency.
Here is the modified POM.XML file.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>zkloginexample1</groupId>
<artifactId>zkloginexample1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<zk.version>6.5.1</zk.version>
<commons-io>1.3.1</commons-io>
<maven.build.timestamp.format>yyyy-MM-dd</maven.build.timestamp.format>
<packname>-${project.version}-FL-${maven.build.timestamp}</packname>
</properties>
<packaging>war</packaging>
<name>The zkloginexample1 Project</name>
<description>The zkloginexample1 Project</description>
<licenses>
<license>
<name>GNU LESSER GENERAL PUBLIC LICENSE, Version 3</name>
<url>http://www.gnu.org/licenses/lgpl.html</url>
<distribution>repo</distribution>
</license>
</licenses>
<repositories>
<repository>
<id>ZK CE</id>
<name>ZK CE Repository</name>
<url>http://mavensync.zkoss.org/maven2</url>
</repository>
<repository>
<id>ZK EVAL</id>
<name>ZK Evaluation Repository</name>
<url>http://mavensync.zkoss.org/eval</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>zkmaven</id>
<name>ZK Maven Plugin Repository</name>
<url>http://mavensync.zkoss.org/maven2/</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zkbind</artifactId>
<version>${zk.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zul</artifactId>
<version>${zk.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zkplus</artifactId>
<version>${zk.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zhtml</artifactId>
<version>${zk.version}</version>
</dependency>

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io}</version>
</dependency>

<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>

<!-- ZK 5 breeze theme <dependency> <groupId>org.zkoss.theme</groupId>
<artifactId>breeze</artifactId> <version>${zk.version}</version> <optional>true</optional>
</dependency> -->
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<!-- Run with Jetty -->
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.10</version>
<configuration>
<scanIntervalSeconds>5</scanIntervalSeconds>
<stopKey>foo</stopKey>
<stopPort>9999</stopPort>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Compile java -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<!-- Build war -->
<plugin>
<artifactId>maven-war-plugin</artifactId>
<groupId>org.apache.maven.plugins</groupId>
<version>2.1.1</version>
</plugin>
<!-- Pack zips -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>webapp</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>zkloginexample1${packname}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>assembly/webapp.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>


Step 4:
Next step we will update web.xml to take care spring filter.
Here is the updated web.xml file.

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<description><![CDATA[My ZK Application]]></description>
<display-name>zkloginexample1</display-name>

<!-- ====================================================== -->
<!-- CONFIGURATION FILES -->
<!-- ====================================================== -->

<!-- =========================================================================================================== -->
<!-- The security configuration is done in XML file and can have any name such as applicationContext-security.xml. -->
<!-- This file needs to be loaded explicitly from web.xml. This is done by adding ContextLoadListener. -->
<!-- The following lines needs to be added before security filter definition in web.xml. -->
<!-- =========================================================================================================== -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-security.xml
</param-value>
</context-param>

<!-- ====================================================== -->
<!-- SPRING CONTEXT LOADER -->
<!-- ====================================================== -->

<!-- The org.springframework.web.context.ContextLoaderListener class uses a context parameter called contextConfigLocation to
determine the location of the Spring configuration file. The context parameter is configured using the context-parameter element.
The context-param element has two children that specify parameters and their values.
The param-name element specifies the parameter's name. The param-value element specifies the parameter's value
-->

<listener>
<display-name>Spring Context Loader</display-name>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Spring Security -->
<!-- A servlet filter capturing every user requests and sending them to the configured security filters to make sure access is authorized. -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- //// -->
<!-- ZK -->
<listener>
<description>ZK listener for session cleanup</description>
<listener-class>org.zkoss.zk.ui.http.HttpSessionListener</listener-class>
</listener>
<servlet>
<description>ZK loader for ZUML pages</description>
<servlet-name>zkLoader</servlet-name>
<servlet-class>org.zkoss.zk.ui.http.DHtmlLayoutServlet</servlet-class>

<!-- Must. Specifies URI of the update engine (DHtmlUpdateServlet). It
must be the same as <url-pattern> for the update engine. -->
<init-param>
<param-name>update-uri</param-name>
<param-value>/zkau</param-value>
</init-param>
<!-- Optional. Specifies whether to compress the output of the ZK loader.
It speeds up the transmission over slow Internet. However, if you configure
a filter to post-processing the output, you might have to disable it. Default:
true <init-param> <param-name>compress</param-name> <param-value>true</param-value>
</init-param> -->
<!-- [Optional] Specifies the default log level: OFF, ERROR, WARNING, INFO,
DEBUG and FINER. If not specified, the system default is used. <init-param>
<param-name>log-level</param-name> <param-value>OFF</param-value> </init-param> -->
<load-on-startup>1</load-on-startup><!-- Must -->
</servlet>
<servlet-mapping>
<servlet-name>zkLoader</servlet-name>
<url-pattern>*.zul</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>zkLoader</servlet-name>
<url-pattern>*.zhtml</url-pattern>
</servlet-mapping>
<!-- [Optional] Uncomment it if you want to use richlets. <servlet-mapping>
<servlet-name>zkLoader</servlet-name> <url-pattern>/zk/*</url-pattern> </servlet-mapping> -->
<servlet>
<description>The asynchronous update engine for ZK</description>
<servlet-name>auEngine</servlet-name>
<servlet-class>org.zkoss.zk.au.http.DHtmlUpdateServlet</servlet-class>

<!-- [Optional] Specifies whether to compress the output of the ZK loader.
It speeds up the transmission over slow Internet. However, if your server
will do the compression, you might have to disable it. Default: true <init-param>
<param-name>compress</param-name> <param-value>true</param-value> </init-param> -->
<!-- [Optional] Specifies the AU extension for particular prefix. <init-param>
<param-name>extension0</param-name> <param-value>/upload=com.my.MyUploader</param-value>
</init-param> -->
</servlet>
<servlet-mapping>
<servlet-name>auEngine</servlet-name>
<url-pattern>/zkau/*</url-pattern>
</servlet-mapping>

<!-- [Optional] Uncomment if you want to use the ZK filter to post process
the HTML output generated by other technology, such as JSP and velocity.
<filter> <filter-name>zkFilter</filter-name> <filter-class>org.zkoss.zk.ui.http.DHtmlLayoutFilter</filter-class>
<init-param> <param-name>extension</param-name> <param-value>html</param-value>
</init-param> <init-param> <param-name>compress</param-name> <param-value>true</param-value>
</init-param> </filter> <filter-mapping> <filter-name>zkFilter</filter-name>
<url-pattern>your URI pattern</url-pattern> </filter-mapping> -->
<!-- //// -->

<!-- ///////////// -->
<!-- DSP (optional) Uncomment it if you want to use DSP However, it is turned
on since zksandbox uses DSP to generate CSS. <servlet> <servlet-name>dspLoader</servlet-name>
<servlet-class>org.zkoss.web.servlet.dsp.InterpreterServlet</servlet-class>
<init-param> <param-name>class-resource</param-name> <param-value>true</param-value>
</init-param> </servlet> <servlet-mapping> <servlet-name>dspLoader</servlet-name>
<url-pattern>*.dsp</url-pattern> </servlet-mapping> -->

<!-- /////////// -->
<!-- [Optional] Session timeout -->
<session-config>
<session-timeout>60</session-timeout>
</session-config>

<!-- [Optional] MIME mapping -->
<mime-mapping>
<extension>doc</extension>
<mime-type>application/vnd.ms-word</mime-type>
</mime-mapping>
<mime-mapping>
<extension>gif</extension>
<mime-type>image/gif</mime-type>
</mime-mapping>
<mime-mapping>
<extension>htm</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<mime-mapping>
<extension>html</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<mime-mapping>
<extension>jpeg</extension>
<mime-type>image/jpeg</mime-type>
</mime-mapping>
<mime-mapping>
<extension>jpg</extension>
<mime-type>image/jpeg</mime-type>
</mime-mapping>
<mime-mapping>
<extension>js</extension>
<mime-type>text/javascript</mime-type>
</mime-mapping>
<mime-mapping>
<extension>pdf</extension>
<mime-type>application/pdf</mime-type>
</mime-mapping>
<mime-mapping>
<extension>png</extension>
<mime-type>image/png</mime-type>
</mime-mapping>
<mime-mapping>
<extension>txt</extension>
<mime-type>text/plain</mime-type>
</mime-mapping>
<mime-mapping>
<extension>xls</extension>
<mime-type>application/vnd.ms-excel</mime-type>
</mime-mapping>
<mime-mapping>
<extension>xml</extension>
<mime-type>text/xml</mime-type>
</mime-mapping>
<mime-mapping>
<extension>zhtml</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<mime-mapping>
<extension>zul</extension>
<mime-type>text/html</mime-type>
</mime-mapping>

<welcome-file-list>
<welcome-file>index.zul</welcome-file>
<welcome-file>index.zhtml</welcome-file>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
</web-app>

Step 5:
As you can see in the web.xml file, we are loading new xml file configuration named as “spring-security.xml”.
Select the Folder “WEB-INF”, right click, Select New->Other-XML File and give the file name as “spring-security.xml”

image
Paste the following content



<!-- Spring namespace-based configuration -->

<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">

<!-- ====================================================== -->
<!-- For catching the @Secured annotation methods -->
<!-- Tells the Spring Security engine that we will use Spring Security's -->
<!-- pre and post invocation Java annotations (@PreFilter, @PreAuthorize, -->
<!-- @PostFilter, -->
<!-- @PostAuthorize) to secure service layer methods.. -->
<!-- Look in GFCBaseCtrl.java onEvent() method. -->
<!-- ====================================================== -->

<!-- Enable the @Secured annotation to secure service layer methods -->
<global-method-security secured-annotations="enabled" />

<http auto-config="true">

<!-- ====================================================== -->
<!-- If we have our own LoginPage. So we must -->
<!-- tell Spring the name and the place. -->
<!-- In our case we take the same page -->
<!-- for a error message by a failure. -->
<!-- Further the page after a successfully login. -->
<!-- ====================================================== -->
<form-login login-page="/login.zul"
authentication-failure-url="/login.zul?login_error=1"
default-target-url="/index.zul" />
<intercept-url pattern="/login.zul" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/*.zul" access="IS_AUTHENTICATED_REMEMBERED" />
<intercept-url pattern="/zk/*" access="IS_AUTHENTICATED_REMEMBERED" />

</http>

<authentication-manager>
<authentication-provider user-service-ref="myUserDetailsService">
</authentication-provider>
</authentication-manager>

<beans:bean id="myUserDetailsService"
class="zkloginexample2.MyUserDetailsService"/>


</beans:beans>



login-page : The URL that should be used to render the login page.
Just for this example, we have some user names and their password are encoded.

As you can see that, we have removed all the user name and password in the xml file and used our own custom authentication pointer by referring java bean with id as “myUserDetailsService”. So let us create this java class now

In the zkloginexample2 package(which is created by default), right click-> New->Other->Class and Give the name as MyUserDetailsService.
MyUserDetailsService.java file will be created as shown here.

image

Here is the content

package zkloginexample2;

import java.util.ArrayList;
import java.util.List;

import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class MyUserDetailsService implements UserDetailsService {

/*
* You just have to make sure that the user-by-username-query returns three
* fields. 1) the userName 2) the password 3) boolean for is the user
* active. If you don't have an active field, make your query always return
* true for that third field.
*/
public UserDetails loadUserByUsername(String arg0)
throws UsernameNotFoundException, DataAccessException {

String username = "rod";
String password = "koala";
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>(1);
authList.add(new GrantedAuthorityImpl("ROLE_SUPERVISOR"));

User user = null;
try {
user = new User(username, password, enabled, accountNonExpired,
credentialsNonExpired, accountNonLocked, authList);
} catch (Exception e) {
e.printStackTrace();
}
return user;

}

}


Step 6:
Next step is to add the login.zul. Select the folder “webapp”. Right click, Select New->Other->Zul file. Enter the file name as login.zul
Here is the file content.

<?page id="loginPage" title="Digital medical sheet - Login page" onLoad="win.doOverlapped();"?>
<window id="win" title="LOGIN" border="normal" width="300px"
position="center">

<!-- this form-login-page form is also used as the
form-error-page to ask for a login again. -->
<html style="color:red" if="${not empty param.login_error}">

<![CDATA[ Your login attempt was not successful, try
again.<br/><br/> Reason:
${SPRING_SECURITY_LAST_EXCEPTION.message} ]]>

</html>

<groupbox>
<caption>Login</caption>
<h:form id="f" name="f" action="j_spring_security_check"
method="POST" xmlns:h="http://www.w3.org/1999/xhtml">
<grid>
<columns sizable="false">
<column width="50%" />
<column width="50%" />
</columns>
<rows>
<row>
<label value="User:" />
<textbox id="u" name="j_username" />
</row>
<row>
<label value="Password:" />
<textbox id="p" type="password"
name="j_password" />
</row>
<row spans="2">
<div align="center">
<h:input type="submit" value="login" />
<h:input type="reset" value="Reset" />
</div>
</row>
</rows>
</grid>
</h:form>
</groupbox>
</window>

Step 7:
Now the let us change the index.zul file content which is created by default.

<zk>
<window >
Welcome to ZK Secured Page
<button label="Logout" href="/j_spring_security_logout"/>
</window>
</zk>


Step 8:
Now you can select the Project “zkloginexample2”, right click-> Run as –> Run on Server
image_thumb4
Select the tomcat server and Click finish button


image_thumb5[1]
Now you can enter any valid username/passwords as follows
rod/koala
 

You can download the source here

Reference
1.
Introduction to Spring Security Concepts.
2. Getting Started Spring Security
3. Understanding Spring Security
4. Configuring spring security

Read More
Posted in ZK Spring | No comments

Monday, 18 March 2013

ZK + Spring Security Login form–Part 1

Posted on 18:18 by Unknown
In this post, we will see how to create a custom login form using ZK and ask Spring Security to use it for login authentication.

Technologies used in this example:

1. ZK 6.5.1 CE Version.
2. Spring-security-core 3.0.5

Step 1:
Download this document and setup the development environment.

Step 2:
Let us create ZK Maven Project. Follow the below instruction.
In the Eclipse IDE, Select File –> New-> Other-> Maven Project as shown here.
image

Click Next.
image
Uncheck the option “Create a simple Project(skip archetype selection) and Click next.
image
Select “ZK” in the catalog and select “ZK-archetype-webapp 6.0” as shown here."
image
Click Next after selecting the ZK Archetype.
image
Enter “zkloginexample1” for Group ID, Artifact id and Package. And important, please select “ZK-Version-since” from the bottom list and then select finish.
Now, the following folder structure will be created.
image

Step 3:
Next we will include the spring dependency in the POM File.
Double click the POM.XML file in the project navigator.
image

Click on the POM.XML tab. The following modification has been done.
1. Change the ZK Version to latest CE Version.
2. Remove the Maven ZK EE Version Repository.
3. Add the spring security dependency.
Here is the modified POM.XML file.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>zkloginexample1</groupId>
<artifactId>zkloginexample1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<zk.version>6.5.1</zk.version>
<commons-io>1.3.1</commons-io>
<maven.build.timestamp.format>yyyy-MM-dd</maven.build.timestamp.format>
<packname>-${project.version}-FL-${maven.build.timestamp}</packname>
</properties>
<packaging>war</packaging>
<name>The zkloginexample1 Project</name>
<description>The zkloginexample1 Project</description>
<licenses>
<license>
<name>GNU LESSER GENERAL PUBLIC LICENSE, Version 3</name>
<url>http://www.gnu.org/licenses/lgpl.html</url>
<distribution>repo</distribution>
</license>
</licenses>
<repositories>
<repository>
<id>ZK CE</id>
<name>ZK CE Repository</name>
<url>http://mavensync.zkoss.org/maven2</url>
</repository>
<repository>
<id>ZK EVAL</id>
<name>ZK Evaluation Repository</name>
<url>http://mavensync.zkoss.org/eval</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>zkmaven</id>
<name>ZK Maven Plugin Repository</name>
<url>http://mavensync.zkoss.org/maven2/</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zkbind</artifactId>
<version>${zk.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zul</artifactId>
<version>${zk.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zkplus</artifactId>
<version>${zk.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zhtml</artifactId>
<version>${zk.version}</version>
</dependency>

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io}</version>
</dependency>

<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>

<!-- ZK 5 breeze theme <dependency> <groupId>org.zkoss.theme</groupId>
<artifactId>breeze</artifactId> <version>${zk.version}</version> <optional>true</optional>
</dependency> -->
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<!-- Run with Jetty -->
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.10</version>
<configuration>
<scanIntervalSeconds>5</scanIntervalSeconds>
<stopKey>foo</stopKey>
<stopPort>9999</stopPort>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Compile java -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<!-- Build war -->
<plugin>
<artifactId>maven-war-plugin</artifactId>
<groupId>org.apache.maven.plugins</groupId>
<version>2.1.1</version>
</plugin>
<!-- Pack zips -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>webapp</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>zkloginexample1${packname}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>assembly/webapp.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>


Step 4:
Next step we will update web.xml to take care spring filter.
Here is the updated web.xml file.

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<description><![CDATA[My ZK Application]]></description>
<display-name>zkloginexample1</display-name>

<!-- ====================================================== -->
<!-- CONFIGURATION FILES -->
<!-- ====================================================== -->

<!-- =========================================================================================================== -->
<!-- The security configuration is done in XML file and can have any name such as applicationContext-security.xml. -->
<!-- This file needs to be loaded explicitly from web.xml. This is done by adding ContextLoadListener. -->
<!-- The following lines needs to be added before security filter definition in web.xml. -->
<!-- =========================================================================================================== -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-security.xml
</param-value>
</context-param>

<!-- ====================================================== -->
<!-- SPRING CONTEXT LOADER -->
<!-- ====================================================== -->

<!-- The org.springframework.web.context.ContextLoaderListener class uses a context parameter called contextConfigLocation to
determine the location of the Spring configuration file. The context parameter is configured using the context-parameter element.
The context-param element has two children that specify parameters and their values.
The param-name element specifies the parameter's name. The param-value element specifies the parameter's value
-->

<listener>
<display-name>Spring Context Loader</display-name>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Spring Security -->
<!-- A servlet filter capturing every user requests and sending them to the configured security filters to make sure access is authorized. -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- //// -->
<!-- ZK -->
<listener>
<description>ZK listener for session cleanup</description>
<listener-class>org.zkoss.zk.ui.http.HttpSessionListener</listener-class>
</listener>
<servlet>
<description>ZK loader for ZUML pages</description>
<servlet-name>zkLoader</servlet-name>
<servlet-class>org.zkoss.zk.ui.http.DHtmlLayoutServlet</servlet-class>

<!-- Must. Specifies URI of the update engine (DHtmlUpdateServlet). It
must be the same as <url-pattern> for the update engine. -->
<init-param>
<param-name>update-uri</param-name>
<param-value>/zkau</param-value>
</init-param>
<!-- Optional. Specifies whether to compress the output of the ZK loader.
It speeds up the transmission over slow Internet. However, if you configure
a filter to post-processing the output, you might have to disable it. Default:
true <init-param> <param-name>compress</param-name> <param-value>true</param-value>
</init-param> -->
<!-- [Optional] Specifies the default log level: OFF, ERROR, WARNING, INFO,
DEBUG and FINER. If not specified, the system default is used. <init-param>
<param-name>log-level</param-name> <param-value>OFF</param-value> </init-param> -->
<load-on-startup>1</load-on-startup><!-- Must -->
</servlet>
<servlet-mapping>
<servlet-name>zkLoader</servlet-name>
<url-pattern>*.zul</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>zkLoader</servlet-name>
<url-pattern>*.zhtml</url-pattern>
</servlet-mapping>
<!-- [Optional] Uncomment it if you want to use richlets. <servlet-mapping>
<servlet-name>zkLoader</servlet-name> <url-pattern>/zk/*</url-pattern> </servlet-mapping> -->
<servlet>
<description>The asynchronous update engine for ZK</description>
<servlet-name>auEngine</servlet-name>
<servlet-class>org.zkoss.zk.au.http.DHtmlUpdateServlet</servlet-class>

<!-- [Optional] Specifies whether to compress the output of the ZK loader.
It speeds up the transmission over slow Internet. However, if your server
will do the compression, you might have to disable it. Default: true <init-param>
<param-name>compress</param-name> <param-value>true</param-value> </init-param> -->
<!-- [Optional] Specifies the AU extension for particular prefix. <init-param>
<param-name>extension0</param-name> <param-value>/upload=com.my.MyUploader</param-value>
</init-param> -->
</servlet>
<servlet-mapping>
<servlet-name>auEngine</servlet-name>
<url-pattern>/zkau/*</url-pattern>
</servlet-mapping>

<!-- [Optional] Uncomment if you want to use the ZK filter to post process
the HTML output generated by other technology, such as JSP and velocity.
<filter> <filter-name>zkFilter</filter-name> <filter-class>org.zkoss.zk.ui.http.DHtmlLayoutFilter</filter-class>
<init-param> <param-name>extension</param-name> <param-value>html</param-value>
</init-param> <init-param> <param-name>compress</param-name> <param-value>true</param-value>
</init-param> </filter> <filter-mapping> <filter-name>zkFilter</filter-name>
<url-pattern>your URI pattern</url-pattern> </filter-mapping> -->
<!-- //// -->

<!-- ///////////// -->
<!-- DSP (optional) Uncomment it if you want to use DSP However, it is turned
on since zksandbox uses DSP to generate CSS. <servlet> <servlet-name>dspLoader</servlet-name>
<servlet-class>org.zkoss.web.servlet.dsp.InterpreterServlet</servlet-class>
<init-param> <param-name>class-resource</param-name> <param-value>true</param-value>
</init-param> </servlet> <servlet-mapping> <servlet-name>dspLoader</servlet-name>
<url-pattern>*.dsp</url-pattern> </servlet-mapping> -->

<!-- /////////// -->
<!-- [Optional] Session timeout -->
<session-config>
<session-timeout>60</session-timeout>
</session-config>

<!-- [Optional] MIME mapping -->
<mime-mapping>
<extension>doc</extension>
<mime-type>application/vnd.ms-word</mime-type>
</mime-mapping>
<mime-mapping>
<extension>gif</extension>
<mime-type>image/gif</mime-type>
</mime-mapping>
<mime-mapping>
<extension>htm</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<mime-mapping>
<extension>html</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<mime-mapping>
<extension>jpeg</extension>
<mime-type>image/jpeg</mime-type>
</mime-mapping>
<mime-mapping>
<extension>jpg</extension>
<mime-type>image/jpeg</mime-type>
</mime-mapping>
<mime-mapping>
<extension>js</extension>
<mime-type>text/javascript</mime-type>
</mime-mapping>
<mime-mapping>
<extension>pdf</extension>
<mime-type>application/pdf</mime-type>
</mime-mapping>
<mime-mapping>
<extension>png</extension>
<mime-type>image/png</mime-type>
</mime-mapping>
<mime-mapping>
<extension>txt</extension>
<mime-type>text/plain</mime-type>
</mime-mapping>
<mime-mapping>
<extension>xls</extension>
<mime-type>application/vnd.ms-excel</mime-type>
</mime-mapping>
<mime-mapping>
<extension>xml</extension>
<mime-type>text/xml</mime-type>
</mime-mapping>
<mime-mapping>
<extension>zhtml</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<mime-mapping>
<extension>zul</extension>
<mime-type>text/html</mime-type>
</mime-mapping>

<welcome-file-list>
<welcome-file>index.zul</welcome-file>
<welcome-file>index.zhtml</welcome-file>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
</web-app>


Step 5:
As you can see in the web.xml file, we are loading new xml file configuration named as “spring-security.xml”.
Select the Folder “WEB-INF”, right click, Select New->Other-XML File and give the file name as “spring-security.xml”

image
Paste the following content


<!-- Spring namespace-based configuration -->

<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">

<!-- ====================================================== -->
<!-- For catching the @Secured annotation methods -->
<!-- Tells the Spring Security engine that we will use Spring Security's -->
<!-- pre and post invocation Java annotations (@PreFilter, @PreAuthorize, -->
<!-- @PostFilter, -->
<!-- @PostAuthorize) to secure service layer methods.. -->
<!-- Look in GFCBaseCtrl.java onEvent() method. -->
<!-- ====================================================== -->

<!-- Enable the @Secured annotation to secure service layer methods -->
<global-method-security secured-annotations="enabled" />

<http auto-config="true">

<!-- ====================================================== -->
<!-- If we have our own LoginPage. So we must -->
<!-- tell Spring the name and the place. -->
<!-- In our case we take the same page -->
<!-- for a error message by a failure. -->
<!-- Further the page after a successfully login. -->
<!-- ====================================================== -->
<form-login login-page="/login.zul"
authentication-failure-url="/login.zul?login_error=1"
default-target-url="/index.zul" />
<intercept-url pattern="/login.zul" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/*.zul" access="IS_AUTHENTICATED_REMEMBERED" />
<intercept-url pattern="/zk/*" access="IS_AUTHENTICATED_REMEMBERED" />

</http>



<!-- Usernames/Passwords are rod/koala dianne/emu scott/wombat peter/opal -->
<authentication-manager>
<authentication-provider>

<password-encoder hash="md5" />
<user-service>
<user name="rod" password="a564de63c2d0da68cf47586ee05984d7"
authorities="ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER" />
<user name="dianne" password="65d15fe9156f9c4bbffd98085992a44e"
authorities="ROLE_USER,ROLE_TELLER" />
<user name="scott" password="2b58af6dddbd072ed27ffc86725d7d3a"
authorities="ROLE_USER" />
<user name="peter" password="22b5c9accc6e1ba628cedc63a72d57f8"
authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>



login-page : The URL that should be used to render the login page.
Just for this example, we have some user names and their password are encoded.


Step 6:
Next step is to add the login.zul. Select the folder “webapp”. Right click, Select New->Other->Zul file. Enter the file name as login.zul
image

image
Here is the file content.


<?page id="loginPage" title="Digital medical sheet - Login page" onLoad="win.doOverlapped();"?>
<window id="win" title="LOGIN" border="normal" width="300px"
position="center">

<!-- this form-login-page form is also used as the
form-error-page to ask for a login again. -->
<html style="color:red" if="${not empty param.login_error}">

<![CDATA[ Your login attempt was not successful, try
again.<br/><br/> Reason:
${SPRING_SECURITY_LAST_EXCEPTION.message} ]]>

</html>

<groupbox>
<caption>Login</caption>
<h:form id="f" name="f" action="j_spring_security_check"
method="POST" xmlns:h="http://www.w3.org/1999/xhtml">
<grid>
<columns sizable="false">
<column width="50%" />
<column width="50%" />
</columns>
<rows>
<row>
<label value="User:" />
<textbox id="u" name="j_username" />
</row>
<row>
<label value="Password:" />
<textbox id="p" type="password"
name="j_password" />
</row>
<row spans="2">
<div align="center">
<h:input type="submit" value="login" />
<h:input type="reset" value="Reset" />
</div>
</row>
</rows>
</grid>
</h:form>
</groupbox>
</window>

Step 7:
Now the let us change the index.zul file content which is created by default.

<zk>
<window >
Welcome to ZK Secured Page
<button label="Logout" href="/j_spring_security_logout"/>
</window>
</zk>


Step 8:
Now you can select the Project “zkloginexample1”, right click-> Run as –> Run on Server
image
Select the tomcat server and Click finish button


image
Now you can enter any valid username/passwords as follows
rod/koala
dianne/emu
scott/wombat
peter/opal

You can download the source here

Reference
1.
Introduction to Spring Security Concepts.
2. Getting Started Spring Security
3. Understanding Spring Security
4. Configuring spring security

Read More
Posted in ZK Spring | No comments

Saturday, 9 March 2013

ZK MVVM CRUD with Spring 3. and Hibernate 4

Posted on 07:05 by Unknown

In this post, we will see step by step tutorial on simple CRUD operation.

Technologies Used

    1. ZK 6.5.1 CE Version
    3. Hibernate Core Version 4.1.10 Final
    4. Spring ORM Version 3.2.0
    5. MySQL version 5
    6. Maven 3


Part 1, This article will focus on the How to setup the development environment, maven POM File for dependency, Hibernate and spring configuration in web.xml. After that we will create listing page which will list all the records from the DB.

Part 2, This article will focus on the How to ADD new record in the database using CRUD Modal window and after close, refresh the listing screen again.

Part 3, This article will focus on the How to EDIT existing record in the database using the same CRUD Modal window and after close, refresh the listing screen again.

Part 4, This article will focus on the How to VIEW existing record in the database using the same CRUD Modal window

Part 5, This article will focus on the How to  DELETE existing record in the database using the same CRUD Modal window and after close, refresh the listing screen again.

Screen shot
image

image

Project Structure

image

Read More
Posted in ZK MVVM CRUD | No comments

Friday, 8 March 2013

ZK MVVM CRUD With Spring 3 + JPA + Hibernate 4 Entity Manager

Posted on 21:14 by Unknown

A simple CRUD Application based on JPA.

Overview
This article will explain you step by step how to create simple CRUD application using ZK as Presentation layer with Spring 3 and JPA (Hibernate vendor).

What is JPA and why JPA
The Java Persistence API, referred as JPA is a object-relational mapping solution to enterprise Java applications.
JPA is a spec and not an implementation, so if you choose JPA, you still have to pick an implementation. You can pick Hibernate, Top link, and any other ORM that implements JPA.

Using JPA does not tie you to any particular ORM Like hibernate, toplink, etc. EntityManager provides vendor independent access to persistence. Portability across application servers and persistence products (avoids vendor lock-in).

Developers can choose the best ORM implementation according to the application requirement. For example, production can be started from the free versions of ORM implementation and when the needs arise it can be switched to the commercial version of the ORM framework. You can switch the persistence provides without changing the code. So, ORM framework independence is another another big benefit of JPA

Hibernate ORM
In this example, we are going to choose Hibernate as ORM vendor to build the simple CRUD Application.

Spring and Hibernate ORM Framework Integration.
There are lot of articles on the net about this topic. I recommend to the read following articles on this subject.

1. http://www.javabeat.net/2007/10/integrating-spring-framework-with-hibernate-orm-framework/
2. http://static.springsource.org/spring/docs/2.5.x/reference/orm.html
3. http://blog.springsource.org/2012/04/06/migrating-to-spring-3-1-and-hibernate-4-1/
4. http://javaprogrammingtips4u.blogspot.in/2010/04/spring-integration-with-hibernate_23.html

Technologies used in this example:

1. ZK 6.5.1 CE Version.
2. Hibernate-entitymanager 4.1.9 Final
3. Spring-orm 3.2.0 Release
4. Spring-web 3.2.0 Release
5. Java mysql connector 5.1.22

In mysql, create the following table
image

Part 1:  First let us setup the development environment. Download this document and follow the step by step instruction to install the necessary software’s.

Part 2: This post explain how to create ZK Maven project in eclipse IDE as step by step.
Part 3: This post explain how to configure database, user name, password, etc using persistence.xml file
Part 4: This post explain how to integrate Spring and Hibernate.
Part 5: This post explain how to create DAO and service layer for the CRUD operation.
Part 6: This post explain how to create Presentation layer using ZK Framework.
Part 7: This post explain how to change the default ZK CSS for each component and change the look and feel of our application.


Output before with ZK Default CSS Style

image

image

Output after defining our own CSS for each component.

image

image

Video demo:
http://screencast.com/t/F74aYHqqr

You can download the source code here

Read More
Posted in ZK MVVM CRUD, ZK Spring | No comments

Friday, 1 March 2013

ZK MVVM CRUD With Spring 3 + JPA + Hibernate 4 Entity Manager–Part 7

Posted on 10:09 by Unknown

Look and Feel –> Change the default ZK CSS

We have completed all our CRUD operation in the last post. Now we will see how to override the default ZK CSS and change the look and feel our application.

Changing the style of any ZK Component is pretty easy, all we need to override the css class and define our CSS Properties. There are different ways to you can change the CSS as described here. In this , we are going to define sclass styling.

First let us create the following two folders in webapp folder. Folders are “css” and “images” as shown.
image

Under the folder css, let us create css file named as “style.css” and copy the below code.

image

CSS Code

@CHARSET "ISO-8859-1";

/* ----------------------------------------------------------------------------------------------------------------------- */
/* Modal Window CSS Customization
/* ----------------------------------------------------------------------------------------------------------------------- */
.mymodal .z-window-modal-header,.mymodal .z-window-modal-header-noborder
{
padding-top: 1px;
padding-right: -1px;
padding-bottom: 1px;
padding-left: 0;
margin-right: -4px;
color: white;
font-size: 12px;
font-weight: bolder;
}

/* ----------------------------------------------------------------------------------------------------------------------- */
/* Modal Window CSS Customization
/* ----------------------------------------------------------------------------------------------------------------------- */
.mymodal .z-window-modal-hm,.mymodal .z-window-modal-br,.mymodal .z-window-modal-cr,.mymodal .z-window-modal-cl,.mymodal .z-window-modal-hr,.mymodal .z-window-modal-tr,.mymodal .z-window-modal-hl
{
background-image: none;
background: transparent repeat-x 0 0;
background: #6F8992; /* Old browsers */
background-image: -ms-linear-gradient(top, #6F8992 0%, #6F8992 100%);
/* IE10+ */
background-image: -moz-linear-gradient(top, #6F8992 0%, #6F8992 100%);
/* Firefox 3.6+ */
background-image: -o-linear-gradient(top, #6F8992 0%, #6F8992 100%);
/* Opera 11.10+ */
background-image: -webkit-gradient(linear, top, bottom, color-stop(0%, #6F8992),
color-stop(100%,, #6F8992) ); /* Chrome,Safari4+ */
background-image: -webkit-linear-gradient(top, #6F8992 0%, #6F8992 100%);
/* Chrome10+,Safari5.1+ */
background-image: linear-gradient(to bottom, #6F8992 0%, #6F8992 100%);
/* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#6F8992',
endColorstr='#6F8992', GradientType=0 ); /* IE6-9 */
}

.mymodal .z-window-modal-icon {
width: 20px;
height: 16px;
border-width: 1px;
border-style: solid;
border-color: #6F8992 #6F8992 #6F8992 #6F8992;
box-shadow: inset 0 1px 0 #6F8992, inset -1px -1px 0 #6F8992, inset -1px
-2px 0 #6F8992;
}

.mymodal .z-window-modal-close {
background: url('../images/CloseBlue.gif') transparent no-repeat 0 0;
}

/* ----------------------------------------------------------------------------------------------------------------------- */
/* Listbox CSS Customization
/* ----------------------------------------------------------------------------------------------------------------------- */
.z-listcell.highlightcell .z-listcell-cnt,.z-label.highlightcell {
color: blue;
cursor: pointer;
text-decoration: underline;
}

.mylist .z-listbox {
background: none repeat scroll 0 0 #FFFFFF;
border: 1px solid #CFCFCF;
overflow: hidden;
}

.mylist .z-listitem-seld {
background-image: none;
background-color: #DDF0FB;
}

.mylist .z-listitem.z-listbox-odd.z-listitem-seld {
background-image: none;
background-color: #E0F7BA;
}

.mylist .z-listitem.z-listitem-over {
background-image: none;
background-color: #E0F7BA;
}

.mylist .z-listitem-odd-seld {
background-image: none;
background-color: #DDF0FB;
}

.mylist .z-listbox-header tr.z-listhead,div.z-listbox-header
tr.z-auxhead {
background-color: #6F8992;
}

/* Header and Footer Font and Height */
.mylist
.z-listfooter-cnt,.mylist .z-listheader-cnt {
border: 0 none;
color: white;
font-size: 13px;
margin: 0;
height: 14px;
}

/* Cell Height and Font */
.mylist .z-listcell-cnt {
font-size: 13px;
height: 20px;
}

.mylist .z-listbox-body .z-listcell,.mylist.z-listbox-footer
.z-listfooter {
cursor: default;
}

.mylist .z-listheader-sort-img {
float: left;
font-size: 0;
left: 90%;
margin-left: auto;
margin-right: auto;
position: absolute;
}

.mylist .z-listbox-header tr.z-listhead,div.z-listbox-header
tr.z-auxhead {
background-image: none;
color: white;
}

.mylist .z-listbox-header th.z-listheader-sort-over {
background-image: none;
}

/* ----------------------------------------------------------------------------------------------------------------------- */
/* Label CSS Customization
/* ----------------------------------------------------------------------------------------------------------------------- */
.TitleWBold.z-label {
font-weight: bolder;
color: #FFFFFF;
}

.TitleBold.z-label {
font-weight: bolder;
}

.sectionTitleLabel.z-label {
font-size: 14px;
font-weight: bolder;
color: #0C6BA8;
}

.flabel.z-label {
font-size: 12px;
font-weight: normal;
}

/* ----------------------------------------------------------------------------------------------------------------------- */
/* Text Box
/* ----------------------------------------------------------------------------------------------------------------------- */
.ftextbox.z-textbox.z-textbox-focus {
border-style: solid;
border-width: 1px;
border-color: blue;
}

/* ----------------------------------------------------------------------------------------------------------------------- */
/* Vertical Grid
/* ----------------------------------------------------------------------------------------------------------------------- */
.vgrid tr.z-row
td.z-row-inner,tr.z-row,div.z-grid-body div.z-cell,div.z-grid {
border: none;
overflow: hidden;
zoom: 1;
background: white;
border-top: none;
border-left: none;
border-right: none;
border-bottom: none;
}

.vgrid .z-grid-odd .vgrid .z-row-inner,.vgrid .z-grid-odd .z-cell {
background-color: transparent;
border-bottom: 1px solid transparent;
border-left: 1px solid transparent;
border-top: 1px solid transparent;
}

.vgrid .z-grid-odd .vgrid.z-row-inner,.vgrid.z-grid-odd .z-cell,.vgrid.z-grid-odd
{
background: none repeat scroll 0 0 transparent;
}

.vgrid tr.z-row td.z-row-inner,.vgrid tr.z-row .z-cell {
line-height: 12px;
}

.vgrid tr.z-grid-odd td.z-row-inner,.vgrid tr.z-grid-odd .z-cell,.vgrid tr.z-grid-odd
{
background: white
}

.vgrid tr.z-row td.z-row-inner,.vgrid tr.z-row .z-cell {
background: white;
border-top: none;
}

/* End: Form Grid
---------------------------------------------- */

/* Start: Action Images- Auditlog
---------------------------------------------- */
.fImageAudit {
width: 25px;
background-image: url('../images/AuditLog.jpg');
background-repeat: no-repeat;
border: 0 none;
cursor: pointer;
}

/* Start: Action Images- Edit
---------------------------------------------- */
.fimageedit {
width: 25px;
background-image: url('../images/EditRecord.png');
background-repeat: no-repeat;
border: 0 none;
cursor: pointer;
}

/* End: Action Images - Edit
---------------------------------------------- */

/* Start: Action Images- Delete
---------------------------------------------- */
.fimageDelete {
width: 25px;
background-image: url('../images/DeleteRecord.png');
background-repeat: no-repeat;
border: 0 none;
cursor: pointer;
}

.fimageView {
width: 25px;
background-image: url('../images/view.png');
background-repeat: no-repeat;
border: 0 none;
cursor: pointer;
}

/* End: Action Images - Delete
---------------------------------------------- */

/* Start: Action Images- Active
---------------------------------------------- */
.fimageActive {
width: 25px;
background-image: url('../images/ActiveRecord.png');
background-repeat: no-repeat;
border: 0 none;
cursor: pointer;
}

/* End: Action Images - Active
---------------------------------------------- */

/* Start: Action Images- Inactive
---------------------------------------------- */
.fimageInactive {
width: 25px;
background-image: url('../images/DeactivateRecord.png');
background-repeat: no-repeat;
border: 0 none;
cursor: pointer;
}

/* End: Action Images - InActive
---------------------------------------------- */

/* ----------------------------------------------------------------------------------------------------------------------- */
/* Label CSS Customization
/* ----------------------------------------------------------------------------------------------------------------------- */
.sectionTitleLabel.z-label {
color: #0C6BA8;
}

/* ----------------------------------------------------------------------------------------------------------------------- */
/* Div(s)
/* ----------------------------------------------------------------------------------------------------------------------- */
.sectionTitle {
float: left;
padding-left: 10px;
}

.sectionTitleBar {
background: none repeat scroll 0 0 #6F8992;
margin-left: 20px;
padding: 2px 5px;
}

.sectionSeperator {
margin-bottom: 18px;
padding-bottom: 0.25em;
margin-left: 10px;
border-bottom: 4px solid #DFDFDF
}

/* ----------------------------------------------------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------------------------------------------------------- */
/* Patient Cases
/* ----------------------------------------------------------------------------------------------------------------------- */
.patientcaseHeader {
background: none repeat scroll 0 0 #6F8992;
padding: 2px 10px;
}

/* ----------------------------------------------------------------------------------------------------------------------- */
/* End of Patient Cases
/* ----------------------------------------------------------------------------------------------------------------------- */
.mybutton.z-button .z-button-cm {
background-image: none;
color: white;
font-weight: bolder;
}

.mybutton.z-button .z-button-tm,.z-button .z-button-bm {
background-image: none;
}

.mybutton.z-button .z-button-cl,.z-button .z-button-cr {
background-image: none;
}

.mybutton.z-button .z-button-tl {
background-image: none;
}

.mybutton.z-button .z-button-bl {
background-image: none;
}

.mybutton.z-button .z-button-tr {
background-image: none;
}

.mybutton.z-button .z-button-br {
background-image: none;
}

.button {
display: inline-block;
zoom: 1; /* zoom and *display = ie7 hack for display:inline-block */
*display: inline;
vertical-align: baseline;
margin: 0 2px;
outline: none;
cursor: pointer;
text-align: center;
text-decoration: none;
font: 14px/100% Arial, Helvetica, sans-serif;
padding: .5em 2em .55em;
text-shadow: 0 1px 1px rgba(0, 0, 0, .3);
-webkit-border-radius: .5em;
-moz-border-radius: .5em;
border-radius: .5em;
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .2);
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, .2);
box-shadow: 0 1px 2px rgba(0, 0, 0, .2);
}

.button:hover {
text-decoration: none;
}

.button:active {
position: relative;
top: 1px;
}

.bigrounded {
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius: 2em;
}

.medium {
font-size: 12px;
padding: .4em 1.5em .42em;
}

.small {
font-size: 11px;
padding: .2em 1em .275em;
}

/* color styles
---------------------------------------------- */

/* black */
.black {
color: #d7d7d7;
border: solid 1px #333;
background: #333;
background: -webkit-gradient(linear, left top, left bottom, from(#666),
to(#000) );
background: -moz-linear-gradient(top, #666, #000);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#666666',
endColorstr='#000000' );
}

.black:hover {
background: #000;
background: -webkit-gradient(linear, left top, left bottom, from(#444),
to(#000) );
background: -moz-linear-gradient(top, #444, #000);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#444444',
endColorstr='#000000' );
}

.black:active {
color: #666;
background: -webkit-gradient(linear, left top, left bottom, from(#000),
to(#444) );
background: -moz-linear-gradient(top, #000, #444);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#000000',
endColorstr='#666666' );
}

/* gray */
.gray {
color: #e9e9e9;
border: solid 1px #555;
background: #6e6e6e;
background: -webkit-gradient(linear, left top, left bottom, from(#888),
to(#575757) );
background: -moz-linear-gradient(top, #888, #575757);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#888888',
endColorstr='#575757' );
}

.gray:hover {
background: #616161;
background: -webkit-gradient(linear, left top, left bottom, from(#757575),
to(#4b4b4b) );
background: -moz-linear-gradient(top, #757575, #4b4b4b);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#757575',
endColorstr='#4b4b4b' );
}

.gray:active {
color: #afafaf;
background: -webkit-gradient(linear, left top, left bottom, from(#575757),
to(#888) );
background: -moz-linear-gradient(top, #575757, #888);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#575757',
endColorstr='#888888' );
}

/* white */
.white {
color: #606060;
border: solid 1px #b7b7b7;
background: #fff;
background: -webkit-gradient(linear, left top, left bottom, from(#fff),
to(#ededed) );
background: -moz-linear-gradient(top, #fff, #ededed);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',
endColorstr='#ededed' );
}

.white:hover {
background: #ededed;
background: -webkit-gradient(linear, left top, left bottom, from(#fff),
to(#dcdcdc) );
background: -moz-linear-gradient(top, #fff, #dcdcdc);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',
endColorstr='#dcdcdc' );
}

.white:active {
color: #999;
background: -webkit-gradient(linear, left top, left bottom, from(#ededed),
to(#fff) );
background: -moz-linear-gradient(top, #ededed, #fff);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',
endColorstr='#ffffff' );
}

/* orange */
.orange {
color: #fef4e9;
border: solid 1px #da7c0c;
background: #f78d1d;
background: -webkit-gradient(linear, left top, left bottom, from(#faa51a),
to(#f47a20) );
background: -moz-linear-gradient(top, #faa51a, #f47a20);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#faa51a',
endColorstr='#f47a20' );
}

.orange:hover {
background: #f47c20;
background: -webkit-gradient(linear, left top, left bottom, from(#f88e11),
to(#f06015) );
background: -moz-linear-gradient(top, #f88e11, #f06015);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f88e11',
endColorstr='#f06015' );
}

.orange:active {
color: #fcd3a5;
background: -webkit-gradient(linear, left top, left bottom, from(#f47a20),
to(#faa51a) );
background: -moz-linear-gradient(top, #f47a20, #faa51a);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f47a20',
endColorstr='#faa51a' );
}

/* red */
.red {
color: #faddde;
border: solid 1px #980c10;
background: #d81b21;
background: -webkit-gradient(linear, left top, left bottom, from(#ed1c24),
to(#aa1317) );
background: -moz-linear-gradient(top, #ed1c24, #aa1317);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ed1c24',
endColorstr='#aa1317' );
}

.red:hover {
background: #b61318;
background: -webkit-gradient(linear, left top, left bottom, from(#c9151b),
to(#a11115) );
background: -moz-linear-gradient(top, #c9151b, #a11115);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#c9151b',
endColorstr='#a11115' );
}

.red:active {
color: #de898c;
background: -webkit-gradient(linear, left top, left bottom, from(#aa1317),
to(#ed1c24) );
background: -moz-linear-gradient(top, #aa1317, #ed1c24);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#aa1317',
endColorstr='#ed1c24' );
}

/* blue */
.blue {
color: #d9eef7;
border: solid 1px #0076a3;
background: #0095cd;
background: -webkit-gradient(linear, left top, left bottom, from(#00adee),
to(#0078a5) );
background: -moz-linear-gradient(top, #00adee, #0078a5);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00adee',
endColorstr='#0078a5' );
}

.blue:hover {
background: #007ead;
background: -webkit-gradient(linear, left top, left bottom, from(#0095cc),
to(#00678e) );
background: -moz-linear-gradient(top, #0095cc, #00678e);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0095cc',
endColorstr='#00678e' );
}

.blue:active {
color: #80bed6;
background: -webkit-gradient(linear, left top, left bottom, from(#0078a5),
to(#00adee) );
background: -moz-linear-gradient(top, #0078a5, #00adee);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0078a5',
endColorstr='#00adee' );
}

/* rosy */
.rosy {
color: #fae7e9;
border: solid 1px #b73948;
background: #da5867;
background: -webkit-gradient(linear, left top, left bottom, from(#f16c7c),
to(#bf404f) );
background: -moz-linear-gradient(top, #f16c7c, #bf404f);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f16c7c',
endColorstr='#bf404f' );
}

.rosy:hover {
background: #ba4b58;
background: -webkit-gradient(linear, left top, left bottom, from(#cf5d6a),
to(#a53845) );
background: -moz-linear-gradient(top, #cf5d6a, #a53845);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cf5d6a',
endColorstr='#a53845' );
}

.rosy:active {
color: #dca4ab;
background: -webkit-gradient(linear, left top, left bottom, from(#bf404f),
to(#f16c7c) );
background: -moz-linear-gradient(top, #bf404f, #f16c7c);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#bf404f',
endColorstr='#f16c7c' );
}

/* green */
.green {
color: #e8f0de;
border: solid 1px #538312;
background: #64991e;
background: -webkit-gradient(linear, left top, left bottom, from(#7db72f),
to(#4e7d0e) );
background: -moz-linear-gradient(top, #7db72f, #4e7d0e);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#7db72f',
endColorstr='#4e7d0e' );
}

.green:hover {
background: #538018;
background: -webkit-gradient(linear, left top, left bottom, from(#6b9d28),
to(#436b0c) );
background: -moz-linear-gradient(top, #6b9d28, #436b0c);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#6b9d28',
endColorstr='#436b0c' );
}

.green:active {
color: #a9c08c;
background: -webkit-gradient(linear, left top, left bottom, from(#4e7d0e),
to(#7db72f) );
background: -moz-linear-gradient(top, #4e7d0e, #7db72f);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#4e7d0e',
endColorstr='#7db72f' );
}

/* pink */
.pink {
color: #feeef5;
border: solid 1px #d2729e;
background: #f895c2;
background: -webkit-gradient(linear, left top, left bottom, from(#feb1d3),
to(#f171ab) );
background: -moz-linear-gradient(top, #feb1d3, #f171ab);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#feb1d3',
endColorstr='#f171ab' );
}

.pink:hover {
background: #d57ea5;
background: -webkit-gradient(linear, left top, left bottom, from(#f4aacb),
to(#e86ca4) );
background: -moz-linear-gradient(top, #f4aacb, #e86ca4);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f4aacb',
endColorstr='#e86ca4' );
}

.pink:active {
color: #f3c3d9;
background: -webkit-gradient(linear, left top, left bottom, from(#f171ab),
to(#feb1d3) );
background: -moz-linear-gradient(top, #f171ab, #feb1d3);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f171ab',
endColorstr='#feb1d3' );
}

Now let us refer the above CSS in our project. In order to do, please do the following steps.
1. Add ZKAddon.xml(it can be any name), under the webapp folder as shown

image


Copy the below code.

<?xml version="1.0" encoding="UTF-8"?>
<language-addon>
<addon-name>myaddon</addon-name>
<language-name>xul/html</language-name>
<stylesheet href="/css/style.css" type="text/css" />

</language-addon>



2. Open the zk.xml and add the following line

<?xml version="1.0" encoding="UTF-8"?>

<zk>
<language-config>
<addon-uri>/ZKAddon.xml</addon-uri>
</language-config>

</zk>


Now , we will modify our two zul files to include the sclass attribute for each component
Here is the modified AddressList.zul

<?page title="Address List" contentType="text/html;charset=UTF-8"?>
<zk>
<window id="addressList" border="none"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('zkoss.vm.AddressListVM')">
<separator />
<separator />
<div width="100%">
<div sclass="sectionTitle">
<separator />
<label value="Address Book" sclass="sectionTitleLabel" />
<separator />
</div>
<div style="float:right">
<button label="Add New" onClick="@command('onAddNew')"
mold="trendy" sclass="mybutton button blue small" />
</div>
<div style="clear: both;"></div>
<div sclass="sectionSeperator"></div>
</div>
<separator />
<listbox id="" mold="paging" pageSize="11" pagingPosition="top"
sclass="mylist" selectedItem="@bind(vm.selectedItem)"
model="@load(vm.dataSet)">
<listhead sizable="true">
<listheader label="Full Name" sortDirection="ascending"
sort="auto(fullName)" />
<listheader label="Email" sort="auto(email)" />
<listheader label="Mobile" sort="auto(mobile)" />
<listheader label="Action" />
</listhead>
<template name="model" var="p1">
<listitem>
<listcell label="@load(p1.fullName)" />
<listcell label="@load(p1.email)" />
<listcell label="@load(p1.mobile)" />
<listcell>
<hbox spacing="20px">
<image
onClick="@command('onEdit',addressRecord=p1)"
sclass="fimageedit">
</image>
<image
onClick="@command('openAsReadOnly',addressRecord=p1)"
sclass="fimageView">
</image>
<image
onClick="@command('onDelete',addressRecord=p1)"
sclass="fimageDelete">
</image>
</hbox>
</listcell>
</listitem>
</template>
</listbox>
</window>
</zk>


Here is the modified AddressCRUD.zul

<?page title="new page title" contentType="text/html;charset=UTF-8"?>
<zk>
<window title="Address" id="addressCRUD" border="normal" width="30%"
mode="modal" maximizable="false" closable="true" sclass="mymodal"
position="center,parent" apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('zkoss.vm.AddressListCRUDVM')">
<panel width="100%">
<panelchildren>
<separator />
<grid sclass="vgrid">
<columns>
<column></column>
<column></column>
</columns>
<rows>
<row>
<cell colspan="2">
<vlayout>
<label value="Full Name" />
<textbox id="fullName" hflex="1"
readonly="@load(vm.makeAsReadOnly)"
value="@load(vm.selectedRecord.fullName) @save(vm.selectedRecord.fullName, before='saveThis')"
mold="rounded" />
</vlayout>
</cell>
</row>
<row>
<cell colspan="2">
<vlayout>
<label value="Address" />
<textbox id="address1" hflex="1"
readonly="@load(vm.makeAsReadOnly)"
value="@load(vm.selectedRecord.address1) @save(vm.selectedRecord.address2, before='saveThis')"
mold="rounded" />
</vlayout>
</cell>
</row>
<row>
<cell colspan="2">
<vlayout>
<textbox id="address2" hflex="1"
readonly="@load(vm.makeAsReadOnly)"
value="@load(vm.selectedRecord.address2) @save(vm.selectedRecord.address2, before='saveThis')"
mold="rounded" />
</vlayout>
</cell>
</row>
<row>
<vlayout>
<label value="City" />
<textbox id="City" hflex="1"
readonly="@load(vm.makeAsReadOnly)"
value="@load(vm.selectedRecord.city) @save(vm.selectedRecord.city, before='saveThis')"
mold="rounded" />
</vlayout>
<vlayout>
<grid sclass="vgrid">
<columns>
<column width="30%"></column>
<column></column>
</columns>
<rows>
<row>
<vlayout>
<label value="State" />
<textbox id="State"
readonly="@load(vm.makeAsReadOnly)"
value="@load(vm.selectedRecord.state) @save(vm.selectedRecord.state, before='saveThis')"
hflex="1" mold="rounded" />
</vlayout>
<vlayout>
<label value="ZipCode" />
<textbox id="zipcode"
readonly="@load(vm.makeAsReadOnly)"
value="@load(vm.selectedRecord.zipCode) @save(vm.selectedRecord.zipCode, before='saveThis')"
hflex="1" mold="rounded" />
</vlayout>
</row>
</rows>
</grid>
</vlayout>
</row>
<row>
<cell colspan="2">
<vlayout>
<label value="Email" />
<textbox id="email" hflex="1"
readonly="@load(vm.makeAsReadOnly)"
value="@load(vm.selectedRecord.email) @save(vm.selectedRecord.email, before='saveThis')"
mold="rounded" />
</vlayout>
</cell>
</row>
<row>
<vlayout>
<label value="Mobile" />
<textbox id="Mobile" hflex="1"
readonly="@load(vm.makeAsReadOnly)"
value="@load(vm.selectedRecord.mobile) @save(vm.selectedRecord.mobile, before='saveThis')"
mold="rounded" />
</vlayout>
</row>

</rows>
</grid>
</panelchildren>
</panel>
<separator />
<separator />
<separator />
<div align="center">
<button label="Save" visible="@load(not vm.makeAsReadOnly)"
onClick="@command('saveThis')" mold="trendy"
sclass="mybutton button blue small" />
<button label="@load(vm.makeAsReadOnly ?'Ok':'Cancel')"
onClick="@command('closeThis')" mold="trendy"
sclass="mybutton button blue small" />
</div>
<separator />
</window>
</zk>


Now run the application, you can see the output as follows.


image
image


You can view the Video demo here

Read More
Posted in ZK Spring | No comments
Newer Posts Older Posts Home
Subscribe to: Posts (Atom)

Popular Posts

  • EDI 270–5010 Documentation - ISA – Interchange Control Header
    ISA – Interchange Control Header ISA – Interchange Control Header   The ISA is a fixed record length segment and all positions within ea...
  • Understanding EDI Structure
    EDI Structure Primary Levels are 1. Interchange Envelops 2. Functional Group 3. Transaction set Data Element A data element is equival...
  • ZK Example for inline Editing with Add New and Delete
    I am quite impressed on this demo from ZK . But adding new record and delete existing record is missing as part of typical CRUD. So i thoug...
  • EDI Instructions
    HIPAA Compliant Codes All the Health care EDI Transaction set should use only the following HIPAA Compliant Codes Physicians Current Pro...
  • ZK ListBox
    Let us first design a simple  static list box with crud Buttons as last column. Here is the code <?page title="Practice List" c...
  • Types of Reimbursement
    Fee-For-Service Fee-for-service is a method of payment where the provider is paid a fee for each procedure performed and billed.Most payer ...
  • List Item Connected with Hibernate and Search Parameter
      Summary This example contains one list box with First name and Last Name as search Field. If the user do not give any values for first n...
  • EDI 270 - 5010 Health Care Eligibility/Benefit Inquiry
    If you are new to Medical Billing, then please read this article first . If you are new to EDI, then  read the following articles 1. What i...
  • EDI Transactions
    The HIPAA transactions and code set standards are rules that standardize the electronic exchange of health-related administrative informati...
  • Hibernate Validator Example 2
    In this example, we will see some more validation constraints such as @email, @past, @length, etc. And also we will also define custom error...

Categories

  • Billing Process
  • C Workbook
  • C++ Workbook
  • Eclipse Tips
  • EDI 5010
  • EMR Appointment Features
  • EMR Labs Stuff
  • EMR PMS Links
  • EMR Use cases
  • EMR Vital Sign
  • Good Website Design
  • Hibernate Criteria Queries
  • Hibernate Introduction
  • Hibernate Introduction Setup
  • Hibernate Mapping
  • Hibernate POC
  • Hibernate Validator
  • Hibernate–Java Environment setup
  • HPI
  • Java
  • Maven
  • MU Certification
  • NPI
  • PQRS
  • Practice Management System
  • Spring Security
  • Tech Links
  • Today Tech Stuff
  • zk
  • ZK Hibernate
  • ZK 5 Databinding
  • ZK Application
  • ZK Calling Another ZUL
  • ZK CheckBox
  • ZK CreateComponents
  • ZK CSS
  • ZK extended Components
  • ZK Foreach
  • ZK Forum Posts
  • ZK Framework
  • ZK Hibernate Setup
  • ZK ID Space
  • ZK Include
  • ZK Installation
  • ZK iReport
  • ZK Layout
  • ZK Listitem Pagination
  • ZK Message Box
  • ZK MVC
  • ZK MVC Combox Box
  • ZK MVC CRUD Examples
  • ZK MVC Listbox
  • ZK MVVM
  • ZK MVVM Combo
  • ZK MVVM CRUD
  • ZK MVVM ListBox
  • ZK Spring
  • ZK TextBox

Blog Archive

  • ▼  2013 (105)
    • ▼  December (3)
      • EDI Instructions
      • Understanding EDI Structure
      • What is an EDI ?
    • ►  September (7)
    • ►  August (13)
    • ►  July (1)
    • ►  June (11)
    • ►  May (3)
    • ►  April (14)
    • ►  March (19)
    • ►  February (21)
    • ►  January (13)
  • ►  2012 (177)
    • ►  December (1)
    • ►  November (13)
    • ►  October (19)
    • ►  September (24)
    • ►  August (26)
    • ►  July (6)
    • ►  June (37)
    • ►  May (30)
    • ►  April (16)
    • ►  March (1)
    • ►  January (4)
  • ►  2011 (5)
    • ►  December (1)
    • ►  November (1)
    • ►  July (1)
    • ►  June (1)
    • ►  April (1)
  • ►  2010 (1)
    • ►  September (1)
Powered by Blogger.

About Me

Unknown
View my complete profile