Requirement Constraints

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

Thursday, 11 April 2013

ZK MVVM Form Binding CRUD with Spring and Hibernate - Part 8

Posted on 05:45 by Unknown

ZK Theme customization for each user.

        


Well, now we can create users and login using the newly created users. How about changing the look and feel for each user ?.
Yes this can be done using “Packaging Themes Inside Folders in ZK 6.5.2”

ZK Reference
1. Packaging Themes Inside Folders in ZK 6.5.2
2. Providing Theme Resources
3. Switch different themes dynamically

So what we are going to do now ?
1. For each user, we will ask what is their preferred theme while creating their information. In this example, I am going to have 5 different of colors such as red,blue,green,purple and brown.
2. After user is created and set their preferred theme, then after user is logged in, then we will change the theme.

Let’s start.

Step 1:
First let us organize our images folder. As per the previous article, the images folder structure as shown.
[image%255B20%255D.png]

You can see, we have been using low_bkg.gif, side_bkg.gif, side_mid.gif, side_top.gif,top_bkg.gif. All these images are in blue color. So we should have the same set of images with green, purple, brown and red. Where we can get this images. Either you can get from the source provided at the bottom or you can get it from here.

Now let us change our images folder structure such as each color will have folder and the folder have the corresponding images as shown.
image

Step 2:
Next we will modify our CSS Folder. As per previous article, the CSS Folder will look as follows
image
If you look the code on the above css file, you can observe that style.css does not contain any color related CSS Property. But the themestyle.css contains all color (blue) related property.

So we have already have the blue color css ? what about for other colors such as purple, red, brown and green. Well, just take a copy of the themestyle.css and paste 4 times and change to corresponding color. Finally rename the themeStyle.css to blueTheme.css. So the modified structure will look as follows
image
You can get the code from the source provided at the bottom of this post. Finally, modify the zkAddon.xml as follows

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

</language-addon>

At the bottom of each file, we have three css classes such as .theme, .theme:hover and .theme:active. Even though class names are same, but the background color is different. We will use this class for our buttons.

Step 3:
In the UserCRUD.zul and userList.zul, change the button sclass from “mybutton button blue small” to “mybutton button theme small”.

Step 4:
Next we will create all 5 theme using folder structure. For zk documentation, please refer here. Follow the steps to create theme folders.

1. Download ZK 6.5.2 CE Bin Zip file
2. Create a folder zk_jars in your drive. For example c:\zk_jars.
3. Extract all the files from zk-bin-6.5.2\zk-bin-6.5.2\dist\lib  and copy to c:\zk_jars
4. Download the ztx.bat and copy in c:\zk_jars.
5. In the command line, goto to the folder c:\zk_jars and run the command ztx.bat C:\zk_jars bluetheme
6. Now, ztx batch file will create a jar file in the name of bluetheme.jar
7. Extract the bluetheme.jar and will contain two root folders such as js and zul.
7. Now come to eclipse and under the webapp folder , create a folder called “theme”.
8. In the theme folder, copy the bluetheme folder.
9. Similarly, create 4 more jars in the name of browntheme, greentheme, purpletheme and redtheme.
10. Now the folder structure will look as follows
image
Then, in the web.xml, include the following lines


<servlet>
    <servlet-name>dspLoader</servlet-name>
    <servlet-class>org.zkoss.web.servlet.dsp.InterpreterServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>dspLoader</servlet-name>
    <url-pattern>*.dsp</url-pattern>
</servlet-mapping>

Step 5:
Next we will add one more column in the table userprofile such as theme varchar(300) Null. We will update our domain object as follows


package zkexample.domain;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.NamedQuery;

@Entity
@Table(name = "userprofile")
@NamedQuery(name = "UserProfile.findUserByUserID", query = "SELECT usr FROM UserProfile as usr WHERE usr.userLoginID = ?")
public class UserProfile implements Serializable {

*********Other Code**************
private String theme;

*********Other Code**************

public String getTheme() {
return theme;

}


public void setTheme(String theme) {
this.theme = theme;
}

}

Step 6:
As we said in the introduction, while creating user, we will load all the theme and ask the user to set their preference. So we will add one more component next to password field such as combo box. Here is the code snipped to include combo box.


	<rows>
<row>
<vlayout>
<label value="Login ID"
sclass="flabel" />
<textbox id="loginid" hflex="1"
readonly="@load(vm.makeAsReadOnly)" mold="rounded"
value="@bind(fx.userLoginID)" />
</vlayout>
<vlayout>
<label value="Password"
sclass="flabel" />
<textbox id="password" width="80%"
readonly="@load(vm.makeAsReadOnly)" mold="rounded"
value="@bind(fx.password)" />
</vlayout>
<vlayout>
<label value="Theme"
sclass="flabel" />
<combobox model="@load(vm.themes)"
width="30%" mold="rounded"
selectedItem="@bind(fx.theme)"
value="@bind(fx.theme)" />
</vlayout>
</row>

Next we have to register the new themes and we will load all the theme in the above combo box. So we need to modify zkexample.zkoss.UserCRUDVM


package zkexample.zkoss;

import java.util.Arrays;
import java.util.HashMap;

import org.zkoss.bind.BindUtils;
import org.zkoss.bind.annotation.AfterCompose;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.ExecutionArgParam;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.web.theme.StandardTheme.ThemeOrigin;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.select.Selectors;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zkplus.spring.SpringUtil;
import org.zkoss.zul.Center;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.theme.Themes;

