Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

made the UI support search, as well as save capabilities

  • Loading branch information...
commit 27f36ec281a17d45e12da2422e13994a6a9a5d33 1 parent 0f803cd
@joshlong authored
Showing with 355 additions and 246 deletions.
  1. +6 −0 .gitignore
  2. +1 −0  pom.xml
  3. +25 −12 src/main/java/org/springsource/examples/spring31/services/CustomerService.java
  4. +0 −85 src/main/java/org/springsource/examples/spring31/services/config/AppFogDataSourceConfiguration.java
  5. +3 −8 src/main/java/org/springsource/examples/spring31/services/config/CloudFoundryDataSourceConfiguration.java
  6. +1 −1  src/main/java/org/springsource/examples/spring31/services/config/DataSourceConfiguration.java
  7. +24 −23 src/main/java/org/springsource/examples/spring31/services/config/LocalDataSourceConfiguration.java
  8. +12 −23 src/main/java/org/springsource/examples/spring31/services/config/ServicesConfiguration.java
  9. +70 −0 src/main/java/org/springsource/examples/spring31/util/SeedDataGenerator.java
  10. +30 −20 src/main/java/org/springsource/examples/spring31/web/CustomerApiController.java
  11. +0 −20 src/main/java/org/springsource/examples/spring31/web/CustomerViewController.java
  12. +1 −1  src/main/java/org/springsource/examples/spring31/web/SpringApplicationContextInitializer.java
  13. +5 −4 src/main/java/org/springsource/examples/spring31/web/WebMvcConfiguration.java
  14. +16 −10 src/main/resources/import_h2.sql
  15. +16 −10 src/main/resources/import_psql.sql
  16. +1 −1  src/main/resources/log4j.properties
  17. +54 −19 src/main/webapp/WEB-INF/views/customers.jsp
  18. +0 −1  src/main/webapp/WEB-INF/web.xml
  19. +85 −8 src/main/webapp/web/views/customers.js
  20. +5 −0 todo.txt
