From a4fc69b4f8eccd822c31fe3148a746148dc142d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Gonz=C3=A1lez=20Fern=C3=A1ndez?= Date: Thu, 5 Nov 2009 17:30:15 +0100 Subject: [PATCH] ItEr33S14CUCreacionUnidadesPlanificacion: Creating Constraint class --- .../ganttz/data/constraint/Constraint.java | 88 +++++++++++ .../data/constraint/ConstraintTest.java | 137 ++++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 ganttzk/src/main/java/org/zkoss/ganttz/data/constraint/Constraint.java create mode 100644 ganttzk/src/test/java/org/zkoss/ganttz/data/constraint/ConstraintTest.java diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/constraint/Constraint.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/constraint/Constraint.java new file mode 100644 index 000000000..35d873af0 --- /dev/null +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/constraint/Constraint.java @@ -0,0 +1,88 @@ +/* + * This file is part of ###PROJECT_NAME### + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.zkoss.ganttz.data.constraint; + +import java.util.Arrays; +import java.util.Collection; + +import org.zkoss.ganttz.util.WeakReferencedListeners; +import org.zkoss.ganttz.util.WeakReferencedListeners.IListenerNotification; + +/** + * @author Óscar González Fernández + * + */ +public abstract class Constraint { + + public interface IConstraintViolationListener { + public void constraintViolated(Constraint constraint, T value); + } + + public static T apply(T currentValue, Constraint... constraints) { + return apply(currentValue, Arrays.asList(constraints)); + } + + public static T apply(T currentValue, + Collection> constraints) { + T result = currentValue; + for (Constraint each : constraints) { + result = each.applyTo(result); + } + for (Constraint each : constraints) { + if (!each.isSatisfiedBy(result)) { + each.fireNotSatisfied(result); + } + } + return result; + } + + private WeakReferencedListeners> weakListeners = WeakReferencedListeners + .create(); + + public final T applyTo(T currentValue) { + T result = applyConstraintTo(currentValue); + if (!isSatisfiedBy(result)) { + throw new IllegalStateException(result + + " doesn't fulfill this constraint: " + this); + } + return result; + } + + protected abstract T applyConstraintTo(T currentValue); + + public abstract boolean isSatisfiedBy(T value); + + private void fireNotSatisfied(final T value) { + weakListeners + .fireEvent(new IListenerNotification>() { + + @Override + public void doNotify( + IConstraintViolationListener listener) { + listener.constraintViolated(Constraint.this, value); + } + }); + } + + public void addConstraintViolationListener(IConstraintViolationListener listener) { + weakListeners.addListener(listener); + } + +} diff --git a/ganttzk/src/test/java/org/zkoss/ganttz/data/constraint/ConstraintTest.java b/ganttzk/src/test/java/org/zkoss/ganttz/data/constraint/ConstraintTest.java new file mode 100644 index 000000000..b2b993ba1 --- /dev/null +++ b/ganttzk/src/test/java/org/zkoss/ganttz/data/constraint/ConstraintTest.java @@ -0,0 +1,137 @@ +/* + * This file is part of ###PROJECT_NAME### + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.zkoss.ganttz.data.constraint; + +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.isA; +import static org.easymock.classextension.EasyMock.createNiceMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.zkoss.ganttz.data.constraint.Constraint.IConstraintViolationListener; + +/** + * @author Óscar González Fernández + * + */ +public class ConstraintTest { + + private Constraint biggerThanFive = new Constraint() { + + @Override + protected Integer applyConstraintTo(Integer currentValue) { + return currentValue; + } + + @Override + public boolean isSatisfiedBy(Integer value) { + return value != null && value > 5; + } + }; + private Constraint lessThanFive = new Constraint() { + + @Override + public boolean isSatisfiedBy(Integer value) { + return value!=null && value <5; + } + + @Override + protected Integer applyConstraintTo(Integer currentValue) { + return Math.min(4, currentValue); + } + }; + + @Test + public void ifThereIsNoConstraintsTheOriginalValueIsReturned() { + assertThat(Constraint.apply(2), equalTo(2)); + } + + @Test + public void aNewValueFullfillingTheConstraintIsReturned() { + Constraint biggerThanFive = new Constraint() { + + @Override + protected Integer applyConstraintTo(Integer currentValue) { + return Math.max(6, currentValue); + } + + @Override + public boolean isSatisfiedBy(Integer value) { + return value != null && value > 5; + } + }; + assertThat(biggerThanFive.applyTo(5), equalTo(6)); + } + + @Test(expected = IllegalStateException.class) + public void aConstraintMustReturnValuesThatSatisfiesItsCriterion() { + biggerThanFive.applyTo(4); + } + + + @SuppressWarnings("unchecked") + @Test + public void applyingSeveralConstraintsCallsApplyToOfEveryone() { + List> constraints = new ArrayList>(); + final int numerOfConstraints = 5; + for (int i = 0; i < numerOfConstraints; i++) { + Constraint constraint = createNiceMock(Constraint.class); + expect(constraint.applyConstraintTo(isA(Object.class))) + .andReturn(2).atLeastOnce(); + expect(constraint.isSatisfiedBy(isA(Object.class))).andReturn(true) + .atLeastOnce(); + constraints.add(constraint); + } + replay(constraints.toArray()); + Constraint.apply(2, constraints); + verify(constraints.toArray()); + } + + @SuppressWarnings("unchecked") + @Test + public void theLastConstraintHasPriority() { + Integer result = Constraint.apply(6, biggerThanFive, + lessThanFive); + assertThat(result, equalTo(4)); + } + + @Test + public void theViolatedConstraintsNotifiesItsListeners() { + final Constraint[] constraintViolated = new Constraint[1]; + biggerThanFive + .addConstraintViolationListener(new IConstraintViolationListener() { + + @Override + public void constraintViolated( + Constraint constraint, Integer value) { + constraintViolated[0] = constraint; + } + }); + Constraint.apply(6, biggerThanFive, lessThanFive); + assertThat(constraintViolated[0], equalTo(biggerThanFive)); + } + +}