import zkexample.domain.UserProfile;
import zkexample.service.CRUDService;

public class UserCRUDVM {

private Center centerArea;

@WireVariable
private CRUDService CRUDService;

private UserProfile selectedRecord;
private String recordMode;
private boolean makeAsReadOnly;
private DataFilter dataFilter = new DataFilter();

// Available themes
private ListModel<String> _themes = null;
// Current theme name
private String currentTheme = null;

public ListModel<String> getThemes() {
return _themes;
}

public String getCurrentTheme() {
return currentTheme;
}

@NotifyChange("currentTheme")
public void setCurrentTheme(String currentTheme) {
this.currentTheme = currentTheme;
}

public DataFilter getDataFilter() {
return dataFilter;
}

public void setDataFilter(DataFilter dataFilter) {
this.dataFilter = dataFilter;
}

public UserProfile getSelectedRecord() {
return selectedRecord;
}

public void setSelectedRecord(UserProfile selectedRecord) {
this.selectedRecord = selectedRecord;
}

public String getRecordMode() {
return recordMode;
}

public void setRecordMode(String recordMode) {
this.recordMode = recordMode;
}

public boolean isMakeAsReadOnly() {
return makeAsReadOnly;
}

public void setMakeAsReadOnly(boolean makeAsReadOnly) {
this.makeAsReadOnly = makeAsReadOnly;
}

@AfterCompose
public void initSetup(@ContextParam(ContextType.VIEW) Component view,
@ExecutionArgParam("selectedRecord") UserProfile userProfile,
@ExecutionArgParam("recordMode") String recordMode,
@ExecutionArgParam("centerArea") Center centerArea) {

Selectors.wireComponents(view, this, false);
setRecordMode(recordMode);
CRUDService = (CRUDService) SpringUtil.getBean("CRUDService");
this.centerArea = centerArea;

Themes.register("bluetheme", ThemeOrigin.FOLDER);
Themes.register("greentheme", ThemeOrigin.FOLDER);
Themes.register("browntheme", ThemeOrigin.FOLDER);
Themes.register("purpletheme", ThemeOrigin.FOLDER);
Themes.register("redtheme", ThemeOrigin.FOLDER);

String[] themes = Themes.getThemes();
themes = Arrays.copyOf(themes, themes.length + 1);

// Attempting to switch to a theme that is not registered
// will switch to the default theme (i.e. breeze)
themes[themes.length - 1] = "unknown";
_themes = new ListModelList<String>(themes);

currentTheme = Themes.getCurrentTheme();

if (recordMode.equals("NEW")) {
this.selectedRecord = new UserProfile();
this.selectedRecord.setSystem(0);
}

if (recordMode.equals("EDIT")) {
this.selectedRecord = userProfile;
}

if (recordMode == "READ") {
setMakeAsReadOnly(true);
this.selectedRecord = userProfile;
}
}

@Command
public void saveThis(@BindingParam("action") Integer action) {
CRUDService.Save(this.selectedRecord);
if (action == 0) {
final HashMap<String, Object> map = new HashMap<String, Object>();
map.put("centerArea", centerArea);
centerArea.getChildren().clear();
Executions.createComponents("userList.zul", centerArea, map);
}
if (action == 1) {
this.selectedRecord = new UserProfile();
BindUtils.postNotifyChange(null, null, UserCRUDVM.this,
"selectedRecord");

}
}

@Command
public void cancel() {
final HashMap<String, Object> map = new HashMap<String, Object>();
map.put("centerArea", centerArea);
centerArea.getChildren().clear();
Executions.createComponents("userList.zul", centerArea, map);
}

}

Step 7:
Next we have inject our theme(color) css file into zk theme provider. For zk documentation, please refer here.
Create a new class called MyThemeProvider.java under the zkoss package as shown.
image



package zkexample.zkoss;

import java.util.Collection;
import java.util.List;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.zkoss.zk.ui.Execution;
import org.zkoss.zk.ui.util.ThemeProvider;

public class MyThemeProvider implements ThemeProvider {

public Collection<Object> getThemeURIs(Execution exec, List<Object> uris) {

if ("greentheme".equals(getSkinCookie(exec))) {
uris.add("/css/greenTheme.css");
}
if ("bluetheme".equals(getSkinCookie(exec))) {
uris.add("/css/blueTheme.css");
}
if ("browntheme".equals(getSkinCookie(exec))) {
uris.add("/css/brownTheme.css");
}
if ("purpletheme".equals(getSkinCookie(exec))) {
uris.add("/css/purpleTheme.css");
}
if ("redtheme".equals(getSkinCookie(exec))) {
uris.add("/css/redTheme.css");
}

return uris;
}

public int getWCSCacheControl(Execution exec, String uri) {
return -1;
}

public String beforeWCS(Execution exec, String uri) {
return uri;
}

public String beforeWidgetCSS(Execution exec, String uri) {
return uri;
}

/** Returns the skin specified in cookie. */
private static String getSkinCookie(Execution exec) {
Cookie[] cookies = ((HttpServletRequest) exec.getNativeRequest())
.getCookies();
if (cookies != null)

for (int i = 0; i < cookies.length; i++) {

if ("zktheme".equals(cookies[i].getName()))
return cookies[i].getValue();
}
return "";
}

}

Then, you configure WEB-INF/zk.xml by adding the following lines.