View
6 .gitignore
@@ -0,0 +1,6 @@
+target
+*project
+.idea
+*iml
+*settings
+*classpath
View
1  pom.xml
@@ -18,6 +18,7 @@
<artifactId>postgresql</artifactId>
<version>9.1-901-1.jdbc4</version>
</dependency>
+ <dependency><groupId>commons-dbcp</groupId><artifactId>commons-dbcp</artifactId><version>1.4</version></dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
View
37 src/main/java/org/springsource/examples/spring31/services/CustomerService.java
@@ -1,59 +1,72 @@
package org.springsource.examples.spring31.services;
-import org.hibernate.SessionFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+import org.springsource.examples.spring31.services.config.ServicesConfiguration;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import java.util.Collection;
import java.util.Date;
import java.util.List;
@Service
+@SuppressWarnings("unchecked")
@Transactional
public class CustomerService {
static private final String CUSTOMERS_REGION = "customers";
- @Autowired
- private SessionFactory sessionFactory;
+ @PersistenceContext
+ private EntityManager em;
public Customer createCustomer(String firstName, String lastName, Date signupDate) {
Customer customer = new Customer();
customer.setFirstName(firstName);
customer.setLastName(lastName);
customer.setSignupDate(signupDate);
-
- sessionFactory.getCurrentSession().save(customer);
+ em.persist(customer);
return customer;
}
- @SuppressWarnings("unchecked")
+ public Collection<Customer> search(String name) {
+ String sqlName = ("%" + name + "%").toLowerCase();
+ String sql = "select {c.*} from customer c where (LOWER( c.firstName ) LIKE :fn OR LOWER( c.lastName ) LIKE :ln)";
+ return em.createNativeQuery(sql, Customer.class)
+ .setParameter("fn", sqlName)
+ .setParameter("ln", sqlName)
+ .getResultList();
+ }
+
+
@Transactional(readOnly = true)
public List<Customer> getAllCustomers() {
- return sessionFactory.getCurrentSession().createCriteria(Customer.class).list();
+ return em.createQuery("SELECT * FROM " + Customer.class.getName()).getResultList();
}
@Cacheable(CUSTOMERS_REGION)
@Transactional(readOnly = true)
public Customer getCustomerById(Integer id) {
- return (Customer) sessionFactory.getCurrentSession().get(Customer.class, id);
+ return em.find(Customer.class, id);
}
@CacheEvict(CUSTOMERS_REGION)
public void deleteCustomer(Integer id) {
Customer customer = getCustomerById(id);
- sessionFactory.getCurrentSession().delete(customer);
+ em.remove(customer);
}
- @CacheEvict( value = CUSTOMERS_REGION , key = "#id")
+ @CacheEvict(value = CUSTOMERS_REGION, key = "#id")
public void updateCustomer(Integer id, String fn, String ln, Date birthday) {
Customer customer = getCustomerById(id);
customer.setLastName(ln);
customer.setSignupDate(birthday);
customer.setFirstName(fn);
- sessionFactory.getCurrentSession().update(customer);
+ //sessionFactory.getCurrentSession().update(customer);
+ em.merge(customer);
}
}
View
85 ...ava/org/springsource/examples/spring31/services/config/AppFogDataSourceConfiguration.java
@@ -1,85 +0,0 @@
-package org.springsource.examples.spring31.services.config;
-
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonNode;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.hibernate.dialect.PostgreSQLDialect;
-import org.springframework.cache.Cache;
-import org.springframework.cache.CacheManager;
-import org.springframework.cache.concurrent.ConcurrentMapCache;
-import org.springframework.cache.support.SimpleCacheManager;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Profile;
-import org.springframework.jdbc.datasource.SimpleDriverDataSource;
-import org.springframework.util.Assert;
-
-import javax.sql.DataSource;
-import java.sql.Driver;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * Implementation of the {@link DataSourceConfiguration dataSourceConfiguration} contract
- * that works with AppFog.
- * <p/>
- * Mainly, this is the same as the {@link CloudFoundryDataSourceConfiguration}, except that
- * it doesn't require Redis, since AppFog doesn't have Redis.
- *
- * @author Josh Long
- */
-@Configuration
-@Profile("appfog")
-public class AppFogDataSourceConfiguration implements DataSourceConfiguration {
- @Bean
- public CacheManager cacheManager() throws Exception {
- SimpleCacheManager scm = new SimpleCacheManager();
- Cache cache = new ConcurrentMapCache("customers");
- scm.setCaches(Arrays.asList(cache));
- return scm;
- }
-
- private JsonNode fromString(String jsonFragment) throws Exception {
- ObjectMapper mapper = new ObjectMapper();
- JsonFactory factory = mapper.getJsonFactory();
- JsonParser jp = factory.createJsonParser(jsonFragment);
- return mapper.readTree(jp);
- }
-
- @Bean
- public DataSource dataSource() throws Exception {
- String vcapServices = System.getenv("VCAP_SERVICES");
- JsonNode jsonNode = fromString(vcapServices);
- Iterator<JsonNode> pgsqls = jsonNode.get("postgresql-9.1").getElements();
- Assert.isTrue(pgsqls.hasNext(), "there must be at least one postgres instance configured!");
- JsonNode postgresInformation = pgsqls.next();
- Assert.notNull(postgresInformation != null);
- JsonNode credentials = postgresInformation.get("credentials");
- Assert.notNull(credentials, "the credentials can't be null");
- String schemaOrDb = credentials.get("name").getTextValue();
- String host = credentials.get("host").getTextValue();
- int port = credentials.get("port").getNumberValue().intValue();
- String user = credentials.get("user").getTextValue();
- String pw = credentials.get("password").getTextValue();
- SimpleDriverDataSource simpleDriverDataSource = new SimpleDriverDataSource();
- Class<? extends Driver> d = org.postgresql.Driver.class;
- simpleDriverDataSource.setDriverClass(d);
- simpleDriverDataSource.setUsername(user);
- simpleDriverDataSource.setPassword(pw);
- simpleDriverDataSource.setUrl(String.format("jdbc:postgresql://%s:%s/%s", host, port + "", schemaOrDb));
- return simpleDriverDataSource;
- }
-
- @Override
- public Map<String, String> contributeSessionFactoryProperties() {
- Map<String, String> p = new HashMap<String, String>();
- p.put(org.hibernate.cfg.Environment.HBM2DDL_AUTO, "create");
- p.put(org.hibernate.cfg.Environment.DIALECT, PostgreSQLDialect.class.getName());
- p.put(org.hibernate.cfg.Environment.SHOW_SQL, "true");
- return p;
- }
-
-}
View
11 ...g/springsource/examples/spring31/services/config/CloudFoundryDataSourceConfiguration.java
@@ -24,22 +24,17 @@
@Profile("cloud")
public class CloudFoundryDataSourceConfiguration implements DataSourceConfiguration {
- @Bean
- public CloudEnvironment environment() {
- return new CloudEnvironment();
- }
+ private CloudEnvironment cloudEnvironment = new CloudEnvironment();
@Bean
public DataSource dataSource() throws Exception {
- CloudEnvironment environment = environment();
- Collection<RdbmsServiceInfo> mysqlSvc = environment.getServiceInfos(RdbmsServiceInfo.class);
+ Collection<RdbmsServiceInfo> mysqlSvc = cloudEnvironment.getServiceInfos(RdbmsServiceInfo.class);
RdbmsServiceCreator dataSourceCreator = new RdbmsServiceCreator();
return dataSourceCreator.createService(mysqlSvc.iterator().next());
}
@Bean
public RedisTemplate<String, Object> redisTemplate() throws Exception {
- CloudEnvironment cloudEnvironment = environment();
RedisServiceInfo info = cloudEnvironment.getServiceInfos(RedisServiceInfo.class).iterator().next();
RedisServiceCreator creator = new RedisServiceCreator();
RedisConnectionFactory connectionFactory = creator.createService(info);
@@ -53,7 +48,7 @@ public CacheManager cacheManager() throws Exception {
return new RedisCacheManager(redisTemplate());
}
- public Map<String, String> contributeSessionFactoryProperties() {
+ public Map<String, String> contributeJpaEntityManagerProperties() {
Map<String, String> p = new HashMap<String, String>();
p.put(org.hibernate.cfg.Environment.HBM2DDL_AUTO, "create");
p.put(org.hibernate.cfg.Environment.DIALECT, PostgreSQLDialect.class.getName());
View
2  ...main/java/org/springsource/examples/spring31/services/config/DataSourceConfiguration.java
@@ -16,5 +16,5 @@
DataSource dataSource() throws Exception;
- Map<String, String> contributeSessionFactoryProperties() throws Exception;
+ Map<String, String> contributeJpaEntityManagerProperties() throws Exception;
}
View
47 ...java/org/springsource/examples/spring31/services/config/LocalDataSourceConfiguration.java
@@ -1,13 +1,8 @@
package org.springsource.examples.spring31.services.config;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.sql.DataSource;
-
import org.hibernate.dialect.H2Dialect;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCache;
@@ -15,40 +10,46 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
+import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
+import javax.sql.DataSource;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
@Configuration
-@Profile("local")
+@Profile("default")
public class LocalDataSourceConfiguration implements DataSourceConfiguration {
- //@Autowired
- //private Environment environment;
+ @Autowired
+ private Environment environment;
@Bean
public DataSource dataSource() throws Exception {
+
return new EmbeddedDatabaseBuilder()
.setName("crm")
.setType(EmbeddedDatabaseType.H2)
.build();
-/*
- // here's how you would do this if you were connecting to a
- // regular DS (perhaps a real PostgreSQL instance or a non in-memory H2 instance)
- SimpleDriverDataSource simpleDriverDataSource = new SimpleDriverDataSource();
-
- Class<? extends Driver> d = (Class<? extends Driver>) Class.forName(environment.getProperty("ds.driverClass"));
-
+ /*
String user = environment.getProperty("ds.user"),
pw = environment.getProperty("ds.password"),
url = environment.getProperty("ds.url");
+ Class<Driver> driverClass = environment.getPropertyAsClass( "ds.driverClass", Driver.class );
- simpleDriverDataSource.setDriverClass(d);
- simpleDriverDataSource.setUsername(user);
- simpleDriverDataSource.setPassword(pw);
- simpleDriverDataSource.setUrl(url);
- return simpleDriverDataSource;
+ BasicDataSource basicDataSource = new BasicDataSource();
+ basicDataSource.setDriverClassName( driverClass.getName() );
+ basicDataSource.setPassword( pw );
+ basicDataSource.setUrl( url );
+ basicDataSource.setUsername( user );
+ basicDataSource.setInitialSize( 5 );
+ basicDataSource.setMaxActive( 10 );
+ return basicDataSource;
*/
+
}
@Bean
@@ -59,10 +60,10 @@ public CacheManager cacheManager() throws Exception {
return scm;
}
- public Map<String, String> contributeSessionFactoryProperties() {
+ public Map<String, String> contributeJpaEntityManagerProperties() {
Map<String, String> p = new HashMap<String, String>();
p.put(org.hibernate.cfg.Environment.HBM2DDL_AUTO, "create");
- p.put(org.hibernate.cfg.Environment.HBM2DDL_IMPORT_FILES , "import_h2.sql");
+ p.put(org.hibernate.cfg.Environment.HBM2DDL_IMPORT_FILES, "import_h2.sql");
p.put(org.hibernate.cfg.Environment.DIALECT, H2Dialect.class.getName());
p.put(org.hibernate.cfg.Environment.SHOW_SQL, "true");
return p;
View
35 src/main/java/org/springsource/examples/spring31/services/config/ServicesConfiguration.java
@@ -1,23 +1,19 @@
package org.springsource.examples.spring31.services.config;
-import org.hibernate.SessionFactory;
+import org.hibernate.ejb.HibernatePersistence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
-import org.springframework.orm.hibernate4.HibernateTransactionManager;
-import org.springframework.orm.hibernate4.LocalSessionFactoryBuilder;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springsource.examples.spring31.services.Customer;
import org.springsource.examples.spring31.services.CustomerService;
-import java.util.Map;
-import java.util.Properties;
-
-
@Configuration
@PropertySource("/config.properties")
@@ -26,27 +22,20 @@
@ComponentScan(basePackageClasses = {CustomerService.class})
public class ServicesConfiguration {
- @Autowired
- private DataSourceConfiguration dataSourceConfiguration;
+ @Autowired private DataSourceConfiguration dataSourceConfiguration;
@Bean
- @SuppressWarnings("deprecation")
- public SessionFactory sessionFactory() throws Exception {
- Properties props = new Properties();
-
- Map<String, String> propsMap = this.dataSourceConfiguration.contributeSessionFactoryProperties();
-
- for (String k : propsMap.keySet())
- props.setProperty(k, propsMap.get(k));
-
- return new LocalSessionFactoryBuilder(dataSourceConfiguration.dataSource())
- .addAnnotatedClasses(Customer.class)
- .addProperties(props)
- .buildSessionFactory();
+ public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean() throws Exception {
+ LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
+ em.setDataSource(dataSourceConfiguration.dataSource());
+ em.setPackagesToScan(Customer.class.getPackage().getName());
+ em.setPersistenceProvider(new HibernatePersistence());
+ em.setJpaPropertyMap(dataSourceConfiguration.contributeJpaEntityManagerProperties());
+ return em;
}
@Bean
public PlatformTransactionManager transactionManager() throws Exception {
- return new HibernateTransactionManager(sessionFactory());
+ return new JpaTransactionManager(localContainerEntityManagerFactoryBean().getObject());
}
}
View
70 src/main/java/org/springsource/examples/spring31/util/SeedDataGenerator.java
@@ -0,0 +1,70 @@
+package org.springsource.examples.spring31.util;
+
+import com.sun.deploy.util.SystemUtils;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.util.StringUtils;
+
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * @author Josh Long
+ */
+public class SeedDataGenerator implements InitializingBean {
+
+ private String names = "Juergen Hoeller, Mark Fisher, Rod Johnson, David Syer, Gunnar Hillert, Dave McCrory, Josh Long, Patrick Chanezon, Andy Piper, Eric Bottard, Chris Richardson, Raja Rao, Rajdeep Dua, Monica Wilkinson, Mark Pollack";
+
+ private Set<String[]> orderedUniqueNames = new LinkedHashSet<String[]>();
+
+ private String h2SqlTemplate = "INSERT INTO customer(firstname, lastname, signupdate) values ('%s','%s', NOW() );";
+
+ private String postgreSqlTemplate = "INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , '%s', '%s', NOW());";
+
+ public void setNames(String n){
+ this.names = n ;
+ }
+
+ public void addName (String f, String l){
+ this.orderedUniqueNames.add(new String[]{f,l});
+ }
+
+ public void generate(Writer writer, String sqlTemplate) throws Exception {
+
+ for (String[] nameParts : this.orderedUniqueNames) {
+ writer.write(String.format(sqlTemplate, nameParts[0], nameParts[1]) );
+ writer.write(System.getProperty("line.separator"));
+ }
+ }
+
+ public void generate() throws Exception {
+ String[] templates = {h2SqlTemplate, postgreSqlTemplate};
+ for (String t : templates) {
+ StringWriter stringWriter = new StringWriter();
+ generate(stringWriter, t);
+ String sql = stringWriter.getBuffer().toString();
+ System.out.println("--" + t);
+ System.out.println(sql);
+ }
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ assert StringUtils.hasText(this.names) : "the names property should have a comma delimited list of first and last name pairs, like this 'Josh Long, Mark Fisher, ...'";
+ String[] nameArr = names.split(",");
+ assert nameArr.length > 0 : "you must specify values for the names";
+ for (String noms : nameArr) {
+ String[] nameParts = noms.trim().split(" ");
+ nameParts[0] = nameParts[0].trim();
+ nameParts[1] = nameParts[1].trim();
+ addName(nameParts[0], nameParts[1]);
+ }
+ }
+
+ public static void main (String [] args) throws Exception {
+ SeedDataGenerator seedDataGenerator = new SeedDataGenerator();
+ seedDataGenerator.afterPropertiesSet();
+ seedDataGenerator.generate();
+ }
+}
View
50 src/main/java/org/springsource/examples/spring31/web/CustomerApiController.java
@@ -1,50 +1,60 @@
package org.springsource.examples.spring31.web;
-import java.util.List;
-
-import javax.validation.Valid;
-
+import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.*;
import org.springsource.examples.spring31.services.Customer;
import org.springsource.examples.spring31.services.CustomerService;
-@RequestMapping("/crm/")
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+
+//
+//@RequestMapping(
+// //consumes = MediaType.APPLICATION_JSON_VALUE,
+// produces = MediaType.APPLICATION_JSON_VALUE)
@Controller
public class CustomerApiController {
+ private Logger log = Logger.getLogger(getClass());
+
@Autowired
private CustomerService customerService;
@ResponseBody
- @RequestMapping(value = "/customer/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
- public Customer customerById(@PathVariable("id") Integer id) {
- Customer customer = this.customerService.getCustomerById(id);
+ @RequestMapping(value = "/crm/search", method = RequestMethod.GET)
+ public Collection<Customer> search(@RequestParam("q") String query) throws Exception {
+ Collection<Customer> customers = customerService.search(query);
+ if (log.isDebugEnabled())
+ log.debug(String.format("retrieved %s results for search query '%s'", Integer.toString(customers.size()), query));
+ return customers;
+ }
- return customer ;
+ @ResponseBody
+ @RequestMapping(value = "/crm/customer/{id}", method = RequestMethod.GET)
+ public Customer customerById(@PathVariable("id") Integer id) {
+ return this.customerService.getCustomerById(id);
}
// http://springmvc31.joshlong.micro/crm/customers
@ResponseBody
- @RequestMapping(value = "/customers", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
+ @RequestMapping(value = "/crm/customers", method = RequestMethod.GET)
public List<Customer> customers() {
return this.customerService.getAllCustomers();
}
// http://springmvc31.joshlong.micro/crm/customers
- @RequestMapping(value = "/customers", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
- public void addCustomer(@Valid @RequestBody Customer customer) {
- customerService.createCustomer(customer.getFirstName(), customer.getLastName(), customer.getSignupDate());
+ @ResponseBody
+ @RequestMapping(value = "/crm/customers", method = RequestMethod.PUT)
+ public Integer addCustomer(@RequestParam("firstName") String fn, @RequestParam("lastName") String ln) {
+ return customerService.createCustomer(fn, ln, new Date()).getId();
}
+
@ResponseBody
- @RequestMapping(value = "/customer/{id}", method = RequestMethod.POST ) //, consumes = MediaType.APPLICATION_JSON_VALUE)
+ @RequestMapping(value = "/crm/customer/{id}", method = RequestMethod.POST)
public Integer updateCustomer(@PathVariable("id") Integer id, @RequestBody Customer customer) {
customerService.updateCustomer(id, customer.getFirstName(), customer.getLastName(), customer.getSignupDate());
return id;
View
20 src/main/java/org/springsource/examples/spring31/web/CustomerViewController.java
@@ -1,20 +0,0 @@
-package org.springsource.examples.spring31.web;
-
-import org.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-
-import javax.servlet.http.HttpServletRequest;
-
-@Controller
-public class CustomerViewController {
-
- @RequestMapping(value = "/", method = RequestMethod.GET)
- public String customer(HttpServletRequest httpServletRequest, Model model) {
- String ctxPath = httpServletRequest.getContextPath();
- model.addAttribute("context", ctxPath );
- return "customers";
- }
-
-}
View
2  ...main/java/org/springsource/examples/spring31/web/SpringApplicationContextInitializer.java
@@ -28,7 +28,7 @@ private boolean isLocal() {
public void initialize(AnnotationConfigWebApplicationContext applicationContext) {
- String profile = "local";
+ String profile = "default";
if (isAppFog()) {
profile = "appfog";
} else if (isCloudFoundry()) {
View
9 src/main/java/org/springsource/examples/spring31/web/WebMvcConfiguration.java
@@ -5,10 +5,7 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.support.ResourceBundleMessageSource;
-import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
-import org.springframework.web.servlet.config.annotation.EnableWebMvc;
-import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
import org.springsource.examples.spring31.services.config.ServicesConfiguration;
@@ -41,6 +38,10 @@ public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/web/**").addResourceLocations("/web/");
}
+ @Override
+ public void addViewControllers(ViewControllerRegistry registry) {
+ registry.addViewController("/").setViewName("customers");
+ }
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
View
26 src/main/resources/import_h2.sql
@@ -1,10 +1,16 @@
- insert into customer (firstname ,lastname ,signupdate ) values( 'Juergen' , 'Hoeller', NOW()) ;
- insert into customer (firstname ,lastname ,signupdate ) values( 'Mark' , 'Fisher', NOW()) ;
- insert into customer (firstname ,lastname ,signupdate ) values( 'Chris' , 'Richardson', NOW()) ;
- insert into customer (firstname ,lastname ,signupdate ) values( 'Josh' , 'Long', NOW()) ;
- insert into customer (firstname ,lastname ,signupdate ) values( 'Dave' , 'Syer', NOW()) ;
- insert into customer (firstname ,lastname ,signupdate ) values( 'Matt' , 'Quinlan', NOW()) ;
- insert into customer (firstname ,lastname ,signupdate ) values( 'Gunnar' , 'Hillert', NOW()) ;
- insert into customer (firstname ,lastname ,signupdate ) values( 'Dave' , 'McCrory', NOW()) ;
- insert into customer (firstname ,lastname ,signupdate ) values( 'Raja' , 'Rao', NOW()) ;
- insert into customer (firstname ,lastname ,signupdate ) values( 'Monica' , 'Wilkinson', NOW()) ;
+--INSERT INTO customer(firstname, lastname, signupdate) values ('%s','%s', NOW() );
+INSERT INTO customer(firstname, lastname, signupdate) values ('Juergen','Hoeller', NOW() );
+INSERT INTO customer(firstname, lastname, signupdate) values ('Mark','Fisher', NOW() );
+INSERT INTO customer(firstname, lastname, signupdate) values ('Rod','Johnson', NOW() );
+INSERT INTO customer(firstname, lastname, signupdate) values ('David','Syer', NOW() );
+INSERT INTO customer(firstname, lastname, signupdate) values ('Gunnar','Hillert', NOW() );
+INSERT INTO customer(firstname, lastname, signupdate) values ('Dave','McCrory', NOW() );
+INSERT INTO customer(firstname, lastname, signupdate) values ('Josh','Long', NOW() );
+INSERT INTO customer(firstname, lastname, signupdate) values ('Patrick','Chanezon', NOW() );
+INSERT INTO customer(firstname, lastname, signupdate) values ('Andy','Piper', NOW() );
+INSERT INTO customer(firstname, lastname, signupdate) values ('Eric','Bottard', NOW() );
+INSERT INTO customer(firstname, lastname, signupdate) values ('Chris','Richardson', NOW() );
+INSERT INTO customer(firstname, lastname, signupdate) values ('Raja','Rao', NOW() );
+INSERT INTO customer(firstname, lastname, signupdate) values ('Rajdeep','Dua', NOW() );
+INSERT INTO customer(firstname, lastname, signupdate) values ('Monica','Wilkinson', NOW() );
+INSERT INTO customer(firstname, lastname, signupdate) values ('Mark','Pollack', NOW() );
View
26 src/main/resources/import_psql.sql
@@ -1,10 +1,16 @@
- INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Mark', 'Fisher', NOW()) ;
- INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Juergen', 'Hoeller', NOW()) ;
- INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Chris', 'Richardson', NOW()) ;
- INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Dave', 'Syer', NOW()) ;
- INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Matt', 'Quinlan', NOW()) ;
- INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Gunnar', 'Hiller', NOW()) ;
- INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Josh', 'Long', NOW()) ;
- INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Dave', 'McCrory', NOW()) ;
- INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Raja', 'Rao', NOW()) ;
- INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Monica', 'Wilkinson', NOW()) ;
+--INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , '%s', '%s', NOW());
+INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Juergen', 'Hoeller', NOW());
+INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Mark', 'Fisher', NOW());
+INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Rod', 'Johnson', NOW());
+INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'David', 'Syer', NOW());
+INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Gunnar', 'Hillert', NOW());
+INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Dave', 'McCrory', NOW());
+INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Josh', 'Long', NOW());
+INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Patrick', 'Chanezon', NOW());
+INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Andy', 'Piper', NOW());
+INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Eric', 'Bottard', NOW());
+INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Chris', 'Richardson', NOW());
+INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Raja', 'Rao', NOW());
+INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Rajdeep', 'Dua', NOW());
+INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Monica', 'Wilkinson', NOW());
+INSERT INTO customer(id, firstname, lastname, signupdate) values( nextval( 'hibernate_sequence') , 'Mark', 'Pollack', NOW());
View
2  src/main/resources/log4j.properties
@@ -5,5 +5,5 @@ log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
# Root logger option
-log4j.rootLogger=INFO,stdout
+log4j.rootLogger=DEBUG,stdout
View
73 src/main/webapp/WEB-INF/views/customers.jsp
@@ -1,34 +1,63 @@
+<%@ page session="false" %>
<!doctype html>
<html ng-app>
<head>
- <script src="${context}/web/assets/js/jquery-1.7.2.min.js"></script>
- <script src="${context}/web/assets/js/angular-1.0.0rc6.js"></script>
- <link rel="stylesheet" href="${context}/web/assets/bootstrap/bootstrap.css">
- <script src="${context}/web/views/customers.js"></script>
- <link rel="stylesheet" href="${context}/web/views/customers.css"/>
+ <script src="${pageContext.request.contextPath}/web/assets/js/jquery-1.7.2.min.js"></script>
+ <script src="${pageContext.request.contextPath}/web/assets/js/angular-1.0.0rc6.js"></script>
+ <script src="${pageContext.request.contextPath}/web/views/customers.js"></script>
+
+ <link rel="stylesheet" href="${pageContext.request.contextPath}/web/assets/bootstrap/bootstrap.css">
+ <link rel="stylesheet" href="${pageContext.request.contextPath}/web/views/customers.css"/>
+
</head>
<body>
- <script language = "javascript" type = "text/javascript">
- <!--
- $(function(){
- utils.setup( '${context}');
- })
- // utils.setup( '${context}');
+<script language="javascript" type="text/javascript">
+ <!--
+ $(function () {
+ utils.setup('${pageContext.request.contextPath}');
+ });
+
//-->
- </script>
-<h2>Customer Data </h2>
+</script>
<div ng-controller="CustomerCtrl">
+
+ <div style=" z-index: -21; float: left;padding-top :10px; padding:10px;min-width: 250px;max-width:300px; ">
+ <form class="well form-search" ng-submit="search()">
+ <div>
+ <input type="text" id="search" class="input-medium search-query" ng-model="query"/>
+ <a href="#" class="icon-search" ng-click="search()"></a>
+ </div>
+ <div style="padding-top: 10px;">
+ <div ng-show=" !searchResultsFound()">
+ <span class="no-records">(no results)</span>
+ </div>
+
+ <div ng-show=" searchResultsFound()">
+
+ <div ng-repeat="customer in customers" class="search-results">
+ <span class="title">
+ <span style="font-size: smaller"><span>#</span>{{customer.id}}</span>
+ <a ng-click="load(customer)">{{customer.firstName}} {{customer.lastName}}</a> </span>
+ </div>
+
+ </div>
+ </div>
+ </form>
+ </div>
+<%--
+
<div>
<form class="well form-search" ng-submit="lookupCustomer()">
- <label> Search by ID</label>
- <input type="text" ng-model="id" class="input-medium search-query" width="5" size="5" placeholder="customer #">
- <button type="submit" class="btn btn-primary" ng-click="lookupCustomer()" >
+ <label> Search by Name</label>
+ <input type="text" ng-model="name" class="input-medium search-query" width="5" size="5"
+ placeholder="customer name">
+ <button type="submit" class="btn btn-primary" ng-click="lookupCustomer()">
<a class="icon-search"></a>
</button>
</form>
- </div>
+ </div>--%>
<form class="form-horizontal" ng-submit="updateCustomer">
<fieldset>
@@ -38,15 +67,21 @@
</legend>
<div class="control-group">
<label class="control-label" for="fn">First Name:</label>
+
<div class="controls">
- <input class="input-xlarge" id="fn" type="text" ng-model="customer.firstName" placeholder="first name" required="required"/>
+ <input class="input-xlarge" id="fn" type="text" ng-model="customer.firstName"
+ placeholder="first name" required="required"/>
+
<p class="help-block">Change the first name</p>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ln">Last Name:</label>
+
<div class="controls">
- <input class="input-xlarge" id="ln" type="text" ng-model="customer.lastName" placeholder="last name" required="required"/>
+ <input class="input-xlarge" id="ln" type="text" ng-model="customer.lastName" placeholder="last name"
+ required="required"/>
+
<p class="help-block">Change the last name</p>
</div>
</div>
View
1  src/main/webapp/WEB-INF/web.xml
@@ -10,7 +10,6 @@
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
- <url-pattern>/</url-pattern>
<servlet-name>appServlet</servlet-name>
</filter-mapping>
View
93 src/main/webapp/web/views/customers.js
@@ -11,7 +11,7 @@ var utils = {
this._url = u;
},
url:function (u) {
- return this._url + u;
+ return this._url + u;
},
get:function (url, data, cb) {
$.ajax({
@@ -26,12 +26,32 @@ var utils = {
}
});
},
+ put:function (url, data, cb) {
+ var k = '_method',
+ v = 'PUT';
+ data[k] = v;
+ var headers = {};
+ headers[k] = v;
+ $.ajax({
+ type:'POST',
+ url:url,
+ cache:false,
+ headers:headers,
+ data:data,
+ success:function (result) {
+ cb(result);
+ },
+ error:function (e) {
+ console.log('error PUT\'ing to url ' + url + '. ' + JSON.stringify(e));
+ }
+ }); // todo
+
+ },
post:function (u, data, cb) {
$.ajax({
type:'POST',
url:u,
cache:false,
- // headers : getAuthorizationHeader(),
dataType:'json',
data:data,
contentType:'application/json; charset=utf-8',
@@ -44,29 +64,86 @@ var utils = {
};
function CustomerCtrl($scope) {
+ $scope.customers = [];
+
+ $scope.query = 'juergen';
+
+ $scope.searchResultsFound = function () {
+ return $scope.customers != null && $scope.customers.length > 0;
+ };
+ $scope.load = function (customer) {
+ $scope.customer = customer;
+ $scope.id = customer.id;
+ };
+
+ $scope.search = function () {
+ var u = utils.url('/crm/search?q=' + $scope.query);
+ utils.get(u, {}, function (customers) {
+ $scope.$apply(function () {
+ $scope.customers = customers;
+ if ($scope.searchResultsFound()) {
+ if (customers.length == 1) {
+ $scope.load(customers[0]);
+ }
+ }
+ });
+ });
+ };
$scope.isCustomerLoaded = function () {
- return $scope.customer != null;
+ return $scope.customer != null && $scope.customer.id != null && $scope.customer.id > 0;
};
function loadCustomerById(id, cb) {
var u = utils.url('/crm/customer/' + id);
- utils.get( u, {}, cb);
+ utils.get(u, {}, cb);
}
$scope.lookupCustomer = function () {
loadCustomerById($scope.id, function (c) {
$scope.$apply(function () {
- $scope.customer = c;
+ $scope.load(c);
});
});
};
$scope.save = function () {
var id = $scope.id;
- var u = utils.url('/crm/customer/' + id);
- var data = JSON.stringify($scope.customer);
- utils.post(u, data, function(){});
+ var data = { firstName:$scope.customer.firstName, lastName:$scope.customer.lastName };
+
+ function exists(o, p, cb) {
+ if (o[p] && o[p] != null) {
+ cb(p, o[p]);
+ }
+ }
+
+ exists($scope.customer, 'id', function (pName, val) {
+ data[pName] = val;
+ });
+ exists($scope.customer, 'signupDate', function (pN, v) {
+ data[pN] = v;
+ });
+ var idReceivingCallback = function (id) {
+ console.log('id is ' + id);
+ $scope.$apply(function () {
+ $scope.id = id;
+ $scope.lookupCustomer();
+ });
+
+ };
+
+ var u = null;
+ if (id != null && id > 0) {
+ // then we're simply going to update it
+ u = utils.url('/crm/customer/' + id);
+ console.log('JSON to send' + JSON.stringify(data))
+ utils.post(u, JSON.stringify(data), idReceivingCallback);
+ }
+ else {
+ u = utils.url('/crm/customers');
+ utils.put(u, data, idReceivingCallback);
+ }
+
};
$scope.trash = function () {
View
5 todo.txt
@@ -0,0 +1,5 @@
+ - remove the AppFog specific configuratoin (but test that it's not needed, first!)
+ - add a search field (which shows search results)
+ - add an create capability to the form
+ - list search results
+ - setup a dentists appointment for next week
Please sign in to comment.
Something went wrong with that request. Please try again.