Java Connector to SugarCRM Webservices

This would a small post will less explanation and more of code snippets (Too  busy to write description and code has proper comments).

Here is my effort to minimize research work in getting started with sugar CRM webservice invocation in java

Original code was taken from https:/ /github.com /amusarra/SugarCRMJavaSOAPClient  and added more functions to it

/**
 *
 */
package com.northalley.sugarcrm;

import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map.Entry;

import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.ServiceFactory;

import org.apache.axis.AxisFault;

import com.sugarcrm.www.sugarcrm.Entry_value;
import com.sugarcrm.www.sugarcrm.Field;
import com.sugarcrm.www.sugarcrm.Get_entry_list_result_version2;
import com.sugarcrm.www.sugarcrm.Get_entry_result_version2;
import com.sugarcrm.www.sugarcrm.Link_field;
import com.sugarcrm.www.sugarcrm.Link_name_to_fields_array;
import com.sugarcrm.www.sugarcrm.Module_list;
import com.sugarcrm.www.sugarcrm.Name_value;
import com.sugarcrm.www.sugarcrm.New_module_fields;
import com.sugarcrm.www.sugarcrm.New_set_entry_result;
import com.sugarcrm.www.sugarcrm.SugarsoapBindingStub;
import com.sugarcrm.www.sugarcrm.SugarsoapLocator;
import com.sugarcrm.www.sugarcrm.User_auth;

/**
 * This implements basic methods which are used commonly
 *
 * @author ashwin kumar
 */
public class SugarCRMSoapDemoClient {
	private static final String END_POINT_URL = "http://localhost/SugarCE/service/v2/soap.php?wsdl";
	private static final String USER_NAME = "admin";
	private static final String USER_PASSWORD = "sugarcrm";
	private static final String APPLICATION_NAME = Class.class.getName();
	private static final Integer TIMEOUT = 6000;

	/**
	 * Main Program
	 *
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		String sessionID = null;

		try {
			// Create a URL end point for the client
			URL wsdlUrl = null;
			if (END_POINT_URL.isEmpty()) {
				wsdlUrl = new URL(new SugarsoapLocator()
						.getsugarsoapPortAddress()
						+ "?wsdl");
			} else {
				wsdlUrl = new URL(END_POINT_URL);
			}

			System.out.println("URL endpoint created successfully!");

			// Create Service for test configuration
			ServiceFactory serviceFactory = ServiceFactory.newInstance();
			Service service = serviceFactory.createService(wsdlUrl,
					new SugarsoapLocator().getServiceName());

			System.out.println("Service created successfully");
			System.out.println("Service Name:"
					+ service.getServiceName().toString());
			System.out.println("Service WSDL:"
					+ service.getWSDLDocumentLocation().toString());

			// Trying to create a stub
			SugarsoapBindingStub binding = new SugarsoapBindingStub(wsdlUrl,
					service);
			binding.setTimeout(TIMEOUT);
			System.out.println("Stub created successfully!");

			/**
			 * Try to login on SugarCRM
			 *
			 * 1) Prepare a MD5 hash password 2) Prepare a User Auth object 3)
			 * Execute login
			 */

			// 1. Prepare a MD5 hash password
			MessageDigest messageDiget = MessageDigest.getInstance("MD5");
			messageDiget.update(USER_PASSWORD.getBytes());

			// 2. Prepare a User Auth object
			User_auth userAuthInfo = new User_auth();
			userAuthInfo.setUser_name(USER_NAME);
			userAuthInfo.setPassword((new BigInteger(1, messageDiget.digest()))
					.toString(16));

			try {
				// 3. Execute login
				Entry_value loginResult = binding.login(userAuthInfo,
						APPLICATION_NAME, null);
				System.out.println("Login Successfully for " + USER_NAME);
				System.out.println("Your session Id: " + loginResult.getId());
				sessionID = loginResult.getId();
			} catch (RemoteException ex) {
				System.out.println("Login failed. Message: " + ex.getMessage());
				ex.printStackTrace();
			}
			// binding.
			// binding.get_available_modules(session);
			// retreiveEntriesByModule(sessionID, binding, "Accounts",new
			// String[]{"name","description"},0,10);
			retreiveEntriesByModule(sessionID, binding, "Leads", new String[] {
					"name", "description", "account_name", "campaign_name",
					"salutation", "first_name", "last_name", "full_name",
					"title", "department", "email1", "email2" }, 0, 10);
			retreiveEntriesByModule(sessionID, binding, "Campaigns",
					new String[] { "name", "description", "assigned_user_name",
							"status", "campaign_type", "expected_cost" }, 0, 10);
			// retreiveModuleFields(sessionID, binding);
			// retreiveModules(sessionID, binding);
			// createAndRetreiveContact(sessionID, binding);

			/**
			 * Logout
			 */
			try {
				binding.logout(sessionID);
				System.out.println("Logout Successfully for " + USER_NAME);
				sessionID = null;
			} catch (RemoteException ex) {
				System.out.println("Login failed. Message: " + ex.getMessage());
				ex.printStackTrace();
			}

		} catch (MalformedURLException ex) {
			System.out.println("URL endpoing creation failed. Message: "
					+ ex.getMessage());
			ex.printStackTrace();
		} catch (ServiceException ex) {
			System.out.println("Service creation failed. Message: "
					+ ex.getMessage());
			ex.printStackTrace();
		} catch (AxisFault ex) {
			System.out.println("AxisFault. Message: " + ex.getMessage());
			ex.printStackTrace();
		}
	}

	/**
	 * Sample to show how to do creation operation using webservice
	 *
	 * @param sessionID
	 * @param binding
	 */
	private static void createAndRetreiveContact(String sessionID,
			SugarsoapBindingStub binding) {
		/**
		 * Create a new Contact
		 *
		 * 1) Setting a new entry 2) Setting up parameters for set_entry call 3)
		 * Creating a name value list array from a hash map. This is not
		 * necessary just more elegant way to initialize and add name values to
		 * an array
		 */
		HashMap<String, String> nameValueMap = new HashMap<String, String>();
		nameValueMap.put("first_name", "Suresh");
		nameValueMap.put("last_name", "Paladugu");
		nameValueMap.put("title", "IT Senior Consultant");
		nameValueMap.put("description", "Test Client SOAP Java");
		nameValueMap.put("email1", "suresh.paladugu@gmail.com");

		// Creating a new Name_value array and adding each map entry as 'name'
		// and 'value'
		Name_value nameValueListSetEntry[] = new Name_value[nameValueMap.size()];
		int i = 0;
		for (Entry<String, String> entry : nameValueMap.entrySet()) {
			Name_value nameValue = new Name_value();
			nameValue.setName(entry.getKey());
			nameValue.setValue(entry.getValue());
			nameValueListSetEntry[i] = nameValue;
			i++;
		}

		// Trying to set a new entry
		New_set_entry_result setEntryResponse = null;
		try {
			setEntryResponse = binding.set_entry(sessionID, "Contacts",
					nameValueListSetEntry);
		} catch (RemoteException e) {
			System.out.println("Set entry failed. Message: " + e.getMessage());
			e.printStackTrace();
		}
		System.out.println("Set entry was successful! Contacts Id: "
				+ setEntryResponse.getId());

		/**
		 * Getting an Contacts Entry (the one we just set)
		 */
		Link_name_to_fields_array[] link_name_to_fields_array = null;
		String[] select_fields = null;

		Get_entry_result_version2 getEntryResponse = null;

		// Trying to get entry
		try {
			getEntryResponse = binding.get_entry(sessionID, "Contacts",
					setEntryResponse.getId(), select_fields,
					link_name_to_fields_array);
		} catch (RemoteException e) {
			System.out.println("Get entry failed. Message: " + e.getMessage());
			e.printStackTrace();
		}
		System.out.println("Get entry was successful! Response: ");

		// Getting the fields for entry we got.
		Entry_value[] entryList = getEntryResponse.getEntry_list();
		for (int k = 0; k < entryList.length; k++) {
			Entry_value entry = entryList[k];
			Name_value[] entryNameValueList = entry.getName_value_list();
			for (int j = 0; j < entryNameValueList.length; j++) {
				Name_value entryNameValue = entryNameValueList[j];
				// Outputting only non empty fields
				if (!entryNameValue.getValue().isEmpty()) {
					System.out.println("Attribute Name: '"
							+ entryNameValue.getName() + "' Attribute Value: '"
							+ entryNameValue.getValue() + "'");
				}
			}
		}
	}

	/**
	 *
	 * TO get list of values /rows for a given modules based on selection
	 * criteria
	 *
	 * @param sessionID
	 * @param binding
	 * @param moduleName
	 *            TODO
	 * @param select_fields
	 * @param l
	 * @param offset
	 */
	private static void retreiveEntriesByModule(String sessionID,
			SugarsoapBindingStub binding, String moduleName,
			String[] select_fields, int offset, int rowCount) {
		Link_name_to_fields_array[] link_name_to_fields_array = null;

		Get_entry_result_version2 getEntryResponse = null;
		Get_entry_list_result_version2 entryListResultVersion2 = null;

		// Trying to get entry
		try {
			/*
			 * getEntryResponse = binding.get_entry(sessionID,moduleName, null,
			 * select_fields, link_name_to_fields_array);
			 */
			entryListResultVersion2 = binding.get_entry_list(sessionID,
					moduleName, "", "", offset, select_fields,
					link_name_to_fields_array, rowCount, 0);
			// getEntryResponse = binding.get_entries(sessionID, moduleName,
			// null, new String[]{"name","description"},
			// link_name_to_fields_array);

		} catch (RemoteException e) {
			System.out.println("Get entry failed. Message: " + e.getMessage());
			e.printStackTrace();
		}
		System.out.println("Get entry was successful! Response: ");

		// Getting the fields for entry we got.
		Entry_value[] entryList = entryListResultVersion2.getEntry_list();
		for (int k = 0; k < entryList.length; k++) {
			Entry_value entry = entryList[k];
			Name_value[] entryNameValueList = entry.getName_value_list();
			System.out.println();
			for (int j = 0; j < entryNameValueList.length; j++) {
				Name_value entryNameValue = entryNameValueList[j];
				// Outputting only non empty fields
				if (!entryNameValue.getValue().isEmpty()) {
					System.out.print(entryNameValue.getName() + ":"
							+ entryNameValue.getValue() + "    ;   ");
				}
			}
		}
	}

	/**
	 *
	 * To list out all fields of a given module
	 *
	 * @param sessionID
	 * @param binding
	 * @param moduleName
	 */
	private static void retreiveModuleFields(String sessionID,
			SugarsoapBindingStub binding, String moduleName) {
		/**
		 * Create a new Contact
		 *
		 * 1) Setting a new entry 2) Setting up parameters for set_entry call 3)
		 * Creating a name value list array from a hash map. This is not
		 * necessary just more elegant way to initialize and add name values to
		 * an array
		 */

		/**
		 * Getting an Contacts Entry (the one we just set)
		 */
		Link_name_to_fields_array[] link_name_to_fields_array = null;
		String[] select_fields = null;

		Get_entry_result_version2 getEntryResponse = null;
		New_module_fields moduleFields = null;
		// Trying to get entry
		try {
			moduleFields = binding.get_module_fields(sessionID, moduleName,
					select_fields);
		} catch (RemoteException e) {
			// System.out.println("Get entry failed. Message: " +
			// e.getMessage());
			// e.printStackTrace();
		}
		// System.out.println("Get entry was successful! Response: ");

		if (moduleFields != null) {
			for (Field field : moduleFields.getModule_fields()) {
				System.out.print(field.getName() + ",");
			}

			System.out.println("--Link Fields");
			/**
			 * Now get Link Fields
			 */

			for (Link_field linkField : moduleFields.getLink_fields()) {
				System.out.print("[" + linkField.getName() + " : "
						+ linkField.getBean_name() + " : "
						+ linkField.getRelationship() + "],");
			}
		}

	}

	/**
	 * To list out all modules aavailable to given user
	 *
	 * @param sessionID
	 * @param binding
	 */
	private static void retreiveModules(String sessionID,
			SugarsoapBindingStub binding) {
		/**
		 * Create a new Contact
		 *
		 * 1) Setting a new entry 2) Setting up parameters for set_entry call 3)
		 * Creating a name value list array from a hash map. This is not
		 * necessary just more elegant way to initialize and add name values to
		 * an array
		 */

		/**
		 * Getting an Contacts Entry (the one we just set)
		 */
		Link_name_to_fields_array[] link_name_to_fields_array = null;
		String[] select_fields = null;

		Get_entry_result_version2 getEntryResponse = null;
		Module_list moduleList = null;
		// Trying to get entry
		try {
			moduleList = binding.get_available_modules(sessionID);
		} catch (RemoteException e) {
			System.out.println("Get entry failed. Message: " + e.getMessage());
			e.printStackTrace();
		}
		// System.out.println("Get entry was successful! Response: ");

		for (String moduleName : moduleList.getModules()) {
			System.out.println("\n" + moduleName + "{");
			retreiveModuleFields(sessionID, binding, moduleName);
			System.out.println("}");
		}

	}

}

Project code has been checked into

https://linkwithweb.googlecode.com/svn/trunk/CRM/SugarCRM/JavaSOAPClient/SugarCRMClient

List of all fields by module is also located at

https://linkwithweb.googlecode.com/svn/trunk/CRM/SugarCRM/ModuleWiseFieldsAndLinkedFieldsList.txt

Same can also be extracted by running above program

Njoy working with SugarCRM..

Fell free to contact me if any questions

Spring Integration Webapp( JPA/Hibernate | Webservices (JAX-WS|Apache CXF) | JQuery | EJB3 | Maven | Jboss | Annoatations)

Spring is one of the best Framework’s around in J2EE field which has made integration to various Framework pretty easy. This article is in series of articles which teach about spring integration in details. All source code is checked into svn which can be checked out and tested.

Assumption : Readers has basic knowledge of Servlets and JSP technologies.

Background : Sample project named testspring has been create in modular manner using Maven.  I used 2 differrent database schema names of mysql testjpa/testejb to test this project. I have configured

<property name=”hibernate.hbm2ddl.auto” value=”update” />

so that once proper connectivity is made program on startup will generate all tables in database

Any framework that has to integrated into J2EE frontend technology has to get control from Servlet Container, As all “http”(There can be other requests RMI/JMS..etc) requests are passed on to servlet container first which inturn based on configuration passes to corresponding framework.

All the integrations are generally handle using servlet mapping, or using listeners or filters in Webapplication.

To to integrate spring in webapplication we have to do the following

  • Configure spring Listener and Servlet in web.xml
	<!-- Configuration files for spring  -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
            /WEB-INF/spring/app-config.xml,
            /WEB-INF/spring/app-*-config.xml
        </param-value>
	</context-param>

	<!-- Spring listeners -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<listener>
		<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
	</listener>
	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>dispatcher</servlet-name>
		<url-pattern>/services/*</url-pattern>
	</servlet-mapping>

Now that you have configured spring now start configuring spring beans in Spring configuration files.( As per the above configuration file. All requests with url pattern services/* will get routed to spring dispatcher servlet. Which inturn takes care of request mapping based on Configuration files or using Annotations.

if you have observerd the spring servlet name is “dispatcher”

so the configuration file that is read by default will be dispatcher-servlet.xml and then other files with same name pattern defined in context-param will get loaded.

Attached is my Dispatcher Servlet Sample code

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

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

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />
	<resources mapping="/assets/**" location="/assets/" />
	<resources mapping="/CSS/**" location="/CSS/" />
	<resources mapping="/images/**" location="/images/" />
	<resources mapping="/JS/**" location="/JS/" />
	<resources mapping="/swfupload/**" location="/swfupload/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>
    -->

	<!-- freemarker config -->
	<beans:bean id="freemarkerConfig"
		class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
		<beans:property name="templateLoaderPath" value="/WEB-INF/freemarker/" />
		<beans:property name="freemarkerVariables">
			<beans:map>
				<beans:entry key="xml_escape" value-ref="fmXmlEscape" />
			</beans:map>
		</beans:property>
	</beans:bean>

	<beans:bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape" />

	<!--

		View resolvers can also be configured with ResourceBundles or XML
		files. If you need different view resolving based on Locale, you have
		to use the resource bundle resolver.
	-->
	<beans:bean id="viewResolver"
		class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
		<beans:property name="cache" value="true" />
		<beans:property name="prefix" value="" />
		<beans:property name="suffix" value=".html" />

		<!--
			if you want to use the Spring FreeMarker macros, set this property to
			true
		-->
		<beans:property name="exposeSpringMacroHelpers" value="true" />

	</beans:bean>

</beans:beans>

Above code has Configuration to define view resolver (We can integrate different View Technologies in it JSP/Freemarker/Velocity…etc). I’m using freemarker in my example. It also has a commented code which uses jsp as view resolver

The above configuration is basic configuration for Spring MVC. If you have observed it we have defined that spring should discover beans by itself based on annotations rather than configuration stuff. Annotations make is easier for developer to define beans avoiding unnecessary xml configuration which is difficult to remember

Above configuration also lists out url pattern’s that have to be excluded in this flow (Example all css/js/images etc files ).

Below is same Spring MVC controller which is configured through annotations

C:\development\linkwithweb\svn\SpringTutorials\testspring\images

/*
 * Copyright 2011 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.northalley.template.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;

import com.northalley.template.services.WelcomeService;

/**
 * @author ashwin kumar
 *
 */
@Controller
public class GenericController {

	@Autowired
	@Qualifier("welcomeService")
	private WelcomeService welcomeService;

	/**
	 * Constructor
	 */
	public GenericController() {
	}

	/**
	 * @param searchCriteria
	 * @param formBinding
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/test", method = RequestMethod.POST)
	@ResponseBody
	public Response search(SearchCriteria searchCriteria,
			BindingResult formBinding, WebRequest request) {
		Response response = new Response();
		response.setWelcome(welcomeService.hello("Ashwin"));

		return response;
	}

	@RequestMapping("/freemarkertest")
	public ModelAndView hello() {
		return new ModelAndView("hello", "greeting", "Hello world!");
	}

}

If you look into the code it defines that this class is a Spring MVC Controller(Class that handles all requests)

All the methods that you want to expose in this class should get a RequestMapping annotation with URL pattern and corresponding attributes defined for that

Ex:@RequestMapping(value = “/test”, method = RequestMethod.POST)   (This says any URL with services/test has to be handled by this method).. “services” is base url for spring requests which is configured in web.xml

You can directly render response from here using ResponseBody annotation or you can create model object and pass it to View Technology to render that by creating ModelAndView as response object

In the above example i have @ResponseBody annotation configured for one method and i have configured to receive JSON repsonse for any ResponseBody annotation in my app-config.xml

	<!--
		Define the OXM marshaller which is used to convert the Objects <->
		JSON/XML.
	-->
	<beans:bean id="oxmMarshaller"
		class="org.springframework.oxm.xstream.XStreamMarshaller" />

	<beans:bean id="marshallingHttpMessageConverter"
		class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
		<beans:property name="marshaller" ref="oxmMarshaller" />
		<beans:property name="unmarshaller" ref="oxmMarshaller" />
	</beans:bean>

	<!--
		Required for REST services in order to bind the return value to the
		ResponseBody.
	-->
	<beans:bean
		class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
		<beans:property name="messageConverters">
			<util:list id="beanList">
				<ref bean="marshallingHttpMessageConverter" />
			</util:list>
		</beans:property>
	</beans:bean>

Here is sample Spring MVC Design

Read more about spring MVC in

 

http://static.springsource.org/spring/docs/2.0.x/reference/mvc.html

The below one is one of best link which explains all different way you can use Rest Style URL in Spring MVC

http://blog.springsource.com/2009/03/08/rest-in-spring-3-mvc/

 

Now that i have given basic Introduction to Spring MVC integration i’ll take you through JPA Configuration both in Tomcat as well as JBOSS.

JPA can be used in 2 ways ( Using Spring and Using EJB3 container) . As we don’t have EJB container in tomcat we use spring to configure JPA for us.

Let me start with JPA/Hibernate  using Spring in tomcat

I have configured JPA in app-jpa-config.xml in testspring-webapp/WEB-INF/spring   folder (Checkout code from svn to see project structure)

Here is snippet of the JPA config file

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

<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

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

	<!--
        Data source
    -->
	<beans:bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<beans:property name="driverClassName">
			<beans:value>org.hsqldb.jdbcDriver</beans:value>
		</beans:property>
		<beans:property name="url">
			<beans:value>jdbc:hsqldb:mem:testspring-db</beans:value>
		</beans:property>
		<beans:property name="username">
			<beans:value>sa</beans:value>
		</beans:property>
		<beans:property name="password">
			<beans:value></beans:value>
		</beans:property>
	</beans:bean>

	<!--
        Configuration for Hibernate/JPA
    -->
	<beans:bean id="entityManagerFactory"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<beans:property name="persistenceUnitName" value="testspring-jpa" />
		<beans:property name="dataSource" ref="dataSource" />
		<beans:property name="jpaDialect">
			<beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
		</beans:property>
		<beans:property name="jpaVendorAdapter">
			<beans:bean
				class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
				<beans:property name="showSql" value="false" />
				<beans:property name="generateDdl" value="true" />
				<beans:property name="databasePlatform"
					value="org.hibernate.dialect.HSQLDialect" />
			</beans:bean>
		</beans:property>
	</beans:bean>

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

</beans:beans>

As you see here we have configured persistenceUnitName as “testspring-jpa”. This name has been configured in persistence.xml of  testspring-java project module. Here is the snippet for that

<persistence
  xmlns="http://java.sun.com/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
  version="1.0">

 <persistence-unit name="testspring-jpa">
 </persistence-unit>

</persistence>

And now that we have configured spring we can create entities in JPA style and use EntityManager to fire our queries.

Here is the sample welcomeService that is used in our Spring MVC controller

/*

 */

package org.northalley.template.testspring.services;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.northalley.template.testspring.entities.Welcome;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("welcomeService")
public class WelcomeServiceImpl implements WelcomeService {

	@PersistenceContext
	private EntityManager entityManager;

	@Transactional
	public Welcome hello(String name) {
		if (name == null || name.trim().length() == 0)
			throw new RuntimeException("Name cannot be null or empty");

		Welcome welcome = null;
		try {
			Query q = entityManager
					.createQuery("select w from Welcome w where w.name = :name");
			q.setParameter("name", name);
			welcome = (Welcome) q.getSingleResult();
		} catch (NoResultException e) {
			welcome = new Welcome();
			welcome.setName(name);
			welcome.setMessage("Welcome " + name);
			entityManager.persist(welcome);
		}
		return welcome;
	}
}

Now Lets switch to other part of using JPA with EJB ( This can be tested in jboss)

Here is sample snippet of stateless session bean in testspring-ejb project that is using JPA to get list of users

package org.testspring.ejb.dao;

import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.testspring.ejb.entity.User;

/**
 * @author ashwin kumar
 *
 */
@Stateless(mappedName = "userDAOBean")
public class UserDAOBean implements UserDAO {
	private static Log log = LogFactory.getLog(UserDAOBean.class);

	private EntityManager em;

	@PersistenceContext(unitName = "TestEntityManager")
	public void setEm(EntityManager em) {
		this.em = em;
	}

	public List<User> getUsers() {
		log.debug("getUsers");
		List<User> users = this.em.createQuery(
				"select user from User user order by user.lastName")
				.getResultList();
		return users;
	}

	// not using this method in this example app
	public User saveUser(User user) {
		log.debug("saveUser: " + user);
		this.em.persist(user);
		this.em.flush();
		return user;
	}
}

Below is code of User Entity i have created

package org.testspring.ejb.entity;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
//if the table name matches your class name, you don't need the 'name' annotation
@Table(name="lt_user")
public class User extends BaseEntity {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    //we don't need the Column annotation here bc the column name and this field name are the same
    private Long id;

    @Column(name="first_name",nullable=false,length=50)
    private String firstName;

    @Column(name="last_name",nullable=false,length=50)
    private String lastName;

    private Date birthday;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

}

Now that we are done with basic end to end integration .I’ll also show how to inject EJB in Servlet/Spring MVC

Below is sample servlet which called stateless bean . Same method is used in spring MVC too

package com.testspring.servlet;

import java.io.IOException;
import java.util.Hashtable;
import java.util.List;

import javax.ejb.EJB;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.testspring.ejb.dao.UserDAO;
import org.testspring.ejb.entity.User;

import com.testspring.service.MathService;

/**
 * @author ashwin kumar
 *
 */
public class UserAdminServlet extends HttpServlet {

	@EJB(mappedName = "testspring-ear-0.0.1-SNAPSHOT/UserDAOBean/local")
	private UserDAO userDao;

	WebApplicationContext context = null;

	/**
	 * @param filterConfig
	 * @throws ServletException
	 */
	public void init(ServletConfig filterConfig) throws ServletException {
		System.out.println("Inti calleddddddddddddddd");
		super.init(filterConfig);
		ServletContext servletContext = filterConfig.getServletContext();
		context = WebApplicationContextUtils
				.getWebApplicationContext(servletContext);
		// set up an injected bean into application scope
		// servletContext.setAttribute("mybean", context.getBean("aBean"));
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest
	 * , javax.servlet.http.HttpServletResponse)
	 */
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		System.out.println(((MathService) context.getBean("mathService")).add(
				1, 2));

		if (userDao == null) {
			try {
				Hashtable environment = new Hashtable();
				environment.put(Context.INITIAL_CONTEXT_FACTORY,
						"org.jnp.interfaces.NamingContextFactory");
				environment.put(Context.URL_PKG_PREFIXES,
						"org.jboss.naming:org.jnp.interfaces");
				environment.put(Context.PROVIDER_URL, "jnp://localhost:1099"); // remote
				// machine
				// IP

				Context context = new InitialContext(environment);
				userDao = (UserDAO) context
						.lookup("testspring-ear-0.0.1-SNAPSHOT/UserDAOBean/local");
				// context.lookup("userDAOBean");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		doPost(req, resp);
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		List<User> users = userDao.getUsers();
		for (int i = 0; i < users.size(); i++) {
			response.getWriter().append(
					"UserName :" + users.get(i).getFirstName() + " "
							+ users.get(i).getLastName()).append("<br/>");
			response.getWriter().append("id :" + users.get(i).getId()).append(
					"<br/>");
		}
	}
}

 

Now that i have covered all topics from frontend to db, now i’ll take you though how to configure webservices. I’ll show examples with both Apache CXF and JAX-WS

 

Webservices

Similar to spring MVC configuration through servlet , we have to configure both JAX-WS and Apache CXF through their own servlets. Below is servlet configuration to enable them

<!--  jax-ws -->
	<servlet>
		<servlet-name>jaxws-servlet</servlet-name>
		<servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class>
	</servlet>

	<servlet-mapping>
		<servlet-name>jaxws-servlet</servlet-name>
		<url-pattern>/ws/*</url-pattern>
	</servlet-mapping>

<!-- CXF Configuration -->
	<servlet>
		<servlet-name>CXFServlet</servlet-name>
		<servlet-class>
			 org.apache.cxf.transport.servlet.CXFServlet
		</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>CXFServlet</servlet-name>
		<url-pattern>/webservice/*</url-pattern>
	</servlet-mapping>

Now that we have configured respective URL patterns now lets see configuration in Spring that is required to expose Beans as webservices

Webservice configuration for spring is configured in app-ws-config.xml

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

	<!--
	-->

<beans:beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ws="http://jax-ws.dev.java.net/spring/core"
	xmlns:wss="http://jax-ws.dev.java.net/spring/servlet" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:beans="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
        http://jax-ws.dev.java.net/spring/core  http://jax-ws.dev.java.net/spring/core.xsd
        http://jax-ws.dev.java.net/spring/servlet http://jax-ws.dev.java.net/spring/servlet.xsd
        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

	<!-- Web service config for Apache CXF -->
	<import resource="classpath:META-INF/cxf/cxf.xml" />
	<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

	<jaxws:endpoint id="orderProcess"
		implementor="org.northalley.template.testspring.controller.OrderProcessImpl"
		address="/OrderProcess" />

	<!-- Web service config for JAX-WS -->

	<wss:binding url="/ws">
		<wss:service>
			<ws:service bean="#helloWs" />
		</wss:service>
	</wss:binding>

	<beans:bean id="helloWs"
		class="org.northalley.template.testspring.controller.WebserviceController">
	</beans:bean>

</beans:beans>

Below is how i have expose OrderService as webservice for apache CXF

package org.northalley.template.testspring.controller;

import javax.jws.WebService;

@WebService(endpointInterface = "org.northalley.template.testspring.controller.OrderProcess")
public class OrderProcessImpl implements OrderProcess {

    public String processOrder(Order order) {
        return order.validate();
    }
}

Below is code of bean which is exposed by JAX-WS

/*
 *
 */
package org.northalley.template.testspring.controller;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

import org.northalley.template.testspring.services.WelcomeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

/**
 * @author ashwin kumar
 *
 */
@WebService(name = "/hello")
@SOAPBinding(style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.LITERAL)
public class WebserviceController {

	@Autowired
	@Qualifier("welcomeService")
	private WelcomeService welcomeService;

	/**
	 * Constructor
	 */
	public WebserviceController() {
	}

	/**
	 * @param searchCriteria
	 * @param formBinding
	 * @param request
	 * @return
	 */
	@WebMethod(operationName = "getMessage")
	public String search() {
		return welcomeService.hello("Ashwin").getMessage();

	}

	@WebMethod(operationName = "sayHello")
	public String sayHelloToTheUser(@WebParam(name = "name") String userName) {
		return "Testing: " + " " + userName;
	}

}

Sample WSDL URL’s

http://localhost:8080/testspring-webapp/webservice/OrderProcess?wsdl

http://localhost:8080/testspring-webapp/ws?wsdl

 

And finally one more thing which i haven’t used in example. I have configured HSQLDB to used so that any demo’s need not have an external database but have Inbuilt DB

Here is how you do that

	<!-- H2 Database Console for managing the app's database -->
	<servlet>
		<servlet-name>H2Console</servlet-name>
		<servlet-class>org.h2.server.web.WebServlet</servlet-class>
		<init-param>
			<param-name>-webAllowOthers</param-name>
			<param-value>true</param-value>
		</init-param>
		<load-on-startup>2</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>H2Console</servlet-name>
		<url-pattern>/admin/h2/*</url-pattern>
	</servlet-mapping>

 

If you use http://localhost:8080/appname/admin/h2 you will goto to HSQLDB Admin console

I think i have covered all concepts and code snippets to get you started.

Code has been checked in to

https://linkwithweb.googlecode.com/svn/trunk/SpringTutorials/testspring

 

 

 

Checkout

mvn clean install package

testspring-war ( Webapp code for ear file)  (To be deployed on Jboss

testspring-ejb (Has ejb code)

testspring-ear  – Combining both ejb and war to create ear

———————————————–

testspring-java (Java code used in tomcat)

testspring-webapp ( Web configuration for tomcat)

to test on tomcat follow the below steps

cd testspring-webapp

mvn tomcat:run  and njoy playing with code

Njoy playing with code. Get back to me if you have any questions.

 

 

 

 

 

 

 

 

GIT HTTPS Access Problem

Recently i was working on some OSGI sample and was trying to download code from GIT hub. Here is the problem i face in downloading code

git error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed while accessing https:…………………………….

I work on windows system and i have cygwin installed on my system.

Here is how i fixed it

The problem is that you do not have any of Certification Authority certificates installed on your system. And these certs cannot be installed with cygwin’s setup.exe.

There are two solutions: 1. Ignore ssl certificate verification:

$ env GIT_SSL_NO_VERIFY=true git clone https://github... (This dosen't work in all systems)

2. Actually install root certificates. Curl guys extracted for you certificates from mozilla: (This works in most of the system)

http://curl.haxx.se/docs/caextract.html

cacert.pem file is what you are looking for. This file contains > 250 CA certs (Lots of people you are going to trust with this command) . You need to download this file, split it to individual certificates put them to /usr/ssl/certs (your CApath) and index them.

Here is how to do it: With cygwin setup.exe install curl and openssl packages Execute  (AWK program us used to automate the steps)

$ cd /usr/ssl/certs 
$ curl http://curl.haxx.se/ca/cacert.pem | awk 'split_after==1{n++;split_after=0} /-----END CERTIFICATE-----/ {split_after=1} {print > "cert" n ".pem"}' 
$ c_rehash


You can get more options in
http://returnbooleantrue.blogspot.com/2009/06/using-github-through-draconian-proxies.html

Njoy migrating to GITHub

Liferay Build From Source and Deploy to Local Maven Repository

First of all download source from

http://www.liferay.com/downloads/liferay-portal/available-releases or you can download from svn using following command

svn –username guest co svn://svn.liferay.com/repos/public/portal/trunk portal-trunk

Once you download source extract to one Folder.(Dont have long path it might cross maximum path length in windows if you store this deep inside some path)

Prerequisites

———————–

ANT: Download apache ant and place it in path

Below one is needed for deployment to maven repository

GPG : http://www.gpg4win.org/download.html  (You might have to get older version as build searches for gpg.exe )

Older version can be downloaded from http://ftp.gpg4win.org/

If you want to setup maven repository on your machine then do the following

  1. Download nexus(Opensource Maven Repository) from http://nexus.sonatype.org/downloads/nexus-oss-webapp-1.9.2-bundle.tar.gz
  2. Follow following instructions for Installation http://www.sonatype.com/books/nexus-book/reference/install.html
  3. Start nexus and Open your browser to your newly created nexus (http://localhost:8081/nexus)
  4. Login as administrator (default login is admin / admin123) and Change your password
  5. Go to Repositories and click Add -> Hosted Repository
  6. Create Hosted Repository
  • Repository ID: liferay-ce-snapshots
  • Repository Name: Liferay Snapshot Repository
  • Provider: Maven2 Repository
  • Repository Policy: Snapshot
Now configure your maven to point to local repository
<?xml version="1.0" encoding="UTF-8"?>
<settings>
	<mirrors>
		<mirror>
			<id>local</id>
			<name>Local mirror repository</name>
			<url>http://localhost:8081/nexus/content/groups/public</url>
			<mirrorOf>*</mirrorOf>
		</mirror>
	</mirrors>
	<servers>
		<server>
			<id>liferay</id>
			<username>admin</username>
			<password>ashwin@123</password>
		</server>
	</servers>
</settings>

Now Goto to folder where you have liferay source

Open build.properties  and paste following in bottom  ( You can use other property file names . Just look at build-common.xml for more property filenames you can use)

 

maven.url=http://localhost:8081/nexus/content/repositories/liferay-ce-snapshots
gpg.passphrase=ashwin
gpg.keyname=Ashwin
lp.version=6.0.6
maven.repository.id=liferay
maven.version=${lp.version}-SNAPSHOT

 

Now Lets generate Key File using GPG which we downloaded before

LiferayGPG

LiferayGPG

 

Once you generate the key. you can now use it in deployment.

Now follow these steps

  1. C:\liferay-portal-src-6.0.6>set ANT_OPTS=”-Xmx1024m -XX:MaxPermSize=256m”
  2. ant jar
  3. ant -f build-maven.xml deploy-artifacts ( This will deploy all the Liferay Artifacs to maven repository you have just configured using nexus)
Now njoy using maven with liferay. Next articles would be to create portlets in Liferay and Using liferay to create portals

     

     

     

     

     

     

     

     

    jsoup HTMLParser and Parsing Dzone Links using CSS Selectors in Java

    I was working on a task to parse some of Amazon web-services. There are lots of ways to parse it Using DOM/SAX/Stax .  All of them require some amount of coding. I wanted a quick fix and i finally landed on to JSoup an opensource HTML Parser ( Other html parser i like is HTMLParser) . In this article i’m going to explain how i’m going to parse DZone HTML links in java.

    I’ll be retreiving description’s of all links in Dzone using the code

    Note: This is not the best way to read links from Dzone ( You can use rss feed’s instead).  This tutorial is to take you through css selectors for Java

    All DZone pagination queries looks like this

    http://www.dzone.com/links/?type=html&p=2

    i used an opensource java library to parse this and extract link text description (jsoup)

    Here is sample tags we have in dzone response

    <a name="link-613399">
    </a>
    
    <div class="linkblock frontpage " id="link-613399">
    	<div id="thumb_613399" class="thumb">
    		<a onmouseup="track(this, 'twitter4j_oauth_on_android', ''); "
    			href="http://www.xoriant.com/blog/mobile-application-development/twitter4j-oauth-on-android.html">
    			<img width="120" height="90"
    				src="http://cdn.dzone.com/links/images/thumbs/120x90/613399-1307624607000.jpg"
    				class="thumbnail" alt="Link 613399 thumbnail"
    				onmouseover="return OLgetAJAX('/links/themes/reader/jsps/nodecoration/thumb-load.jsp?linkId=613399', OLcmdExT1,
     300, 'bigThumbBody');"
    				onmouseout="OLclearAJAX(); nd(100);" />
    		</a>
    	</div>
    	<div id="hidden_thumb_613399">
    
    	</div>
    	<div class="tools">
    	</div>
    	<div class="details">
    		<div class="vwidget" id="vwidget-613399">
    			<a id="upcount-613399" href="#" class="upcount"
    				onclick="showLoginDialog(613399, null); return false">7</a>
    
    			<a id="downcount-613399" href="#"
    				onclick="showLoginDialog(613399, null); return false;" class="downcount">0</a>
    		</div>
    		<h3>
    			<a onmouseup="track(this, 'twitter4j_oauth_on_android', ''); "
    				href="http://www.xoriant.com/blog/mobile-application-development/twitter4j-oauth-on-android.html"
    				rel="bookmark"> Twitter4j OAuth on Android</a>
    		</h3>
    		<p class="voteblock">
    			<a href="/links/users/profile/811805.html">
    				<img width="24" height="24"
    					src="http://cdn.dzone.com/links/images/std/avatars/default_24.gif"
    					class="avatar" alt="User 811805 avatar" />
    			</a>
    		</p>
    		<p class="fineprint byline">
    			<a href="/links/users/profile/811805.html">RituR</a>
    			via
    			<a href="/links/search.html?query=domain%3Axoriant.com">xoriant.com</a>
    		</p>
    		<p class="fineprint byline">
    			<b>Promoted: </b>
    			Jun 08 / 17:27. Views:
    			520, Clicks: 266
    		</p>
    		<p class="description">
    			OAuth is an open protocol
    			which allows the users to share their private information and assets
    			like photos, videos etc. with another site...&nbsp;
    			<a href='/links/twitter4j_oauth_on_android.html'>more&nbsp;&raquo;
    			</a>
    		</p>
    		<p class="fineprint stats">
    			<a
    				href="http://twitter.com/home?status=RT+%40DZone+%22Twitter4j+OAuth+on+Android%22+http%3A%2F%2Fdzone.com%2FTBxR"
    				class="twitter">Tweet</a>
    			<a href="/links/twitter4j_oauth_on_android.html" class="comment">0
    				Comments</a>
    			<span class="linkUnsaved" id="save-link-613399"
    				onclick="showLoginDialog(613399); return false;">Save</span>
    			<span class="linkUnshared" id="share-link-613399"
    				onclick="showLoginDialog(613399); return false;">Share</span>
    			Tags:
    			<a href="/links/tag/mobile.html" class="tags" rel="tag">mobile</a>
    			,
    			<a href="/links/tag/standards.html" class="tags" rel="tag">standards</a>
    		</p>
    
    	</div>
    </div>

     

    To get description we have to get data from element “P” with class “description” which is actually present in DIV with class “details” Here is how we can do that in java

     

    /**
     *
     */
    package com.linkwithweb.parser;
    
    import java.io.File;
    
    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.nodes.Element;
    import org.jsoup.select.Elements;
    
    /****************************************************************
     * Description
     * jsoup elements support a CSS (or jquery) like selector syntax to find matching elements, that allows very powerful and robust queries.
     *
     * The select method is available in a Document, Element, or in Elements. It is contextual, so you can filter by selecting from a specific element, or
     * by chaining select calls.
     *
     * Select returns a list of Elements (as Elements), which provides a range of methods to extract and manipulate the results.
     *
     * Selector overview
     * tagname: find elements by tag, e.g. a
     * ns|tag: find elements by tag in a namespace, e.g. fb|name finds <fb:name> elements
     * #id: find elements by ID, e.g. #logo
     * .class: find elements by class name, e.g. .masthead
     * [attribute]: elements with attribute, e.g. [href]
     * [^attr]: elements with an attribute name prefix, e.g. [^data-] finds elements with HTML5 dataset attributes
     * [attr=value]: elements with attribute value, e.g. [width=500]
     * [attr^=value], [attr$=value], [attr*=value]: elements with attributes that start with, end with, or contain the value, e.g. [href*=/path/]
     * [attr~=regex]: elements with attribute values that match the regular expression; e.g. img[src~=(?i)\.(png|jpe?g)]
     * : all elements, e.g. *
     * Selector combinations
     * el#id: elements with ID, e.g. div#logo
     * el.class: elements with class, e.g. div.masthead
     * el[attr]: elements with attribute, e.g. a[href]
     * Any combination, e.g. a[href].highlight
     * ancestor child: child elements that descend from ancestor, e.g. .body p finds p elements anywhere under a block with class "body"
     * parent > child: child elements that descend directly from parent, e.g. div.content > p finds p elements; and body > * finds the direct children of
     * the body tag
     * siblingA + siblingB: finds sibling B element immediately preceded by sibling A, e.g. div.head + div
     * siblingA ~ siblingX: finds sibling X element preceded by sibling A, e.g. h1 ~ p
     * el, el, el: group multiple selectors, find unique elements that match any of the selectors; e.g. div.masthead, div.logo
     * Pseudo selectors
     * :lt(n): find elements whose sibling index (i.e. its position in the DOM tree relative to its parent) is less than n; e.g. td:lt(3)
     * :gt(n): find elements whose sibling index is greater than n; e.g. div p:gt(2)
     * :eq(n): find elements whose sibling index is equal to n; e.g. form input:eq(1)
     * :has(seletor): find elements that contain elements matching the selector; e.g. div:has(p)
     * :not(selector): find elements that do not match the selector; e.g. div:not(.logo)
     * :contains(text): find elements that contain the given text. The search is case-insensitive; e.g. p:contains(jsoup)
     * :containsOwn(text): find elements that directly contain the given text
     * :matches(regex): find elements whose text matches the specified regular expression; e.g. div:matches((?i)login)
     * :matchesOwn(regex): find elements whose own text matches the specified regular expression
     * Note that the above indexed pseudo-selectors are 0-based, that is, the first element is at index 0, the second at 1, etc
     * See the Selector API reference for the full supported list and details.
     *
     * @author Ashwin Kumar
     *
     */
    public class HTMLParser {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		try {
    			File input = new File("input/dZoneLinks.xml");
    			Document doc = Jsoup.parse(input, "UTF-8",
    					"http://www.dzone.com/links/?type=html&p=2");
    
    			Elements descriptions = doc.select("div.details > p.description"); // get all description elements in this HTML file
    			/*
    			 * Elements pngs = doc.select("img[src$=.png]");
    			 * // img with src ending .png
    			 *
    			 * Element masthead = doc.select("div.masthead").first();
    			 */
    			// div with
    
    			// Elements resultLinks = doc.select("h3.r > a"); // direct a after h3
    			/**
    			 * Iterate over all descriptions and display them
    			 */
    			for (Element element : descriptions) {
    				System.out.println(element.ownText());
    				System.out.println("--------------");
    			}
    
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    
    }

    Mavenized code has been checked in to svn at following location

    http://code.google.com/p/linkwithweb/source/browse/trunk/Utilities/HTMLParser

    Njoy parsing anything easily using jsoup

     

    PDF Generation Using Templates and OpenOffice and Itext in Java


    Recently i had a task where in i had to create PDF dynamically by merging data and template. I have been using lots of pdf libraries since i started my programming to do such tasks. The previous one i admired a lot was Jasper Reports. But after researching some more time i found out that IText with Openoffice Draw is a simplest way we can generate PDF forms.

    This visual tutorial first Explain’s how to Create PDF forms in Openoffice Draw

    Save PDF to folder where you have your program or just change path for input source in program

    Now here is java code which can convert this pdf to final pdf by filling in Values using IText

    /**
     *
     */
    package com.linkwithweb.reports;
    
    import java.io.ByteArrayOutputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    import com.lowagie.text.DocumentException;
    import com.lowagie.text.pdf.PdfReader;
    import com.lowagie.text.pdf.PdfStamper;
    
    /**
     * @author Ashwin Kumar
     *
     */
    public class ITextStamperSample {
    
    	/**
    	 * @param args
    	 * @throws IOException
    	 * @throws DocumentException
    	 */
    	public static void main(String[] args) throws IOException,
    			DocumentException {
    		// createSamplePDF();
    		generateAshwinFriends();
    	}
    
    	/**
    	 *
    	 */
    	private static void generateAshwinFriends() throws IOException,
    			FileNotFoundException, DocumentException {
    		PdfReader pdfTemplate = new PdfReader("mytemplate.pdf");
    		FileOutputStream fileOutputStream = new FileOutputStream("test.pdf");
    		ByteArrayOutputStream out = new ByteArrayOutputStream();
    		PdfStamper stamper = new PdfStamper(pdfTemplate, fileOutputStream);
    		stamper.setFormFlattening(true);
    
    		stamper.getAcroFields().setField("name", "Ashwin Kumar");
    		stamper.getAcroFields().setField("id", "1\n2\n3\n");
    		stamper.getAcroFields().setField("friendname",
    				"kumar\nsirisha\nsuresh\n");
    		stamper.getAcroFields().setField("relation", "self\nwife\nfriend\n");
    
    		stamper.close();
    		pdfTemplate.close();
    
    	}
    
    }
    

    Here is sample pom.xml

    <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>com.linkwithweb.reports</groupId>
      <artifactId>ReportTemplateTutorial</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <name>ReportTemplateTutorial</name>
      <description>ReportTemplateTutorial</description>
      <dependencies>
      	<dependency>
      		<groupId>com.lowagie</groupId>
      		<artifactId>itext</artifactId>
      		<version>2.1.7</version>
      	</dependency>
      </dependencies>
    </project>

     

    A pdf file with data filled in placeholders is created with name test.pdf


    OSGI for Beginners Using Maven with Equinox(HowTo)

    I have struggled to understand what OSGI really means for a long time. It has been around since a very long time but not many people are aware of it. It has been hyped as a very complex technology to understand. Here is my attempt to make it simple for any Java Developer. In my view if you understand concept of Interface , JNDI or EJB( Or registering some service in some form)  you will understand OSGI. In short OSGI is a Container where you can register your services through interfaces and those can be accessed any time. Another benefit of OSGI is that all these services can be Installed/Uninstalled/Started/Stopped at runtime (i.e Code can be hot deployed at runtime ) rather than normal requirement we have where we have restart J2EE server. Similar to J2ee containers (Tomcat, WebSphere, Jboss , Weblogic ) OSGI also has container like Equinox( Which is base for Eclipse), Apache Felix …etc

    In this article i’m going to explain OSGI with Eclipse Equinox container. Anyone who has Eclipse IDE installed on their machine has OSGI container also installed in Eclipse plugin’s folder.

    Name of OSGI container jar file looks like   org.eclipse.osgi_<version>.jar

    You can start OSGI like this

    java -jar org.eclipse.osgi_3.5.2.R35x_v20100126.jar -console

    Attached is sample screenshot of how i started my OSGI container ( Its analogous to starting tomcat)

    Now that we started OSGI , let me start creation a HelloWorld OSGI Application using Maven. Lemme show you my project structure first and then display my pom.xml


    Now i’ll display my pom.xml. My pom.xml has 2 more profiles added to create 2 more new modules(MathService and MathServiceClient) which will be later explained in this article

    <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>com.linkwithweb.osgi</groupId>
    	<artifactId>HelloWorld</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<name>HelloWorld</name>
    	<dependencies>
    		<dependency>
    			<groupId>org.osgi</groupId>
    			<artifactId>org.osgi.core</artifactId>
    			<version>4.2.0</version>
    		</dependency>
    	</dependencies>
    
    	<build>
    		<finalName>HelloWorld-${version}</finalName>
    		<plugins>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<version>2.3.1</version>
    				<configuration>
    					<source>1.5</source>
    					<target>1.5</target>
    				</configuration>
    			</plugin>
    
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-jar-plugin</artifactId>
    				<configuration>
    					<archive>
    						<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
    					</archive>
    				</configuration>
    			</plugin>
    		</plugins>
    	</build>
    
    	<profiles>
    		<profile>
    			<id>MathService</id>
    			<build>
    				<finalName>MathService-${version}</finalName>
    				<plugins>
    					<plugin>
    						<groupId>org.apache.maven.plugins</groupId>
    						<artifactId>maven-compiler-plugin</artifactId>
    						<version>2.3.1</version>
    						<configuration>
    							<source>1.5</source>
    							<target>1.5</target>
    						</configuration>
    					</plugin>
    
    					<plugin>
    						<groupId>org.apache.maven.plugins</groupId>
    						<artifactId>maven-jar-plugin</artifactId>
    						<configuration>
    
    							<excludes>
    								<exclude>**/*.xml</exclude>
    								<exclude>**/*.bsh</exclude>
    								<exclude>**/*.properties</exclude>
    							</excludes>
    							<archive>
    								<manifestFile>src/main/resources/MathService/META-INF/MANIFEST.MF</manifestFile>
    							</archive>
    						</configuration>
    					</plugin>
    
    				</plugins>
    			</build>
    		</profile>
    		<profile>
    			<id>MathServiceClient</id>
    			<build>
    				<finalName>MathServiceClient-${version}</finalName>
    				<plugins>
    					<plugin>
    						<groupId>org.apache.maven.plugins</groupId>
    						<artifactId>maven-compiler-plugin</artifactId>
    						<version>2.3.1</version>
    						<configuration>
    							<source>1.5</source>
    							<target>1.5</target>
    						</configuration>
    					</plugin>
    
    					<plugin>
    						<groupId>org.apache.maven.plugins</groupId>
    						<artifactId>maven-jar-plugin</artifactId>
    						<configuration>
    
    							<excludes>
    								<exclude>**/*.xml</exclude>
    								<exclude>**/*.bsh</exclude>
    								<exclude>**/*.properties</exclude>
    							</excludes>
    							<archive>
    								<manifestFile>src/main/resources/MathServiceClient/META-INF/MANIFEST.MF</manifestFile>
    							</archive>
    						</configuration>
    					</plugin>
    
    				</plugins>
    			</build>
    		</profile>
    	</profiles>
    
    </project>

    Now if you observe pom.xml there are 3 different MANIFEST.MF defined for 3 different OSGI bundle’s we create.  Saying so lemme explain you that OSGI bundles are same as Java jar file with its configuration defined in Manifest file of standard jar. OSGI defined few entries in manifest file which are related to OSGi which are read by container to activate the bundle, thus avoiding learning of any new metadata format we generally have for other frameworks

    Here is sample Manifest.MF i have defined for MathServiceClient

    Manifest-Version: 1.0
    Bundle-Name: MathServiceClient
    Bundle-Activator: com.linkwithweb.osgi.service.client.MathServiceClientActivator
    Bundle-SymbolicName: MathServiceClient
    Bundle-Version: 1.0.0
    Import-Package: org.osgi.framework,com.linkwithweb.osgi.service

    If you observe above manifest file you can observer that all the entries except Manifest-Version are OSGI specific entries. These are the entries which define how to deploy a bundles what all it is dependent on and what are extension points it exposes for other services to consume.. etc

    Having explained this lemme first explain a HelloWorld bundle with its MANIFEST.MF and Activator class and its installation into Equinox OSGI Container

    /**
     *
     */
    package com.linkwithweb.osgi;
    
    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;
    
    /**
     * @author Ashwin Kumar
     *
     */
    public class HelloActivator implements BundleActivator {
    	public void start(BundleContext context) {
    		System.out.println("Hello World");
    	}
    
    	public void stop(BundleContext context) {
    		System.out.println("Goodbye All");
    	}
    }
    Manifest-Version: 1.0
    Bundle-Name: HelloWorld
    Bundle-Activator: com.linkwithweb.osgi.HelloActivator
    Bundle-SymbolicName: HelloWorld
    Bundle-Version: 1.0.0
    Import-Package: org.osgi.framework

    Now run “mvn clean package” to build our bundle

    It will create HelloWorld-0.0.1-SNAPSHOT.jar in target folder and we can install that into Equinox to test. Here is the image which shows how to install and start our HelloWorld into Equinox

    install file:K:\Ashwin\OSGI\MavenProject\target\HelloWorld-0.0.1-SNAPSHOT.jar

    If you observe above screenshot you can use install command to install the bundle and use the start command on bundle id to start the bundle

    On start of Bundle start method of Activator class is called and while stopping bundle stop method of Activator is called and so you are seeing HelloWorld

    Congratulations you have learned basics of OSGI and you have just deployed your first bundle.

    Now lemme explain my second part of article which explains how to Expose and Consume services of modules

    Exposing and Consuming Services

    To explain this i’ll take a very simple example where i’ll publish a service which can add 2 numbers

    Here is the code which does that

    First we need to define an Interface which we are thinking of exposing to external bundles

    /**
     *
     */
    package com.linkwithweb.osgi.service;
    
    /**
     * @author Ashwin Kumar
     *
     */
    public interface MathService {
    
    	/**
    	 * @param a
    	 * @param b
    	 * @return
    	 */
    	public int add(int a, int b);
    }

    Now the implementation Class

    /**
     *
     */
    package com.linkwithweb.osgi.service;
    
    /**
     * @author Ashwin Kumar
     *
     */
    public class MathServiceImpl implements MathService {
    
    	/* (non-Javadoc)
    	 * @see com.linkwithweb.osgi.service.MathService#add(int, int)
    	 */
    	public int add(int a, int b) {
    		// TODO Auto-generated method stub
    		return a+b;
    	}
    
    }

    Now Activator class which register’s this service with OSGI container

    /**
     *
     */
    package com.linkwithweb.osgi.service;
    
    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;
    
    /**
     * @author Ashwin Kumar
     *
     */
    public class MathServiceActivator implements BundleActivator {
    	/*
    	 * (non-Javadoc)
    	 *
    	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
    	 */
    	public void start(BundleContext context) {
    		MathService service = new MathServiceImpl();
    		// Third parameter is a hashmap which allows to configure the service
    		// Not required in this example
    		context.registerService(MathService.class.getName(), service, null);
    		System.out.println("Math Service Registered");
    	}
    
    	/*
    	 * (non-Javadoc)
    	 *
    	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
    	 */
    	public void stop(BundleContext context) {
    		System.out.println("Goodbye From math service");
    	}
    }

    Here is the manifest file which exposes service

    Manifest-Version: 1.0
    Bundle-Name: MathService
    Bundle-Activator: com.linkwithweb.osgi.service.MathServiceActivator
    Bundle-SymbolicName: MathService
    Bundle-Version: 1.0.0
    Import-Package: org.osgi.framework
    Export-Package: com.linkwithweb.osgi.service

    If you observe this we are Exporting some packages so that they can be consumed later. Also all the package that we are thinking of importign have to be defined here

    Use the following command to build the jar file

    mvn -PMathService package

    and Here is image which displays how to Install and Run the service

    Now lemme explain how to implement consumer

    /**
     *
     */
    package com.linkwithweb.osgi.service.client;
    
    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;
    import org.osgi.framework.ServiceReference;
    
    import com.linkwithweb.osgi.service.MathService;
    
    /**
     * @author Ashwin Kumar
     *
     */
    public class MathServiceClientActivator implements BundleActivator {
    	MathService service;
    	private BundleContext context;
    
    	/*
    	 * (non-Javadoc)
    	 *
    	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
    	 */
    	public void start(BundleContext context) {
    		this.context = context;
    		// Register directly with the service
    		ServiceReference reference = context
    				.getServiceReference(MathService.class.getName());
    		service = (MathService) context.getService(reference);
    		System.out.println(service.add(1, 2));
    	}	/*
    	 * (non-Javadoc)
    	 *
    	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
    	 */
    	public void stop(BundleContext context) {
    		System.out.println(service.add(5, 6));
    	}
    }

    And now manifest file

    Manifest-Version: 1.0
    Bundle-Name: MathServiceClient
    Bundle-Activator: com.linkwithweb.osgi.service.client.MathServiceClientActivator
    Bundle-SymbolicName: MathServiceClient
    Bundle-Version: 1.0.0
    Import-Package: org.osgi.framework,com.linkwithweb.osgi.service

