ItEr07S05CUCreacionRecursoTraballadorItEr06S07: Creates, edits and lists workers. Test for WorkerCRUDController. EasyMock is added as dependency.
This commit is contained in:
parent
3763f322d0
commit
d5bb95e490
19 changed files with 718 additions and 270 deletions
|
|
@ -1,5 +1,4 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<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>
|
||||
|
|
@ -37,6 +36,11 @@
|
|||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymock</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package org.navalplanner.business.common.daos;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
|
||||
|
||||
|
|
@ -27,4 +28,6 @@ public interface IGenericDao <E, PK extends Serializable>{
|
|||
|
||||
public void remove(PK id) throws InstanceNotFoundException;
|
||||
|
||||
public <T extends E> List<T> list(Class<T> klass);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ package org.navalplanner.business.common.daos.impl;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.criterion.Projections;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
|
||||
import org.navalplanner.business.common.daos.IGenericDao;
|
||||
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
|
@ -33,8 +33,8 @@ import org.springframework.orm.hibernate3.SessionFactoryUtils;
|
|||
* @param <E> Entity class
|
||||
* @param <PK> Primary key class
|
||||
*/
|
||||
public class GenericDaoHibernate<E, PK extends Serializable>
|
||||
implements IGenericDao<E, PK> {
|
||||
public class GenericDaoHibernate<E, PK extends Serializable> implements
|
||||
IGenericDao<E, PK> {
|
||||
|
||||
private Class<E> entityClass;
|
||||
|
||||
|
|
@ -43,8 +43,8 @@ public class GenericDaoHibernate<E, PK extends Serializable>
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
public GenericDaoHibernate() {
|
||||
this.entityClass = (Class<E>) ((ParameterizedType) getClass().
|
||||
getGenericSuperclass()).getActualTypeArguments()[0];
|
||||
this.entityClass = (Class<E>) ((ParameterizedType) getClass()
|
||||
.getGenericSuperclass()).getActualTypeArguments()[0];
|
||||
}
|
||||
|
||||
protected Session getSession() {
|
||||
|
|
@ -52,9 +52,9 @@ public class GenericDaoHibernate<E, PK extends Serializable>
|
|||
}
|
||||
|
||||
protected DataAccessException convertHibernateAccessException(
|
||||
HibernateException e) {
|
||||
HibernateException e) {
|
||||
|
||||
return SessionFactoryUtils.convertHibernateAccessException(e);
|
||||
return SessionFactoryUtils.convertHibernateAccessException(e);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -91,10 +91,9 @@ public class GenericDaoHibernate<E, PK extends Serializable>
|
|||
|
||||
try {
|
||||
|
||||
return getSession().createCriteria(entityClass).
|
||||
add(Restrictions.idEq(id)).
|
||||
setProjection(Projections.id()).
|
||||
uniqueResult() != null;
|
||||
return getSession().createCriteria(entityClass).add(
|
||||
Restrictions.idEq(id)).setProjection(Projections.id())
|
||||
.uniqueResult() != null;
|
||||
|
||||
} catch (HibernateException e) {
|
||||
throw convertHibernateAccessException(e);
|
||||
|
|
@ -112,4 +111,10 @@ public class GenericDaoHibernate<E, PK extends Serializable>
|
|||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends E> List<T> list(Class<T> klass) {
|
||||
return getSession().createCriteria(klass).list();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,12 +2,12 @@ package org.navalplanner.business.common.daos.impl;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.criterion.Projections;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
|
||||
import org.navalplanner.business.common.daos.IGenericDao;
|
||||
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
|
@ -33,8 +33,8 @@ import org.springframework.orm.hibernate3.HibernateTemplate;
|
|||
* @param <E> Entity class
|
||||
* @param <PK> Primary key class
|
||||
*/
|
||||
public class GenericDaoHibernateTemplate<E, PK extends Serializable>
|
||||
implements IGenericDao<E, PK> {
|
||||
public class GenericDaoHibernateTemplate<E, PK extends Serializable> implements
|
||||
IGenericDao<E, PK> {
|
||||
|
||||
private Class<E> entityClass;
|
||||
|
||||
|
|
@ -42,8 +42,8 @@ public class GenericDaoHibernateTemplate<E, PK extends Serializable>
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
public GenericDaoHibernateTemplate() {
|
||||
this.entityClass = (Class<E>) ((ParameterizedType) getClass().
|
||||
getGenericSuperclass()).getActualTypeArguments()[0];
|
||||
this.entityClass = (Class<E>) ((ParameterizedType) getClass()
|
||||
.getGenericSuperclass()).getActualTypeArguments()[0];
|
||||
}
|
||||
|
||||
protected HibernateTemplate getHibernateTemplate() {
|
||||
|
|
@ -76,10 +76,9 @@ public class GenericDaoHibernateTemplate<E, PK extends Serializable>
|
|||
|
||||
return (Boolean) hibernateTemplate.execute(new HibernateCallback() {
|
||||
public Object doInHibernate(Session session) {
|
||||
return session.createCriteria(entityClass).
|
||||
add(Restrictions.idEq(id)).
|
||||
setProjection(Projections.id()).
|
||||
uniqueResult() != null;
|
||||
return session.createCriteria(entityClass).add(
|
||||
Restrictions.idEq(id)).setProjection(Projections.id())
|
||||
.uniqueResult() != null;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -89,4 +88,10 @@ public class GenericDaoHibernateTemplate<E, PK extends Serializable>
|
|||
hibernateTemplate.delete(find(id));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends E> List<T> list(Class<T> klass) {
|
||||
return hibernateTemplate.loadAll(klass);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
package org.navalplanner.business.resources.services;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
import org.navalplanner.business.resources.entities.Worker;
|
||||
|
||||
/**
|
||||
* Interface for the resource management service.
|
||||
|
|
@ -12,14 +15,14 @@ import org.navalplanner.business.resources.entities.Resource;
|
|||
public interface ResourceService {
|
||||
|
||||
/**
|
||||
* It updates or inserts the resource passed as a parameter. If the
|
||||
* resource is a composite resource, updating or inserting is cascaded to
|
||||
* the resources contained in it.
|
||||
* It updates or inserts the resource passed as a parameter. If the resource
|
||||
* is a composite resource, updating or inserting is cascaded to the
|
||||
* resources contained in it.
|
||||
*/
|
||||
public void saveResource(Resource resource);
|
||||
|
||||
public Resource findResource(Long resourceId)
|
||||
throws InstanceNotFoundException;
|
||||
throws InstanceNotFoundException;
|
||||
|
||||
/**
|
||||
* It adds a resource to a resource group. It the resource already belongs
|
||||
|
|
@ -36,6 +39,8 @@ public interface ResourceService {
|
|||
* resources contained in it are not removed.
|
||||
*/
|
||||
public void removeResource(Long resourceId)
|
||||
throws InstanceNotFoundException;
|
||||
throws InstanceNotFoundException;
|
||||
|
||||
public List<Worker> getWorkers();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
package org.navalplanner.business.resources.services.impl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
|
||||
import org.navalplanner.business.resources.daos.IResourceDao;
|
||||
import org.navalplanner.business.resources.daos.IResourceGroupDao;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
import org.navalplanner.business.resources.entities.ResourceGroup;
|
||||
import org.navalplanner.business.resources.entities.Worker;
|
||||
import org.navalplanner.business.resources.services.ResourceService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
|
@ -31,14 +34,14 @@ public class ResourceServiceImpl implements ResourceService {
|
|||
|
||||
@Transactional(readOnly = true)
|
||||
public Resource findResource(Long resourceId)
|
||||
throws InstanceNotFoundException {
|
||||
throws InstanceNotFoundException {
|
||||
|
||||
return resourceDao.find(resourceId);
|
||||
|
||||
}
|
||||
|
||||
public void addResourceToResourceGroup(Long resourceId,
|
||||
Long resourceGroupId) throws InstanceNotFoundException {
|
||||
public void addResourceToResourceGroup(Long resourceId, Long resourceGroupId)
|
||||
throws InstanceNotFoundException {
|
||||
|
||||
ResourceGroup resourceGroup = resourceGroupDao.find(resourceGroupId);
|
||||
|
||||
|
|
@ -48,16 +51,20 @@ public class ResourceServiceImpl implements ResourceService {
|
|||
|
||||
@Transactional(readOnly = true)
|
||||
public int getResourceDailyCapacity(Long resourceId)
|
||||
throws InstanceNotFoundException {
|
||||
throws InstanceNotFoundException {
|
||||
|
||||
return resourceDao.find(resourceId).getDailyCapacity();
|
||||
|
||||
}
|
||||
|
||||
public void removeResource(Long resourceId)
|
||||
throws InstanceNotFoundException {
|
||||
throws InstanceNotFoundException {
|
||||
|
||||
resourceDao.find(resourceId).remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Worker> getWorkers() {
|
||||
return resourceDao.list(Worker.class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
*
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations={BUSINESS_SPRING_CONFIG_FILE,
|
||||
BUSINESS_SPRING_CONFIG_TEST_FILE})
|
||||
@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE,
|
||||
BUSINESS_SPRING_CONFIG_TEST_FILE })
|
||||
@Transactional
|
||||
public class ResourceServiceTest {
|
||||
|
||||
|
|
@ -40,13 +40,13 @@ public class ResourceServiceTest {
|
|||
|
||||
@Test
|
||||
public void testAddResourceToResourceGroup()
|
||||
throws InstanceNotFoundException {
|
||||
throws InstanceNotFoundException {
|
||||
|
||||
/* Two workers. One of them belongs to a resource group. */
|
||||
Worker worker1 = new Worker("worker-1", "worker-1-surname",
|
||||
"11111111A", 8);
|
||||
"11111111A", 8);
|
||||
Worker worker2 = new Worker("worker-2", "worker-2-surname",
|
||||
"22222222B", 7);
|
||||
"22222222B", 7);
|
||||
ResourceGroup resourceGroup1 = new ResourceGroup();
|
||||
resourceGroup1.addResource(worker1);
|
||||
resourceService.saveResource(resourceGroup1); // worker1 is also saved.
|
||||
|
|
@ -58,13 +58,13 @@ public class ResourceServiceTest {
|
|||
|
||||
/* Add workers to resource group. */
|
||||
resourceService.addResourceToResourceGroup(worker1.getId(),
|
||||
resourceGroup2.getId());
|
||||
resourceGroup2.getId());
|
||||
resourceService.addResourceToResourceGroup(worker2.getId(),
|
||||
resourceGroup2.getId());
|
||||
resourceGroup2.getId());
|
||||
|
||||
/* Check resource group. */
|
||||
ResourceGroup resourceGroup = (ResourceGroup)
|
||||
resourceService.findResource(resourceGroup2.getId());
|
||||
ResourceGroup resourceGroup = (ResourceGroup) resourceService
|
||||
.findResource(resourceGroup2.getId());
|
||||
|
||||
assertEquals(2, resourceGroup.getResources().size());
|
||||
assertTrue(resourceGroup.getResources().contains(worker1));
|
||||
|
|
@ -76,23 +76,22 @@ public class ResourceServiceTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testGetResourceDailyCapacity()
|
||||
throws InstanceNotFoundException {
|
||||
public void testGetResourceDailyCapacity() throws InstanceNotFoundException {
|
||||
|
||||
/* Three workers. */
|
||||
Worker worker1 = new Worker("worker-1", "worker-1-surname",
|
||||
"11111111A", 8);
|
||||
"11111111A", 8);
|
||||
Worker worker2 = new Worker("worker-2", "worker-2-surname",
|
||||
"22222222B", 7);
|
||||
"22222222B", 7);
|
||||
Worker worker3 = new Worker("worker-3", "worker-3-surname",
|
||||
"33333333C", 6);
|
||||
"33333333C", 6);
|
||||
|
||||
/* A group of two workers. */
|
||||
ResourceGroup resourceGroup1 = new ResourceGroup();
|
||||
Worker worker4 = new Worker("worker-4", "worker-4-surname",
|
||||
"44444444D", 5);
|
||||
"44444444D", 5);
|
||||
Worker worker5 = new Worker("worker-5", "worker-5-surname",
|
||||
"55555555E", 4);
|
||||
"55555555E", 4);
|
||||
resourceGroup1.addResource(worker4);
|
||||
resourceGroup1.addResource(worker5);
|
||||
|
||||
|
|
@ -107,17 +106,16 @@ public class ResourceServiceTest {
|
|||
resourceGroup2.addResource(resourceGroup1);
|
||||
|
||||
/* Calculate total daily capacity. */
|
||||
int totalDailyCapacity =
|
||||
worker1.getDailyCapacity() + worker2.getDailyCapacity() +
|
||||
worker3.getDailyCapacity() + worker4.getDailyCapacity() +
|
||||
worker5.getDailyCapacity();
|
||||
int totalDailyCapacity = worker1.getDailyCapacity()
|
||||
+ worker2.getDailyCapacity() + worker3.getDailyCapacity()
|
||||
+ worker4.getDailyCapacity() + worker5.getDailyCapacity();
|
||||
|
||||
/* Save the second group (and in consequence all resources). */
|
||||
resourceService.saveResource(resourceGroup2);
|
||||
|
||||
/* Test ResourceService's getResourceDailyCapacity. */
|
||||
int resourceGroupDailyCapacity =
|
||||
resourceService.getResourceDailyCapacity(resourceGroup2.getId());
|
||||
int resourceGroupDailyCapacity = resourceService
|
||||
.getResourceDailyCapacity(resourceGroup2.getId());
|
||||
|
||||
assertEquals(totalDailyCapacity, resourceGroupDailyCapacity);
|
||||
|
||||
|
|
@ -129,11 +127,11 @@ public class ResourceServiceTest {
|
|||
/* A group of three workers. */
|
||||
ResourceGroup resourceGroup = new ResourceGroup();
|
||||
Worker worker1 = new Worker("worker-1", "worker-2-surname",
|
||||
"11111111A", 8);
|
||||
"11111111A", 8);
|
||||
Worker worker2 = new Worker("worker-2", "worker-3-surname",
|
||||
"22222222B", 6);
|
||||
"22222222B", 6);
|
||||
Worker worker3 = new Worker("worker-3", "worker-3-surname",
|
||||
"33333333C", 4);
|
||||
"33333333C", 4);
|
||||
resourceGroup.addResource(worker1);
|
||||
resourceGroup.addResource(worker2);
|
||||
resourceGroup.addResource(worker3);
|
||||
|
|
@ -146,8 +144,8 @@ public class ResourceServiceTest {
|
|||
assertFalse(resourceDao.exists(worker3.getId()));
|
||||
|
||||
/*
|
||||
* Check worker 3 is not in resource group and the other workers
|
||||
* are still in the group.
|
||||
* Check worker 3 is not in resource group and the other workers are
|
||||
* still in the group.
|
||||
*/
|
||||
assertFalse(resourceGroup.getResources().contains(worker3));
|
||||
assertTrue(resourceGroup.getResources().contains(worker1));
|
||||
|
|
@ -177,4 +175,24 @@ public class ResourceServiceTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListWorkers() throws Exception {
|
||||
ResourceGroup resourceGroup = new ResourceGroup();
|
||||
Worker worker1 = new Worker("worker-1", "worker-2-surname",
|
||||
"11111111A", 8);
|
||||
Worker worker2 = new Worker("worker-2", "worker-3-surname",
|
||||
"22222222B", 6);
|
||||
Worker worker3 = new Worker("worker-3", "worker-3-surname",
|
||||
"33333333C", 4);
|
||||
resourceGroup.addResource(worker1);
|
||||
resourceGroup.addResource(worker2);
|
||||
resourceService.saveResource(resourceGroup);
|
||||
assertEquals(
|
||||
"Two workers has been created when saving the resource group",
|
||||
2, resourceService.getWorkers().size());
|
||||
resourceService.saveResource(worker3);
|
||||
assertEquals("Three workers has been created", 3, resourceService
|
||||
.getWorkers().size());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<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>
|
||||
|
|
@ -55,6 +54,14 @@
|
|||
<groupId>org.navalplanner</groupId>
|
||||
<artifactId>navalplanner-business</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymock</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
package org.navalplanner.web.common;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.zkoss.zk.ui.Component;
|
||||
|
||||
/**
|
||||
* Utility for enforcing that only one of the supplied component is visible. <br />
|
||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
*/
|
||||
public class OnlyOneVisible {
|
||||
|
||||
private List<Component> components;
|
||||
|
||||
public OnlyOneVisible(Component... components) {
|
||||
this.components = Arrays.asList(components);
|
||||
showOnly(null);
|
||||
}
|
||||
|
||||
public void showOnly(Component component) {
|
||||
for (Component c : components) {
|
||||
c.setVisible(component != null && c.equals(component));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package org.navalplanner.web.common;
|
||||
|
||||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zkplus.databind.DataBinder;
|
||||
|
||||
/**
|
||||
* Utilities class. <br />
|
||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
*/
|
||||
public class Util {
|
||||
|
||||
public static void reloadBindings(Component reload) {
|
||||
DataBinder binder = Util.getBinder(reload);
|
||||
if (binder != null) {
|
||||
binder.loadComponent(reload);
|
||||
}
|
||||
}
|
||||
|
||||
public static DataBinder getBinder(Component component) {
|
||||
return (DataBinder) component.getVariable("binder", false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package org.navalplanner.web.resources;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.navalplanner.business.resources.entities.Worker;
|
||||
|
||||
/**
|
||||
* Interface for workerModel. <br />
|
||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
*/
|
||||
public interface IWorkerModel {
|
||||
|
||||
Worker createNewInstance();
|
||||
|
||||
void save(Worker worker);
|
||||
|
||||
List<Worker> getWorkers();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
package org.navalplanner.web.resources;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.navalplanner.business.resources.entities.Worker;
|
||||
import org.navalplanner.web.common.OnlyOneVisible;
|
||||
import org.navalplanner.web.common.Util;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.util.GenericForwardComposer;
|
||||
import org.zkoss.zul.api.Window;
|
||||
|
||||
/**
|
||||
* Controller for {@link Worker} resource <br />
|
||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
*/
|
||||
public class WorkerCRUDController extends GenericForwardComposer {
|
||||
|
||||
private static final Log LOG = LogFactory
|
||||
.getLog(WorkerCRUDController.class);
|
||||
|
||||
private Window createWindow;
|
||||
|
||||
private Window listWindow;
|
||||
|
||||
private Window editWindow;
|
||||
|
||||
private IWorkerModel workerModel;
|
||||
|
||||
private Worker worker;
|
||||
|
||||
private OnlyOneVisible visibility;
|
||||
|
||||
public WorkerCRUDController() {
|
||||
|
||||
}
|
||||
|
||||
public WorkerCRUDController(Window createWindow, Window listWindow,
|
||||
Window editWindow, IWorkerModel workerModel) {
|
||||
this.createWindow = createWindow;
|
||||
this.listWindow = listWindow;
|
||||
this.editWindow = editWindow;
|
||||
this.workerModel = workerModel;
|
||||
}
|
||||
|
||||
public Worker getWorker() {
|
||||
if (worker == null) {
|
||||
worker = workerModel.createNewInstance();
|
||||
}
|
||||
return worker;
|
||||
}
|
||||
|
||||
public List<Worker> getWorkers() {
|
||||
return workerModel.getWorkers();
|
||||
}
|
||||
|
||||
public void save() {
|
||||
workerModel.save(worker);
|
||||
getVisibility().showOnly(listWindow);
|
||||
Util.reloadBindings(listWindow);
|
||||
worker = null;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
getVisibility().showOnly(listWindow);
|
||||
worker = null;
|
||||
}
|
||||
|
||||
public void goToEditForm(Worker worker) {
|
||||
if (worker == null)
|
||||
throw new IllegalArgumentException("worker cannot be null");
|
||||
this.worker = worker;
|
||||
getVisibility().showOnly(editWindow);
|
||||
Util.reloadBindings(editWindow);
|
||||
}
|
||||
|
||||
public void goToCreateForm() {
|
||||
worker = workerModel.createNewInstance();
|
||||
getVisibility().showOnly(createWindow);
|
||||
Util.reloadBindings(createWindow);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAfterCompose(Component comp) throws Exception {
|
||||
super.doAfterCompose(comp);
|
||||
comp.setVariable("controller", this, true);
|
||||
getVisibility().showOnly(listWindow);
|
||||
}
|
||||
|
||||
private OnlyOneVisible getVisibility() {
|
||||
if (visibility == null) {
|
||||
visibility = new OnlyOneVisible(listWindow, editWindow,
|
||||
createWindow);
|
||||
}
|
||||
return visibility;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package org.navalplanner.web.resources;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.navalplanner.business.resources.entities.Worker;
|
||||
import org.navalplanner.business.resources.services.ResourceService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* Model for worker <br />
|
||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
*/
|
||||
public class WorkerModel implements IWorkerModel {
|
||||
|
||||
private final ResourceService resourceService;
|
||||
|
||||
@Autowired
|
||||
public WorkerModel(ResourceService resourceService) {
|
||||
if (resourceService == null)
|
||||
throw new IllegalArgumentException("resourceService cannot be null");
|
||||
this.resourceService = resourceService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Worker createNewInstance() {
|
||||
return new Worker();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(Worker worker) {
|
||||
resourceService.saveResource(worker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Worker> getWorkers() {
|
||||
return resourceService.getWorkers();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,16 +1,19 @@
|
|||
<?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:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx" 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.5.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
|
||||
|
||||
<!-- For enabling annotation-based configuration (in particular, required
|
||||
for "@Autowired") -->
|
||||
<context:annotation-config/>
|
||||
<!--
|
||||
For enabling annotation-based configuration (in particular,
|
||||
required for "@Autowired")
|
||||
-->
|
||||
<context:annotation-config />
|
||||
|
||||
<bean id="workerModel" class="org.navalplanner.web.resources.WorkerModel"
|
||||
scope="prototype" />
|
||||
</beans>
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<window id="${arg.top_id}" title="${arg.title}">
|
||||
<grid fixedLayout="true">
|
||||
<columns>
|
||||
<column label="Type" width="150px" />
|
||||
<column label="Content" />
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<label value="first_name" width="150px" />
|
||||
<textbox value="@{controller.worker.firstName}"
|
||||
width="150px" />
|
||||
</row>
|
||||
<row>
|
||||
<label value="last_name" width="150px" />
|
||||
<textbox value="@{controller.worker.surname}"
|
||||
width="150px" />
|
||||
</row>
|
||||
<row>
|
||||
<label value="nif" width="150px" />
|
||||
<textbox value="@{controller.worker.nif}" width="150px" />
|
||||
</row>
|
||||
<row>
|
||||
<label value="daily_hours" width="150px" />
|
||||
<textbox value="@{controller.worker.dailyHours}"
|
||||
width="150px" />
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<button onClick="controller.save();" label="${arg.save_button_label}" />
|
||||
<button onClick="controller.cancel();" label="${arg.cancel_button_label}" />
|
||||
</window>
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<window id="${arg.top_id}" title="List">
|
||||
<grid id="listing" model="@{controller.workers}" mold="paging"
|
||||
pageSize="5">
|
||||
<columns>
|
||||
<column label="First Name" />
|
||||
<column label="Surname" />
|
||||
<column label="nif" />
|
||||
<column label="daily_hours" />
|
||||
<column label="operations" />
|
||||
</columns>
|
||||
<rows>
|
||||
<row self="@{each='worker'}" value="@{worker}">
|
||||
<label value="@{worker.firstName}" />
|
||||
<label value="@{worker.surname}" />
|
||||
<label value="@{worker.nif}" />
|
||||
<label value="@{worker.dailyHours}" />
|
||||
<hbox>
|
||||
<button label="Edit"
|
||||
onClick="controller.goToEditForm(self.getParent().getParent().value);">
|
||||
</button>
|
||||
</hbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<button id="show_create_form" onClick="controller.goToCreateForm();"
|
||||
label="Create">
|
||||
</button>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
|
||||
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
|
||||
<?page id="Create"?>
|
||||
<?init class="org.zkoss.zk.ui.util.Composition" arg0="/common/layout/template.zul"?>
|
||||
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
|
||||
<?component name="list" inline="true" macroURI="_list.zul"?>
|
||||
<?component name="edition" inline="true" macroURI="_edition.zul"?>
|
||||
<zk>
|
||||
<window title="Worker" self="@{define(content)}"
|
||||
apply="org.navalplanner.web.resources.WorkerCRUDController">
|
||||
<list top_id="listWindow" />
|
||||
<edition top_id="createWindow" title="Create"
|
||||
save_button_label="Save" cancel_button_label="Cancel" />
|
||||
<edition top_id="editWindow" title="Edit"
|
||||
save_button_label="Save" cancel_button_label="Cancel" />
|
||||
</window>
|
||||
</zk>
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
package org.navalplanner.web.resources;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.createNiceMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.navalplanner.business.resources.entities.Worker;
|
||||
import org.zkoss.zul.api.Window;
|
||||
|
||||
/**
|
||||
* Tests for {@link WorkerCRUDController} <br />
|
||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
*/
|
||||
public class WorkerCRUDControllerTest {
|
||||
|
||||
private Window createWindow;
|
||||
private Window listWindow;
|
||||
private Window editWindow;
|
||||
|
||||
private WorkerCRUDController createControllerForModel(
|
||||
IWorkerModel workerModel) {
|
||||
createWindow = createNiceMock(Window.class);
|
||||
listWindow = createNiceMock(Window.class);
|
||||
editWindow = createNiceMock(Window.class);
|
||||
|
||||
WorkerCRUDController workerCRUDController = new WorkerCRUDController(
|
||||
createWindow, listWindow, editWindow, workerModel);
|
||||
return workerCRUDController;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSave() throws Exception {
|
||||
IWorkerModel workerModel = createMock(IWorkerModel.class);
|
||||
Worker workerToReturn = new Worker();
|
||||
|
||||
WorkerCRUDController workerCRUDController = createControllerForModel(workerModel);
|
||||
replay(createWindow, listWindow, editWindow);
|
||||
// expectations
|
||||
expect(workerModel.createNewInstance()).andReturn(workerToReturn);
|
||||
workerModel.save(workerToReturn);
|
||||
replay(workerModel);
|
||||
// action
|
||||
workerCRUDController.goToCreateForm();
|
||||
workerCRUDController.save();
|
||||
// verify
|
||||
verify(workerModel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGoToSaveAndThenCancel() {
|
||||
IWorkerModel workerModel = createMock(IWorkerModel.class);
|
||||
Worker workerToReturn = new Worker();
|
||||
// expectations
|
||||
WorkerCRUDController workerCRUDController = createControllerForModel(workerModel);
|
||||
expect(workerModel.createNewInstance()).andReturn(workerToReturn);
|
||||
expect(createWindow.setVisible(true)).andReturn(false);
|
||||
expect(createWindow.setVisible(false)).andReturn(true);
|
||||
expect(listWindow.setVisible(true)).andReturn(false);
|
||||
replay(createWindow, listWindow, editWindow, workerModel);
|
||||
// actions
|
||||
workerCRUDController.goToCreateForm();
|
||||
workerCRUDController.cancel();
|
||||
// verify
|
||||
verify(workerModel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEditWorker() throws Exception {
|
||||
IWorkerModel workerModel = createMock(IWorkerModel.class);
|
||||
WorkerCRUDController workerCRUDController = createControllerForModel(workerModel);
|
||||
List<Worker> workersToReturn = new ArrayList<Worker>(Arrays.asList(
|
||||
new Worker("firstName", "surname", "nif", 4), new Worker(
|
||||
"firstName", "surname", "nif", 4)));
|
||||
// expectations
|
||||
expect(workerModel.getWorkers()).andReturn(workersToReturn);
|
||||
expect(editWindow.setVisible(true)).andReturn(false);
|
||||
workerModel.save(workersToReturn.get(0));
|
||||
replay(createWindow, listWindow, editWindow, workerModel);
|
||||
// perform actions
|
||||
List<Worker> workers = workerCRUDController.getWorkers();
|
||||
assertEquals(workersToReturn, workers);
|
||||
workerCRUDController.goToEditForm(workers.get(0));
|
||||
workerCRUDController.save();
|
||||
// verify
|
||||
verify(workerModel, editWindow);
|
||||
}
|
||||
}
|
||||
147
pom.xml
147
pom.xml
|
|
@ -1,5 +1,4 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<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>
|
||||
|
|
@ -9,7 +8,9 @@
|
|||
<version>1.0.0</version>
|
||||
<name>Naval Planner</name>
|
||||
|
||||
<!-- =================================================================== -->
|
||||
<!--
|
||||
===================================================================
|
||||
-->
|
||||
<!-- Modules -->
|
||||
<modules>
|
||||
<module>navalplanner-business</module>
|
||||
|
|
@ -17,10 +18,13 @@
|
|||
<module>navalplanner-webapp</module>
|
||||
</modules>
|
||||
|
||||
<!-- =================================================================== -->
|
||||
<!-- Default values for properties. These default values are expected to be
|
||||
valid for most profiles. Specific profiles can overwrite values when
|
||||
necessary.
|
||||
<!--
|
||||
===================================================================
|
||||
-->
|
||||
<!--
|
||||
Default values for properties. These default values are expected
|
||||
to be valid for most profiles. Specific profiles can overwrite
|
||||
values when necessary.
|
||||
-->
|
||||
<properties>
|
||||
<!-- Data source properties -->
|
||||
|
|
@ -31,46 +35,34 @@
|
|||
<testDataSource.password>${dataSource.password}</testDataSource.password>
|
||||
</properties>
|
||||
|
||||
<!-- =================================================================== -->
|
||||
<!-- Profiles.
|
||||
|
||||
* The build is always executed by selecting at least two non-exclusive
|
||||
profiles. By default, such profiles are "dev" and "postgresql"
|
||||
(meaning "use PostgreSQL assuming a development environment").
|
||||
|
||||
* General profiles. There are two general (database-independent)
|
||||
profiles: "dev" and "prod". The former is used for development
|
||||
(including testing) and the latter is used for production (including
|
||||
testing). As shown below, two dataSources (databases schemas) are
|
||||
used in both profiles: one for running (dataSource) and another one
|
||||
for the Maven test fase (testDataSource). Note the Maven test fase
|
||||
is executed both with development and production profiles.
|
||||
|
||||
* Database-specific profiles. There is a profile for each supported
|
||||
database.
|
||||
|
||||
* Specific profiles can be defined to better adapt to a particular
|
||||
environment by overwriting/adding properties and/or including other
|
||||
chunks of valid XML.
|
||||
|
||||
* Usage:
|
||||
|
||||
+ mvn <<goal>> => Execute <<goal>> with default profiles.
|
||||
+ mvn -Pdev,<<database>> <<goal> => Execute <<goal>> with "dev"
|
||||
and <<database>> profiles.
|
||||
+ mvn -Pprod,<<database>> <<goal>> => Execute <<goal>> with
|
||||
"prod" and <<database>> profiles.
|
||||
+ Note that when using -P option all desired profiles must be
|
||||
specified (e.g. "-Pprod" with the intention to select "prod" and
|
||||
the default database profile is not correct;
|
||||
"-Pprod,<<database>>" must be used instead).
|
||||
|
||||
* Examples:
|
||||
|
||||
+ mvn <<goal>>
|
||||
+ mvn -Ppostgresql,prod <<goal>>
|
||||
+ mvn -Ppostgresql,dev <<goal>>
|
||||
|
||||
<!--
|
||||
===================================================================
|
||||
-->
|
||||
<!--
|
||||
Profiles. * The build is always executed by selecting at least
|
||||
two non-exclusive profiles. By default, such profiles are "dev"
|
||||
and "postgresql" (meaning "use PostgreSQL assuming a development
|
||||
environment"). * General profiles. There are two general
|
||||
(database-independent) profiles: "dev" and "prod". The former is
|
||||
used for development (including testing) and the latter is used
|
||||
for production (including testing). As shown below, two
|
||||
dataSources (databases schemas) are used in both profiles: one
|
||||
for running (dataSource) and another one for the Maven test fase
|
||||
(testDataSource). Note the Maven test fase is executed both with
|
||||
development and production profiles. * Database-specific
|
||||
profiles. There is a profile for each supported database. *
|
||||
Specific profiles can be defined to better adapt to a particular
|
||||
environment by overwriting/adding properties and/or including
|
||||
other chunks of valid XML. * Usage: + mvn <<goal>> => Execute
|
||||
<<goal>> with default profiles. + mvn -Pdev,<<database>> <<goal>
|
||||
=> Execute <<goal>> with "dev" and <<database>> profiles. + mvn
|
||||
-Pprod,<<database>> <<goal>> => Execute <<goal>> with "prod" and
|
||||
<<database>> profiles. + Note that when using -P option all
|
||||
desired profiles must be specified (e.g. "-Pprod" with the
|
||||
intention to select "prod" and the default database profile is
|
||||
not correct; "-Pprod,<<database>>" must be used instead). *
|
||||
Examples: + mvn <<goal>> + mvn -Ppostgresql,prod <<goal>> + mvn
|
||||
-Ppostgresql,dev <<goal>>
|
||||
-->
|
||||
<profiles>
|
||||
|
||||
|
|
@ -153,7 +145,7 @@
|
|||
<jdbcDriver.className>org.hsqldb.jdbcDriver</jdbcDriver.className>
|
||||
<!-- Data source properties -->
|
||||
<dataSource.user>sa</dataSource.user>
|
||||
<dataSource.password/>
|
||||
<dataSource.password />
|
||||
<dataSource.url>jdbc:hsqldb:${java.io.tmpdir}/naval${navalplanner.mode};shutdown=true</dataSource.url>
|
||||
<testDataSource.url>jdbc:hsqldb:${java.io.tmpdir}/naval${navalplanner.mode}test;shutdown=true</testDataSource.url>
|
||||
<!-- Hibernate properties -->
|
||||
|
|
@ -163,7 +155,9 @@
|
|||
|
||||
</profiles>
|
||||
|
||||
<!-- =================================================================== -->
|
||||
<!--
|
||||
===================================================================
|
||||
-->
|
||||
<!-- Dependency management -->
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
|
@ -181,14 +175,25 @@
|
|||
<version>3.2.6.ga</version>
|
||||
</dependency>
|
||||
<!-- JUnit -->
|
||||
<!-- IMPORTANT: Spring TestContext 2.5.x is not compatible with
|
||||
JUnit 4.5. -->
|
||||
<!--
|
||||
IMPORTANT: Spring TestContext 2.5.x is not compatible
|
||||
with JUnit 4.5.
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Easy mock -->
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymock</artifactId>
|
||||
<version>2.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
|
|
@ -264,8 +269,10 @@
|
|||
<!-- Filtering -->
|
||||
<resources>
|
||||
|
||||
<!-- Apply filtering to files matching the following expressions
|
||||
in src/main/resources. -->
|
||||
<!--
|
||||
Apply filtering to files matching the following
|
||||
expressions in src/main/resources.
|
||||
-->
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
|
|
@ -275,8 +282,10 @@
|
|||
</includes>
|
||||
</resource>
|
||||
|
||||
<!-- Continue considering resources the files in src/main/resources,
|
||||
but without applying filtering. -->
|
||||
<!--
|
||||
Continue considering resources the files in
|
||||
src/main/resources, but without applying filtering.
|
||||
-->
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
|
|
@ -294,8 +303,10 @@
|
|||
|
||||
<testResources>
|
||||
|
||||
<!-- Apply filtering to files matching the following expressions
|
||||
in src/test/resources. -->
|
||||
<!--
|
||||
Apply filtering to files matching the following
|
||||
expressions in src/test/resources.
|
||||
-->
|
||||
<testResource>
|
||||
<directory>src/test/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
|
|
@ -305,8 +316,10 @@
|
|||
</includes>
|
||||
</testResource>
|
||||
|
||||
<!-- Continue considering resources the files in src/test/resources,
|
||||
but without applying filtering. -->
|
||||
<!--
|
||||
Continue considering resources the files in
|
||||
src/test/resources, but without applying filtering.
|
||||
-->
|
||||
<testResource>
|
||||
<directory>src/test/resources</directory>
|
||||
</testResource>
|
||||
|
|
@ -361,17 +374,17 @@
|
|||
|
||||
<!-- Log to the console. -->
|
||||
<requestLog implementation="org.mortbay.jetty.NCSARequestLog">
|
||||
<!-- This do anything for Jetty, but is a workaround
|
||||
for a Maven bug that prevents the requestLog from
|
||||
being set. -->
|
||||
<!--
|
||||
This do anything for Jetty, but is a
|
||||
workaround for a Maven bug that prevents the
|
||||
requestLog from being set.
|
||||
-->
|
||||
<append>true</append>
|
||||
</requestLog>
|
||||
<!--
|
||||
<connectors>
|
||||
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
|
||||
<port>9090</port>
|
||||
</connector>
|
||||
</connectors>
|
||||
<connectors> <connector
|
||||
implementation="org.mortbay.jetty.nio.SelectChannelConnector">
|
||||
<port>9090</port> </connector> </connectors>
|
||||
-->
|
||||
</configuration>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue