You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by bp...@apache.org on 2014/04/16 14:58:38 UTC

[1/3] git commit: added crud module

Repository: struts-examples
Updated Branches:
  refs/heads/crud_branch [created] 37cb87df7


added crud module

Project: http://git-wip-us.apache.org/repos/asf/struts-examples/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts-examples/commit/e0d0c871
Tree: http://git-wip-us.apache.org/repos/asf/struts-examples/tree/e0d0c871
Diff: http://git-wip-us.apache.org/repos/asf/struts-examples/diff/e0d0c871

Branch: refs/heads/crud_branch
Commit: e0d0c871945be52f09abd17c985c95cb45f0ae08
Parents: b659700
Author: phillips1021 <ph...@hotmail.com>
Authored: Wed Apr 16 07:44:41 2014 -0500
Committer: phillips1021 <ph...@hotmail.com>
Committed: Wed Apr 16 07:44:41 2014 -0500

----------------------------------------------------------------------
 pom.xml | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts-examples/blob/e0d0c871/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 5065411..8d4310e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -58,6 +58,7 @@
         <module>exclude_parameters</module>
         <module>restful2actionmapper</module>
         <module>bean_validation</module>
+        <module>crud</module>
     </modules>
 
 


[3/3] git commit: changed logging

Posted by bp...@apache.org.
changed logging


Project: http://git-wip-us.apache.org/repos/asf/struts-examples/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts-examples/commit/37cb87df
Tree: http://git-wip-us.apache.org/repos/asf/struts-examples/tree/37cb87df
Diff: http://git-wip-us.apache.org/repos/asf/struts-examples/diff/37cb87df

Branch: refs/heads/crud_branch
Commit: 37cb87df70cc4e0259641d5359b245d5339c6aa9
Parents: 7724ee3
Author: phillips1021 <ph...@hotmail.com>
Authored: Wed Apr 16 07:58:03 2014 -0500
Committer: phillips1021 <ph...@hotmail.com>
Committed: Wed Apr 16 07:58:03 2014 -0500

----------------------------------------------------------------------
 crud/src/main/resources/log4j.xml | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts-examples/blob/37cb87df/crud/src/main/resources/log4j.xml
----------------------------------------------------------------------
diff --git a/crud/src/main/resources/log4j.xml b/crud/src/main/resources/log4j.xml
new file mode 100755
index 0000000..a642174
--- /dev/null
+++ b/crud/src/main/resources/log4j.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration PUBLIC "-//log4j/log4j Configuration//EN" "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+    
+    <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
+       <layout class="org.apache.log4j.PatternLayout"> 
+          <param name="ConversionPattern" value="%d %-5p %c.%M:%L - %m%n"/> 
+       </layout> 
+    </appender>
+ 
+    <!-- specify the logging level for loggers from other libraries -->
+
+    <logger name="org.apache.struts">
+    	 <level value="INFO" />
+    </logger>
+  
+   <!-- for all other loggers log only debug and above log messages -->
+     <root>
+        <priority value="WARN"/> 
+        <appender-ref ref="STDOUT" /> 
+     </root> 
+    
+</log4j:configuration> 
+


[2/3] git commit: initial commit of Struts 2 CRUD example

Posted by bp...@apache.org.
initial commit of Struts 2 CRUD example

Project: http://git-wip-us.apache.org/repos/asf/struts-examples/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts-examples/commit/7724ee34
Tree: http://git-wip-us.apache.org/repos/asf/struts-examples/tree/7724ee34
Diff: http://git-wip-us.apache.org/repos/asf/struts-examples/diff/7724ee34

Branch: refs/heads/crud_branch
Commit: 7724ee348a23d5984b954e1d29d9aec908a8c0dd
Parents: e0d0c87
Author: phillips1021 <ph...@hotmail.com>
Authored: Wed Apr 16 07:54:14 2014 -0500
Committer: phillips1021 <ph...@hotmail.com>
Committed: Wed Apr 16 07:54:14 2014 -0500