    Now here is how we create package and install

    mvn -PMathServiceClient package

    Source code have been checkedin to following location

    https://linkwithweb.googlecode.com/svn/trunk/osgi-tutorials/MavenProject

     

    Njoy creating OSGI bundles . Main benefit is you can redeploy your bundles/services at runtime.

    Mail me incase you have any doubts

    Capture picture on Webpage with Java Backend

    In most of the projects we try to capture user’s face on web page. Till recently many projects have been implementing this using either Activex objects or Using Java Plugin’s or some other media plugin’s. With advent of flash and it’s related technologies this and it’s increase in presence over the web flash has become favorite technology to build such application.  Thus making it browser agnostic as compared to ActiveX Objects.

    There is a project on web named JPEGCam which is free and opensource which has capability to do that.

    http://code.google.com/p/jpegcam/

    My effort is to create a java backend to it’s frontend ( Default one comes with php backend). Following example explains my effort

    I have created a mavenized application to make it run without any extra server deployment. Here is the description

    I’ve created a simple servlet which just capture’s input stream

    Stores data in a folder named uploads

    Send the file url back to Client to display

    Here is the code

    package com.linkwithweb.jpegcam;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Date;
    
    import javax.servlet.Servlet;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * Ashwin Kumar
     * Servlet implementation class PictureCaptureServlet
     */
    public class PictureCaptureServlet extends HttpServlet {
    	private static final long serialVersionUID = 1L;
    	private String fileStoreURL = "";
    
    	/**
    	 * @see HttpServlet#HttpServlet()
    	 */
    	public PictureCaptureServlet() {
    		super();
    		// TODO Auto-generated constructor stub
    	}
    
    	/**
    	 * @see Servlet#init(ServletConfig)
    	 */
    	public void init(ServletConfig config) throws ServletException {
    		fileStoreURL = config.getServletContext().getRealPath("") + "/uploads";
    		try {
    			File f = new File(fileStoreURL);
    			if (!f.exists()) {
    				f.mkdirs();
    			}
    		} catch (Exception e) {
    			// TODO: handle exception
    		}
    	}
    
    	/**
    	 * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
    	 */
    	protected void service(HttpServletRequest request,
    			HttpServletResponse response) throws ServletException, IOException {
    		try {
    			long time = new Date().getTime();
    
    			FileOutputStream fileOutputStream = new FileOutputStream(
    					fileStoreURL + "/"+time+".jpg");
    			int res;
    			while ((res = request.getInputStream().read()) != -1) {
    				fileOutputStream.write(res);
    			}
    			fileOutputStream.close();
    			/**
    			 * To make sure each url is differeent and not cached added time to tit
    			 */
    			response.getWriter().append(
    					"http://localhost:8080/uploads/" + time
    							+ ".jpg");
    
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    
    		}
    	}
    
    }

    Below is sample javascript which handles frontend

    	<!-- First, include the JPEGCam JavaScript Library -->
    	<script type="text/javascript" src="webcam.js"></script>
    
    	<!-- Configure a few settings -->
    	<script language="JavaScript">
    		webcam.set_api_url( '/capture' );
    		webcam.set_quality( 90 ); // JPEG quality (1 - 100)
    		webcam.set_shutter_sound( true ); // play shutter click sound
    	</script>
    
    	<!-- Next, write the movie to the page at 320x240 -->
    	<script language="JavaScript">
    		document.write( webcam.get_html(320, 240) );
    	</script>
    	<!-- Code to handle the server response (see test.php) -->
    	<script language="JavaScript">
    		webcam.set_hook( 'onComplete', 'my_completion_handler' );
    
    		function take_snapshot() {
    			// take snapshot and upload to server
    			document.getElementById('upload_results').innerHTML = '<h1>Uploading...</h1>';
    			webcam.snap();
    		}
    
    		function my_completion_handler(msg) {
    			// extract URL out of PHP output
    			if (msg.match(/(http\:\/\/\S+)/)) {
    				var image_url = RegExp.$1;
    				// show JPEG image in page
    				document.getElementById('upload_results').innerHTML =
    					'<h1>Upload Successful!</h1>' +
    					'<h3>JPEG URL: ' + image_url + '</h3>' +
    					'<img src="' + image_url + '">';
    
    				// reset camera for another shot
    				webcam.reset();
    			}
    			else alert("Java Error: " + msg);
    		}
    	</script>

    Now let me paste my pom.xml

    <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/maven-v4_0_0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    	<groupId>com.linkwithweb.browsercam</groupId>
    	<artifactId>JPEGCamIntegration</artifactId>
    	<packaging>war</packaging>
    	<version>0.0.1-SNAPSHOT</version>
    	<name>JPEGCamIntegration Maven Webapp</name>
    	<url>http://maven.apache.org</url>
    	<dependencies>
    		<dependency>
    			<groupId>junit</groupId>
    			<artifactId>junit</artifactId>
    			<version>3.8.1</version>
    			<scope>test</scope>
    		</dependency>
    		<dependency>
    			<groupId>javax.servlet</groupId>
    			<artifactId>servlet-api</artifactId>
    			<version>2.5</version>
    			<scope>provided</scope>
    		</dependency>
    	</dependencies>
    	<build>
    		<finalName>JPEGCamIntegration</finalName>
    		<plugins>
    			<plugin>
    				<groupId>org.mortbay.jetty</groupId>
    				<artifactId>jetty-maven-plugin</artifactId>
    				<version>8.0.0.M2</version>
    				<configuration>
    					<scanIntervalSeconds>3</scanIntervalSeconds>
    				</configuration>
    			</plugin>
    
    			<!-- Facilitates downloading source and javadoc in Eclipse -->
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-eclipse-plugin</artifactId>
    				<version>2.8</version>
    				<configuration>
    					<wtpversion>2.0</wtpversion>
    					<downloadSources>true</downloadSources>
    					<downloadJavadocs>true</downloadJavadocs>
    				</configuration>
    			</plugin>
    
    			<!-- Ensures we are compiling at 1.6 level -->
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<version>2.3.2</version>
    				<configuration>
    					<source>1.6</source>
    					<target>1.6</target>
    				</configuration>
    			</plugin>
    		</plugins>
    	</build>
    </project>

    Here is how you run this and test

    mvn jetty:run-exploded

    and click this URL

    http://localhost:8080

    Code has been checked in to following location

    http://code.google.com/p/linkwithweb/source/browse/trunk/Utilities/JPEGCamIntegration.rar

    Struts2 , JSON , JQGrid with annotations

    This article explains my hardships which trying to get the example work. It is still not fully working solution but a solution which takes you through steps any new guys goes through while trying to configure struts2 using annotation. With introduction of annotation concept in Java5 , many framework’s tried to exploit it very well to make themselves developer friendly. With respect to Web Framework’s Spring MVC is the leader as well as frontrunner in using this. Struts2 has tried to implement the same concepts but for any new developer it be little hard to get it to work as there are not many working articles over the web. I never suggest using any fremawork tags in building UI elements which these framework’s profess ( It would be difficult to reuse/migrate if at all we have migrate in future). I never support people/framework’s who push UI development in hands of developers rather then to designer’s.

    Saying this here is example of a sample struts2 application where i have a html named index.jsp which call a Struts2 Action in back-end to get data and presentation is defined in HTML

    First of all i’ll define by build structure and dependencies. As i’m planning to use Maven my build structure is default maven build structure here is my pom.xml

    <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/maven-v4_0_0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    	<groupId>com.linkwithweb.struts2</groupId>
    	<artifactId>Struts2Example</artifactId>
    	<packaging>war</packaging>
    	<version>1.0</version>
    	<name>Struts2Example Maven Webapp</name>
    	<url>http://maven.apache.org</url>
    	<dependencies>
    
    		<dependency>
    			<groupId>junit</groupId>
    			<artifactId>junit</artifactId>
    			<version>3.8.1</version>
    			<scope>test</scope>
    		</dependency>
    
    		<dependency>
    			<groupId>org.apache.struts</groupId>
    			<artifactId>struts2-core</artifactId>
    			<version>2.1.8</version>
    		</dependency>
    
    		<dependency>
    			<groupId>org.apache.struts</groupId>
    			<artifactId>struts2-convention-plugin</artifactId>
    			<version>2.1.8</version>
    		</dependency>
    
    		<dependency>
    			<groupId>org.apache.struts</groupId>
    			<artifactId>struts2-json-plugin</artifactId>
    			<version>2.1.8</version>
    		</dependency>
    
    		<dependency>
    			<groupId>javax.servlet</groupId>
    			<artifactId>servlet-api</artifactId>
    			<version>2.5</version>
    			<scope>provided</scope>
    		</dependency>
    	</dependencies>
    	<build>
    		<finalName>Struts2Example</finalName>
    		<plugins>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<version>2.3.1</version>
    				<configuration>
    					<source>1.5</source>
    					<target>1.5</target>
    				</configuration>
    			</plugin>
    			<plugin>
    				<groupId>org.codehaus.mojo</groupId>
    				<artifactId>tomcat-maven-plugin</artifactId>
    				<version>1.0</version>
    				<configuration></configuration>
    			</plugin>
    
    			<plugin>
    				<groupId>org.mortbay.jetty</groupId>
    				<artifactId>jetty-maven-plugin</artifactId>
    				<version>7.1.4.v20100610</version>
    				<configuration>
    					<webApp>${basedir}/target/medihits-admin</webApp>
    				</configuration>
    			</plugin>
    		</plugins>
    	</build>
    </project>

    The struts2-convention-plugin-version jar file is needed if your are using annotations.

    Struts2 has made life little simple by avoiding all the Configuration files it needed before this version by providing configuration by annotation if we just see our web.xml , it’s pretty straightforward where we configure Struts2 Filter to route all requests to corresponding actions

    <!DOCTYPE web-app PUBLIC
     "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
     "http://java.sun.com/dtd/web-app_2_3.dtd" >
    
    <web-app>
    	<display-name>Struts 2 Sample Web Application</display-name>
    
    	<filter>
    		<filter-name>struts2</filter-name>
    		<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    	</filter>
    
    	<filter-mapping>
    		<filter-name>struts2</filter-name>
    		<url-pattern>/struts/*</url-pattern>
    	</filter-mapping>
    
    </web-app>

    If you observer web.xml i’m filtering all requests that are starting with /struts/* using struts filter. This is entry point of struts application. Now let me describe how we define an Action in Struts2

    package com.linkwithweb.user.action;
    
    import org.apache.struts2.convention.annotation.Action;
    import org.apache.struts2.convention.annotation.Namespace;
    import org.apache.struts2.convention.annotation.Result;
    import org.apache.struts2.convention.annotation.ResultPath;
    
    import com.opensymphony.xwork2.ActionSupport;
    /**
    *Example : http://localhost:8080/struts/User
    */
    @Namespace("/struts/User")
    @ResultPath(value="/")
    public class WelcomeUserAction extends ActionSupport{
    
    	private String username;
    
    	public String getUsername() {
    		return username;
    	}
    
    	public void setUsername(String username) {
    		this.username = username;
    	}
    
            // Example URL : http://localhost:8080/struts/User/Welcome
    	@Action(value="Welcome", results={
    			@Result(name="success",location="pages/welcome_user.jsp")
    	})
    	public String execute() {
    
    		return SUCCESS;	}
    }

    Looking at above code by now you might have understood how URL are mapped in Struts2.

    Now let me describe my effort to add JSON-Plugin. If you have previously observed my pom i have added JSON plugin depdendency