<desktop-config>
<theme-provider-class>zkexample.zkoss.MyThemeProvider</theme-provider-class>
</desktop-config>

Step 8:
Next we need dynamically switch the theme after user logged in. We will do this in MainVM as follows


package zkexample.zkoss;

import java.util.HashMap;

import org.zkoss.bind.annotation.AfterCompose;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.Init;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Session;
import org.zkoss.zk.ui.select.Selectors;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Center;
import org.zkoss.zul.theme.Themes;

public class MainVM {

@Wire("#mainlayout")
private Borderlayout borderLayout;

@WireVariable
private Session _sess;

/**
* This method will be called after host component composition has been done
* (AfterCompose)
*
* @param view
* Root Component of the ZUL File.
*/

@AfterCompose
public void initSetup(@ContextParam(ContextType.VIEW) Component view) {

if (_sess.getAttribute("theme") == null) {
Themes.setTheme(Executions.getCurrent(), FHSessionUtil.getCurrentUser().getTheme());
_sess.setAttribute("theme", 1);
Executions.sendRedirect(null);
}

final HashMap<String, Object> map = new HashMap<String, Object>();

Selectors.wireComponents(view, this, false);

/* get an instance of the searched CENTER layout area */
Center c1 = borderLayout.getCenter();

/* clear the center child */
c1.getChildren().clear();

map.put("centerArea", c1);
/* Load the left navigation menu for patient cases */
Executions.createComponents("userList.zul", c1, map);

}


}


After successful login, store the user object in the MyUserDetailsService.java as follows


FHSessionUtil.setCurrentUser(dbUser);

In the next part 9, we will fix some bugs in this project.

You can download the source from here
For online demo, click here.

Use the following user id and password to check out different theme for each user
a) For blue theme, user id : lee and password : lee.
b) For brown theme, user id : wing and password : wing
c) for Green theme, user id : dennis and password : dennis
d) For purple theme, user id : senthil and password : senthil
e) For red theme, user id : zkoss and password : zkoss


        




 

Read More
Posted in | No comments

Wednesday, 10 April 2013

ZK MVVM Form Binding CRUD with Spring and Hibernate - Part 7

Posted on 04:22 by Unknown

Some more features.

        


So we have successfully completed our spring security integration with ZK Application as per the previous article.
In this post, we will add some more features to our application.

Define System Level users.
In the standard login based application, always there will be some users are defined as system and the end users of the application cannot modify or Delete those users from the system. That’s what we are going to do now.

As a first step, in the mysql table, add one more column as shown

image

As you can see, we have given default value for this column as zero. So any user created thru the application will have zero value. So users having system=0 will be treated as normal user and users having system=1 will be treated as system normal users. So in the back end itself, make some users are system by changing the value to 1.

Next step, we need add this new column in our domain object. In the zkexample.domain.UserProfile.java add this and include the getter and setter as shown.

private Integer system;

public Integer getSystem() {
return system;
}

public void setSystem(Integer system) {
this.system = system;
}


Next step, we need to modify our userList.zul. For system users, we will NOT show EDIT and DELETE action. We will only allow View option.
And also, we will see how we can use ZK Popup component for this use case.(Please refer here and here). For system users, we will show one more question mark image with popup bind to inform the user about this.

Update style.css


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

And you need to have the QuestionmarkButton-16x16.png in the images folder
Here is the modified zul file



<?page title="Users List" contentType="text/html;charset=UTF-8"?>
<zk>
<window id="userList" border="none" height="80%" width="96%"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('zkexample.zkoss.UserListVM')">
<separator />
<separator />
<div width="100%">
<div sclass="sectionTitle">
<separator />
<label value="Users" sclass="sectionTitleLabel" />
<separator />
</div>
<div style="float:right">
<button label="Add New" onClick="@command('onAddNew')"
mold="trendy" sclass="mybutton button blue small" />
<button label="Logout" mold="trendy" id="btnlogout"
sclass="mybutton button blue small" onClick="@command('Logout')" />
</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="First Name" sortDirection="ascending"
sort="auto(firstName)" />
<listheader label="Last Name" sort="auto(lastName)" />
<listheader label="Email" sort="auto(email)" />
<listheader label="Login ID" sort="auto(userLoginID)" />
<listheader label="Action" />
</listhead>
<template name="model" var="p1">
<listitem>
<listcell label="@load(p1.firstName)" />
<listcell label="@load(p1.lastName)" />
<listcell label="@load(p1.email)" />
<listcell label="@load(p1.userLoginID)" />
<listcell>
<hbox spacing="20px">
<image
onClick="@command('onEdit',userRecord=p1)" sclass="fimageedit"
visible="@load(p1.system eq 0)"
tooltiptext="To Edit the user details">
</image>
<image
onClick="@command('openAsReadOnly',userRecord=p1)"
sclass="fimageView" tooltiptext="To view the user details">
</image>
<image
tooltip="msgPopup, position=before_start, delay=500" sclass="fImageSystem"
visible="@load(p1.system eq 1)" />
<image
onClick="@command('onDelete',userRecord=p1)"
visible="@load(p1.system eq 0)" sclass="fimageDelete"
tooltiptext="To Delete the user ">
</image>
</hbox>
</listcell>
</listitem>
</template>
</listbox>
<popup id="msgPopup">
<label id="msg"
value="Sytem defined user. Edit and Delete are not allowed.">
</label>
</popup>
</window>
</zk>


