http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
http://msdn.microsoft.com/en-us/library/ms228966.aspx
Source http://www.careerride.com/Spring-bean-lifecycle-in-spring-framework.aspx Question/response JAVA Spring What is Spring? Spring is a framework that resolves common problems in JEE architecture. (JDBC ,integration later, presentation layer …) Spring is managing business objects and encouraging practices POJO model (vs programming model) It’s highly recommended to use a architectural tiers (presentation,business,dao Layer) ; the inejection of the different beans
Le Grand collisionneur de hadrons (LHC) est un gigantesque instrument scientifique situé près de Genève, à cheval sur la frontière franco-suisse, à environ 100 mètres sous terre. C’est un accélérateur de particules, avec lequel les physiciens étudient les plus petites particules connues : les composants fondamentaux de la matière. Le LHC va révolutionner notre compréhension du monde,
Rendre un Jar executable en Spring Nous allons voir dans cet article comment packager un executable jar avec Maven 2 . Ayant rencontrer quelque problème dans le chargement des Beans Spring . Pour cela il faut inclure dans le packaging du jar les fichiers spring.handlers et spring.schemas. Nous utiliserons ici le plugin shade plutot
Samba permet de partager des dossiers sous Linux avec des ordinateurs locaux sous Windows, très pratique, donc ! De plus, il permet d’établir un réseau relativement sécurisé grâce à ses nombreuses fonctions. Commencez d’abord par l’installer : loguez vous en root puis tapez : apt-get install samba Il faut ensuite configurer quelques lignes du fichier
juil
01
Posted by : 1 juillet 2014
| On :http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
http://msdn.microsoft.com/en-us/library/ms228966.aspx
juin
24
Posted by : 24 juin 2014
| On :http://www.kanazawa-net.ne.jp/~pmansato/parallel/parallel_taskfactory.htm
http://codereview.stackexchange.com/questions/44547/writing-highly-asynchronous-code
https://www.dropbox.com/s/f053j1pgw2qo9fz/AsynchronousProgramming.rar
http://chsakell.com/2014/01/11/asynchronous-programming-using-tasks/
http://slynetblog.blogspot.fr/2013/04/downloading-multiple-files-on-windows.html
Connection SQL Serveur
https://www.connectionstrings.com/sql-server-2008/
http://robbincremers.me/2011/12/31/wcf-asynchronous-client-proxy-and-asynchronous-service-operations/
http://stackoverflow.com/questions/8040002/how-to-make-a-wcf-rest-method-entirely-asynchronous-with-the-task-parallel-libra
using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace AsynchronousProgramming { class Program { //const string connectionString = "Data source = localhost; Initial catalog = Chinook; Integrated security = SSPI;"; const string connectionString = "Data Source=ARTAUDHOME\\SQLEXPRESS;Initial Catalog=Chinook;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False"; static void Main(string[] args) { Thread.CurrentThread.Name = "MainThread"; #region This will block the thread... DataSet dsArtists = GetArtistsAsync().Result; foreach (DataRow row in dsArtists.Tables["Artists"].Rows) { foreach (DataColumn col in dsArtists.Tables[0].Columns) { Console.Write(row[col] + "\t"); } Console.WriteLine(); } #endregion #region This won't block the main thread //GetArtistsAsync().ContinueWith(task => //{ // DataSet dsArtists = task.Result; // foreach (DataRow row in dsArtists.Tables["Artists"].Rows) // { // foreach (DataColumn col in dsArtists.Tables[0].Columns) // { // Console.Write(row[col] + "\t"); // } // Console.WriteLine(); // } //}); #endregion #region This won't block the thread and catches exceptions //GetArtistsAsync().ContinueWith(task => //{ // DataSet dsArtists = task.Result; // foreach (DataRow row in dsArtists.Tables["Artists"].Rows) // { // foreach (DataColumn col in dsArtists.Tables[0].Columns) // { // Console.Write(row[col] + "\t"); // } // Console.WriteLine(); // } //}, TaskContinuationOptions.NotOnFaulted); //GetArtistsAsync().ContinueWith(task => //{ // Console.WriteLine(task.Exception.InnerException.Message); //}, TaskContinuationOptions.OnlyOnFaulted); #endregion #region Task Composition - Multithreading //var watch = Stopwatch.StartNew(); //Task<DataSet> artistsTask = GetArtistsAsync(); //Task<DataSet> albumsTask = GetAlbumsAsync(); //Task.Factory.ContinueWhenAll(new[] { artistsTask, albumsTask }, (tasks) => //{ // foreach (var task in tasks) // { // if (task.Status == TaskStatus.RanToCompletion) // { // DataSet ds = task.Result; // if (ds.Tables[0].TableName == "Artists") // { // foreach (DataRow row in ds.Tables["Artists"].Rows) // { // foreach (DataColumn col in ds.Tables[0].Columns) // { // Console.Write(row[col] + "\t"); // } // Console.WriteLine(); // } // } // else if (ds.Tables[0].TableName == "Albums") // { // foreach (DataRow row in ds.Tables["Albums"].Rows) // { // foreach (DataColumn col in ds.Tables[0].Columns) // { // Console.Write(row[col] + "\t"); // } // Console.WriteLine(); // } // } // } // else // { // Console.WriteLine("An error has occurred.."); // Console.WriteLine(task.Exception.InnerException.Message); // } // Console.WriteLine(); // Console.WriteLine("------------------------------------------------"); // Console.WriteLine(); // } // watch.Stop(); // Console.WriteLine("Time elapsed: " + watch.ElapsedMilliseconds + " milliseconds"); //}); #endregion #region Asynchronous - No multithreading //GetCustomersAsync().ContinueWith((task) => //{ // DataSet dsCustomers = task.Result; // foreach (DataRow row in dsCustomers.Tables["Customers"].Rows) // { // foreach (DataColumn col in dsCustomers.Tables[0].Columns) // { // Console.Write(row[col] + "\t"); // }az // Console.WriteLine(); // } //}); #endregion Console.WriteLine(); Console.WriteLine("Thread: " + Thread.CurrentThread.Name); Console.WriteLine("Press any key..."); Console.ReadKey(); } static Task<DataSet> GetArtistsAsync() { DataSet ds = new DataSet(); return Task<DataSet>.Factory.StartNew(() => { using (SqlConnection con = new SqlConnection(connectionString)) { string sqlSelect = @"WAITFOR DELAY '000:00:05' SELECT TOP 10 * FROM Artist"; SqlDataAdapter da = new SqlDataAdapter(sqlSelect, con); da.Fill(ds); ds.Tables[0].TableName = "Artists"; } Console.WriteLine("Thread: " + Thread.CurrentThread.Name); return ds; }); } static Task<DataSet> GetAlbumsAsync() { DataSet ds = new DataSet(); return Task<DataSet>.Factory.StartNew(() => { using (SqlConnection con = new SqlConnection(connectionString)) { string sqlSelect = @"WAITFOR DELAY '000:00:05' SELECT TOP 10 * FROM Album"; SqlDataAdapter da = new SqlDataAdapter(sqlSelect, con); da.Fill(ds); ds.Tables[0].TableName = "Albums"; } Console.WriteLine("Thread: " + Thread.CurrentThread.Name); return ds; }); } static Task<DataSet> GetCustomersAsync() { var tcs = new TaskCompletionSource<DataSet>(); DataSet ds = new DataSet(); using (SqlConnection con = new SqlConnection(connectionString)) { string sqlSelect = @"WAITFOR DELAY '000:00:05' SELECT TOP 10 * FROM Customer"; SqlDataAdapter da = new SqlDataAdapter(sqlSelect, con); da.Fill(ds); ds.Tables[0].TableName = "Customers"; } Console.WriteLine("Thread in GetCustomersAsync: " + Thread.CurrentThread.Name); tcs.SetResult(ds); return tcs.Task; } } }
août
17
Posted by : 17 août 2013
| On :mai
11
Posted by : 11 mai 2012
| On :This tutorial is inspired from (run under glassfish)
http://java.dzone.com/articles/ejb-30-and-spring-25
In this following page I modified the spring configuration and test the deployment on Jboss 4.2
Environnement tool requirement
- Spring Tools suite or Eclipse
- Jboss 4.2.x (tested on version jboss-4.2.3.GA)
- Spring 2.5.6
The data layer is using @Entity to define the Table (or pojo) that will correspond to our data model
Here we have a simple table called Customer with a series of fields
then we need to ask ourself which services do we want to expose to others ?
As in Facade design pattern we will expose an interface and the method that the client can attack on the server side
So here we define an interface call CustomerService that is annoted with @Remote
Then we’ve implement the CRUD operation and @PersistenceContext in CustomerServiceImpl class
Then in the second part of the tutorial we are viewing how to bind Spring with EJB 3
To do that you’ll need to investigate the name of jndi register in your server.
The tag jee:jndi-lookup will bind both EJB context and spring context
Once your project is set up you can easily use Spring test or more simply define a Java project that reference your Ejb project (write a main )
Go further
http://what-when-how.com/enterprise-javabeans-3/combining-the-power-of-ejb-3-and-spring/
Project look like
Setup Jboss
When you start your server you should have the following log
17:30:56,041 INFO [SessionFactoryObjectFactory] Factory name: persistence.units:jar=CustomerService.jar,unitName=Customer
17:30:56,041 INFO [NamingHelper] JNDI InitialContext properties:{java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces}
17:30:56,041 INFO [SessionFactoryObjectFactory] Bound factory to JNDI name: persistence.units:jar=CustomerService.jar,unitName=Customer
17:30:56,041 WARN [SessionFactoryObjectFactory] InitialContext did not implement EventContext
17:30:56,041 INFO [SchemaUpdate] Running hbm2ddl schema update
17:30:56,041 INFO [SchemaUpdate] fetching database metadata
17:30:56,041 INFO [SchemaUpdate] updating schema
17:30:56,072 INFO [TableMetadata] table found: PUBLIC.CUSTOMER
17:30:56,072 INFO [TableMetadata] columns: [first_name, middle_name, last_name, email_id, customer_id]
17:30:56,072 INFO [TableMetadata] foreign keys: []
17:30:56,072 INFO [TableMetadata] indexes: [sys_idx_60]
17:30:56,072 INFO [SchemaUpdate] schema update complete
17:30:56,072 INFO [NamingHelper] JNDI InitialContext properties:{java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces}
17:30:56,150 INFO [JmxKernelAbstraction] creating wrapper delegate for: org.jboss.ejb3.stateless.StatelessContainer
17:30:56,150 INFO [JmxKernelAbstraction] installing MBean: jboss.j2ee:jar=CustomerService.jar,name=CustomerServiceImpl,service=EJB3 with dependencies:
17:30:56,150 INFO [JmxKernelAbstraction] persistence.units:jar=CustomerService.jar,unitName=Customer
17:30:56,182 INFO [EJBContainer] STARTED EJB: com.ejb.service.CustomerServiceImpl ejbName: CustomerServiceImpl
17:30:56,213 INFO [EJB3Deployer] Deployed: file:/C:/jboss-4.2.3.GA-jdk6/jboss-4.2.3.GA/server/default/deploy/CustomerService.jar
17:30:56,229 INFO [DefaultEndpointRegistry] register: jboss.ws:context=CustomerService,endpoint=CustomerServiceImpl
17:30:56,338 INFO [TomcatDeployer] deploy, ctxPath=/CustomerService, warUrl=…/tmp/deploy/CustomerService.jar38776.war/
17:30:57,432 INFO [WSDLFilePublisher] WSDL published to: file:/C:/jboss-4.2.3.GA-jdk6/jboss-4.2.3.GA/server/default/data/wsdl/CustomerService.jar/CustomerService38777.wsdl
17:30:57,744 INFO [TomcatDeployer] deploy, ctxPath=/jmx-console, warUrl=…/deploy/jmx-console.war/
17:30:57,885 INFO [Http11Protocol] Démarrage de Coyote HTTP/1.1 sur http-127.0.0.1-8080
Compy spring.jar in the path
<Jboss_HOME>\server\default\lib
check the deployement of webservices
http://127.0.0.1:8080/CustomerService/CustomerServiceImpl?wsdl
Jmx console
check the deployement of EJB3
Check the JNDI view deployment you should view
Mbean database=localDB,service=Hypersonic call the Mbean Hypersonic and click start
package com.ejb.domain; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; @Entity //@Table(name = "CUSTOMER", catalog = "", schema = "ADMIN") public class Customer implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "CUSTOMER_ID") private Long customerId; @Column(name = "FIRST_NAME") private String firstName; @Column(name = "LAST_NAME") private String lastName; @Column(name = "MIDDLE_NAME") private String middleName; @Column(name = "EMAIL_ID") private String emailId; public Customer() { } public Customer(Long customerId) { this.customerId = customerId; } public Long getCustomerId() { return customerId; } public void setCustomerId(Long customerId) { this.customerId = customerId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getMiddleName() { return middleName; } public void setMiddleName(String middleName) { this.middleName = middleName; } public String getEmailId() { return emailId; } public void setEmailId(String emailId) { this.emailId = emailId; } } package com.ejb.service; import java.util.Collection; import javax.ejb.Remote; import com.ejb.domain.Customer; @Remote public interface CustomerService { Customer create(Customer info); Customer update(Customer info); void remove(Long customerId); Collection<Customer> findAll(); Customer[] findAllAsArray(); Customer findByPrimaryKey(Long customerId); } package com.ejb.service; import java.util.Collection; import javax.ejb.Stateless; import javax.jws.WebMethod; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import com.ejb.domain.Customer; @WebService(name = "CustomerService", serviceName = "CustomerService", targetNamespace = "urn:CustomerService") @SOAPBinding(style = SOAPBinding.Style.RPC) @Stateless(name = "CustomerServiceImpl") public class CustomerServiceImpl implements CustomerService { @PersistenceContext(name="Customer") private EntityManager manager; @WebMethod public Customer create(Customer info) { this.manager.persist(info); return info; } @WebMethod public Customer update(Customer info) { return this.manager.merge(info); } @WebMethod public void remove(Long customerId) { this.manager.remove(this.manager.getReference(Customer.class, customerId)); } public Collection<Customer> findAll() { Query query = this.manager.createQuery("SELECT c FROM Customer c"); return query.getResultList(); } @WebMethod public Customer[] findAllAsArray() { Collection<Customer> collection = findAll(); return (Customer[]) collection.toArray(new Customer[collection.size()]); } @WebMethod public Customer findByPrimaryKey(Long customerId) { return (Customer) this.manager.find(Customer.class, customerId); } } package com.spring.service; import com.ejb.domain.Customer; public interface CustomerManager { public void addCustomer(Customer customer); public void removeCustomer(Long customerId); public Customer[] listCustomers(); } package com.spring.service; import com.ejb.domain.Customer; import com.ejb.service.CustomerService; public class CustomerManagerImpl implements CustomerManager { CustomerService customerService; public void setCustomerService(CustomerService customerService) { this.customerService = customerService; } public void removeCustomer(Long customerId) { customerService.remove(customerId); } public Customer[] listCustomers() { return customerService.findAllAsArray(); } public void addCustomer(Customer customer) { customerService.create(customer); } }
Persistence Unit
in HSQL embein Jboss the configuration will be
<persistence> <persistence-unit name="Customer"> <class>com.ejb.domain.Customer</class> <jta-data-source>java:/DefaultDS</jta-data-source> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/> <property name="hibernate.hbm2ddl.auto" value="update"/> </properties> </persistence-unit> </persistence>
in MySQL the configuration will be
<properties> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test" /> <property name="javax.persistence.jdbc.user" value="root" /> <property name="javax.persistence.jdbc.password" value="" /> <!-- EclipseLink should create the database schema automatically --> <property name="eclipselink.ddl-generation" value="create-tables" /> <property name="eclipselink.ddl-generation.output-mode" value="database" /> </properties>
the Spring configuration
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd"> <!-- Use a custom JNDI bean factory configured not to prepend lookups with "java:comp/env" --> <bean id="jndiFactory" class="org.springframework.jndi.support.SimpleJndiBeanFactory"> <property name="resourceRef" value="false" /> </bean> <!-- Configure the CommonAnnotationBeanPostProcessor to always use JNDI lookup (for EJBs) and use the custom JNDI bean factory above. --> <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"> <property name="alwaysUseJndiLookup" value="true" /> <property name="jndiFactory" ref="jndiFactory" /> </bean> <!-- <jee:jndi-lookup id="customerService" jndi-name="com.ejb.service.CustomerServiceImpl"> </jee:jndi-lookup> --> <jee:jndi-lookup id="customerService" jndi-name="CustomerServiceImpl/remote" lookup-on-startup="false" proxy-interface="com.ejb.service.CustomerService"></jee:jndi-lookup> <bean id="manageCustomer" class="com.spring.service.CustomerManagerImpl"> <property name="customerService" ref="customerService" /> </bean> </beans>
The client test configuration project
you’re project should like like this
*in the classpath create a jndi.propertiesand java class client
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces java.naming.provider.url=localhost:1099
package com.spring.client; import javax.naming.Context; import javax.naming.InitialContext; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.ejb.domain.Customer; import com.ejb.service.CustomerService; import com.spring.service.CustomerManager; public class SpringAndEJBMain { public static void main(String[] args) { try { Context context = new InitialContext(); CustomerService stock = (CustomerService) context.lookup("CustomerService/remote"); ApplicationContext contextSpring =new ClassPathXmlApplicationContext("SpringXMLConfig.xml"); CustomerManager service = (CustomerManager) contextSpring.getBean("manageCustomer"); Customer customer = new Customer(); customer.setFirstName("Meera"); customer.setLastName("Subbarao"); customer.setMiddleName("B"); customer.setEmailId("meera@springandejb.com"); customer.setCustomerId(new Long(1)); service.addCustomer(customer); for (Customer cust : service.listCustomers()) { System.out.println(cust.getFirstName()); System.out.println(cust.getLastName()); System.out.println(cust.getMiddleName()); System.out.println(cust.getEmailId()); } // service.removeCustomer(new Long(1)); } catch (Exception e) { e.printStackTrace(); } } }
mar
09
Posted by : 9 mars 2010
| On :
In this article, we will walk through some of the capabilities provided by Spring batch Framework
Why use Spring Batch? Personally, when I sit down to work with batch, I get frustrated with the amount of code that you need to write to do simple things I/O, manage batches error cases …
Spring batch let’s us use all capability of spring and provide powerful tool with few lines XML configuration.
You can checkout the source in Eclipse IDE using SVN here is the address of the source :
http://code.google.com/p/artaud/source/browse/#svn/springbatch
https://github.com/aartaud300/artaud
https://github.com/DoctusHartwald/artaud
In this article we’ll walk through these case :
-Case 1 : Hello World
-Case 2 : Import CSV => Database
Case 3 : Export Database => flat file
-Case 4 : Export Database=> XML
-Case 5 : Couple Spring Batch and Velocity template.
-Case 6 : export our database to a Jasper Report in PDF.
I assume the reader to have good knowledge in basic Spring and Spring Annotations.
Database : MySQL
JDK 5 or more
Apache Maven
MySQL or an other Database provider
Internet Connection
Eclipse
JDK 5 or more
Apache Maven
MySQL or an other Database provider
sudo apt-get install apache2 mysql-server php5 php5-mysql phpmyadmin
Eclipse
APACHE MAVEN
In you ~/.bashrc add the following lines .
export JAVA_HOME=/usr/lib/jvm/java-6-sun/jre export PATH=${PATH}:$JAVA_HOME/bin export M2_HOME=/usr/local/apache-maven/apache-maven-2.2.1 export M2=$M2_HOME/bin export MAVEN_OPTS="-Xms512m -Xmx1024m" export PATH=${PATH}:$M2 export ROO_HOME=/home/<USER>/dev/spring-roo-1.0.2.RELEASE export ROO_OPTS="-Droo.bright=true"
RUN THE PROJET
SEE job.sh in in the folder documentation/ download the code source here.
First let’s see the 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>org.batch</groupId> <artifactId>springbatch</artifactId> <name>SpringbatchDemo</name> <version>1.0</version> <packaging>jar</packaging> <description>Springbatch Sample Projet </description> <properties> <spring.version>2.5.6</spring.version> <!--<spring-batch.version>1.0.1.RELEASE</spring-batch.version>--> <spring-batch.version>2.1.0.RELEASE</spring-batch.version> <mysql-version>5.1.6</mysql-version> </properties> <dependencies> <!-- MySQL --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql-version}</version> </dependency> <!-- SPRING --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework.batch</groupId> <artifactId>spring-batch-core</artifactId> <version>${spring-batch.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework.ws</groupId> <artifactId>spring-oxm</artifactId> <version>1.5.5</version> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.osgi</groupId> <artifactId>spring-osgi-core</artifactId> <version>1.1.2</version> <optional>true</optional> </dependency> <!-- Log --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.14</version> <optional>true</optional> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.13</version> </dependency> <!-- Junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.4</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>org.springframework.test</artifactId> <version>2.5.6</version> <scope>test</scope> </dependency> <!-- Jasper report --> <dependency> <groupId>jasperreports</groupId> <artifactId>jasperreports</artifactId> <version>3.1.2</version> </dependency> <!-- XML STAX --> <dependency> <groupId>stax</groupId> <artifactId>stax</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>org.springframework.batch</groupId> <artifactId>spring-batch-test</artifactId> <version>${spring-batch.version}</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.4</version> </dependency> <!-- Velocity --> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity</artifactId> <version>1.6.3</version> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-tools</artifactId> <version>1.3</version> </dependency> </dependencies> <distributionManagement> <repository> <id>spring-release</id> <name>Spring Release Repository</name> <url>s3://maven.springframework.org/release</url> </repository> <snapshotRepository> <id>spring-snapshot</id> <name>Spring Snapshot Repository</name> <url>s3://maven.springframework.org/snapshot</url> </snapshotRepository> </distributionManagement> <repositories> <repository> <id>objectstyle</id> <name>ObjectStyle.org Repository</name> <url>http://objectstyle.org/maven2</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>com.springsource.repository.bundles.release</id> <name>EBR Spring Release Repository</name> <url>http:// repository.springsource.com/maven/bundles/release</url> </repository> <repository> <id>com.springsource.repository.bundles.external</id> <name>EBR External Release Repository</name> <url>http:// repository.springsource.com/maven/bundles/external</url> </repository> <repository> <id>codehaus</id> <name>Maven Codehaus repository</name> <url>http://repository.codehaus.org/</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>com.springsource.repository.bundles.milestone</id> <name>SpringSource Enterprise Bundle Repository - SpringSource Bundle Milestones</name> <url>http://repository.springsource.com/maven/bundles/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> <pluginRepository> <id>com.springsource.repository.bundles.snapshot</id> <name>SpringSource Enterprise Bundle Repository - SpringSource Bundle Snapshots</name> <url>http://repository.springsource.com/maven/bundles/snapshot</url> </pluginRepository> </pluginRepositories> <ciManagement> <system>Hudson</system> </ciManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.4.3</version> <configuration> </configuration> </plugin> <!-- Decomment this blog if you want to run it with -Dexec.mainClass="org.springframework.batch.core.launch.support.CommandLineJobRunner" -Dexec.args="com/batch/simpletask/simpletaskletcontext.xml simpleJob" --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <executions> <execution> <id>glue-processing</id> <phase>install</phase> <goals> <goal>exec</goal> </goals> </execution> </executions> <configuration> <debug>true</debug> <executable>java</executable> <mainClass>app_example2.Example2</mainClass> <!-- <mainClass>org.springframework.batch.core.launch.support.CommandLineJobRunner</mainClass> <arguments> <argument>com/batch/simpletask/simpletaskletcontext.xml</argument> <argument>simpleJob</argument> </arguments> --> </configuration> </plugin> </plugins> </build> </project>
We’ll use Spring annotation couple with standard Spring to realize our sample project
create a package src/main/java/com.batch
these 2 class AppJobExecutionListener and ItemFailureLoggerListener let us log the job execution.
package com.batch; import org.apache.log4j.Logger; import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobExecutionListener; import org.springframework.stereotype.Component; @Component("appJobExecutionListener") public class AppJobExecutionListener implements JobExecutionListener { private final static Logger logger = Logger .getLogger(AppJobExecutionListener.class); public void afterJob(JobExecution jobExecution) { if (jobExecution.getStatus() == BatchStatus.COMPLETED) { logger.info("Job completed: " + jobExecution.getJobId()); } else if (jobExecution.getStatus() == BatchStatus.FAILED) { logger.info("Job failed: " + jobExecution.getJobId()); } } public void beforeJob(JobExecution jobExecution) { if (jobExecution.getStatus() == BatchStatus.COMPLETED) { logger.info("Job completed: " + jobExecution.getJobId()); } else if (jobExecution.getStatus() == BatchStatus.FAILED) { logger.info("Job failed: " + jobExecution.getJobId()); } } } package com.batch; import org.apache.log4j.Logger; import org.springframework.batch.core.listener.ItemListenerSupport; import org.springframework.stereotype.Component; @Component("itemFailureLoggerListener") public class ItemFailureLoggerListener extends ItemListenerSupport { private final static Logger logger = Logger .getLogger(ItemFailureLoggerListener.class); public void onReadError(Exception ex) { logger.error("Encountered error on read", ex); } public void onWriteError(Exception ex, Object item) { logger.error("Encountered error on write", ex); } }
HelloWorld in Spring Batch
Create a package name com.batch.simpletask under src/main/java
package com.batch.simpletask; import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.scope.context.ChunkContext; import org.springframework.batch.core.step.tasklet.Tasklet; import org.springframework.batch.repeat.RepeatStatus; public class HelloTask implements Tasklet { private String taskStartMessage; public void setTaskStartMessage(String taskStartMessage) { this.taskStartMessage = taskStartMessage; } public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) throws Exception { System.out.println(taskStartMessage); return RepeatStatus.FINISHED; } }
package com.batch.simpletask; import java.util.Calendar; import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.scope.context.ChunkContext; import org.springframework.batch.core.step.tasklet.Tasklet; import org.springframework.batch.repeat.RepeatStatus; public class TimeTask implements Tasklet { public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) throws Exception { System.out.println(Calendar.getInstance().getTime()); return RepeatStatus.FINISHED; } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:batch="http://www.springframework.org/schema/batch" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <!-- 1) USE ANNOTATIONS TO IDENTIFY AND WIRE SPRING BEANS. --> <!-- We indicate to Spring that we scan @Component annotation based on package com.batch --> <context:component-scan base-package="com.batch" /> <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"> </bean> <!-- 3) JOB REPOSITORY - WE USE IN-MEMORY REPOSITORY FOR OUR EXAMPLE --> <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"> <property name="transactionManager" ref="transactionManager" /> </bean> <!-- 4) LAUNCH JOBS FROM A REPOSITORY --> <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher"> <property name="jobRepository" ref="jobRepository" /> </bean> <!-- 5) Beans representing the 2 job steps. --> <!-- Step1 - print hello world --> <bean id="helloTask"> <property name="taskStartMessage" value="Hello World - the time is now " /> </bean> <!-- Step2 - print current time --> <bean id="timeTask" /> <!-- 6) FINALLY OUR JOB DEFINITION. THIS IS A 2 STEP JOB --> <batch:job id="simpleJob"> <batch:listeners> <batch:listener ref="appJobExecutionListener" /> </batch:listeners> <batch:step id="step1" next="step2"> <batch:tasklet ref="helloTask" /> </batch:step> <batch:step id="step2"> <batch:tasklet ref="timeTask" /> </batch:step> </batch:job> </beans>
package com.batch.simpletask; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.AbstractDependencyInjectionSpringContextTests; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.util.StopWatch; @ContextConfiguration(locations = "classpath*:com/batch/simpletask/simpletaskletcontext.xml") @RunWith(SpringJUnit4ClassRunner.class) public class SimpleTaskletTestCase extends AbstractDependencyInjectionSpringContextTests { private final static Logger logger = Logger .getLogger(SimpleTaskletTestCase.class); @Autowired private JobLauncher launcher; @Autowired private Job job; private JobParameters jobParameters = new JobParameters(); @Before public void setup() { //PropertyConfigurator.configure("C:/Users/admin/workspace-test/springbatch2/src/com/batch/log4j.properties"); } @Test public void testLaunchJob() throws Exception { StopWatch sw = new StopWatch(); sw.start(); launcher.run(job, jobParameters); sw.stop(); logger.info(">>> TIME ELAPSED:" + sw.prettyPrint()); } @Autowired public void setLauncher(JobLauncher bootstrap) { this.launcher = bootstrap; } @Autowired public void setJob(Job job) { this.job = job; } }
sudo apt-get isntall apache2 mysql-server php5 php5-mysql phpmyadmin
Check that the process are running
sudo /etc/init.d/apache2 start sudo /etc/init.d/mysql restart
Download EasyPHP or Xampp and launch the application
Connect to MySql whether by prompt or via Phpmyadmin http://localhost/phpmyadmin
Enter login : test / password testand tick the right rules on the database as the following screenshot
Via prompt :
sudo mysql -u root -p
CREATE USER 'test'@'%' IDENTIFIED BY '***'; GRANT SELECT , INSERT , UPDATE , DELETE , CREATE , DROP , FILE , INDEX , ALTER , CREATE TEMPORARY TABLES , CREATE VIEW , EVENT, TRIGGER, SHOW VIEW , CREATE ROUTINE, ALTER ROUTINE, EXECUTE ON * . * TO 'test'@'%' IDENTIFIED BY '***' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
CREATE DATABASE `seamdb` ;
[sql]
create table ledger (
ID INT NOT NULL AUTO_INCREMENT,
rcv_dt date,
mbr_nm VARCHAR(100) not null,
chk_nbr VARCHAR(10) not null,
chk_dt date,
pymt_typ VARCHAR(50) not null,
dpst_amt double,
pymt_amt double,
comments VARCHAR(100),
PRIMARY KEY (ID)
);
[/sql]
create a new package com.batch.todb in /src/main/java
Create a Model Bean call Ledger
package com.batch.todb;
import java.util.Date;
public class Ledger {
private int id;
private Date receiptDate;
private String memberName;
private String checkNumber;
private Date checkDate;
private String paymentType;
private double depositAmount;
private double paymentAmount;
private String comments;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Date getReceiptDate() {
return receiptDate;
}
public void setReceiptDate(Date receiptDate) {
this.receiptDate = receiptDate;
}
public String getMemberName() {
return memberName;
}
public void setMemberName(String memberName) {
this.memberName = memberName;
}
public String getCheckNumber() {
return checkNumber;
}
public void setCheckNumber(String checkNumber) {
this.checkNumber = checkNumber;
}
public Date getCheckDate() {
return checkDate;
}
public void setCheckDate(Date checkDate) {
this.checkDate = checkDate;
}
public String getPaymentType() {
return paymentType;
}
public void setPaymentType(String paymentType) {
this.paymentType = paymentType;
}
public double getDepositAmount() {
return depositAmount;
}
public void setDepositAmount(double depositAmount) {
this.depositAmount = depositAmount;
}
public double getPaymentAmount() {
return paymentAmount;
}
public void setPaymentAmount(double paymentAmount) {
this.paymentAmount = paymentAmount;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
}
package com.batch.todb;
public interface LedgerDAO {
public void save(final Ledger note);
}
package com.batch.todb;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Component
public class LedgerDAOImpl extends JdbcTemplate implements LedgerDAO {
@Autowired
public void setDataSource(DataSource dataSource) {
super.setDataSource(dataSource);
}
@Transactional(propagation = Propagation.REQUIRED)
public void save(final Ledger item) {
super
.update(
« insert into ledger (rcv_dt, mbr_nm, chk_nbr, chk_dt, pymt_typ, dpst_amt, pymt_amt, comments) values(?,?,?,?,?,?,?,?) »,
new PreparedStatementSetter() {
public void setValues(PreparedStatement stmt)
throws SQLException {
stmt.setDate(1, new java.sql.Date(item
.getReceiptDate().getTime()));
stmt.setString(2, item.getMemberName());
stmt.setString(3, item.getCheckNumber());
stmt.setDate(4, new java.sql.Date(item
.getCheckDate().getTime()));
stmt.setString(5, item.getPaymentType());
stmt.setDouble(6, item.getDepositAmount());
stmt.setDouble(7, item.getPaymentAmount());
stmt.setString(8, item.getComments());
}
});
}
}
package com.batch.todb;
import java.text.DecimalFormat;
import java.text.ParseException;
import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
@Component(« ledgerMapper »)
public class LedgerMapper implements FieldSetMapper {
private final static String DATE_PATTERN = « mm/DD/yy »;
private final static String DOLLAR_PATTERN = « $###,###.### »;
public Object mapFieldSet(FieldSet fs) {
Ledger item = new Ledger();
int idx = 0;
item.setReceiptDate(fs.readDate(idx++, DATE_PATTERN));
item.setMemberName(fs.readString(idx++));
item.setCheckNumber(fs.readString(idx++));
item.setCheckDate(fs.readDate(idx++, DATE_PATTERN));
item.setPaymentType(fs.readString(idx++));
// deposit amount
try {
DecimalFormat fmttr = new DecimalFormat(DOLLAR_PATTERN);
Number number = fmttr.parse(fs.readString(idx++));
item.setDepositAmount(number.doubleValue());
} catch (ParseException e) {
item.setDepositAmount(0);
}
// payment amount
try {
DecimalFormat fmttr = new DecimalFormat(DOLLAR_PATTERN);
Number number = fmttr.parse(fs.readString(idx++));
item.setPaymentAmount(number.doubleValue());
} catch (ParseException e) {
item.setPaymentAmount(0);
}
//
return item;
}
}
package com.batch.todb;
import java.util.Iterator;
import java.util.List;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component(« itemWriter »)
public class LedgerWriter implements ItemWriter {
@Autowired
private LedgerDAO itemDAO;
public void write(List items) throws Exception {
for (Iterator<Ledger> iterator = items.iterator(); iterator.hasNext();) {
Ledger item = iterator.next();
itemDAO.save(item);
}
}
}
In src/test/java create this class of Test
We’ll launch our test using Spring Test framework by using these annotations :
[java]
<pre>@ContextConfiguration(locations = « classpath:com/batch/todb/contextToDB.xml »)
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(transactionManager = « transactionManager », defaultRollback = false)</pre>
[/java]
[java]
package com.batch.todb;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.util.StopWatch;
@ContextConfiguration(locations = « classpath:com/batch/todb/contextToDB.xml »)
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(transactionManager = « transactionManager », defaultRollback = false)
public class ToDBBatchTestCase extends
AbstractTransactionalJUnit4SpringContextTests {
private final static Logger logger = Logger.getLogger(ToDBBatchTestCase.class);
@Autowired
private JobLauncher launcher;
@Autowired
private Job job;
private JobParameters jobParameters = new JobParameters();
@Before
public void setup() {
//PropertyConfigurator.configure(« C:/Users/admin/workspace-test/springbatch2/src/com/batch/log4j.properties »);
}
@Test
public void testLaunchJob() throws Exception {
StopWatch sw = new StopWatch();
sw.start();
launcher.run(job, jobParameters);
sw.stop();
logger.info(« >>> TIME ELAPSED: » + sw.shortSummary());
}
@Autowired
public void setLauncher(JobLauncher bootstrap) {
this.launcher = bootstrap;
}
@Autowired
public void setJob(Job job) {
this.job = job;
}
}
[/java]
the source are locate into com/batch/velocity
The apache Velocity framework is issue from Jakarta project and is a powerful tool for generating SQL code,Java class C++ , whatever ..
In this study case I propose to see how with Spring batch we can couple the two framework together.
We could also use different implementation of ItemProcessor<T,V> between the ItemReader<T> and ItemWriter<T> provided by Spring batch , but in this study case it’s not the purpose.
The purpose it to respond fast to our need , generate a bunch of file according to a pattern file .
For instance , you want to generate « a large and complex bouchon class » or « the same SQL code a number of time « .
The problem is that in a project time is precious so you don’t want to waste it by doing long and repetitif task . I think you grab I want to say
in this sample I start from CSV file and want to replace two variable $name and $ project using this file pattern (the .vm file in Apache Velocity)
Raw input that I have
-Input :
Apache Velocity,Jakarta
Spring batch,Spring source
Spring Roo,Spring Source
-Output expected by the client :
Hello from $name in the $project project.
What we need is to configure a of a velocityEngine and ItemReader to read our CSV .
[xml]
<bean id= »velocityEngine »
>
<property name= »velocityProperties »>
<value>
resource.loader=class
class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
</value>
</property>
</bean>
[/xml]
[xml]
<bean id= »itemReader »>
<property name= »resource » value= »classpath:com/batch/velocity/project.txt » />
<!– property name= »linesToSkip » value= »1″ /–>
<property name= »lineMapper »>
<bean>
<property name= »lineTokenizer »>
<bean
class= »org.springframework.batch.item.file.transform.DelimitedLineTokenizer »>
<property name= »names » value= »name,project » />
</bean>
</property>
<property name= »fieldSetMapper » ref= »projectMapper » />
</bean>
</property>
</bean>
[/xml]
[xml]
<?xml version= »1.0″ encoding= »UTF-8″?>
<beans xmlns= »http://www.springframework.org/schema/beans »
xmlns:xsi= »http://www.w3.org/2001/XMLSchema-instance » xmlns:p= »http://www.springframework.org/schema/p »
xmlns:aop= »http://www.springframework.org/schema/aop » xmlns:tx= »http://www.springframework.org/schema/tx »
xmlns:batch= »http://www.springframework.org/schema/batch »
xmlns:context= »http://www.springframework.org/schema/context »
xmlns:jms= »http://www.springframework.org/schema/jms » xmlns:amq= »http://activemq.apache.org/schema/core »
xmlns:util= »http://www.springframework.org/schema/util »
xsi:schemaLocation= »http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
« >
<!– 1) USE ANNOTATIONS TO CONFIGURE SPRING BEANS –>
<context:component-scan base-package= »com.batch.velocity » />
<!– Author Artaud Antoine –>
<bean id= »velocityEngine »
class= »org.springframework.ui.velocity.VelocityEngineFactoryBean »>
<property name= »velocityProperties »>
<value>
resource.loader=class
class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
</value>
</property>
</bean>
<bean id= »itemReader »>
<property name= »resource » value= »classpath:com/batch/velocity/project.txt » />
<!– property name= »linesToSkip » value= »1″ /–>
<property name= »lineMapper »>
<bean>
<property name= »lineTokenizer »>
<bean
class= »org.springframework.batch.item.file.transform.DelimitedLineTokenizer »>
<property name= »names » value= »name,project » />
</bean>
</property>
<property name= »fieldSetMapper » ref= »projectMapper » />
</bean>
</property>
</bean>
</beans>
[/xml]
-Aim : use the 2 framework together and add some basic treatement on data you receive from a CSV file for instance
The configuration XML is the same as previously.
- the only difference reside in the vm template (VTL) that we write in Apache Velocity template .
[xml]
<?xml version= »1.0″ encoding= »UTF-8″?>
<beans xmlns= »http://www.springframework.org/schema/beans »
xmlns:xsi= »http://www.w3.org/2001/XMLSchema-instance » xmlns:p= »http://www.springframework.org/schema/p »
xmlns:aop= »http://www.springframework.org/schema/aop » xmlns:tx= »http://www.springframework.org/schema/tx »
xmlns:batch= »http://www.springframework.org/schema/batch »
xmlns:context= »http://www.springframework.org/schema/context »
xmlns:jms= »http://www.springframework.org/schema/jms » xmlns:amq= »http://activemq.apache.org/schema/core »
xmlns:util= »http://www.springframework.org/schema/util »
xsi:schemaLocation= »http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
« >
<!– 1) USE ANNOTATIONS TO CONFIGURE SPRING BEANS –>
<context:component-scan base-package= »com.batch.velocity.genClass » />
<!– Author Artaud Antoine –>
<bean id= »velocityEngine »
class= »org.springframework.ui.velocity.VelocityEngineFactoryBean »>
<property name= »velocityProperties »>
<value>
resource.loader=cla
ss
class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
</value>
</property>
</bean>
<bean id= »itemReader »>
<property name= »resource » value= »classpath:com/batch/velocity/genClass/dataTest.csv » />
<!– property name= »linesToSkip » value= »1″ /–>
<property name= »lineMapper »>
<bean>
<property name= »lineTokenizer »>
<bean>
<!–<property name= »delimiter » value= »MonDel »/> –>
<property name= »names » value= »champ1,data1Type,documentation1,champ2,data2Type,documentation2″ />
</bean>
</property>
<property name= »fieldSetMapper » ref= »genMapperFactoryMapper » />
</bean>
</property>
</bean>
</beans>
[/xml]
what interest us is the bold part of the bellow code .It indicate to apache Velocity that you call this custom metod treatement on the data you furnish on the « pipe ».
SEE the it /src/test/ressources/com/batch/velocity/genClass/example2.vm
[bash]
/**
*
*/
public class $name {
#foreach( $element in $mylist )
private $element.Data1Type $element.champ1;
/**
*
* Map : $element.champ1,$element.data1Type,$element.documentation1
* To : $element.champ2,$element.data2Type,$element.documentation2
* $element.documentation1
* @return the $element.champ1
*
*/
public $element.data1Type <strong>get${utility.getInputU($element.champ1)}</strong>() {
return $element.champ1;
}
/**
* Map : $element.champ1,$element.data1Type,$element.documentation1
* To : $element.champ2,$element.data2Type,$element.documentation2
* $element.documentation1
* @param $element.champ1 the $element.champ1 to set
* #set( $setter = « set » )
*/
public void <strong>set${utility.getInputU($element.champ1)}</strong>($element.data1Type $element.champ1) {
this.$element.champ1 = $element.champ1;
}
#end
}
[/bash]
Bellow the Java code that is being called by Apache Velocity
[java]
public class GeneratorUtility {
/**
* set$utility.firstToUpperCase($att.Name)
* @param input the input to set
*/
public String <strong>getInput</strong>U(String pInput) {
pInput.split(« _ »);
return StringUtils.capitalizeFirstLetter(pInput);
}
}
[/java]
[java]
@ContextConfiguration(locations = « classpath:com/batch/velocity/genClass/contextVelocity.xml »)
@RunWith(SpringJUnit4ClassRunner.class)
public class VelocityCodeTemplateGenClassGenerator {
@Autowired
private VelocityEngine velocityEngine;
@Autowired
private FlatFileItemReader vFlatFileItemReader;
@Test
public void testFlatReaderItemToVelocityProcessor(){
System.out.println(« [INFO] ———————————————————————————- »);
System.out.println(« [INFO] Running test : testFlatReaderItemToVelocityProcessor / « + getClass().getName());
System.out.println(« [INFO] ———————————————————————————- »);
vFlatFileItemReader.open(new ExecutionContext());
boolean hasNext = true ;
GenMapperFactory vGenMapperFactory = null;
GeneratorUtility vUtility = new GeneratorUtility();
List<GenMapperFactory> vGenMapperFactoryList = new ArrayList<GenMapperFactory>();
//vMyClasseGen.setGenMapperFactory(new ArrayList<GenMapperFactory>());
while (hasNext) {
try {
vGenMapperFactory = (GenMapperFactory) vFlatFileItemReader.read();
vGenMapperFactoryList.add(vGenMapperFactory);
} catch (UnexpectedInputException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
if (vGenMapperFactory == null) {
hasNext = false;
}
else {
Map model = new HashMap();
model.put(« utility », vUtility);
model.put(« mylist », vGenMapperFactoryList);
model.put(« name », « ClassDeTest »);
String text = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, « com/batch/velocity/genClass/example2.vm », model);
System.out.println( » « +text);
System.out.println(vGenMapperFactory.toString());
}
}
}
}
[/java]