    		<dependency>
    			<groupId>org.apache.struts</groupId>
    			<artifactId>struts2-json-plugin</artifactId>
    			<version>2.1.8</version>
    		</dependency>

    Here is some background how struts2 works

    The Convention plug-in is the one which does everything in the background. The Convention plug-in does the following things.

    • By default the Convention plug-in looks for the action classes inside the following packagesstrut, struts2, action or actions. Here our package name is com.vaannila.action. Any package that matches these names will be considered as the root package for the Convention plug-in.
    • The action class should either implement com.opensymphony.xwork2.Action interface or the name of the action class should end with Action. Here we extend our WelcomeUser class from com.opensymphony.xwork2.ActionSupport which inturn implements com.opensymphony.xwork2.Action.
    • The Convention plug-in uses the action class name to map the action URL. Here our action class name is WelcomeUser and the URL is welcome-user. The plug-in converts the camel case class name to dashes to get the request URL.
    • Now the Convention plug-in knows which Action class to call for a particular request. The next step is to find which result to forward based on the return value of the execute method. By default the Convention plug-in will look for result pages in WEB-INF/contentdirectory.
    • Now the Convention plug-in knows where to look for results, but it doesn’t know which file to display inside the content directory. The Convention plug-in finds this with the help of the result code returned by the Action class. If “success” is returned then the Convention plug-in will look for a file name welcome-user-success.jsp or welcome-user.jsp . It need not be a jsp file it can be even a velocity or freemaker files. If the result value is “input” it will look for a file name welcome-user-input.jsp or welcome-user-input.vm or welcome-user-input.ftl.
    Now id we need to define a Action which return’s JSON String, we need to define that action implements json-convention which is defined this way
    package com.linkwithweb.ajax.action;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.apache.struts2.convention.annotation.Action;
    import org.apache.struts2.convention.annotation.Namespace;
    import org.apache.struts2.convention.annotation.ParentPackage;
    import org.apache.struts2.convention.annotation.Result;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    /**
     * @author Ashwin Kumar
     *
     */
    @Namespace("/struts/Ajax")
    @Result(name = "success", type = "json")
    @ParentPackage("json-default")
    public class AjaxAction extends ActionSupport {
    
    	@Action(
    			value = "grid",
    				results = { @Result(name = "success", type = "json") })
    	public String execute() {
    		return "success";
    	}
    /**
     * To Directly write to response and skip all Struts process flows use the below 2 methofs
     */
    /*	public HttpServletResponse getResponse() {
    		return ServletActionContext.getResponse();
    	}*/
    
    	/**
    	 * Rename to execute to override
    	 *
    	 * @return
    	 * @throws Exception
    	 *//*
    	public String executeToOverrride() throws Exception {
    		PrintWriter printWriter = null;
    		getResponse().setContentType("text / xml;charset = UTF-8");
    		getResponse().setHeader("Cache - Control", "no - cache");
    
    		StringBuffer sb = new StringBuffer("<movie>");
    		// let's say you have A Movie object "movie" that needs to be represented as XML
    		try {
    			printWriter = getResponse().getWriter();
    			sb.append("<director>dir</director>");
    			sb.append("<language>lang</language>");
    			sb.append("<year>year</year>");
    			sb.append("</movie>");
    			printWriter.print(sb.toString());
    		} catch (IOException e) {
    			e.printStackTrace();
    			throw e;
    		} finally {
    			printWriter.close();
    			printWriter = null;
    		}
    		return NONE;
    	}*/
    
    	/**
    	 * @return
    	 */
    	public String getPage() {
    		return "1";
    	}
    
    	public int getTotal() {
    		return 2;
    	}
    
    	public String getRecords() {
    		return "13";
    	}
    
    	public List<String> getRows() {
    		List<String> arrayList = new ArrayList<String>();
    		arrayList.add("{'id':'13','cell':['13','2007-10-06','Client 3','1000.00','0.00','1000.00',null]}");
    		arrayList.add("{'id':'12','cell':['12','2007-10-06','Client 2','700.00','140.00','840.00',null]}");
    		arrayList.add("{'id':'11','cell':['11','2007-10-06','Client 1','600.00','120.00','720.00',null]}");
    		arrayList.add("{'id':'10','cell':['10','2007-10-06','Client 2','100.00','20.00','120.00',null]}");
    		arrayList.add("{'id':'9','cell':['9','2007-10-06','Client 1','200.00','40.00','240.00',null]}");
    		arrayList.add("{'id':'8','cell':['8','2007-10-06','Client 3','200.00','0.00','200.00',null]}");
    		arrayList.add("{'id':'7','cell':['7','2007-10-05','Client 2','120.00','12.00','134.00',null]}");
    		arrayList.add("{'id':'6','cell':['6','2007-10-05','Client 1','50.00','10.00','60.00','']}");
    		arrayList.add("{'id':'5','cell':['5','2007-10-05','Client 3','100.00','0.00','100.00','no tax at all']}");
    		arrayList.add("{'id':'4','cell':['4','2007-10-04','Client 3','150.00','0.00','150.00','no tax']}");
    
    		return arrayList;
    	}
    }
    If you observe the above code any url request of form /struts/Ajax/grid will come to this Action class and as we defined it follows json-default convention and so this class acts as bean and this java bean is converted to json string in response here is sample response for above class
    http://localhost:8080/struts/Ajax/grid
    {"page":"1","records":"13","rows":["{'id':'13','cell':['13','2007-10-06','Client 3','1000.00','0.00','1000.00',null]}","{'id':'12','cell':['12','2007-10-06','Client 2','700.00','140.00','840.00',null]}","{'id':'11','cell':['11','2007-10-06','Client 1','600.00','120.00','720.00',null]}","{'id':'10','cell':['10','2007-10-06','Client 2','100.00','20.00','120.00',null]}","{'id':'9','cell':['9','2007-10-06','Client 1','200.00','40.00','240.00',null]}","{'id':'8','cell':['8','2007-10-06','Client 3','200.00','0.00','200.00',null]}","{'id':'7','cell':['7','2007-10-05','Client 2','120.00','12.00','134.00',null]}","{'id':'6','cell':['6','2007-10-05','Client 1','50.00','10.00','60.00','']}","{'id':'5','cell':['5','2007-10-05','Client 3','100.00','0.00','100.00','no tax at all']}","{'id':'4','cell':['4','2007-10-04','Client 3','150.00','0.00','150.00','no tax']}"],"total":2}
    I have integrated JQGrid multiselect functionality in index.jsp. here is sample code which configures jqgrid multiselect
    jQuery("#list9").jqGrid({
       	url:'response.jsp?time='+new Date().getTime(),
    	datatype: "json",
       	colNames:['Inv No','Date', 'Client', 'Amount','Tax','Total','Notes'],
       	colModel:[
       		{name:'id',index:'id', width:55},
       		{name:'invdate',index:'invdate', width:90},
       		{name:'name',index:'name', width:100},
       		{name:'amount',index:'amount', width:80, align:"right"},
       		{name:'tax',index:'tax', width:80, align:"right"},
       		{name:'total',index:'total', width:80,align:"right"},
       		{name:'note',index:'note', width:150, sortable:false}
       	],
       	rowNum:10,
       	rowList:[10,20,30],
       	pager: '#pager9',
       	sortname: 'id',
    	recordpos: 'left',
        viewrecords: true,
        sortorder: "desc",
    	multiselect: true,
    	caption: "Multi Select Example"
    });
    jQuery("#list9").jqGrid('navGrid','#pager9',{add:false,del:false,edit:false,position:'right'});
    jQuery("#m1").click( function() {
    	var s;
    	s = jQuery("#list9").jqGrid('getGridParam','selarrrow');
    	alert(s);
    });
    jQuery("#m1s").click( function() {
    	jQuery("#list9").jqGrid('setSelection',"13");
    });
    Here is how index.jsp looks like after running ( you can use mvn -Djetty.port=9090 jetty:run or mvn tomcat:run)
    Will make it more professional and fix all issues along with article in coming week. Got to work on something else so leave it here
    Code has been checked in to following svn location. https://linkwithweb.googlecode.com/svn/trunk/Struts
    So play with this as you want

    Build your own WebMockup Tool using jQuery

    This article is to show the capability of Javascript and jQuery Framework’s rather than as reference implementation to create a web mockup tool.  Infact this is not the best architecture to build a mockup tool in javascript.

    Sample demo is hosted at  http://linkwithweb.appspot.com/DynamicForm.html   ( It only Works in Firefox and Chrome) :)

    Concepts like  Drag/Drop , Resizable , Context Menu , Container’s, Grouping,

    Cornering element view’s etc…. are being explained through this article.

    I have used following javascript libraries to create this

    1. jquery
    2. jqueryui
    3. jquery.corner.js
    4. jquery.contextmenu.js

    To create any Mockup tool we first to define few things that are required to build it

    1. Creation of Draggable Objects
    2. Creation of Droppable Area where object’s can be dropped.
    3. Layout of objects on droppable area(Dashboard)
    4. Deleting/Changing properties of objects/elements in the dashboard





    Because i ‘m going to build a HTML mockup tool , i’ll define few html element’s as my draggable objects which i’m going to play with. Apart from this as i’m planning to make all objects/elements in my mockup tool as draggable one’s i’ll define a Dragholder which is used to hold my draggable objects. I have defined a class with name “drag” that defines all draggable objects

    TextBox

    <div id="drag1" class="drag">
         <input type="text" value="test" style="width: 80%; height: 80%;"></input>
    </div>

    Form

    <form id="drag2" class="drag containerdiv">
    
    	<div style=""
    		class="context-menu context-menu-theme-vista context-menu-example-trigger menu-vista">
    		<div class="context-menu-item">
    			<div class="context-menu-item-inner">Form Container</div>
    		</div>
    	</div></form>

    Button

    <div id="drag3" class="drag">
    	<input type="button" value="Drag Me" />
    </div>

    TextArea

    <div id="drag4" class="drag">
    	<textarea name="userInput" style="width: 80%; height: 80%;"></textarea>
    </div>

    SelectBox

    <div id="drag4" class="drag">
    	<select>
    		<option>Small</option>
    		<option selected="true">Medium</option>
    		<option>Large</option>
    		<option>X-Large</option>
    	</select>
    </div>

    All the above elements have been defined with css class “drag” which we use to query latter.

    Now lets define a container where all the above draggable elements will be dragged and played around

    <div id="frame">
    </div>

    the above div element with id “frame” is used as container in our mockup tool.

    Now as we have defined all elements in our HTML playground , let me explain the logic i’m going to use to create this.  Before going into that lemme explain that elements like form can have other elements so lets also make it droppable once it enters our playground