List Data Filter.
Next we will add data filter option as shown in ZK Demo here. First let us add datafilter class in our project. Create one more class named as Datafilter under the zkoss package as shown.
image


package zkexample.zkoss;

public class DataFilter {

private String code = "";
private String firstName = "";
private String lastName = "";
private String email = "";
private String loginID= "";

public String getCode() {
return code;
}

public void setCode(String code) {
this.code = code == null ? "" : code.trim();
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName == null ? "" : firstName.trim();
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName == null ? "" : lastName.trim();
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email == null ? "" : email.trim();
}

public String getLoginID() {
return loginID;
}

public void setLoginID(String loginID) {
this.loginID = loginID == null ? "" : loginID.trim();
}

}

Next we need to add auxhead in our listing file. Here is the modified userList.zul and UserListVM

UserList.zul


<?page title="Users List" contentType="text/html;charset=UTF-8"?>
<zk>
<window id="userList" border="none" height="80%" width="96%"
apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('zkexample.zkoss.UserListVM')">
<separator />
<separator />
<div width="100%">
<div sclass="sectionTitle">
<separator />
<label value="Users" sclass="sectionTitleLabel" />
<separator />
</div>
<div style="float:right">
<button label="Add New" onClick="@command('onAddNew')"
mold="trendy" sclass="mybutton button blue small" />
<button label="Logout" mold="trendy" id="btnlogout"
sclass="mybutton button blue small" onClick="@command('Logout')" />
</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)">
<auxhead>
<auxheader colspan="1">
<image sclass="fImageFilter" />
<textbox cols="30" mold="rounded"
value="@bind(vm.dataFilter.firstName)"
onChange="@command('doFilter')" instant="true" />
</auxheader>
<auxheader colspan="1">
<image sclass="fImageFilter" />
<textbox cols="30" mold="rounded"
value="@bind(vm.dataFilter.lastName)"
onChange="@command('doFilter')" instant="true" />
</auxheader>
<auxheader colspan="1">
<image sclass="fImageFilter" />
<textbox cols="30" mold="rounded"
value="@bind(vm.dataFilter.email)" onChange="@command('doFilter')"
instant="true" />
</auxheader>
<auxheader colspan="1">
<image sclass="fImageFilter" />
<textbox cols="33" mold="rounded"
value="@bind(vm.dataFilter.loginID)"
onChange="@command('doFilter')" instant="true" />
</auxheader>

</auxhead>
<listhead sizable="true">
<listheader label="First Name" sortDirection="ascending"
sort="auto(firstName)" />
<listheader label="Last Name" sort="auto(lastName)" />
<listheader label="Email" sort="auto(email)" />
<listheader label="Login ID" sort="auto(userLoginID)" />
<listheader label="Action" />
</listhead>
<template name="model" var="p1">
<listitem>
<listcell label="@load(p1.firstName)" />
<listcell label="@load(p1.lastName)" />
<listcell label="@load(p1.email)" />
<listcell label="@load(p1.userLoginID)" />
<listcell>
<hbox spacing="20px">
<image
onClick="@command('onEdit',userRecord=p1)" sclass="fimageedit"
visible="@load(p1.system eq 0)"
tooltiptext="To Edit the user details">
</image>
<image
onClick="@command('openAsReadOnly',userRecord=p1)"
sclass="fimageView" tooltiptext="To view the user details">
</image>
<image
tooltip="msgPopup, position=before_start, delay=500"
sclass="fImageSystem" visible="@load(p1.system eq 1)" />
<image
onClick="@command('onDelete',userRecord=p1)"
visible="@load(p1.system eq 0)" sclass="fimageDelete"
tooltiptext="To Delete the user ">
</image>
</hbox>
</listcell>
</listitem>
</template>
</listbox>
<popup id="msgPopup">
<label id="msg"
value="Sytem defined user. Edit and Delete are not allowed.">
</label>
</popup>
</window>
</zk>

UserListVM


package zkexample.zkoss;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.zkoss.bind.BindUtils;
import org.zkoss.bind.annotation.AfterCompose;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.ExecutionArgParam;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.select.Selectors;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zkplus.spring.SpringUtil;
import org.zkoss.zul.Center;
import org.zkoss.zul.Messagebox;

import zkexample.domain.UserProfile;
import zkexample.service.CRUDService;

public class UserListVM {

private Center centerArea;
private DataFilter dataFilter = new DataFilter();

@WireVariable
private CRUDService CRUDService;

private UserProfile selectedItem;
private List<UserProfile> allReordsInDB = null;
private List<UserProfile> userList = null;

public UserProfile getSelectedItem() {
return selectedItem;
}

public void setSelectedItem(UserProfile selectedItem) {
this.selectedItem = selectedItem;
}

public DataFilter getDataFilter() {
return dataFilter;
}

public void setDataFilter(DataFilter dataFilter) {
this.dataFilter = dataFilter;
}

@AfterCompose
public void initSetup(@ContextParam(ContextType.VIEW) Component view,
@ExecutionArgParam("centerArea") Center centerArea) {
Selectors.wireComponents(view, this, false);
this.centerArea = centerArea;
CRUDService = (CRUDService) SpringUtil.getBean("CRUDService");
allReordsInDB = CRUDService.getAll(UserProfile.class);
userList = new ArrayList<UserProfile>((allReordsInDB));

}

public List<UserProfile> getDataSet() {
return allReordsInDB;
}

@Command
public void onAddNew() {
final HashMap<String, Object> map = new HashMap<String, Object>();
map.put("selectedRecord", null);
map.put("recordMode", "NEW");
map.put("centerArea", centerArea);
centerArea.getChildren().clear();
Executions.createComponents("UserCRUD.zul", centerArea, map);
}

@Command
public void onEdit(@BindingParam("userRecord") UserProfile userProfile) {

final HashMap<String, Object> map = new HashMap<String, Object>();
map.put("selectedRecord", userProfile);
map.put("recordMode", "EDIT");
map.put("centerArea", centerArea);
centerArea.getChildren().clear();
Executions.createComponents("UserCRUD.zul", centerArea, map);
}

@Command
public void openAsReadOnly(
@BindingParam("userRecord") UserProfile userProfile) {

final HashMap<String, Object> map = new HashMap<String, Object>();
map.put("selectedRecord", userProfile);
map.put("recordMode", "READ");
map.put("centerArea", centerArea);
centerArea.getChildren().clear();
Executions.createComponents("UserCRUD.zul", centerArea, map);
}

@SuppressWarnings({ "rawtypes", "unchecked" })
@Command
public void onDelete(@BindingParam("userRecord") UserProfile userProfile) {
int OkCancel;
this.selectedItem = userProfile;
String str = "The Selected \"" + userProfile.getUserLoginID()
+ "\" will be deleted.";
OkCancel = Messagebox.show(str, "Confirm", Messagebox.OK
| Messagebox.CANCEL, Messagebox.QUESTION);
if (OkCancel == Messagebox.CANCEL) {
return;
}

str = "The \""
+ userProfile.getUserLoginID()
+ "\" will be permanently deleted and the action cannot be undone.";

Messagebox.show(str, "Confirm", Messagebox.OK | Messagebox.CANCEL,
Messagebox.QUESTION, new EventListener() {
public void onEvent(Event event) throws Exception {
if (((Integer) event.getData()).intValue() == Messagebox.OK) {

CRUDService.delete(selectedItem);
allReordsInDB.remove(allReordsInDB
.indexOf(selectedItem));
BindUtils.postNotifyChange(null, null,
UserListVM.this, "dataSet");

}
}
});
}

@NotifyChange("dataSet")
@Command
public void doFilter() {
allReordsInDB = new ArrayList<UserProfile>();;
for (Iterator<UserProfile> i = userList.iterator(); i.hasNext();) {
UserProfile tmp = i.next();
if (tmp.getFirstName().toLowerCase()
.indexOf(dataFilter.getFirstName().toLowerCase()) == 0
&& tmp.getLastName().toLowerCase()
.indexOf(dataFilter.getLastName().toLowerCase()) == 0
&& tmp.getEmail().toLowerCase()
.indexOf(dataFilter.getEmail().toLowerCase()) == 0
&& tmp.getUserLoginID().toLowerCase()
.indexOf(dataFilter.getLoginID().toLowerCase()) == 0) {
allReordsInDB.add(tmp);

}
}

}

@Command
public void Logout() {
Executions.sendRedirect("/j_spring_security_logout");
}

}


Now the output will be as shown.
image

In the next part 8, ZK Theme customization for each user
You can download the source here.



        

Read More
Posted in | No comments

Tuesday, 9 April 2013

ZK + Spring Security Custom Login form

Posted on 22:55 by Unknown

In this example, we will see step by step how to integrate ZK and Spring security

If you are new to spring security,   please read the following post

1. Spring Security hello world example
2. Spring Security Form Login Example

Now let us see how we can integrate ZK with spring security.

Part 1: 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.
Part 2: In this post, we will see how to Implement custom UserDetailsService for spring security.
Part 3: In this post, we will see how to login with static users into the application.
Part 4: In this post, we will see how to add extra login parameters in the spring security.
Part 5: Real world Example for spring security using ZK MVC + CRUD + Hibernate + JPA + Mysql 

Read More
Posted in ZK Spring | No comments

ZK + Spring Security Login form–Part 5

Posted on 10:43 by Unknown

Connect with database and check user exists or not.

In this post, let us how we can secure ZK Application using custom spring security login form designed in ZK Framework.

So what we are going to do ?

1. We will login page and spring authentication to access the secured pages.
2. After successful authentication, we will re direct to user lists page and from which we can add/edit/delete users.
3. We will also have logout method in the listing page. On Click , it will redirect to login page again.

 

Step 1:
Follow this post and complete all the steps. At the end of the exercise, we will be able add users/edit/delete users. Now we will secure this application using ZK Login page.

Step 2:
First let us update the POM.xml as follows

<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>zkloginexample5</groupId>
<artifactId>zkloginexample5</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 zkloginexample5 Project</name>
<description>The zkloginexample5 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>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.1.9.Final</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>

<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>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>

<!-- AOP dependency -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>

<!-- Persistence Management -->
<dependency> <!-- Apache BasicDataSource -->
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.22</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>zkloginexample5${packname}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>assembly/webapp.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>


Step 3:
Next we will create our login.zul. Select the webapp folder, right click, select New –>Other->zul file and enter the zul file name as login.zul
image

image
Here is the login.zul code


<?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 4:
Next we will update web.xml file. You can copy the content here.

<?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>zkloginexample5</display-name>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<!-- Loads the Spring web application context -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>


<!-- 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>