----------------------------------------------------------------------
 crud/.gitignore                                 |   1 +
 crud/README.md                                  |   1 +
 crud/pom.xml                                    |  23 ++++
 .../apache/struts/crud/action/PersonAction.java |  94 +++++++++++++
 .../apache/struts/crud/dao/MemoryPersonDao.java |  72 ++++++++++
 .../struts/crud/dao/MemoryPersonSupportDao.java |  56 ++++++++
 .../org/apache/struts/crud/dao/PersonDao.java   |  19 +++
 .../struts/crud/dao/PersonSupportDao.java       |  21 +++
 .../org/apache/struts/crud/model/Country.java   |  37 +++++
 .../org/apache/struts/crud/model/Person.java    | 135 +++++++++++++++++++
 .../crud/service/DefaultPersonService.java      |  71 ++++++++++
 .../struts/crud/service/PersonService.java      |  25 ++++
 .../crud/action/PersonAction-validation.xml     |  36 +++++
 .../struts/crud/action/PersonAction.properties  |  30 +++++
 crud/src/main/resources/struts.xml              |  34 +++++
 crud/src/main/webapp/META-INF/MANIFEST.MF       |   3 +
 crud/src/main/webapp/META-INF/context.xml       |   2 +
 crud/src/main/webapp/WEB-INF/jsp/editPerson.jsp |  41 ++++++
 crud/src/main/webapp/WEB-INF/jsp/persons.jsp    |  57 ++++++++
 crud/src/main/webapp/WEB-INF/web.xml            |  21 +++
 crud/src/main/webapp/css/main.css               |  56 ++++++++
 crud/src/main/webapp/index.jsp                  |  16 +++
 22 files changed, 851 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/.gitignore