    1. Get all objects with class “drag”
    2. Add control key listener which add’s class “grouped” to elements if clicked by holding cotrol key ( Kind of selecting a element)
    3. Make all of then resizable.
    4. Add context menu for all elements
    5. Enable drag on them and assign them some id’s
    6. If element contain’s class “grouped” , moved all other elements with class “grouped” same width and height as our draggable element
    7. If elements also have class name “containerdiv” then they droppable apart from draggable, so enable droppable feature on them
    Here is how sample menu is created
    var menu = [
    	{
    		'Show an alert' : function() {
    			alert('This is an alert!');
    		}
    	},
    	{
    		'Turn me red (try it)' : function() {
    			this.style.backgroundColor = 'red';
    		}
    	},
    	{
    		'<b>HTML</b> <i>can be</i> <u>used in</u> <input type="text" value="test"/>' : function(
    				menuItem, cmenu, e) {
    			$t = $(e.target);
    			return false;
    		}
    	},
    	$.contextMenu.separator,
    	{
    		'Just above me was a separator!' : function() {
    		}
    	},
    	{
    		'Option with icon (for themes that support it)' : {
    			onclick : function() {
    			},
    			icon : 'i_save.gif'
    		}
    	},
    	{
    		'Disabled option' : {
    			onclick : function() {
    			},
    			disabled : true
    		}
    	},
    	{
    		'<div><div style="float:left;">Choose a color (don\'t close):</div><div class="swatch" style="background-color:red"></div><div class="swatch" style="background-color:green"></div><div class="swatch" style="background-color:blue"></div><div class="swatch" style="background-color:yellow"></div><div class="swatch" style="background-color:black"></div></div><br>' : function(
    				menuItem, cmenu, e) {
    			$t = $(e.target);
    			if ($t.is('.swatch')) {
    				this.style.backgroundColor = $t.css('backgroundColor');
    				$t.parent().find('.swatch').removeClass('swatch-selected');
    				$t.addClass('swatch-selected');
    			}
    			return false;
    		}
    	},
    	{
    		'Use fadeOut for hide transition' : function(menuItem, cmenu) {
    			cmenu.hideTransition = 'fadeOut';
    			cmenu.hideSpeed = 'fast';
    		}
    	},
    	{
    		'Use slideUp for hide transition (quirky in IE)' : function(
    				menuItem, cmenu) {
    			cmenu.hideTransition = 'slideUp';
    		}
    	},
    	{
    		'Use normal hide transition' : function(menuItem, cmenu) {
    			cmenu.hideTransition = 'hide';
    		}
    	},
    	{
    		'Increments each time menu is displayed using beforeShow hook: #<span class="option-count">1</span>' : function() {
    		}
    	}, {
    		'Custom menu item class and hover class for this item only' : {
    			onclick : function() {
    			},
    			className : 'context-menu-item-custom',
    			hoverClassName : 'context-menu-item-custom-hover'
    		}
    	} ];

    Below is sample code on how we implement above functionality using jquery

    /**
     * Called once document is loaded
     */
    $(document).ready(function() {
    	$('a[rel*=facebox]').facebox({
    		div : '#frame',
    		loading_image : 'loading.gif',
    		close_image : 'closelabel.gif'
    	});
    
    	// Counter
    	counter = 0;
    
    	// Make element draggable
    	// $(".dragged").resizable().draggable();
    	enableDrag("frame", ".drag", "false");
    
    	// $(".drag").corner();
    
    	// Make element droppable
    	$("#frame").droppable({
    		drop : function(ev, ui) {
    			if (ui.helper.attr('id').search(/drag[0-9]/) != -1) {
    				counter++;
    				var element = $(ui.draggable).clone();
    
    				// alert(element);
    				element.addClass("tempclass");
    
    				$(this).append(element);
    
    				$(".tempclass").attr("id", "clonediv" + counter);
    				$("#clonediv" + counter).removeClass("tempclass");
    
    				// Get the dynamically item id
    				draggedNumber = ui.helper.attr('id').search(/drag([0-9])/)
    				// itemDragged = "dragged" + RegExp.$1
    				// //console.log(itemDragged)
    				itemDragged = "dragged";
    
    				$("#clonediv" + counter).addClass(itemDragged);
    
    				enableDrag("parent", "#clonediv" + counter, "true");
    
    			}
    		}
    	});
    });

    Code for function enableDrag which is main funciton in our project

    /**
     * This function enables drag on a object and contains its drag in the passed
     * container
     *
     * @param dragContainment
     * @param draggableClass
     * @param resizable
     */
    function enableDrag(dragContainment, draggableClass, resizable) {
    	// Make element draggable and resizable
    	$(draggableClass).click(function(event) {
    		if (event.ctrlKey) {
    			$(this).toggleClass('grouped');
    		}
    	});
    	/**
    	 * Add Context Menu
    	 */
    	$(draggableClass).find(".menu-vista").contextMenu(menu, {
    		theme : 'vista',
    		beforeShow : beforeShowFunc
    	});
    	$(draggableClass).contextMenu(draggableObjectMenu, {
    		theme : 'vista'
    	});
    
    	var element;
    
    	/**
    	 * Make the element resizable
    	 */
    	if (resizable == "true") {
    		element = $(draggableClass).corner().resizable();
    	} else {
    		element = $(draggableClass).corner();
    	}
    
    	/**
    	 * If element is containerdiv then make it droppable
    	 */
    	if (element.hasClass("containerdiv")) {
    
    		// Make element droppable
    		element.droppable({
    			greedy : true,
    			out : function(event, ui) {
    
    				var element = $(ui.draggable);
    				if (!element.hasClass("containerdiv")) {
    					$(this).parent().append(element);
    				}
    			},
    			drop : function(ev, ui) {
    				if (ui.helper.attr('id').search(/drag[0-9]/) != -1) {
    					var element = $(ui.draggable);
    					counter++;
    
    					element = $(ui.draggable).clone();
    					// alert(element);
    					element.addClass("tempclass");
    
    					$(this).append(element);
    
    					$(".tempclass").attr("id", "clonediv" + counter);
    					$("#clonediv" + counter).removeClass("tempclass");
    
    					// Get the dynamically item id
    					draggedNumber = ui.helper.attr('id').search(/drag([0-9])/)
    					// itemDragged = "dragged" + RegExp.$1
    					// //console.log(itemDragged)
    					itemDragged = "dragged";
    
    					$("#clonediv" + counter).addClass(itemDragged);
    
    					enableDrag("frame", "#clonediv" + counter, "true");
    
    				} else {
    					var element = $(ui.draggable);
    					$(this).append(element);
    				}
    			}
    		});
    
    	}
    
    	/**
    	 * Now make element draggable
    	 */
    	element.draggable({
    		helper : 'clone',
    		containment : dragContainment,
    
    		start : function(event, ui) {
    			posTopArray = [];
    			posLeftArray = [];
    			thisElem = $(this);
    
    			if ($(this).hasClass("grouped")) { // Loop through each element and
    				// store beginning start and
    				// left positions
    
    				$(".grouped").each(function(i) {
    					thiscsstop = $(this).css('top');
    					if (thiscsstop == 'auto')
    						thiscsstop = 0; // For IE
    
    					thiscssleft = $(this).css('left');
    					if (thiscssleft == 'auto')
    						thiscssleft = 0; // For IE
    
    					posTopArray[i] = parseInt(thiscsstop);
    					posLeftArray[i] = parseInt(thiscssleft);
    				});
    			}
    
    			begintop = $(this).offset().top; // Dragged element top position
    			beginleft = $(this).offset().left; // Dragged element left position
    		},
    
    		drag : function(event, ui) {
    			var topdiff = $(this).offset().top - begintop; // Current distance
    			// dragged element
    			// has traveled
    			// vertically
    			var leftdiff = $(this).offset().left - beginleft; // Current
    			// distance
    			// dragged
    			// element has
    			// traveled
    			// horizontally
    
    			var draggingId = $(this).attr("id");
    			if ($(this).hasClass("grouped")) {
    				// //console.log("Initial pos "+begintop +"
    				// Left----"+beginleft);
    				// //console.log("Diff Value is "+topdiff +"
    				// Left----"+leftdiff);
    				$(".grouped").each(function(i) {
    					if (draggingId === $(this).attr("id")) {
    						topdiff = $(this).offset().top - begintop; // Current
    						leftdiff = $(this).offset().left - beginleft; // Current
    					}
    				});
    
    				$(".grouped").each(function(i) {
    					// //console.log("Pres pos for "+$(this).attr('id')+" is
    					// "+posTopArray[i] +" Left----"+posLeftArray[i]);
    					if (draggingId !== $(this).attr("id")) {
    						$(this).css('top', posTopArray[i] + topdiff); // Move
    						$(this).css('left', posLeftArray[i] + leftdiff); // Move
    					}
    				});
    
    			}
    		},
    
    		// When first dragged
    		stop : function(ev, ui) {
    			var pos = $(ui.helper).offset();
    			objName = "#clonediv" + counter
    			var draggingId = $(this).attr("id");
    
    			var leftValue = pos.left;
    			var topValue = pos.top;
    
    			/**
    			 * The below if loop is written to fix the relative and abosiulte
    			 * positioning issue. When any draggable object is dropped into a
    			 * droppable container which resides in another container then the
    			 * droppable with more z-index becomes relative positining for its
    			 * sub elements
    			 */
    			if ($(this).parent().hasClass("containerdiv")) {
    				// console.log("Left Pos "+leftValue);
    				// console.log("Top Pos "+topValue);
    				// console.log("$(this).parent().attr('left')
    				// "+$(this).parent().offset().left);
    				// console.log("$(this).parent().offset().top
    				// "+$(this).parent().offset().top);
    				leftValue = pos.left - $(this).parent().offset().left;
    				topValue = pos.top - $(this).parent().offset().top;
    			}
    
    			if ($(this).hasClass("drag")) {
    				$(objName).css({
    					"left" : leftValue,
    					"top" : topValue
    				});
    				$(objName).removeClass("drag");
    
    			} else {
    				objName = draggingId;
    				thisElem.css({
    					"left" : leftValue,
    					"top" : topValue
    				});
    			}
    
    			// console.log("Left Pos "+leftValue);
    			// console.log("Top Pos "+topValue);
    
    			var topdiff = $(this).offset().top - begintop; // Current distance
    			// dragged element
    			// has traveled
    			// vertically
    			var leftdiff = $(this).offset().left - beginleft; // Current
    			// distance
    			// dragged
    			// element has
    			// traveled
    			// horizontally
    
    			// This logic for Group Elements
    
    			if ($(this).hasClass("grouped")) {
    				// //console.log("Initial pos "+begintop +"
    				// Left----"+beginleft);
    				// //console.log("Diff Value is "+topdiff +"
    				// Left----"+leftdiff);
    				$(".grouped").each(function(i) {
    					if (draggingId === $(this).attr("id")) {
    						topdiff = $(this).offset().top - begintop; // Current
    						// distance
    						// dragged
    						// element
    						// has
    						// traveled
    						// vertically
    						leftdiff = $(this).offset().left - beginleft; // Current
    						// distance
    						// dragged
    						// element
    						// has
    						// traveled
    						// horizontally
    					}
    				});
    
    				$(".grouped").each(function(i) {
    					// //console.log("Pres pos for "+$(this).attr('id')+" is
    					// "+posTopArray[i] +" Left----"+posLeftArray[i]);
    					if (draggingId !== $(this).attr("id")) {
    						$(this).css('top', posTopArray[i] + topdiff); // Move
    						// element veritically - current css top + distance
    						// dragged element has travelled vertically
    						$(this).css('left', posLeftArray[i] + leftdiff); // Move
    						// element horizontally-current css left + distance
    						// dragged element has travelled horizontally
    					}
    				});
    
    			}
    
    		}
    	});
    
    }

    Below is code which generate HTML Code from the design we made

    /**
     * On Spit html button clicked alert the HTML in the frame that gets generated
     */
    function alertHTML() {
    	var htmlClone = $("#frame").clone();
    	alert("<html><head></head><body>" + htmlClone.html() + "</body></html>");
    }

    Code has been checked in to follow svn url https://linkwithweb.googlecode.com/svn/trunk/WebMockup

    Njoy playing with javascript and jQuery

    Follow

    Get every new post delivered to your Inbox.