<!-- Spring filter -->
<filter>
<filter-name>OpenEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenEntityManagerInViewFilter</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>UserList.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:
Next we will create spring-security.xml in the webapp\web-INF folder. Select the webapp folder, right click, Select New->Other->xml file and enter the file name as “spring-security.xml”

image

image
You can copy the code from here.


<!-- 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="/UserList.zul" always-use-default-target="true" />
<intercept-url pattern="/login.zul" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/*.zul" access="IS_AUTHENTICATED_REMEMBERED" />
</http>

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

</authentication-provider>
</authentication-manager>

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


</beans:beans>



Step 6:
Next we will update applicationContext.xml file. You can copy the content here.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">


<!-- The LocalEntityManagerFactoryBean creates an EntityManagerFactory suitable for environments which solely use JPA for data access.
The factory bean will use the JPA PersistenceProvider autodetection mechanism (according to JPA's Java SE bootstrapping) and,
in most cases, requires only the persistence unit name to be specified:
-->

<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="ZKExamples" />
</bean>


<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<!-- tell spring to use annotation based congfigurations -->
<!-- It allow us to use @Autowire, @Required and @Qualifier annotations. -->

<context:annotation-config />

<!-- tell spring where to find the beans -->
<!-- tells Spring to scan the code for injectable beans under the package (and all its subpackages) specified. -->
<!-- It allow @Component, @Service, @Controller, etc.. annotations. -->
<context:component-scan base-package="crudexample" />

<tx:annotation-driven transaction-manager="transactionManager" />

<!-- This will ensure that hibernate or jpa exceptions are automatically
translated into Spring's generic DataAccessException hierarchy for those
classes annotated with Repository -->

<bean
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

<bean id="CRUDService" class="crudexample.service.CRUDServiceImpl" />

</beans>

Step 7:
Next we will need to update our dao and service layer by adding one more method to execute namedquery.
CRUDDao.java


package crudexample.dao;

import java.util.List;

public interface CRUDDao {

<T> List<T> getAll(Class<T> klass);

<T> T save(T t);

<T> T GetUniqueEntityByNamedQuery(String query, Object... params);

<T> void delete(T t);
}
CRUDDaoImpl.java

package crudexample.dao;

import java.util.List;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.Parameter;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.Query;

import org.springframework.stereotype.Repository;

@Repository
public class CRUDDaoImpl implements CRUDDao {

@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager em;

public EntityManager getEm() {
return em;
}

public void setEm(EntityManager em) {
this.em = em;
}

@SuppressWarnings("unchecked")
public <T> List<T> getAll(Class<T> klass) {
return em.createQuery("Select t from " + klass.getSimpleName() + " t")
.getResultList();
}

public <T> T save(T t) {
T newRecord = null;
newRecord = em.merge(t);
return newRecord;
}

public <T> void delete(T t) {
em.remove(em.merge(t));
em.flush();
}

@SuppressWarnings("unchecked")
public <T> T GetUniqueEntityByNamedQuery(String query, Object... params) {

System.out.println("results is ");
Query q = this.em.createNamedQuery(query);
int i = 1;

for (Object o : params) {
q.setParameter(i, o);
}

List<T> results = q.getResultList();
System.out.println("results is "+ results.size());
T foundentity = null;
if (!results.isEmpty()) {
// ignores multiple results
foundentity = results.get(0);
}
return foundentity;
}
}


CRUDService.java

package crudexample.service;

import java.util.List;

public interface CRUDService {
<T> List<T> getAll(Class<T> klass);

<T> T save(T t);

<T> T GetUniqueEntityByNamedQuery(String query, Object... params);

<T> void delete(T t);


}


CRUDServiceImpl.java

package crudexample.service;


import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import crudexample.dao.CRUDDao;


@Service
public class CRUDServiceImpl implements CRUDService {


@Autowired
private CRUDDao CRUDDao;

@Transactional(readOnly = true)
public <T> List<T> getAll(Class<T> klass) {
return CRUDDao.getAll(klass);
}


@Transactional
public <T> T save(T t) {
T newRecord = null;
newRecord = CRUDDao.save(t);
return newRecord;
}

@Transactional
public <T> void delete(T t) {
CRUDDao.delete(t);
}

@Transactional
public <T> T GetUniqueEntityByNamedQuery(String query, Object... params) {
return CRUDDao.GetUniqueEntityByNamedQuery(query, params);
}
}
Step 8:
Next we will create our custom authentication by extending spring UserDetailsService interface. Select the “service” package, right click, select new->Other->Class and enter the class name as “MyUserDetailsService”.

package crudexample.service;

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

import org.springframework.beans.factory.annotation.Autowired;
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;

import crudexample.domain.Appusers;

public class MyUserDetailsService implements UserDetailsService {

@Autowired
private CRUDService CRUDService;

/*
* 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 username)
throws UsernameNotFoundException, DataAccessException {

// Declare a null Spring User
UserDetails user = null;

try {

// Search database for a user that matches the specified username
// You can provide a custom DAO to access your persistence layer
// Or use JDBC to access your database
// DbUser is our custom domain user. This is not the same as
// Spring's User

Appusers dbUser = CRUDService.GetUniqueEntityByNamedQuery(
"Appusers.findUserByUserID", username);

// Populate the Spring User object with details from the dbUser
// Here we just pass the username, password, and access level
// getAuthorities() will translate the access level to the correct
// role type

user = new User(dbUser.getUserID(), dbUser.getPassword()
.toLowerCase(), true, true, true, true,
getAuthorities());

} catch (Exception e) {
throw new UsernameNotFoundException("Error in retrieving user");
}

// Return user to Spring for processing.
// Take note we're not the one evaluating whether this user is
// authenticated or valid
// We just merely retrieve a user that matches the specified username

return user;
}

/**
* Retrieves the correct ROLE type depending on the access level, where
* access level is an Integer. Basically, this interprets the access value
* whether it's for a regular user or admin.
*
* @param access
* an integer value representing the access of the user
* @return collection of granted authorities
*/
public Collection<GrantedAuthority> getAuthorities() {
// Create a list of grants for this user
List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>(2);

// All users are granted with ROLE_USER access
// Therefore this user gets a ROLE_USER by default
authList.add(new GrantedAuthorityImpl("ROLE_USER"));
// User has admin access
authList.add(new GrantedAuthorityImpl("ROLE_ADMIN"));

// Return list of granted authorities
return authList;
}
}

