From d22215fad8c0d66910bcd79829d85462819f764d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Gonz=C3=A1lez=20Fern=C3=A1ndez?= Date: Tue, 19 May 2009 21:13:16 +0200 Subject: [PATCH] ItEr09S09AdministracionGrupos: Creates and edits criterions grouped by CriterionType. The CriterionType tells if the criterions belonging to that type can be edited or more can be added. --- .../bootstrap/CriterionsBootstrap.java | 45 +++-- .../resources/entities/Criterion.java | 11 +- .../resources/entities/CriterionTypeBase.java | 30 ++- .../resources/entities/ICriterionType.java | 6 + .../entities/PredefinedCriterionTypes.java | 27 ++- .../resources/services/CriterionService.java | 2 + .../services/impl/CriterionServiceImpl.java | 12 ++ .../test/resources/entities/ResourceTest.java | 2 +- .../services/CriterionServiceTest.java | 83 ++++++-- .../web/common/IMessagesForUser.java | 3 + .../web/common/MessagesForUser.java | 19 +- .../resources/CriterionAdminController.java | 185 ++++++++++++++++++ .../web/resources/CriterionsModel.java | 136 +++++++++++++ .../web/resources/ICriterionsModel.java | 40 ++++ .../navalplanner-webapp-spring-config.xml | 2 + .../main/webapp/WEB-INF/i3-label.properties | 1 + .../webapp/WEB-INF/i3-label_en_US.properties | 1 + .../main/webapp/common/layout/template.zul | 2 + .../webapp/resources/criterions/_edition.zul | 15 ++ .../webapp/resources/criterions/_list.zul | 7 + .../resources/criterions/criterions.zul | 22 +++ 21 files changed, 612 insertions(+), 39 deletions(-) create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/web/resources/CriterionAdminController.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/web/resources/CriterionsModel.java create mode 100644 navalplanner-webapp/src/main/java/org/navalplanner/web/resources/ICriterionsModel.java create mode 100644 navalplanner-webapp/src/main/webapp/resources/criterions/_edition.zul create mode 100644 navalplanner-webapp/src/main/webapp/resources/criterions/_list.zul create mode 100644 navalplanner-webapp/src/main/webapp/resources/criterions/criterions.zul diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/bootstrap/CriterionsBootstrap.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/bootstrap/CriterionsBootstrap.java index aa8b1e3fb..900fe02ff 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/bootstrap/CriterionsBootstrap.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/bootstrap/CriterionsBootstrap.java @@ -1,17 +1,16 @@ package org.navalplanner.business.resources.bootstrap; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import org.navalplanner.business.IDataBootstrap; import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.ICriterionType; import org.navalplanner.business.resources.services.CriterionService; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -26,20 +25,40 @@ public class CriterionsBootstrap implements IDataBootstrap { @Autowired private CriterionService criterionService; - + @Autowired private List providers; + public List> getTypes() { + ArrayList> result = new ArrayList>(); + for (ICriterionTypeProvider provider : providers) { + result.addAll(provider.getRequiredCriterions().keySet()); + } + return result; + } + @Override public void loadRequiredData() { - for (ICriterionTypeProvider provider: providers) { - for (Entry, List> entry : provider - .getRequiredCriterions() - .entrySet()) { - for (Criterion criterion : entry.getValue()) { - criterionService.createIfNotExists(criterion); - } + Map, List> typesWithCriterions = getTypesWithCriterions(); + for (Entry, List> entry : typesWithCriterions + .entrySet()) { + for (Criterion criterion : entry.getValue()) { + criterionService.createIfNotExists(criterion); } } - } + } + + public Map, List> getTypesWithCriterions() { + HashMap, List> result = new HashMap, List>(); + for (ICriterionTypeProvider provider : providers) { + for (Entry, List> entry : provider + .getRequiredCriterions().entrySet()) { + if (!result.containsKey(entry.getKey())) { + result.put(entry.getKey(), new ArrayList()); + } + result.get(entry.getKey()).addAll(entry.getValue()); + } + } + return result; + } } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java index 9a043c67b..4d8c7302e 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java @@ -58,8 +58,7 @@ public class Criterion implements ICriterion, Serializable { @Override public int hashCode() { - return new HashCodeBuilder().append(name) - .append(type).toHashCode(); + return new HashCodeBuilder().append(name).append(type).toHashCode(); } @Override @@ -72,4 +71,12 @@ public class Criterion implements ICriterion, Serializable { return false; } + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionTypeBase.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionTypeBase.java index e0de3d86c..3ab08da71 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionTypeBase.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionTypeBase.java @@ -1,5 +1,7 @@ package org.navalplanner.business.resources.entities; +import org.apache.commons.lang.Validate; + /** * Base implementation of {@link ICriterionType}
* @author Óscar González Fernández @@ -10,10 +12,21 @@ public abstract class CriterionTypeBase implements ICriterionType { private final boolean allowMultipleValuesPerResource; - protected CriterionTypeBase(boolean allowHierarchy, - boolean allowMultipleValuesPerResource) { + private final String name; + + private final boolean allowAdding; + + private final boolean allowEditing; + + protected CriterionTypeBase(String name, boolean allowHierarchy, + boolean allowMultipleValuesPerResource, boolean allowAdding, + boolean allowEditing) { + Validate.notNull(name, "name is not null"); this.allowHierarchy = allowHierarchy; this.allowMultipleValuesPerResource = allowMultipleValuesPerResource; + this.name = name; + this.allowAdding = allowAdding; + this.allowEditing = allowEditing; } @Override @@ -26,4 +39,17 @@ public abstract class CriterionTypeBase implements ICriterionType { return allowMultipleValuesPerResource; } + public String getName() { + return name; + } + + @Override + public boolean allowAdding() { + return allowAdding; + } + + @Override + public boolean allowEditing() { + return allowEditing; + } } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterionType.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterionType.java index f06352422..0e82a9825 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterionType.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/ICriterionType.java @@ -6,10 +6,16 @@ package org.navalplanner.business.resources.entities; */ public interface ICriterionType { + public String getName(); + public boolean allowMultipleActiveCriterionsPerResource(); public boolean allowHierarchy(); + public boolean allowAdding(); + + public boolean allowEditing(); + public C createCriterion(String name); public boolean contains(ICriterion criterion); diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/PredefinedCriterionTypes.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/PredefinedCriterionTypes.java index 09633aa81..d1c56c384 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/PredefinedCriterionTypes.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/PredefinedCriterionTypes.java @@ -9,13 +9,13 @@ import java.util.List; */ public enum PredefinedCriterionTypes implements ICriterionType { - WORK_RELATIONSHIP(false, false) { + WORK_RELATIONSHIP(false, false, false, false) { @Override public List getPredefined() { return WorkingRelationship.getCriterions(); } }, - LOCATION_GROUP(false, true) { + LOCATION_GROUP(false, true, true, true) { @Override public List getPredefined() { @@ -27,10 +27,17 @@ public enum PredefinedCriterionTypes implements ICriterionType { private final boolean allowMultipleActiveCriterionsPerResource; + private final boolean allowAdding; + + private final boolean allowEditing; + private PredefinedCriterionTypes(boolean allowHierarchy, - boolean allowMultipleActiveCriterionsPerResource) { + boolean allowMultipleActiveCriterionsPerResource, + boolean allowAdding, boolean allowEditing) { this.allowHierarchy = allowHierarchy; this.allowMultipleActiveCriterionsPerResource = allowMultipleActiveCriterionsPerResource; + this.allowAdding = allowAdding; + this.allowEditing = allowEditing; } @Override @@ -74,4 +81,18 @@ public enum PredefinedCriterionTypes implements ICriterionType { + type); } + public String getName() { + return name(); + } + + @Override + public boolean allowAdding() { + return allowAdding; + } + + @Override + public boolean allowEditing() { + return allowEditing; + } + } \ No newline at end of file diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/CriterionService.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/CriterionService.java index 16751ec4f..1867a99c4 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/CriterionService.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/CriterionService.java @@ -43,4 +43,6 @@ public interface CriterionService { ICriterionOnData empower(ICriterion criterion); + Collection getCriterionsFor(ICriterionType type); + } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/impl/CriterionServiceImpl.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/impl/CriterionServiceImpl.java index 8e8c8ae2d..0c8caccbd 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/impl/CriterionServiceImpl.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/services/impl/CriterionServiceImpl.java @@ -153,4 +153,16 @@ public class CriterionServiceImpl implements CriterionService { return (CriterionService) applicationContext.getBeansOfType( CriterionService.class).values().iterator().next(); } + + @Override + public Collection getCriterionsFor(ICriterionType type) { + List list = criterionDAO.list(Criterion.class); + ArrayList result = new ArrayList(); + for (Criterion criterion : list) { + if (type.contains(criterion)) { + result.add(criterion); + } + } + return result; + } } diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/ResourceTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/ResourceTest.java index bfba8d3a4..0420fc53b 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/ResourceTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/entities/ResourceTest.java @@ -92,7 +92,7 @@ public class ResourceTest { final Criterion... criterions) { final HashSet criterionsSet = new HashSet(Arrays .asList(criterions)); - return new CriterionTypeBase(true, true) { + return new CriterionTypeBase("base", true, true, false, false) { @Override public boolean contains(ICriterion c) { diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/services/CriterionServiceTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/services/CriterionServiceTest.java index 836d59ca6..4371e16f0 100644 --- a/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/services/CriterionServiceTest.java +++ b/navalplanner-business/src/test/java/org/navalplanner/business/test/resources/services/CriterionServiceTest.java @@ -1,10 +1,6 @@ package org.navalplanner.business.test.resources.services; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; -import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE; -import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_TEST_FILE; - +import java.util.Collection; import java.util.UUID; import org.hibernate.SessionFactory; @@ -13,6 +9,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.CriterionSatisfaction; +import org.navalplanner.business.resources.entities.ICriterion; import org.navalplanner.business.resources.entities.ICriterionOnData; import org.navalplanner.business.resources.entities.ICriterionType; import org.navalplanner.business.resources.entities.PredefinedCriterionTypes; @@ -29,6 +26,11 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; +import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE; +import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_TEST_FILE; + /** * Test cases for {@link CriterionService}
* @author Óscar González Fernández @@ -80,8 +82,9 @@ public class CriterionServiceTest { .createCriterion(unique); criterionService.createIfNotExists(criterion); assertTrue(criterionService.exists(criterion)); - criterionService.createIfNotExists(PredefinedCriterionTypes.WORK_RELATIONSHIP - .createCriterion(unique)); + criterionService + .createIfNotExists(PredefinedCriterionTypes.WORK_RELATIONSHIP + .createCriterion(unique)); } @Test @@ -138,8 +141,8 @@ public class CriterionServiceTest { Criterion criterion = CriterionDAOTest.createValidCriterion(); criterionService.save(criterion); Worker worker = new Worker("firstName", "surName", "2333232", 10); - new CriterionSatisfaction( - CriterionSatisfactionDAOTest.year(2000), criterion, worker); + new CriterionSatisfaction(CriterionSatisfactionDAOTest.year(2000), + criterion, worker); resourceService.saveResource(worker); assertEquals(1, criterionService.getResourcesSatisfying(criterion) .size()); @@ -195,9 +198,8 @@ public class CriterionServiceTest { criterionService.add(criterionSatisfaction); ICriterionOnData criterionOnData = criterionService.empower(criterion); criterionOnData.getResourcesSatisfying(); - criterionOnData.getResourcesSatisfying( - CriterionSatisfactionDAOTest.year(2001), - CriterionSatisfactionDAOTest.year(2005)); + criterionOnData.getResourcesSatisfying(CriterionSatisfactionDAOTest + .year(2001), CriterionSatisfactionDAOTest.year(2005)); } @Test(expected = IllegalArgumentException.class) @@ -267,4 +269,61 @@ public class CriterionServiceTest { CriterionSatisfactionDAOTest.year(2005)).size()); } + @Test + public void testCriterionsForType() throws Exception { + final Criterion one = CriterionDAOTest.createValidCriterion(); + Criterion other = CriterionDAOTest.createValidCriterion(); + criterionService.save(one); + criterionService.save(other); + ICriterionType type = createTypeThatMatches(one); + Collection criterions = criterionService + .getCriterionsFor(type); + assertEquals(1, criterions.size()); + assertTrue(criterions.contains(one)); + } + + private ICriterionType createTypeThatMatches( + final Criterion criterion) { + return new ICriterionType() { + + @Override + public boolean allowHierarchy() { + return false; + } + + @Override + public boolean allowMultipleActiveCriterionsPerResource() { + return false; + } + + @Override + public boolean contains(ICriterion c) { + return criterion == c; + } + + @Override + public Criterion createCriterion(String name) { + return null; + } + + @Override + public String getName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean allowAdding() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean allowEditing() { + // TODO Auto-generated method stub + return false; + } + }; + } + } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/IMessagesForUser.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/IMessagesForUser.java index 11dd6389f..f3b37ab96 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/IMessagesForUser.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/IMessagesForUser.java @@ -1,6 +1,7 @@ package org.navalplanner.web.common; import org.hibernate.validator.InvalidValue; +import org.navalplanner.business.common.exceptions.ValidationException; /** * Defines the ways in which information messages can be shown to the user
@@ -14,4 +15,6 @@ public interface IMessagesForUser { void clearMessages(); + void showInvalidValues(ValidationException e); + } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/MessagesForUser.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/MessagesForUser.java index b724210ec..14233d109 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/MessagesForUser.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/MessagesForUser.java @@ -6,6 +6,7 @@ import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import org.hibernate.validator.InvalidValue; +import org.navalplanner.business.common.exceptions.ValidationException; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; @@ -21,8 +22,9 @@ import org.zkoss.zul.Label; public class MessagesForUser extends GenericForwardComposer implements IMessagesForUser { - private static final long DEFAULT_MINIMUM_VISUALIZATION_TIME_MILLIS = - 1000 * 2; // 2 seconds + private static final long DEFAULT_MINIMUM_VISUALIZATION_TIME_MILLIS = 1000 * 2; // 2 + + // seconds private class ComponentHolderTimestamped { final Component component; @@ -42,8 +44,7 @@ public class MessagesForUser extends GenericForwardComposer implements private final long minimumVisualizationTimeMilliseconds; - private Queue pendingToDetach = - new ConcurrentLinkedQueue(); + private Queue pendingToDetach = new ConcurrentLinkedQueue(); private static final String DETACH_EVENT_NAME = "onMarkDetached"; @@ -54,8 +55,7 @@ public class MessagesForUser extends GenericForwardComposer implements public MessagesForUser(Component container, long minimumVisualizationTimeMilliseconds) { this.container = container; - this.minimumVisualizationTimeMilliseconds = - minimumVisualizationTimeMilliseconds; + this.minimumVisualizationTimeMilliseconds = minimumVisualizationTimeMilliseconds; container.getPage().getDesktop().addListener(new EventInterceptor() { @Override @@ -130,4 +130,11 @@ public class MessagesForUser extends GenericForwardComposer implements } } + @Override + public void showInvalidValues(ValidationException e) { + for (InvalidValue invalidValue : e.getInvalidValues()) { + invalidValue(invalidValue); + } + } + } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/CriterionAdminController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/CriterionAdminController.java new file mode 100644 index 000000000..a2570bbdd --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/CriterionAdminController.java @@ -0,0 +1,185 @@ +package org.navalplanner.web.resources; + +import java.util.List; + +import org.navalplanner.business.common.exceptions.ValidationException; +import org.navalplanner.business.resources.entities.Criterion; +import org.navalplanner.business.resources.entities.ICriterionType; +import org.navalplanner.web.common.IMessagesForUser; +import org.navalplanner.web.common.MessagesForUser; +import org.navalplanner.web.common.OnlyOneVisible; +import org.navalplanner.web.common.Util; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.util.GenericForwardComposer; +import org.zkoss.zul.Button; +import org.zkoss.zul.Checkbox; +import org.zkoss.zul.Div; +import org.zkoss.zul.GroupsModel; +import org.zkoss.zul.Label; +import org.zkoss.zul.Row; +import org.zkoss.zul.RowRenderer; +import org.zkoss.zul.SimpleGroupsModel; +import org.zkoss.zul.api.Grid; +import org.zkoss.zul.api.Group; + +/** + * Controller for Criterions
+ * @author Óscar González Fernández + */ +public class CriterionAdminController extends GenericForwardComposer { + + private ICriterionsModel criterionsModel; + + private Component messagesContainer; + + private IMessagesForUser messagesForUser; + + private Grid listing; + + private Component editComponent; + + private Component createComponent; + + private OnlyOneVisible onlyOneVisible; + + public CriterionAdminController() { + + } + + private class GroupRenderer implements RowRenderer { + public void render(Row row, java.lang.Object data) { + if (data instanceof Criterion) { + final Criterion criterion = (Criterion) data; + Button editButton = new Button("Editar"); + editButton.setParent(row); + editButton.setDisabled(!criterionsModel.getTypeFor(criterion) + .allowEditing()); + editButton.addEventListener("onClick", new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + goToEditForm(criterion); + } + }); + new Label(criterion.getName()).setParent(row); + Checkbox checkbox = new Checkbox(); + checkbox.setChecked(criterion.isActive()); + checkbox.setDisabled(true); + checkbox.setParent(row); + } else if (data instanceof ICriterionType) { + final ICriterionType type = (ICriterionType) data; + Div div = new Div(); + Button createButton = new Button("Engadir"); + createButton.setDisabled(!type.allowAdding()); + createButton.addEventListener("onClick", new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + goToCreateForm((ICriterionType) type); + } + }); + div.appendChild(createButton); + div.setParent(row); + row.setSpans("3"); + } else { + Group group = (Group) row; + group.setLabel(data.toString()); + group.setSpans("3"); + } + } + + } + + private void goToCreateForm(ICriterionType type) { + onlyOneVisible.showOnly(createComponent); + Util.reloadBindings(createComponent); + criterionsModel.prepareForCreate(type); + } + + private void goToEditForm(Criterion criterion) { + onlyOneVisible.showOnly(editComponent); + criterionsModel.prepareForEdit(criterion); + Util.reloadBindings(editComponent); + } + + public void setCriterionName(String name) { + criterionsModel.setNameForCriterion(name); + } + + public String getCriterionName() { + return criterionsModel.getNameForCriterion(); + } + + public boolean isEditing() { + return criterionsModel.isEditing(); + } + + public boolean isCriterionActive() { + return criterionsModel.isCriterionActive(); + } + + public void setCriterionActive(boolean active) { + criterionsModel.setCriterionActive(active); + } + + public void save() { + onlyOneVisible.showOnly(listing); + try { + criterionsModel.saveCriterion(); + reload(); + } catch (ValidationException e) { + messagesForUser.showInvalidValues(e); + } + } + + public void cancel() { + onlyOneVisible.showOnly(listing); + } + + private RowRenderer getRowRenderer() { + return new GroupRenderer(); + } + + private GroupsModel getTypesWithCriterions() { + List> types = criterionsModel.getTypes(); + Object[][] groups = new Object[types.size()][]; + int i = 0; + for (ICriterionType type : types) { + groups[i] = criterionsModel.getCriterionsFor(type).toArray(); + i++; + } + return new SimpleGroupsModel(groups, asStrings(types), types.toArray()); + } + + private String[] asStrings(List> types) { + String[] result = new String[types.size()]; + int i = 0; + for (ICriterionType criterionType : types) { + result[i++] = criterionType.getName(); + } + return result; + } + + public Criterion getCriterion() { + return criterionsModel.getCriterion(); + } + + @Override + public void doAfterCompose(Component comp) throws Exception { + super.doAfterCompose(comp); + onlyOneVisible = new OnlyOneVisible(listing, editComponent, + createComponent); + onlyOneVisible.showOnly(listing); + comp.setVariable("controller", this, true); + messagesForUser = new MessagesForUser(messagesContainer); + listing = (Grid) comp.getFellow("listing"); + reload(); + listing.setRowRenderer(getRowRenderer()); + } + + private void reload() { + listing.setModel(getTypesWithCriterions()); + } +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/CriterionsModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/CriterionsModel.java new file mode 100644 index 000000000..b928f692c --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/CriterionsModel.java @@ -0,0 +1,136 @@ +package org.navalplanner.web.resources; + +import java.util.Collection; +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.hibernate.validator.ClassValidator; +import org.hibernate.validator.InvalidValue; +import org.navalplanner.business.common.exceptions.ValidationException; +import org.navalplanner.business.resources.bootstrap.CriterionsBootstrap; +import org.navalplanner.business.resources.entities.Criterion; +import org.navalplanner.business.resources.entities.ICriterionType; +import org.navalplanner.business.resources.services.CriterionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +/** + * Model for criterions.
+ * @author Óscar González Fernández + */ +@Component("criterionsModel") +@Scope(BeanDefinition.SCOPE_PROTOTYPE) +public class CriterionsModel implements ICriterionsModel { + + private ClassValidator criterionValidator = new ClassValidator( + Criterion.class); + + @Autowired + private CriterionsBootstrap criterionsBootstrap; + + @Autowired + private CriterionService criterionService; + + private ICriterionType criterionType; + + private Criterion criterion; + + private String nameForCriterion; + + @Override + @Transactional(readOnly = true) + public List> getTypes() { + return criterionsBootstrap.getTypes(); + } + + @Override + @Transactional(readOnly = true) + public Collection getCriterionsFor(ICriterionType type) { + return criterionService.getCriterionsFor(type); + } + + @Override + public Criterion getCriterion() { + return criterion; + } + + @Override + public void setNameForCriterion(String name) { + this.nameForCriterion = name; + } + + @Override + public void prepareForCreate(ICriterionType criterionType) { + this.criterionType = criterionType; + this.criterion = null; + } + + @Override + public void prepareForEdit(Criterion criterion) { + Validate.notNull(criterion); + this.criterion = criterion; + this.criterionType = null; + } + + @Override + public ICriterionType getTypeFor(Criterion criterion) { + for (ICriterionType criterionType : getTypes()) { + if (criterionType.contains(criterion)) + return criterionType; + } + throw new RuntimeException("not found type for criterion " + criterion); + } + + @Override + @Transactional + public void saveCriterion() throws ValidationException { + if (criterionType != null) { + create(); + } else { + saveEdit(); + } + criterion = null; + criterionType = null; + } + + private void saveEdit() { + criterionService.save(criterion); + } + + private void create() throws ValidationException { + Criterion criterion = criterionType.createCriterion(nameForCriterion); + InvalidValue[] invalidValues = criterionValidator + .getInvalidValues(criterion); + if (invalidValues.length > 0) + throw new ValidationException(invalidValues); + criterionService.save(criterion); + } + + @Override + public String getNameForCriterion() { + if (criterion == null) { + return ""; + } + return criterion.getName(); + } + + @Override + public boolean isCriterionActive() { + if (criterion == null) + return false; + return criterion.isActive(); + } + + @Override + public boolean isEditing() { + return criterion != null; + } + + @Override + public void setCriterionActive(boolean active) { + criterion.setActive(active); + } +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/ICriterionsModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/ICriterionsModel.java new file mode 100644 index 000000000..3a9b675c7 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/ICriterionsModel.java @@ -0,0 +1,40 @@ +package org.navalplanner.web.resources; + +import java.util.Collection; +import java.util.List; + +import org.navalplanner.business.common.exceptions.ValidationException; +import org.navalplanner.business.resources.entities.Criterion; +import org.navalplanner.business.resources.entities.ICriterionType; + +/** + * CriterionsModel contract
+ * @author Óscar González Fernández + */ +public interface ICriterionsModel { + + List> getTypes(); + + Collection getCriterionsFor(ICriterionType type); + + Criterion getCriterion(); + + void prepareForCreate(ICriterionType criterionType); + + void prepareForEdit(Criterion criterion); + + ICriterionType getTypeFor(Criterion criterion); + + String getNameForCriterion(); + + void setNameForCriterion(String name); + + void saveCriterion() throws ValidationException; + + boolean isEditing(); + + boolean isCriterionActive(); + + void setCriterionActive(boolean active); + +} diff --git a/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-config.xml b/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-config.xml index c29ea6bf0..e9e243690 100644 --- a/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-config.xml +++ b/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-config.xml @@ -14,6 +14,8 @@ --> + + \ No newline at end of file diff --git a/navalplanner-webapp/src/main/webapp/WEB-INF/i3-label.properties b/navalplanner-webapp/src/main/webapp/WEB-INF/i3-label.properties index f51b51869..07080d2a3 100644 --- a/navalplanner-webapp/src/main/webapp/WEB-INF/i3-label.properties +++ b/navalplanner-webapp/src/main/webapp/WEB-INF/i3-label.properties @@ -28,3 +28,4 @@ mainmenu.manage_dependencies=Administrar dependencias mainmenu.help=Axuda mainmenu.about=Acerca de mainmenu.aclunaga=Aclunaga +mainmenu.manage_criterions=Administrar criterios diff --git a/navalplanner-webapp/src/main/webapp/WEB-INF/i3-label_en_US.properties b/navalplanner-webapp/src/main/webapp/WEB-INF/i3-label_en_US.properties index d755c8d71..182323798 100644 --- a/navalplanner-webapp/src/main/webapp/WEB-INF/i3-label_en_US.properties +++ b/navalplanner-webapp/src/main/webapp/WEB-INF/i3-label_en_US.properties @@ -28,3 +28,4 @@ mainmenu.manage_dependencies=Manage dependences mainmenu.help=Help mainmenu.about=About mainmenu.aclunaga=Aclunaga +mainmenu.manage_criterions=Manage criterions diff --git a/navalplanner-webapp/src/main/webapp/common/layout/template.zul b/navalplanner-webapp/src/main/webapp/common/layout/template.zul index 666ea4ccb..c9ac5c464 100644 --- a/navalplanner-webapp/src/main/webapp/common/layout/template.zul +++ b/navalplanner-webapp/src/main/webapp/common/layout/template.zul @@ -25,6 +25,8 @@ + + + + + +