----------------------------------------------------------------------
diff --git a/crud/.gitignore b/crud/.gitignore
new file mode 100755
index 0000000..9f97022
--- /dev/null
+++ b/crud/.gitignore
@@ -0,0 +1 @@
+target/
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/README.md
----------------------------------------------------------------------
diff --git a/crud/README.md b/crud/README.md
new file mode 100755
index 0000000..a287bd3
--- /dev/null
+++ b/crud/README.md
@@ -0,0 +1 @@
+Template application for building professional crud applications with Struts2.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/pom.xml
----------------------------------------------------------------------
diff --git a/crud/pom.xml b/crud/pom.xml
new file mode 100755
index 0000000..2bcf555
--- /dev/null
+++ b/crud/pom.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<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>
+    <parent>
+        <groupId>struts.apache.org</groupId>
+        <artifactId>struts2examples</artifactId>
+        <version>1.0.0</version>
+    </parent>
+    
+    <artifactId>struts_crud</artifactId>
+    <packaging>war</packaging>
+
+
+    <name>Struts CRUD Example</name>
+    <description>Example of using Struts 2 for a web app that allows users to 
+        Create, Read, Update, and Delete data.</description>
+
+    <build>
+        <finalName>crud_struts</finalName>
+    </build>
+</project>

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/java/org/apache/struts/crud/action/PersonAction.java
----------------------------------------------------------------------
diff --git a/crud/src/main/java/org/apache/struts/crud/action/PersonAction.java b/crud/src/main/java/org/apache/struts/crud/action/PersonAction.java
new file mode 100755
index 0000000..d3fa555
--- /dev/null
+++ b/crud/src/main/java/org/apache/struts/crud/action/PersonAction.java
@@ -0,0 +1,94 @@
+package org.apache.struts.crud.action;
+
+import static com.opensymphony.xwork2.Action.SUCCESS;
+
+//import org.apache.log4j.Logger;
+import org.apache.struts.crud.model.Person;
+import org.apache.struts.crud.model.Country;
+import org.apache.struts.crud.service.PersonService;
+import org.apache.struts.crud.service.DefaultPersonService;
+
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.Preparable;
+
+/**
+ * Acts as a controller to handle actions related to editing a Person.
+ * 
+ * TODO add comments to all code in the project
+ * TODO display country name instead of code
+ * TODO logging
+ * TODO prepareInput 
+ *
+ * @author bruce phillips
+ * @author antonio sánchez
+ */
+public class PersonAction extends ActionSupport implements Preparable {
+//    private static Logger log = Logger.getLogger(PersonAction.class.getName());
+    private PersonService personService = new DefaultPersonService();
+    private Person person;
+    private Person[] persons;
+    private String[] sports;
+    private String[] genders;
+    private Country[] countries;
+    private String[] carModelsAvailable;
+
+    @Override
+    public void prepare() throws Exception {
+        carModelsAvailable = personService.getCarModels();
+        sports = personService.getSports();
+        countries = personService.getCountries();
+        genders = personService.getGenders();
+        
+        if (person != null && person.getPersonId() != null) {
+            person = personService.getPerson(person.getPersonId());
+        }
+    }
+
+    public String list() {
+        persons = personService.getAllPersons();
+        return SUCCESS;
+    }
+    
+    public String save() {
+        if (person.getPersonId() == null) {
+            personService.insertPerson(person);
+        } else {
+            personService.updatePerson(person);
+        }
+        return SUCCESS;
+    }
+
+    public String delete() {
+        personService.deletePerson(person.getPersonId());
+        return SUCCESS;
+    }
+    
+    public Person[] getPersons() {
+        return persons;
+    }
+
+    public Person getPerson() {
+        return person;
+    }
+
+    public void setPerson(Person person) {
+        this.person = person;
+    }
+
+    public String[] getSports() {
+        return sports;
+    }
+
+    public String[] getGenders() {
+        return genders;
+    }
+
+    public Country[] getCountries() {
+        return countries;
+    }
+
+    public String[] getCarModelsAvailable() {
+        return carModelsAvailable;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/java/org/apache/struts/crud/dao/MemoryPersonDao.java
----------------------------------------------------------------------
diff --git a/crud/src/main/java/org/apache/struts/crud/dao/MemoryPersonDao.java b/crud/src/main/java/org/apache/struts/crud/dao/MemoryPersonDao.java
new file mode 100755
index 0000000..60a9e7e
--- /dev/null
+++ b/crud/src/main/java/org/apache/struts/crud/dao/MemoryPersonDao.java
@@ -0,0 +1,72 @@
+package org.apache.struts.crud.dao;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.struts.crud.model.Person;
+
+/**
+ *
+ * @author antonio sanchez
+ */
+public class MemoryPersonDao implements PersonDao {
+
+    private static List<Person> persons;
+
+    static {
+        persons = new ArrayList<Person>();
+        persons.add(new Person(1, "Bruce", "Phillips", "basketball", "male", "US", true, new String[]{"Ford", "Nissan"}, "bphillips@ku.edu", "123-456-9999"));
+        persons.add(new Person(2, "Antonio", "Sanchez", "mtb", "male", "ES", true, new String[]{"Toyota", "Seat"}, "asanchez@correoe.es", "555-999-8888"));
+    }
+
+    @Override
+    public Person getPerson(Integer id) {
+        for (Person p : persons) {
+            if (p.getPersonId().equals(id)) {
+                return p;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Person[] getAllPersons() {
+        return persons.toArray(new Person[persons.size()]);
+    }
+
+    @Override
+    public void updatePerson(Person person) {
+        Integer id = person.getPersonId();
+        for (int i = 0; i < persons.size(); i++) {
+            Person p = persons.get(i);
+            if (p.getPersonId().equals(id)) {
+//                person.setDepartment(departmentsMap.get(person.getDepartment().getDepartmentId()));
+                persons.set(i, person);
+                break;
+            }
+        }
+    }
+
+    @Override
+    public void insertPerson(Person person) {
+        int lastId = 0;
+        for (Person p : persons) {
+            if (p.getPersonId() > lastId) {
+                lastId = p.getPersonId();
+            }
+        }
+//        person.setDepartment(departmentsMap.get(person.getDepartment().getDepartmentId()));
+        person.setPersonId(lastId + 1);
+        persons.add(person);
+    }
+
+    @Override
+    public void deletePerson(Integer id) {
+        for (int i = 0; i < persons.size(); i++) {
+            Person person = persons.get(i);
+            if (person.getPersonId().equals(id)) {
+                persons.remove(i);
+                break;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/java/org/apache/struts/crud/dao/MemoryPersonSupportDao.java
----------------------------------------------------------------------
diff --git a/crud/src/main/java/org/apache/struts/crud/dao/MemoryPersonSupportDao.java b/crud/src/main/java/org/apache/struts/crud/dao/MemoryPersonSupportDao.java
new file mode 100755
index 0000000..cfdc330
--- /dev/null
+++ b/crud/src/main/java/org/apache/struts/crud/dao/MemoryPersonSupportDao.java
@@ -0,0 +1,56 @@
+package org.apache.struts.crud.dao;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.struts.crud.model.Country;
+
+/**
+ * TODO I18e database text data
+ * 
+ * @author antonio sanchez
+ */
+public class MemoryPersonSupportDao implements PersonSupportDao {
+    private static Country[] countries;
+    private static Map<String, Country> countriesMap;
+    private static String[] genders = {"male", "female"};
+    private static String[] sports = {"football", "baseball", "basketball", "mtb" };
+    private static String [] carModelsAvailable = {"Ford", "Chrysler", "Toyota", "Nissan", "Seat"};
+
+    static {
+        countries = new Country[] {new Country("ES", "Spain"),
+                    new Country("IE", "Ireland"),
+                    new Country("IT", "Italy"),
+                    new Country("PL", "Poland"),
+                    new Country("US", "Usa") };
+        
+        countriesMap = new HashMap<>();
+        for (Country c : countries) {
+            countriesMap.put(c.getCountryAbbr(), c);
+        }
+    }
+
+//    @Override
+//    public Map<String, Country> getCountriesMap() {
+//        return countriesMap;
+//    }
+
+    @Override
+    public String[] getCarModels() {
+        return carModelsAvailable;
+    }
+
+    @Override
+    public String[] getSports() {
+        return sports;
+    }
+
+    @Override
+    public String[] getGenders() {
+        return genders;
+    }
+
+    @Override
+    public Country[] getCountries() {
+        return countries;
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/java/org/apache/struts/crud/dao/PersonDao.java
----------------------------------------------------------------------
diff --git a/crud/src/main/java/org/apache/struts/crud/dao/PersonDao.java b/crud/src/main/java/org/apache/struts/crud/dao/PersonDao.java
new file mode 100755
index 0000000..700c522
--- /dev/null
+++ b/crud/src/main/java/org/apache/struts/crud/dao/PersonDao.java
@@ -0,0 +1,19 @@
+package org.apache.struts.crud.dao;
+
+import org.apache.struts.crud.model.Person;
+
+/**
+ * @author antonio sanchez
+ */
+public interface PersonDao {
+    
+    Person getPerson(Integer id);
+    
+    Person[] getAllPersons();
+
+    void updatePerson(Person personBean);
+    
+    void insertPerson(Person personBean);
+    
+    void deletePerson(Integer id);
+}

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/java/org/apache/struts/crud/dao/PersonSupportDao.java
----------------------------------------------------------------------
diff --git a/crud/src/main/java/org/apache/struts/crud/dao/PersonSupportDao.java b/crud/src/main/java/org/apache/struts/crud/dao/PersonSupportDao.java
new file mode 100755
index 0000000..d3d3e40
--- /dev/null
+++ b/crud/src/main/java/org/apache/struts/crud/dao/PersonSupportDao.java
@@ -0,0 +1,21 @@
+package org.apache.struts.crud.dao;
+
+//import java.util.Map;
+import org.apache.struts.crud.model.Country;
+
+/**
+ * @author antonio sanchez
+ */
+public interface PersonSupportDao {
+
+    Country[] getCountries();
+
+//    Map<String, Country> getCountriesMap();
+    
+    String[] getCarModels();
+    
+    String[] getSports();
+    
+    String[] getGenders();
+    
+}

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/java/org/apache/struts/crud/model/Country.java
----------------------------------------------------------------------
diff --git a/crud/src/main/java/org/apache/struts/crud/model/Country.java b/crud/src/main/java/org/apache/struts/crud/model/Country.java
new file mode 100755
index 0000000..f99b2f7
--- /dev/null
+++ b/crud/src/main/java/org/apache/struts/crud/model/Country.java
@@ -0,0 +1,37 @@
+package org.apache.struts.crud.model;
+
+/**
+ * TODO rename 'Abbr'
+ * 
+ * @author antonio sánchez
+ */
+public class Country {
+    private String countryAbbr;
+    private String countryName;
+
+    public Country(String countryAbbr, String countryName) {
+        this.countryAbbr = countryAbbr;
+        this.countryName = countryName;
+    }
+
+    public void setCountryAbbr(String countryAbbr) {
+        this.countryAbbr = countryAbbr;
+    }
+
+    public String getCountryAbbr() {
+        return countryAbbr;
+    }
+
+    public void setCountryName(String countryName) {
+        this.countryName = countryName;
+    }
+
+    public String getCountryName() {
+        return countryName;
+    }
+
+    @Override
+    public String toString() {
+        return getCountryAbbr();
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/java/org/apache/struts/crud/model/Person.java
----------------------------------------------------------------------
diff --git a/crud/src/main/java/org/apache/struts/crud/model/Person.java b/crud/src/main/java/org/apache/struts/crud/model/Person.java
new file mode 100755
index 0000000..ebb9e93
--- /dev/null
+++ b/crud/src/main/java/org/apache/struts/crud/model/Person.java
@@ -0,0 +1,135 @@
+package org.apache.struts.crud.model;
+
+import java.util.Arrays;
+
+/**
+ * Models a Person who registers.
+ *
+ * @author bruce phillips
+ * @author antonio sanchez
+ */
+public class Person {
+    private Integer personId;
+    private String firstName;
+    private String lastName;
+    private String sport;
+    private String gender;
+    private String residency;
+    private boolean over21;
+    private String[] carModels;
+    private String email;
+    private String phoneNumber;
+    
+    public Person()  {
+    
+    }
+    
+    public Person(Integer id, String firstName, String lastName, String sport, 
+                String gender, String residency, boolean over21, String[] carModels, 
+                String email, String phoneNumber) {
+        this.personId = id;
+        this.firstName = firstName;
+        this.lastName = lastName;
+        this.sport = sport;
+        this.gender = gender;
+        this.residency = residency;
+        this.over21 = over21;
+        this.carModels = carModels;
+        this.email = email;
+        this.phoneNumber = phoneNumber;
+    }
+    
+    public Integer getPersonId() {
+        return personId;
+    }
+
+    public void setPersonId(Integer personId) {
+        this.personId = personId;
+    }
+
+    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 getSport() {
+        return sport;
+    }
+
+    public void setSport(String sport) {
+        this.sport = sport;
+    }
+
+    public void setGender(String gender) {
+        this.gender = gender;
+    }
+
+    public String getGender() {
+        return gender;
+    }
+
+    public void setResidency(String residency) {
+        this.residency = residency;
+    }
+
+    public String getResidency() {
+        return residency;
+    }
+
+    public void setOver21(boolean over21) {
+        this.over21 = over21;
+    }
+
+    public boolean isOver21() {
+        return over21;
+    }
+
+    public void setCarModels(String[] carModels) {
+        this.carModels = carModels;
+    }
+
+    public String[] getCarModels() {
+        return carModels;
+    }
+    
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setPhoneNumber(String phoneNumber) {
+        this.phoneNumber = phoneNumber;
+    }
+
+    public String getPhoneNumber() {
+        return phoneNumber;
+    }
+
+    @Override
+    public String toString() {
+        return "Id: " + getPersonId() + " | "
+                + "First Name: " + getFirstName() + " | "
+                + " Last Name:  " + getLastName() + " | "
+                + " Favorite Sport: " + getSport() + " | "
+                + " Gender: " + getGender() + " | "
+                + " Residency: " + getResidency() + " | "
+                + " Over 21: " + isOver21() + " | "
+                + " Car models: " + Arrays.asList(getCarModels()) + " | "
+                + " Email: " + getEmail() + " | "
+                + " Phone: " + getPhoneNumber();
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/java/org/apache/struts/crud/service/DefaultPersonService.java
----------------------------------------------------------------------
diff --git a/crud/src/main/java/org/apache/struts/crud/service/DefaultPersonService.java b/crud/src/main/java/org/apache/struts/crud/service/DefaultPersonService.java
new file mode 100755
index 0000000..e403ef0
--- /dev/null
+++ b/crud/src/main/java/org/apache/struts/crud/service/DefaultPersonService.java
@@ -0,0 +1,71 @@
+package org.apache.struts.crud.service;
+
+import org.apache.struts.crud.dao.MemoryPersonDao;
+import org.apache.struts.crud.dao.MemoryPersonSupportDao;
+import org.apache.struts.crud.dao.PersonDao;
+import org.apache.struts.crud.dao.PersonSupportDao;
+import org.apache.struts.crud.model.Country;
+import org.apache.struts.crud.model.Person;
+
+/**
+ * Implement Services needed to edit and save
+ * a Person object's state.  
+ * 
+ * @author bruce phillips
+ * @author antonio sanchez
+ */
+
+public class DefaultPersonService implements PersonService {
+    PersonDao personDao; 
+    PersonSupportDao personSupportDao; 
+    
+    public DefaultPersonService() {
+        personDao = new MemoryPersonDao();
+        personSupportDao = new MemoryPersonSupportDao();
+    }
+
+    @Override
+    public Person getPerson(Integer id) {
+        return personDao.getPerson(id);
+    }
+
+    @Override
+    public Person[] getAllPersons() {
+        return personDao.getAllPersons();
+    }
+
+    @Override
+    public void updatePerson(Person personBean) {
+        personDao.updatePerson(personBean);
+    }
+
+    @Override
+    public void insertPerson(Person personBean) {
+        personDao.insertPerson(personBean);
+    }
+
+    @Override
+    public void deletePerson(Integer id) {
+        personDao.deletePerson(id);
+    }
+
+    @Override
+    public Country[] getCountries() {
+        return personSupportDao.getCountries();
+    }
+
+    @Override
+    public String[] getCarModels() {
+        return personSupportDao.getCarModels();
+    }
+
+    @Override
+    public String[] getSports() {
+        return personSupportDao.getSports();
+    }
+
+    @Override
+    public String[] getGenders() {
+        return personSupportDao.getGenders();
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/java/org/apache/struts/crud/service/PersonService.java
----------------------------------------------------------------------
diff --git a/crud/src/main/java/org/apache/struts/crud/service/PersonService.java b/crud/src/main/java/org/apache/struts/crud/service/PersonService.java
new file mode 100755
index 0000000..e05c06b
--- /dev/null
+++ b/crud/src/main/java/org/apache/struts/crud/service/PersonService.java
@@ -0,0 +1,25 @@
+package org.apache.struts.crud.service;
+
+import org.apache.struts.crud.model.Country;
+import org.apache.struts.crud.model.Person;
+
+public interface PersonService {
+
+    Person getPerson(Integer id);
+    
+    Person[] getAllPersons();
+
+    void updatePerson(Person personBean);
+    
+    void insertPerson(Person personBean);
+    
+    void deletePerson(Integer id);
+    
+    Country[] getCountries();
+    
+    String[] getCarModels();
+    
+    String[] getSports();
+    
+    String[] getGenders();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/resources/org/apache/struts/crud/action/PersonAction-validation.xml
----------------------------------------------------------------------
diff --git a/crud/src/main/resources/org/apache/struts/crud/action/PersonAction-validation.xml b/crud/src/main/resources/org/apache/struts/crud/action/PersonAction-validation.xml
new file mode 100755
index 0000000..8a147a6
--- /dev/null
+++ b/crud/src/main/resources/org/apache/struts/crud/action/PersonAction-validation.xml
@@ -0,0 +1,36 @@
+<!DOCTYPE validators PUBLIC
+         "-//Apache Struts//XWork Validator 1.0.3//EN"
+           "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
+<!-- TODO I18e messages -->           
+<validators>
+    <validator type="requiredstring">
+        <param name="fieldname">person.firstName</param>
+        <message>First name is required.</message>
+    </validator>
+    <validator type="requiredstring">
+        <param name="fieldname">person.lastName</param>
+        <message>Last name is required.</message>
+    </validator>
+    <validator type="requiredstring">
+        <param name="fieldname">person.email</param>
+        <message>Email address is required.</message>
+    </validator>
+    <validator type="email">
+        <param name="fieldname">person.email</param>
+        <message>Email address not valid.</message>
+    </validator>
+    <validator type="requiredstring">
+        <param name="fieldname">person.phoneNumber</param>
+        <message>Phone number is required.</message>
+    </validator>
+    <validator type="regex">
+        <param name="fieldname">person.phoneNumber</param>
+        <param name="regex"><![CDATA[\d{3}-\d{3}-\d{4}]]></param>
+        <message>Phone number must be entered as 999-999-9999.</message>
+    </validator>
+    <validator type="fieldexpression">
+        <param name="fieldname">person.carModels</param>
+        <param name="expression"><![CDATA[person.carModels.length > 0]]></param>
+        <message>You must select at least one car model.</message>
+    </validator>
+</validators>

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/resources/org/apache/struts/crud/action/PersonAction.properties
----------------------------------------------------------------------
diff --git a/crud/src/main/resources/org/apache/struts/crud/action/PersonAction.properties b/crud/src/main/resources/org/apache/struts/crud/action/PersonAction.properties
new file mode 100755
index 0000000..5c58085
--- /dev/null
+++ b/crud/src/main/resources/org/apache/struts/crud/action/PersonAction.properties
@@ -0,0 +1,30 @@
+#TODO use templates for patterns: X is required... Person...
+
+person.firstName=First name
+person.lastName=Last name
+person.email=Email address
+person.phoneNumber=Phone number (999-999-9999)
+person.sport=Favorite sport
+person.gender=Gender
+person.residency=State resident
+person.over21=21 or older
+person.carModels=Car models owned
+
+#labels
+application.title=Person Maintenance Application
+label.persons=Persons
+label.delete=Delete
+label.edit=Edit
+label.employee.edit=Edit Person
+label.employee.add=Add Person
+
+#button labels
+button.label.submit=Submit
+button.label.cancel=Cancel
+
+##-- errors
+errors.prefix=<span style="color:red;font-weight:bold;">
+errors.suffix=</span>
+errors.general=An Error Has Occcured
+errors.required.firstname=Name is required.
+errors.required.lastname=Last name is required.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/resources/struts.xml
----------------------------------------------------------------------
diff --git a/crud/src/main/resources/struts.xml b/crud/src/main/resources/struts.xml
new file mode 100755
index 0000000..15fb7ef
--- /dev/null
+++ b/crud/src/main/resources/struts.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
+        "http://struts.apache.org/dtds/struts-2.3.dtd">
+
+<struts>
+    <constant name="struts.devMode" value="true" />
+    <constant name="struts.mapper.action.prefix.enabled" value="true" />
+
+    <package name="default" namespace="/" extends="struts-default" >
+	
+        <interceptors>
+            <interceptor-stack name="appDefault">
+                <interceptor-ref name="paramsPrepareParamsStack">
+                    <param name="exception.logEnabled">true</param>
+                    <param name="exception.logLevel">ERROR</param>
+                    <param name="params.excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*,submit</param>
+                </interceptor-ref>
+            </interceptor-stack>
+        </interceptors>
+
+        <default-interceptor-ref name="appDefault" />
+
+        <default-action-ref name="index"/>
+
+        <action name="index" class="org.apache.struts.crud.action.PersonAction" method="list">
+            <result name="success">/WEB-INF/jsp/persons.jsp</result>
+            <interceptor-ref name="basicStack"/>
+        </action>
+        <action name="*Person" class="org.apache.struts.crud.action.PersonAction" method="{1}">
+            <result name="input">/WEB-INF/jsp/editPerson.jsp</result>
+            <result name="success" type="redirectAction">index</result>
+        </action>
+    </package>
+</struts>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/webapp/META-INF/MANIFEST.MF
----------------------------------------------------------------------
diff --git a/crud/src/main/webapp/META-INF/MANIFEST.MF b/crud/src/main/webapp/META-INF/MANIFEST.MF
new file mode 100755
index 0000000..254272e
--- /dev/null
+++ b/crud/src/main/webapp/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path: 
+

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/webapp/META-INF/context.xml
----------------------------------------------------------------------
diff --git a/crud/src/main/webapp/META-INF/context.xml b/crud/src/main/webapp/META-INF/context.xml
new file mode 100755
index 0000000..a7ecd7a
--- /dev/null
+++ b/crud/src/main/webapp/META-INF/context.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Context antiJARLocking="true" path="/crud"/>

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/webapp/WEB-INF/jsp/editPerson.jsp
----------------------------------------------------------------------
diff --git a/crud/src/main/webapp/WEB-INF/jsp/editPerson.jsp b/crud/src/main/webapp/WEB-INF/jsp/editPerson.jsp
new file mode 100755
index 0000000..8480a4a
--- /dev/null
+++ b/crud/src/main/webapp/WEB-INF/jsp/editPerson.jsp
@@ -0,0 +1,41 @@
+<%-- TODO I18e all static text --%>
+<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8"%>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+<s:if test="person==null || person.personId == null">
+    <s:set name="title" value="%{'Add new person'}"/>
+</s:if>
+<s:else>
+    <s:set name="title" value="%{'Update person'}"/>
+</s:else>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+    <head>
+        <s:head />
+        <link href="<s:url value='/css/main.css'/>" rel="stylesheet" type="text/css"/>
+        <style>td { white-space:nowrap; }</style>
+        <title><s:property value="#title"/></title>
+    </head>
+    <body>
+        <div class="titleDiv"><s:text name="application.title"/></div>
+        <h1><s:property value="#title"/></h1>
+        <s:actionerror />
+        <s:actionmessage />
+        <s:form action="savePerson" method="post">
+            <s:textfield key="person.firstName" /> 
+            <s:textfield key="person.lastName" /> 
+            <s:textfield key="person.email" />
+            <s:textfield key="person.phoneNumber" />
+            <s:select key="person.sport" list="sports" />
+            <s:radio key="person.gender" list="genders" />
+            <s:select key="person.residency" list="countries" listKey="countryAbbr" listValue="countryName" />
+            <s:checkbox key="person.over21" />
+            <s:checkboxlist key="person.carModels" list="carModelsAvailable" />
+            
+            <s:hidden name="person.personId" value="%{person.personId}"/>
+
+            <s:submit value="%{getText('button.label.submit')}"/>
+            <s:submit value="%{getText('button.label.cancel')}" action="index"/>
+        </s:form>
+    </body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/webapp/WEB-INF/jsp/persons.jsp
----------------------------------------------------------------------
diff --git a/crud/src/main/webapp/WEB-INF/jsp/persons.jsp b/crud/src/main/webapp/WEB-INF/jsp/persons.jsp
new file mode 100755
index 0000000..94f9fcb
--- /dev/null
+++ b/crud/src/main/webapp/WEB-INF/jsp/persons.jsp
@@ -0,0 +1,57 @@
+<%-- TODO I18e all static text --%>
+<%-- TODO Simplify table header texts  --%>
+<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8"%>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+    <head>
+        <s:head />
+        <link href="<s:url value='/css/main.css'/>" rel="stylesheet" type="text/css"/>
+        <title><s:text name="label.persons"/></title>
+    </head>
+    <body>
+        <div class="titleDiv"><s:text name="application.title"/></div>
+        <h1><s:text name="label.persons"/></h1>
+        <s:url id="url" action="inputPerson" />
+        <a href="<s:property value="#url"/>">Add New Person</a>
+        <br/><br/>
+        <table class="borderAll">
+            <tr>
+                <th><s:text name="person.firstName"/></th>
+                <th><s:text name="person.lastName"/></th>
+                <th><s:text name="person.email"/></th>
+                <th><s:text name="person.phoneNumber"/></th>
+                <th><s:text name="person.sport"/></th>
+                <th><s:text name="person.gender"/></th>
+                <th><s:text name="person.residency"/></th>
+                <th><s:text name="person.over21"/></th>
+                <th><s:text name="person.carModels"/></th>
+                <th>&nbsp;</th>
+            </tr>
+            <s:iterator value="persons" status="status">
+                <tr class="<s:if test="#status.even">even</s:if><s:else>odd</s:else>">
+                    <td class="nowrap"><s:property value="firstName"/></td>
+                    <td class="nowrap"><s:property value="lastName"/></td>
+                    <td class="nowrap"><s:property value="email"/></td>
+                    <td class="nowrap"><s:property value="phoneNumber"/></td>
+                    <td class="nowrap"><s:property value="sport"/></td>
+                    <td class="nowrap"><s:property value="gender"/></td>
+                    <td class="nowrap"><s:property value="residency"/></td>
+                    <td class="nowrap"><s:property value="over21"/></td>
+                    <td class="nowrap"><s:property value="carModels"/></td>
+                    <td class="nowrap">
+                        <s:url action="inputPerson" id="url">
+                            <s:param name="person.personId" value="personId"/>
+                        </s:url>
+                        <a href="<s:property value="#url"/>">Edit</a>
+                        &nbsp;&nbsp;&nbsp;
+                        <s:url action="deletePerson" id="url">
+                            <s:param name="person.personId" value="personId"/>
+                        </s:url>
+                        <a href="<s:property value="#url"/>">Delete</a>
+                    </td>
+                </tr>
+            </s:iterator>
+        </table>
+    </body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/crud/src/main/webapp/WEB-INF/web.xml b/crud/src/main/webapp/WEB-INF/web.xml
new file mode 100755
index 0000000..d0864b2
--- /dev/null
+++ b/crud/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" 
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+    <display-name>Struts 2 CRUD Example</display-name>
+    
+    	<welcome-file-list>
+		<welcome-file>index.jsp</welcome-file>
+	</welcome-file-list>
+  					 
+    <filter>
+        <filter-name>struts2</filter-name>
+        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
+    </filter>
+
+    <filter-mapping>
+        <filter-name>struts2</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+    
+</web-app>

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/webapp/css/main.css
----------------------------------------------------------------------
diff --git a/crud/src/main/webapp/css/main.css b/crud/src/main/webapp/css/main.css
new file mode 100755
index 0000000..27b210b
--- /dev/null
+++ b/crud/src/main/webapp/css/main.css
@@ -0,0 +1,56 @@
+html, body  {
+    margin-left: 10px;
+    margin-right: 10px;
+    margin-bottom: 5px;
+    color: black;
+    background-color: white;
+    font-family: Verdana, Arial, sans-serif;
+    font-size:12px;
+}
+.titleDiv {
+    background-color: #EFFBEF;
+    font-weight:bold;
+    font-size:18px;
+    text-align:left;
+    padding-left:10px;
+    padding-top:10px;
+    padding-bottom:10px;
+    border:2px solid #8F99EF;
+}
+h1 { font-weight:bold; color: brown; font-size:15px; text-align:left;}
+
+td { font-size:12px; padding-right:10px; }
+th { text-align:left; font-weight:bold; font-size:13px; padding-right:10px; }
+.tdLabel { font-weight: bold; white-space:nowrap; vertical-align:top;}
+
+A { color:#4A825A; text-decoration:none;}
+A:link { text-decoration:none;}
+A:visited { text-decoration:none;}
+A:hover { text-decoration:none; color: red;}
+
+.borderAll {
+    border: 2px solid #8F99EF;
+}
+
+.butStnd {
+    font-family:arial,sans-serif;
+    font-size:11px;
+    width:105px;
+    background-color:#DCDFFA ;color:#4A825A;font-weight:bold;
+}
+
+.error {
+    color: red;
+    font-weight: bold;
+}
+.errorSection {
+    padding-left:18px;
+    padding-top:2px;
+    padding-bottom:10px;
+    padding-right:5px;
+}
+
+.even { background-color: #EFFBEF; }
+.odd { background-color: white; }
+
+.nowrap { white-space:nowrap; }

http://git-wip-us.apache.org/repos/asf/struts-examples/blob/7724ee34/crud/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/crud/src/main/webapp/index.jsp b/crud/src/main/webapp/index.jsp
new file mode 100644
index 0000000..70405c6
--- /dev/null
+++ b/crud/src/main/webapp/index.jsp
@@ -0,0 +1,16 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+    pageEncoding="ISO-8859-1"%>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Struts 2 CRUD Example - Welcome</title>
+</head>
+<body>
+<h1>Welcome To Struts 2!</h1>
+
+<p><a href='<s:url action="index" />' >List People</a></p>
+
+</body>
+</html>
\ No newline at end of file