Step 9:
Next we will add logout option in the userlist.zul file as follows. Just add one more button next add new button

	<div style="float:right">
<button label="Add New" mold="trendy" id="btnNew"
sclass="mybutton button blue small" />
<button label="Logout" mold="trendy" id="btnlogout"
sclass="mybutton button blue small" />

</div>


And also, add the following code in the controller.


	public void onClick$btnlogout(Event event)
{
Executions.sendRedirect("/j_spring_security_logout");
}

Now you select the Project and Run using tomcat server.
You can download the source
here

Read More
Posted in ZK Spring | No comments

Monday, 8 April 2013

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

Posted on 11:45 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.


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/DFRiwmpNHq

You can download the source code here

MVVM Version of this tutorial is available here

Read More
Posted in ZK Hibernate, ZK MVC CRUD Examples, ZK Spring | No comments

Tuesday, 2 April 2013

Medical Billing Process in detail

Posted on 00:53 by Unknown

Now let us see each activity on medical Billing

Insurance Verification

Process started from here and usually front desk people are doing this process. Its a process of verifying the patients insurance details by calling insurance or through on line verification. If this department works well, we could resolve more problem. We have to do this even before patient appointment. Here is the nice flowchart from the ZIMMER site on the insurance verification process.

There are different ways you can verify the patient insurance is active or not as follows

  1. Using medical Billing Clearing house, you can verify each patient insurance.
  2. There are some public websites where you can verify each patient insurance.
  3. Most of the insurance company web site has the option of verifying their patient policy is active or not.
  4. You can create Electronic file (EDI) for bunch of patients and then you can submit to the clearing house to verify. Clearing house in turn will give the report of each insurance.
  5. You can call the insurance company customer support and check the status.
  6. You can integrate any third party to check on line with your software to verify the insurance.

By verifying the patient insurance before the appointment, we can save our time and inform the patient to pay from their pocket before the service is rendered.Non- verification of insurance eligibility would lead to problems such as delayed payments, rework, increased errors and patient dissatisfaction. All this underlines the importance of insurance verification in Medical Billing.


Creating the claim and send to the Insurance Company.

Next step is prepare the claim and send to the insurance company via clearing house or directly to the payer.

Claim Processing by the insurance company.

Rejected Claims
When the insurance company receives the claim from the doctor, first level check or first level edit process will start. Here insurance company will check the accuracy  of the date submitted before filing the claim into their computer system. If any data is not valid or missing, then it is treated as rejected claims. A rejected claim is  one that has not been processed due to problems detected before health care claim processing. Claims are typically rejected for incorrect patient names, date of birth, insurance ID’s, address, etc. Since rejected claims have not been processed yet, there is no appeal - the claim just has to be corrected and resubmitted.

Most Common Reasons for Rejected Claims

  1. Errors to patient demographic data - age, date of birth, sex, etc. or address.   
  2. Error in Doctor License No.
  3. Incorrect Patient Policy No.
  4. Patient Insurance is inactive.
  5. Incorrect Treatment code or Disease Code.
  6. Incorrect Modifiers

Claims adjudication
After process of first level edit, the information is reviewed to determine whether the patient was covered at the time of service, and whether the treatment is appropriate for the diagnosis submitted. If the procedure or treatment falls within standard and customary treatment for that condition, it  is considered medically necessary and the bill is approved for payment. The payment amount will depend on the allowed  amount, which varies depending on your particular policy and whether or not your doctor is on a list of network providers. This process is called Claims Adjudication.

There are generally three possible outcomes of adjudication of a claim, whether it is valid and should be paid, it is invalid and should be denied, or more information is need to make a proper determination, in which case it is "pended" for further (usually manual) processing.

Denied Claims
During Claim adjudication, claim may also be denied. Please remember, A denied claim is not the same as a rejected claim, however both terms are frequently used interchangeably. A rejected claim is one that has not been processed due to problems detected before health care claim processing. Claims are typically  rejected for incorrect patient names, date of birth, insurance ID’s, address, etc. Since rejected claims have not been processed yet, there is no appeal - the claim just has to be corrected and resubmitted.

A denied claim is one that has been through health care claim processing and determined by the insurance company that it cannot be paid. A denied claim can be appealed by submitting the required information or correcting the claim and resubmitting.

Most Common Reasons for Denied Claims

  1. Services non-covered. Are the billed services covered under the patient's policy?
  2. Patient's non-coverage or terminated coverage at the time of service may also be the reason of denial That is why, it is very important that you check on your patient's benefits and eligibility before doctor see the patient.
  3. Taken long time to submit the claim from the date of the service provided to the patient. Has the claim been sent within the payers time limits for filing claims? The time limit is generally between 90 and 180 days from the date of service.
  4. Duplicate dates of service.Is the claim billing for a service on the same date that has already been adjudicated?
  5. Valid code linkages.
  6. Missing documentation attached to the claim. Payers may require additional documentation, such as the operative note or implant invoice, attached to the claim

The Following picture demonstrates how insurance company processing the claims received from the clearing house.

image

 

Payment
Next, the insurance company will either send the appropriate payment electronically to the health care provider, or send a notice of denial if the claim has not met the standards for payment. In either case, the patient will also be notified of the result of the claim. This is usually done via a letter called Explanation of Benefits (EOB) letter, which details the amount that was paid and the portion of the bill that is the patient's responsibility. The EOB letter will also give a reason for denial if payment was not made.

EOB means Explanation of Benefits. Insurance companies send information to both the patient and provider on exactly what they paid and allowed. Allowed amount means the maximum amount the insurance company would consider for payment. Any difference above the allowed amount is written off if the provider participates with the insurance company.

You can see some sample EOB here.

 

        

Read More
Posted in | No comments

Monday, 1 April 2013

Clearing House

Posted on 00:23 by Unknown

After claim is generated, where we will send the bill ?
You will immediately say "To the insurance company if the patient has insurance".

That's right. But are we going to send to the claim to each individual insurance company directly ? . Patient might be enrolled with different insurance company not to one particular insurance.   So it may be very tedious job to send the claim to each insurance company directly.

Why ? Here are the reasons

1. Each time if you found new insurance from the patient, then you have to contact the insurance company and get the details how to send the claims directly to them.This process is potentially long and involved testing/certification process to complete and go for live.

2. Billing staff or the Practice management should be able to configure to setup configuration for each insurance transmission method (login, password, mode of transmission, etc).

3. On the other side (Insurance or Payer), think insurance company will receive the claims from different practice. For this, they should have the enough manpower which will increase their cost.

4. The unnecessary added confusion of multiple accounts to log into, and multiple data entries, which increase the opportunity for errors.Lost claims and lack of tools for  efficient claim management

So What is the solution ?
So we need a POST OFFICE, so then if we post the claims to POST Office, then they will take to deliver to individual insurance/Payer. That's what Clearing House is.

Here is the diagram that explains.

image


So Clearing house is a company that passes claims and reports between a provider and insurance company.  Is there any cost for this Post office ? Yes
Clearinghouses charge fees in many ways. Some charge an initial start up fee to the billing service ranging from $125 to $300.  Most of them charge a per claim fee of some sort, depending upon the Insurance(hereinafter i will always mix the words insurance or payer or carrier)

Instead of clearing house, if you send the claims directly to insurance company, there is no cost involved in that. That is the only advantage over clearing house.

Here is the list of advantages using clearing house to send Claims

  • Allows you to catch and fix errors in minutes rather than days or weeks
  • Results in significantly higher claim success --fewer rejected claims.
  • Rapid claims processing: Submitting claims electronically can reduce your reimbursement times to under ten days.
  • Eliminates the need to prepare claims and manually re-key transaction data over and over for each payer
  • Submit all your electronic claims in batch all at once, rather than submitting separately to each individual payer. A medical billing clearinghouse allows you to submit all your claims at the same time, rather than submitting them separately for each individual insurer. Again, the faster and more cleanly your claims are submitted to the carriers, the faster payments are received by your medical billing client.
  • Reduce or eliminate need for paper forms, envelopes and stamp.

You may ask "Can i send the paper claims to the clearing house ? 
No, Only Electronic claim (EDI) you can submit to the clearing house. But there is scenario where suppose particular insurance company does not accept Electronic claim submission(very rare), so in this case, still you can submit the electronic claim format to the clearing house and you can instruct the clearing house to send the claim via paper to that insurance company.

Other than transmitting  the claims to the insurance company, there are some task are performed by the clearing house. Here is the list and we will see in detail about this in the upcoming chapters.

  • Eligibility verification
  • Sent file status
  • Claim status reports
  • Electronic Remittance Advice (ERA)
  • Patient statement services
  • Payment processing reporting
  • Transaction summaries and reports of all your clearinghouse activity

Following are the growing list of Clearing house.

ZirMed
Emdeon
Gateway EDI
Fusion EDI

        

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

Popular Posts

  • Understanding EDI Structure
    EDI Structure Primary Levels are 1. Interchange Envelops 2. Functional Group 3. Transaction set Data Element A data element is equival...
  • 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 ...
  • 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...
  • 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...
  • 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...
  • Java Static Import
    This is one of feature in Java 5. In order to access static members, it is necessary to qualify references with the class they came from. ...
  • ZK MVVM Form Binding CRUD with Spring and Hibernate - Part 4
    Presentation Layer using ZK Framework          In part 3 , We have completed Spring integration with hibernate. In this post, we will des...
  • ZK MVVM CRUD With Spring 3 + JPA + Hibernate 4 Entity Manager–Part 3
    Define the persistence.xml file In the Part 2 article , we have seen how to create ZK Maven project and update the default POM.XML with a...
  • Hibernate–Java Environment setup
    Environment Eclipse 3.7 Indigo IDE Download Hibernate 4.1.1 Download JavaSE 1.6  Download MySQL 5.1 Download JDBC Driver for MyS...

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