r596 - in trunk: sammoa-application/src/main/java/fr/ulr/sammoa/application sammoa-application/src/main/resources/i18n sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/validation sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/ef
Author: fdesbois Date: 2012-09-26 15:12:08 +0200 (Wed, 26 Sep 2012) New Revision: 596 Url: http://forge.codelutin.com/repositories/revision/sammoa/596 Log: fixes #1514 : - add valid flight action - improve valid actions using ValidModel - improve listeners for tables for validationMode Added: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/ValidModel.java trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidFlightAction.java Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/SammoaConfig.java trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/ValidationService.java trunk/sammoa-application/src/main/resources/i18n/sammoa-application_en_GB.properties trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Flights.java trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Routes.java trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/TransectFlights.java trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Validables.java trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUI.css trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUI.jaxx trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUIHandler.java trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUI.css trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUI.jaxx trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUIHandler.java trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidAction.java trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidObservationAction.java trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidRouteAction.java trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidTransectAction.java trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/validation/ValidationBar.css trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/validation/ValidationBar.jaxx trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/effort/EffortPanelHandler.java trunk/sammoa-ui-swing/src/main/resources/i18n/sammoa-ui-swing_en_GB.properties Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/SammoaConfig.java =================================================================== --- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/SammoaConfig.java 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/SammoaConfig.java 2012-09-26 13:12:08 UTC (rev 596) @@ -77,6 +77,8 @@ public static final String PROPERTY_CIRCLE_BACK = "circleBack"; + public static final String PROPERTY_VALID_FLIGHT = "validFlight"; + public static final String PROPERTY_VALID_TRANSECT = "validTransect"; public static final String PROPERTY_VALID_ROUTE = "validRoute"; @@ -474,6 +476,13 @@ false, false), + KEY_VALID_FLIGHT("ui." + PROPERTY_VALID_FLIGHT, + n_("sammoa.config.ui.validFlight"), + "alt pressed F", + KeyStroke.class, + false, + false), + KEY_VALID_TRANSECT("ui." + PROPERTY_VALID_TRANSECT, n_("sammoa.config.ui.validTransect"), "alt pressed T", Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/ValidationService.java =================================================================== --- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/ValidationService.java 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/ValidationService.java 2012-09-26 13:12:08 UTC (rev 596) @@ -23,6 +23,7 @@ * #L% */ +import com.google.common.collect.ImmutableList; import fr.ulr.sammoa.persistence.Flight; import fr.ulr.sammoa.persistence.Observation; import fr.ulr.sammoa.persistence.ObservationDAO; @@ -30,6 +31,7 @@ import fr.ulr.sammoa.persistence.ObserverPositionDAO; import fr.ulr.sammoa.persistence.Route; import fr.ulr.sammoa.persistence.RouteDAO; +import fr.ulr.sammoa.persistence.Routes; import fr.ulr.sammoa.persistence.SammoaDAOHelper; import fr.ulr.sammoa.persistence.TransectFlight; import fr.ulr.sammoa.persistence.TransectFlightDAO; @@ -46,38 +48,56 @@ */ public class ValidationService extends SammoaServiceSupport { - public TransectFlight validateTransectFlight(Flight flight, - TransectFlight transectFlight) { + public void validateFlight(Flight flight, + List<Route> routes, + boolean valid) { TopiaContext tx = beginTransaction(); try { - TransectFlight result; - boolean valid = !transectFlight.isValid(); + TransectFlightDAO transectFlightDAO = SammoaDAOHelper.getTransectFlightDAO(tx); - if (transectFlight.isDeleted()) { + // Valid all transectFlights + List<TransectFlight> transectFlights = ImmutableList.copyOf(flight.getTransectFlight()); + for (int i = 0; i < transectFlights.size(); i++) { + TransectFlight transectFlight = + transectFlightDAO.findByTopiaId(transectFlights.get(i).getTopiaId()); - // Use FlightService for delete - context.getService(FlightService.class).deleteTransectFlight(tx, flight, transectFlight); + validateTransectFlight(tx, flight, transectFlight, valid); - result = null; + flight.getTransectFlight().set(i, transectFlight); + } - } else { + RouteDAO routeDAO = SammoaDAOHelper.getRouteDAO(tx); - TransectFlightDAO transectFlightDAO = SammoaDAOHelper.getTransectFlightDAO(tx); - result = transectFlightDAO.findByTopiaId(transectFlight.getTopiaId()); + Iterable<Route> otherRoutes = Routes.filterWithNoTransectFlight(routes); + for (Route otherRoute : otherRoutes) { + Route route = routeDAO.findByTopiaId(otherRoute.getTopiaId()); + validateRoute(tx, route, valid); + } - RouteDAO routeDAO = SammoaDAOHelper.getRouteDAO(tx); - List<Route> routes = routeDAO.findAllByTransectFlight(result); + tx.commitTransaction(); - for (Route route : routes) { - validateRoute(tx, route, valid); - } + } catch (TopiaException ex) { + throw new TopiaRuntimeException(ex); + } finally { + endTransaction(tx); + } + } - result.setValid(valid); - transectFlightDAO.update(result); - } + public TransectFlight validateTransectFlight(Flight flight, + TransectFlight transectFlight) { + TopiaContext tx = beginTransaction(); + try { + + TransectFlightDAO transectFlightDAO = SammoaDAOHelper.getTransectFlightDAO(tx); + TransectFlight result = transectFlightDAO.findByTopiaId(transectFlight.getTopiaId()); + + boolean valid = !transectFlight.isValid(); + + validateTransectFlight(tx, flight, result, valid); + tx.commitTransaction(); transectFlight.setValid(valid); @@ -139,6 +159,33 @@ } } + protected void validateTransectFlight(TopiaContext tx, + Flight flight, + TransectFlight transectFlight, + boolean valid) + throws TopiaException { + + if (transectFlight.isDeleted()) { + + // Use FlightService for delete + context.getService(FlightService.class).deleteTransectFlight(tx, flight, transectFlight); + + } else { + + TransectFlightDAO transectFlightDAO = SammoaDAOHelper.getTransectFlightDAO(tx); + + RouteDAO routeDAO = SammoaDAOHelper.getRouteDAO(tx); + List<Route> routes = routeDAO.findAllByTransectFlight(transectFlight); + + for (Route route : routes) { + validateRoute(tx, route, valid); + } + + transectFlight.setValid(valid); + transectFlightDAO.update(transectFlight); + } + } + protected void validateRoute(TopiaContext tx, Route route, boolean valid) Modified: trunk/sammoa-application/src/main/resources/i18n/sammoa-application_en_GB.properties =================================================================== --- trunk/sammoa-application/src/main/resources/i18n/sammoa-application_en_GB.properties 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-application/src/main/resources/i18n/sammoa-application_en_GB.properties 2012-09-26 13:12:08 UTC (rev 596) @@ -36,6 +36,7 @@ sammoa.config.ui.rightObservation=Sighting from the right observer sammoa.config.ui.start=Start the flight sammoa.config.ui.stop=Stop the flight +sammoa.config.ui.validFlight=Validate all the flight sammoa.config.ui.validObservation=Validate the selected sighting sammoa.config.ui.validRoute=Validate the selected route sammoa.config.ui.validTransect=Validate the selected transect Modified: trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Flights.java =================================================================== --- trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Flights.java 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Flights.java 2012-09-26 13:12:08 UTC (rev 596) @@ -25,8 +25,11 @@ import com.google.common.base.Function; import com.google.common.base.Predicate; +import com.google.common.base.Predicates; import com.google.common.collect.ComparisonChain; +import com.google.common.collect.FluentIterable; import com.google.common.collect.Ordering; +import org.nuiton.validator.bean.list.BeanListValidator; import java.util.Comparator; @@ -41,6 +44,48 @@ // static class do not have instanciation } + public static boolean withValidFlag(Flight flight, + BeanListValidator<Route> routeValidator) { + + // Check validity of all transectFlights + boolean result = FluentIterable + .from(flight.getTransectFlight()) + .allMatch(Validables.isValid(null)); + + // Check validity of all other routes with no transectFlight + if (result) { + + result = FluentIterable + .from(routeValidator.getBeans()) + .filter(Routes.withNoTransectFlight()) + .allMatch(Validables.isValid(routeValidator)); + } + return result; + } + + public static boolean isValid(Flight flight, + Iterable<Route> routes, + Function<TransectFlight, Boolean> isValidTransectFlight, + Function<Route, Boolean> isValidRoute) { + + // Check validity of all transectFlights + boolean result = FluentIterable + .from(flight.getTransectFlight()) + .transform(isValidTransectFlight) + .allMatch(Predicates.equalTo(true)); + + // Check validity of all other routes with no transectFlight + if (result) { + + result = FluentIterable + .from(routes) + .filter(Routes.withNoTransectFlight()) + .transform(isValidRoute) + .allMatch(Predicates.equalTo(true)); + } + return result; + } + public static Comparator<Flight> orderByDate() { return ORDER_BY_DATE_COMPARATOR; } Modified: trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Routes.java =================================================================== --- trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Routes.java 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Routes.java 2012-09-26 13:12:08 UTC (rev 596) @@ -53,6 +53,10 @@ // static class do not have instanciation } + public static Iterable<Route> filterWithNoTransectFlight(Iterable<Route> routes) { + return Iterables.filter(routes, WITH_NO_TRANSECT_FLIGHT_PREDICATE); + } + public static boolean isAnyMatchTransectFlight(Iterable<Route> routes, TransectFlight transectFlight) { return Iterables.any(routes, withTransectFlight(transectFlight)); } @@ -103,7 +107,8 @@ public static boolean isValid(Route route, BeanListValidator<Route> routeValidator, - BeanListValidator<Observation> observationValidator) { + Iterable<Observation> observations, + Function<Observation, Boolean> isValidObservation) { boolean result; if (route.isDeleted()) { @@ -120,9 +125,10 @@ // Check validity of observations result = FluentIterable - .from(observationValidator.getBeans()) + .from(observations) .filter(Observations.inRoute(route, routes, true)) - .allMatch(Observations.isValid(observationValidator)); + .transform(isValidObservation) + .allMatch(Predicates.equalTo(true)); } } return result; @@ -223,10 +229,14 @@ return new WithTransectFlightPredicate(transectFlight); } - public static Predicate<Route> isValid(BeanListValidator<Route> validator, - BeanListValidator<Observation> obsValidator) { - return new IsValidPredicate(validator, obsValidator); + public static Predicate<Route> withNoTransectFlight() { + return WITH_NO_TRANSECT_FLIGHT_PREDICATE; } +// +// public static Predicate<Route> isValid(BeanListValidator<Route> validator, +// BeanListValidator<Observation> obsValidator) { +// return new IsValidPredicate(validator, obsValidator); +// } public static Comparator<Route> orderByDate() { return BY_DATE_COMPARATOR; @@ -259,6 +269,14 @@ } }; + private static Predicate<Route> WITH_NO_TRANSECT_FLIGHT_PREDICATE = new Predicate<Route>() { + + @Override + public boolean apply(Route input) { + return input.getTransectFlight() == null; + } + }; + private static class WithObservationPredicate implements Predicate<Route> { protected Observation observation; @@ -297,27 +315,27 @@ return withTransectFlight(input, transectFlight); } } +// +// private static class IsValidPredicate implements Predicate<Route> { +// +// protected BeanListValidator<Route> validator; +// +// protected BeanListValidator<Observation> obsValidator; +// +// private IsValidPredicate(BeanListValidator<Route> validator, +// BeanListValidator<Observation> obsValidator) { +// Preconditions.checkNotNull(validator); +// Preconditions.checkNotNull(obsValidator); +// this.validator = validator; +// this.obsValidator = obsValidator; +// } +// +// @Override +// public boolean apply(Route input) { +// return isValid(input, validator, obsValidator); +// } +// } - private static class IsValidPredicate implements Predicate<Route> { - - protected BeanListValidator<Route> validator; - - protected BeanListValidator<Observation> obsValidator; - - private IsValidPredicate(BeanListValidator<Route> validator, - BeanListValidator<Observation> obsValidator) { - Preconditions.checkNotNull(validator); - Preconditions.checkNotNull(obsValidator); - this.validator = validator; - this.obsValidator = obsValidator; - } - - @Override - public boolean apply(Route input) { - return isValid(input, validator, obsValidator); - } - } - private static <T> T getNext(Iterable<T> elements, final T element, final Comparator<T> comparator) { Modified: trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/TransectFlights.java =================================================================== --- trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/TransectFlights.java 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/TransectFlights.java 2012-09-26 13:12:08 UTC (rev 596) @@ -25,9 +25,9 @@ import com.google.common.base.Function; import com.google.common.base.Predicate; +import com.google.common.base.Predicates; import com.google.common.collect.FluentIterable; import com.google.common.collect.Sets; -import org.nuiton.validator.bean.list.BeanListValidator; import java.util.Date; import java.util.Set; @@ -73,8 +73,8 @@ } public static boolean isValid(TransectFlight transectFlight, - BeanListValidator<Route> routeValidator, - BeanListValidator<Observation> observationValidator) { + Iterable<Route> routes, + Function<Route, Boolean> isRouteValid) { boolean result = transectFlight.isValid() || transectFlight.isDeleted(); @@ -82,9 +82,10 @@ // Check validity of routes result = FluentIterable - .from(routeValidator.getBeans()) + .from(routes) .filter(Routes.withTransectFlight(transectFlight)) - .allMatch(Routes.isValid(routeValidator, observationValidator)); + .transform(isRouteValid) + .allMatch(Predicates.equalTo(true)); } return result; } @@ -97,7 +98,7 @@ return TO_TRANSECT_FUNCTION; } - protected static Function<TransectFlight, Transect> TO_TRANSECT_FUNCTION = + private static Function<TransectFlight, Transect> TO_TRANSECT_FUNCTION = new Function<TransectFlight, Transect>() { @Override @@ -106,7 +107,7 @@ } }; - protected static Predicate<TransectFlight> IS_DELETED_PREDICATE = + private static Predicate<TransectFlight> IS_DELETED_PREDICATE = new Predicate<TransectFlight>() { @Override Modified: trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Validables.java =================================================================== --- trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Validables.java 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Validables.java 2012-09-26 13:12:08 UTC (rev 596) @@ -25,6 +25,7 @@ */ import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; import org.nuiton.validator.bean.list.BeanListValidator; /** @@ -38,6 +39,10 @@ // static class do not have instanciation } + public static <E extends Validable> boolean isAnyDeleted(Iterable<E> iterable) { + return Iterables.any(iterable, isDeleted()); + } + public static <E extends Validable> Predicate<E> isDeleted() { return new IsDeletedPredicate<E>(); } @@ -45,7 +50,7 @@ public static <E extends Validable> boolean isValid(E bean, BeanListValidator<E> validator) { return bean.isValid() || bean.isDeleted() - || validator.getContext(bean).isValid(); + || (validator != null && validator.getContext(bean).isValid()); } public static <E extends Validable> Predicate<E> isValid(BeanListValidator<E> validator) { Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUI.css =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUI.css 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUI.css 2012-09-26 13:12:08 UTC (rev 596) @@ -113,6 +113,9 @@ #menuActionRightObservation { _actionName: {"rightObservation"}; } +#menuActionValidFlight { + _actionName: {"validFlight"}; +} #menuActionValidTransect { _actionName: {"validTransect"}; } Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUI.jaxx =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUI.jaxx 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUI.jaxx 2012-09-26 13:12:08 UTC (rev 596) @@ -76,6 +76,7 @@ <JMenuItem id='menuActionLeftObservation'/> <JMenuItem id='menuActionCenterObservation'/> <JMenuItem id='menuActionRightObservation'/> + <JMenuItem id='menuActionValidFlight'/> <JMenuItem id='menuActionValidTransect'/> <JMenuItem id='menuActionValidRoute'/> <JMenuItem id='menuActionValidObservation'/> Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUIHandler.java =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUIHandler.java 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/MainUIHandler.java 2012-09-26 13:12:08 UTC (rev 596) @@ -346,6 +346,8 @@ helper.setOptionCallBack("actions"); helper.addOption(SammoaConfig.SammoaConfigOption.KEY_CIRCLE_BACK); helper.setOptionCallBack("actions"); + helper.addOption(SammoaConfig.SammoaConfigOption.KEY_VALID_FLIGHT); + helper.setOptionCallBack("actions"); helper.addOption(SammoaConfig.SammoaConfigOption.KEY_VALID_TRANSECT); helper.setOptionCallBack("actions"); helper.addOption(SammoaConfig.SammoaConfigOption.KEY_VALID_OBSERVATION); Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUI.css =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUI.css 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUI.css 2012-09-26 13:12:08 UTC (rev 596) @@ -39,12 +39,9 @@ preferredSize:{new Dimension(0,0)}; } -#effortSplitPane { +#effortPanel { orientation:{JSplitPane.VERTICAL_SPLIT}; resizeWeight:0.8; -} - -#effortPanel { minimumSize:{new Dimension(0,0)}; preferredSize:{new Dimension(0,0)}; } Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUI.jaxx =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUI.jaxx 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUI.jaxx 2012-09-26 13:12:08 UTC (rev 596) @@ -184,7 +184,7 @@ </JSplitPane> - <EffortPanel id='effortSplitPane' constructorParams='this'/> + <EffortPanel id='effortPanel' constructorParams='this'/> </JSplitPane> Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUIHandler.java =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUIHandler.java 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/FlightUIHandler.java 2012-09-26 13:12:08 UTC (rev 596) @@ -102,6 +102,7 @@ import fr.ulr.sammoa.ui.swing.flight.action.StartAudioAction; import fr.ulr.sammoa.ui.swing.flight.action.StopAction; import fr.ulr.sammoa.ui.swing.flight.action.StopAudioAction; +import fr.ulr.sammoa.ui.swing.flight.action.ValidFlightAction; import fr.ulr.sammoa.ui.swing.flight.action.ValidObservationAction; import fr.ulr.sammoa.ui.swing.flight.action.ValidRouteAction; import fr.ulr.sammoa.ui.swing.flight.action.ValidTransectAction; @@ -127,6 +128,7 @@ import org.jdesktop.swingx.JXTable; import org.nuiton.util.ApplicationConfig; import org.nuiton.util.TimeLog; +import org.nuiton.validator.bean.list.BeanListValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -158,6 +160,7 @@ import java.io.File; import java.io.IOException; import java.util.Arrays; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.Properties; @@ -197,6 +200,10 @@ protected boolean transectFlightSelectionIsAdjusting; + protected boolean routeSelectionIsAdjusting; + + protected ValidModel validModel; + public FlightUIHandler(SammoaUIContext context, FlightUI ui) { this.context = context; this.ui = ui; @@ -215,6 +222,17 @@ return ui.getModel(); } + public ValidModel getValidModel() { + if (validModel == null) { + BeanListValidator<Observation> observationValidator = + ui.getEffortPanel().getObservationValidator(); + BeanListValidator<Route> routeValidator = + ui.getEffortPanel().getRouteValidator(); + validModel = new ValidModel(observationValidator, routeValidator); + } + return validModel; + } + @Override public void beforeInitUI() { @@ -448,59 +466,92 @@ } }); - // Select the first route matching the transectFlight getModel().addPropertyChangeListener( - FlightUIModel.PROPERTY_TRANSECT_FLIGHT_EDIT_BEAN, new PropertyChangeListener() { + FlightUIModel.PROPERTY_OBSERVATION_EDIT_BEAN, new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { - - TransectFlightModel transectFlight = (TransectFlightModel) evt.getNewValue(); - if (!transectFlightSelectionIsAdjusting && transectFlight != null) { - - transectFlightSelectionIsAdjusting = true; - - Route route = FluentIterable - .from(getModel().getRoutes()) - .filter(Routes.withTransectFlight(transectFlight.getSource())) - .first() - .orNull(); - - getModel().setRouteEditBean(route); - - transectFlightSelectionIsAdjusting = false; - } + onObservationChangedForValidation( + (Observation) evt.getOldValue(), + (Observation) evt.getNewValue()); } }); - // Select the transectFlight matching the route getModel().addPropertyChangeListener( FlightUIModel.PROPERTY_ROUTE_EDIT_BEAN, new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { + onRouteChangedForValidation( + (Route) evt.getOldValue(), + (Route) evt.getNewValue()); + } + }); - if (!transectFlightSelectionIsAdjusting && evt.getNewValue() != null) { + getModel().addPropertyChangeListener( + FlightUIModel.PROPERTY_TRANSECT_FLIGHT_EDIT_BEAN, new PropertyChangeListener() { - transectFlightSelectionIsAdjusting = true; + @Override + public void propertyChange(PropertyChangeEvent evt) { + onTransectFlightChangedForValidation( + (TransectFlightModel) evt.getOldValue(), + (TransectFlightModel) evt.getNewValue()); + } + }); - Route route = (Route) evt.getNewValue(); +// // Select the first route matching the transectFlight +// getModel().addPropertyChangeListener( +// FlightUIModel.PROPERTY_TRANSECT_FLIGHT_EDIT_BEAN, new PropertyChangeListener() { +// +// @Override +// public void propertyChange(PropertyChangeEvent evt) { +// +// TransectFlightModel transectFlight = (TransectFlightModel) evt.getNewValue(); +// if (!transectFlightSelectionIsAdjusting && transectFlight != null) { +// +// transectFlightSelectionIsAdjusting = true; +// +// Route route = FluentIterable +// .from(getModel().getRoutes()) +// .filter(Routes.withTransectFlight(transectFlight.getSource())) +// .first() +// .orNull(); +// +// getModel().setRouteEditBean(route); +// +// transectFlightSelectionIsAdjusting = false; +// } +// } +// }); - if (route.getTransectFlight() != null) { - - int index = TransectFlightModel.indexOfTransectFlight( - getModel().getTransectFlights(), route.getTransectFlight()); - SammoaUtil.selectTableRow(ui.getTransectTable(), index); - - // for TRANSIT/CIRCLE_BACK route, we unselect all the table - } else { - SammoaUtil.unselectAll(ui.getTransectTable()); - } - - transectFlightSelectionIsAdjusting = false; - } - } - }); +// // Select the transectFlight matching the route +// getModel().addPropertyChangeListener( +// FlightUIModel.PROPERTY_ROUTE_EDIT_BEAN, new PropertyChangeListener() { +// +// @Override +// public void propertyChange(PropertyChangeEvent evt) { +// +// if (!transectFlightSelectionIsAdjusting && evt.getNewValue() != null) { +// +// transectFlightSelectionIsAdjusting = true; +// +// Route route = (Route) evt.getNewValue(); +// +// if (route.getTransectFlight() != null) { +// +// int index = TransectFlightModel.indexOfTransectFlight( +// getModel().getTransectFlights(), route.getTransectFlight()); +// SammoaUtil.selectTableRow(ui.getTransectTable(), index); +// +// // for TRANSIT/CIRCLE_BACK route, we unselect all the table +// } else { +// SammoaUtil.unselectAll(ui.getTransectTable()); +// } +// +// transectFlightSelectionIsAdjusting = false; +// } +// } +// }); } NumberCellEditor<Integer> numberCellEditor = JAXXWidgetUtil.newNumberTableCellEditor(Integer.class, false); @@ -893,6 +944,7 @@ putAction("validObservation", new ValidObservationAction(ui)); putAction("validRoute", new ValidRouteAction(ui)); putAction("validTransect", new ValidTransectAction(ui)); + putAction("validFlight", new ValidFlightAction(ui)); putAction("startAudio", new StartAudioAction(ui)); putAction("stopAudio", new StopAudioAction(ui)); } @@ -1137,6 +1189,286 @@ return flightController.getDeviceManager(deviceManagerClass); } + // ---------- VALIDATION MODE METHODS -------- // + + protected void fireRoutesUpdated(TransectFlightModel transectFlight, boolean scrollToFirst) { + + Iterable<Route> routes = Iterables.filter( + getModel().getRoutes(), Routes.withTransectFlight(transectFlight.getSource())); + + SammoaUtil.fireTableRowsUpdated(ui.getEffortPanel().getRouteTable(), + getModel().getRoutes(), + routes, + scrollToFirst); + } + + /** + * Select the {@code route} that matches the given {@code observation}. + * An adjusting flag is used to avoid loop when the route try to + * ensure the current observation with {@link #selectObservationFromRoute(Route)} + * + * @param observation Observation + * @see Routes#findWithObservation(Iterable, Observation, boolean) + */ + protected void selectRouteByObservation(Observation observation) { + + if (!routeSelectionIsAdjusting) { + + routeSelectionIsAdjusting = true; + + Route route = Routes.findWithObservation( + getModel().getRoutes(), observation, true); + + int routeIndex = getModel().indexOfRoutes(route); + SammoaUtil.selectTableRow(ui.getEffortPanel().getRouteTable(), routeIndex); + + routeSelectionIsAdjusting = false; + } + } + + /** + * Unselect the current observation if not in given {@code route}. + * An adjusting flag is used to avoid loop when the observation try to + * select the matching route with {@link #selectRouteByObservation(Observation)} + * + * @param route Route could be null + * @see Observations#inRoute(Observation, Route, Iterable, boolean) + */ + protected void selectObservationFromRoute(Route route) { + + if (!routeSelectionIsAdjusting) { + + routeSelectionIsAdjusting = true; + + if (route == null) { + SammoaUtil.unselectAll(ui.getEffortPanel().getObservationTable()); + + } else { + + // Remove observationEditBean if not in route + Observation previousObservation = getModel().getObservationEditBean(); + if (previousObservation != null + && !Observations.inRoute(previousObservation, route, getModel().getRoutes(), true)) { + + SammoaUtil.unselectAll(ui.getEffortPanel().getObservationTable()); + } + } + + routeSelectionIsAdjusting = false; + } + } + + /** + * Select the {@code transectFlight} that matches the given {@code route}. + * An adjusting flag is used to avoid loop when the transectFlight try to + * select its first route with {@link #selectRouteFromTransectFlight(TransectFlightModel)} + * + * @param route Route that contains the {@code transectFlight} + */ + protected void selectTransectFlightByRoute(Route route) { + + if (!transectFlightSelectionIsAdjusting) { + + transectFlightSelectionIsAdjusting = true; + + TransectFlight transectFlight = route.getTransectFlight(); + + // for TRANSIT/CIRCLE_BACK route, we unselect all the table + if (transectFlight == null) { + SammoaUtil.unselectAll(ui.getTransectTable()); + + } else { + + int index = TransectFlightModel.indexOfTransectFlight( + getModel().getTransectFlights(), transectFlight); + SammoaUtil.selectTableRow(ui.getTransectTable(), index); + } + + transectFlightSelectionIsAdjusting = false; + } + } + + /** + * Select the first route of the given {@code transectFlight}. If the + * {@code transectFlight} doesn't have any route, all the routeTable is + * unselected. + * An adjusting flag is used to avoid loop when the route try to + * select the matching transectFlight with {@link #selectTransectFlightByRoute(Route)} + * + * @param transectFlight TransectFlightModel + * @see Routes#withTransectFlight(Route, TransectFlight) + */ + protected void selectRouteFromTransectFlight(TransectFlightModel transectFlight) { + + if (!transectFlightSelectionIsAdjusting) { + + transectFlightSelectionIsAdjusting = true; + + Route route = FluentIterable + .from(getModel().getRoutes()) + .filter(Routes.withTransectFlight(transectFlight.getSource())) + .first() + .orNull(); + + if (route == null) { + SammoaUtil.unselectAll(ui.getEffortPanel().getRouteTable()); + + } else { + + int routeIndex = getModel().indexOfRoutes(route); + SammoaUtil.selectTableRow(ui.getEffortPanel().getRouteTable(), routeIndex); + } + + transectFlightSelectionIsAdjusting = false; + } + } + + protected GeoPoint ensureGeoPoint(Date date) { + + List<GeoPoint> modelPoints = getModel().getGeoPoints(); + GeoPoint result = Iterables.find(modelPoints, GeoPoints.withDate(date), null); + + if (result == null) { + FlightService service = context.getService(FlightService.class); + result = service.getGeoPoint(getModel().getFlight(), date); + modelPoints.add(result); + } + return result; + } + + protected void setAudioReaderPositionDate(Date date) { + AudioReader audioReader = getFlightController().getDeviceManager(AudioReader.class); + + // Change position only if AudioReader is ready (not running) + if (DeviceState.READY == audioReader.getState()) { + audioReader.setPositionDate(date); + } + } + + private void onTransectFlightChangedForValidation(TransectFlightModel oldValue, + TransectFlightModel newValue) { + + if (oldValue != null) { + oldValue.removePropertyChangeListener(transectFlightChangeListener); + + // Fire routes table (matching routes) + fireRoutesUpdated(oldValue, false); + } + + if (newValue != null) { + newValue.addPropertyChangeListener(transectFlightChangeListener); + + // Fire routes table (matching routes) + fireRoutesUpdated(newValue, true); + + // Select the first route + selectRouteFromTransectFlight(newValue); + + // Reset the ValidModel + getValidModel().resetTransectFlightValid(newValue.getSource()); + } + } + + private void onRouteChangedForValidation(Route oldValue, + Route newValue) { + + getFlightController().setCurrentRoute(newValue); + + if (oldValue != null) { + oldValue.removePropertyChangeListener(routeChangeListener); + } + + // unselect the observation if not matching the route + selectObservationFromRoute(newValue); + + if (newValue != null) { + newValue.addPropertyChangeListener(routeChangeListener); + + // Set audio position + setAudioReaderPositionDate(newValue.getBeginTime()); + + // Select the matching TransectFlight + selectTransectFlightByRoute(newValue); + + // Reset the ValidModel + getValidModel().resetRouteValid(newValue); + } + } + + private void onObservationChangedForValidation(Observation oldValue, + Observation newValue) { + + if (oldValue != null) { + oldValue.removePropertyChangeListener(observationChangeListener); + } + + if (newValue != null) { + newValue.addPropertyChangeListener(observationChangeListener); + + // Select the matching route + selectRouteByObservation(newValue); + + // Set audio position + setAudioReaderPositionDate(newValue.getObservationTime()); + + // Reset the ValidModel + getValidModel().resetObservationValid(newValue); + } + } + + private PropertyChangeListener observationChangeListener = new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + + Observation observation = (Observation) evt.getSource(); + + // Only on observationTime changed + if (evt.getPropertyName().equals(Observation.PROPERTY_OBSERVATION_TIME)) { + + GeoPoint geoPoint = ensureGeoPoint((Date) evt.getNewValue()); + + setObservationGeoPointInMap(observation, geoPoint); + + selectRouteByObservation(observation); + } + + // Reset ValidModel + getValidModel().resetObservationValid(observation); + } + }; + + private PropertyChangeListener routeChangeListener = new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + + Route route = (Route) evt.getSource(); + + // Only on beginTime changed + if (evt.getPropertyName().equals(Route.PROPERTY_BEGIN_TIME)) { + ensureGeoPoint((Date) evt.getNewValue()); + } + + // Reset ValidModel + getValidModel().resetRouteValid(route); + } + }; + + private PropertyChangeListener transectFlightChangeListener = new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + + TransectFlightModel transectFlight = (TransectFlightModel) evt.getSource(); + + // Reset ValidModel + getValidModel().resetTransectFlightValid(transectFlight.getSource()); + } + }; + + // ---------- COMMON LISTENERS -------- // + protected PropertyChangeListener flightObserversListener = new PropertyChangeListener() { @Override Added: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/ValidModel.java =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/ValidModel.java (rev 0) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/ValidModel.java 2012-09-26 13:12:08 UTC (rev 596) @@ -0,0 +1,202 @@ +package fr.ulr.sammoa.ui.swing.flight; + +/* + * #%L + * SAMMOA :: UI Swing + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 UMS 3462, Code Lutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Function; +import com.google.common.base.Throwables; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.Sets; +import fr.ulr.sammoa.persistence.Flight; +import fr.ulr.sammoa.persistence.Flights; +import fr.ulr.sammoa.persistence.Observation; +import fr.ulr.sammoa.persistence.Observations; +import fr.ulr.sammoa.persistence.Route; +import fr.ulr.sammoa.persistence.Routes; +import fr.ulr.sammoa.persistence.TransectFlight; +import fr.ulr.sammoa.persistence.TransectFlights; +import org.nuiton.validator.bean.list.BeanListValidator; + +import java.io.Serializable; +import java.util.Set; +import java.util.concurrent.ExecutionException; + +/** + * This model is used to keep validation for all routes, transectFlights and + * observations. This will avoid multiple check if not necessary. + * <p/> + * We use {@link CacheBuilder} that acts as {@link Function} for different + * validation check. + * <p/> + * Created: 25/09/12 + * + * @author fdesbois <florian.desbois@codelutin.com> + * @see Observations#isValid(Observation, BeanListValidator) + * @see Routes#isValid(Route, BeanListValidator, Iterable, Function) + * @see TransectFlights#isValid(TransectFlight, Iterable, Function) + * @see Flights#isValid(Flight, Iterable, Function, Function) + */ +public class ValidModel implements Serializable { + + private static final long serialVersionUID = 1L; + + protected LoadingCache<Observation, Boolean> observationValid; + + protected LoadingCache<Route, Boolean> routeValid; + + protected LoadingCache<TransectFlight, Boolean> transectFlightValid; + + protected BeanListValidator<Observation> observationValidator; + + protected BeanListValidator<Route> routeValidator; + + protected Set<ValidModelListener> listeners; + + public ValidModel(BeanListValidator<Observation> oValidator, + BeanListValidator<Route> rValidator) { + + this.observationValidator = oValidator; + this.routeValidator = rValidator; + this.listeners = Sets.newHashSet(); + + observationValid = CacheBuilder.newBuilder().build(new CacheLoader<Observation, Boolean>() { + + @Override + public Boolean load(Observation key) throws Exception { + boolean result = Observations.isValid(key, observationValidator); + return result; + } + }); + + routeValid = CacheBuilder.newBuilder().build(new CacheLoader<Route, Boolean>() { + + @Override + public Boolean load(Route key) throws Exception { + boolean result = Routes.isValid(key, routeValidator, observationValidator.getBeans(), observationValid); + return result; + } + }); + + transectFlightValid = CacheBuilder.newBuilder().build(new CacheLoader<TransectFlight, Boolean>() { + + @Override + public Boolean load(TransectFlight key) throws Exception { + boolean result = TransectFlights.isValid(key, routeValidator.getBeans(), routeValid); + return result; + } + }); + } + + public void cleanUpObservationValid() { + observationValid.cleanUp(); + } + + public void resetObservationValid(Observation observation) { + observationValid.invalidate(observation); + + // Reset the route + Route route = Routes.findWithObservation(routeValidator.getBeans(), observation, true); + resetRouteValid(route); + } + + public void cleanUpRouteValid() { + routeValid.cleanUp(); + } + + public void resetRouteValid(Route route) { + routeValid.invalidate(route); + + // Reset the transectFlight + if (route.getTransectFlight() != null) { + resetTransectFlightValid(route.getTransectFlight()); + + } else { + fireReset(); + } + } + + public void cleanUpTransectFlightValid() { + transectFlightValid.cleanUp(); + } + + public void resetTransectFlightValid(TransectFlight transectFlight) { + transectFlightValid.invalidate(transectFlight); + fireReset(); + } + + public boolean isObservationValid(Observation observation) { + try { + return observationValid.get(observation); + } catch (ExecutionException ex) { + throw Throwables.propagate(ex); + } + } + + public boolean isRouteValid(Route route) { + try { + return routeValid.get(route); + } catch (ExecutionException ex) { + throw Throwables.propagate(ex); + } + } + + public boolean isTransectFlightValid(TransectFlight transectFlight) { + try { + return transectFlightValid.get(transectFlight); + } catch (ExecutionException ex) { + throw Throwables.propagate(ex); + } + } + + public boolean isFlightValid(Flight flight) { + boolean result = Flights.isValid(flight, routeValidator.getBeans(), transectFlightValid, routeValid); + return result; + } + + public boolean getFlightValidFlag(Flight flight) { + boolean result = Flights.withValidFlag(flight, routeValidator); + return result; + } + + public void addValidModelListener(ValidModelListener listener) { + listeners.add(listener); + } + + public void removeValidModelListener(ValidModelListener listener) { + listeners.remove(listener); + } + + protected void fireReset() { + for (ValidModelListener listener : listeners) { + listener.onReset(this); + } + } + + public static interface ValidModelListener { + + void onReset(ValidModel source); + } +} Property changes on: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/ValidModel.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidAction.java =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidAction.java 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidAction.java 2012-09-26 13:12:08 UTC (rev 596) @@ -23,21 +23,17 @@ * #L% */ -import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; +import fr.ulr.sammoa.application.FlightService; import fr.ulr.sammoa.application.ValidationService; import fr.ulr.sammoa.persistence.Observation; import fr.ulr.sammoa.persistence.Route; -import fr.ulr.sammoa.persistence.Validable; -import fr.ulr.sammoa.ui.swing.SammoaUIContext; import fr.ulr.sammoa.ui.swing.flight.FlightUI; +import fr.ulr.sammoa.ui.swing.flight.FlightUIHandler; +import fr.ulr.sammoa.ui.swing.flight.ValidModel; import fr.ulr.sammoa.ui.swing.util.SammoaUtil; import jaxx.runtime.JAXXContext; -import org.nuiton.validator.bean.list.BeanListValidator; -import org.nuiton.validator.bean.list.BeanListValidatorEvent; -import org.nuiton.validator.bean.list.BeanListValidatorListener; -import java.util.Map; +import java.util.List; import static org.nuiton.i18n.I18n._; @@ -48,65 +44,81 @@ */ public abstract class ValidAction extends BaseFlightAction { - protected ValidationService validationService; +// private Map<Class<?>, BeanListValidator<?>> validators; - protected Map<Class<?>, BeanListValidator<?>> validators = Maps.newHashMap(); - public ValidAction(String name, JAXXContext context) { super(name, context); - } + getValidModel().addValidModelListener(new ValidModel.ValidModelListener() { - protected ValidationService getValidationService() { - if (validationService == null) { - validationService = - SammoaUIContext.getUIContext().getService(ValidationService.class); - } - return validationService; + @Override + public void onReset(ValidModel source) { + setEnabled(checkEnabled()); + } + }); } +// +// protected Map<Class<?>, BeanListValidator<?>> getValidators() { +// if (validators == null) { +// validators = Maps.newHashMap(); +// } +// return validators; +// } - /** - * Retrieve a validator for the {@code beanClass}. A cache - * is used to keep the validator for this property. A listener is also - * used to call checkEnabled() on each validation change. - * - * @param beanClass Class of the bean - * @param <E> generic type of the bean - * @return the {@link BeanListValidator} found - * @throws NullPointerException if no validator exists in context for the - * given {@code modelPropertyName} - */ - private <E extends Validable> BeanListValidator<E> getValidator(Class<E> beanClass) { - BeanListValidator<E> validator = (BeanListValidator<E>) validators.get(beanClass); - if (validator == null) { - String prefix = beanClass.getSimpleName().toLowerCase(); - String contextValueName = prefix + "Validator"; - validator = context.getContextValue(BeanListValidator.class, - contextValueName); - Preconditions.checkNotNull(validator, - "No validator exists for bean type : " - + beanClass.getName() - + " (property from context = " - + contextValueName + ")" - ); - validator.addBeanListValidatorListener(new BeanListValidatorListener() { - - @Override - public void onFieldChanged(BeanListValidatorEvent event) { - setEnabled(checkEnabled()); - } - }); - validators.put(beanClass, validator); - } - return validator; + protected ValidModel getValidModel() { + return context.getContextValue(FlightUIHandler.class).getValidModel(); } - protected BeanListValidator<Route> getRouteValidator() { - return getValidator(Route.class); + protected ValidationService getValidationService() { + return getSammoaUIContext().getService(ValidationService.class); } - protected BeanListValidator<Observation> getObservationValidator() { - return getValidator(Observation.class); + protected FlightService getFlightService() { + return getSammoaUIContext().getService(FlightService.class); } +// +// /** +// * Retrieve a validator for the {@code beanClass}. A cache +// * is used to keep the validator for this property. A listener is also +// * used to call checkEnabled() on each validation change. +// * +// * @param beanClass Class of the bean +// * @param <E> generic type of the bean +// * @return the {@link BeanListValidator} found +// * @throws NullPointerException if no validator exists in context for the +// * given {@code modelPropertyName} +// */ +// private <E extends Validable> BeanListValidator<E> getValidator(Class<E> beanClass) { +// BeanListValidator<E> validator = (BeanListValidator<E>) getValidators().get(beanClass); +// if (validator == null) { +// String prefix = beanClass.getSimpleName().toLowerCase(); +// String contextValueName = prefix + "Validator"; +// validator = context.getContextValue(BeanListValidator.class, +// contextValueName); +// Preconditions.checkNotNull(validator, +// "No validator exists for bean type : " +// + beanClass.getName() +// + " (property from context = " +// + contextValueName + ")" +// ); +// validator.addBeanListValidatorListener(new BeanListValidatorListener() { +// +// @Override +// public void onFieldChanged(BeanListValidatorEvent event) { +// setEnabled(checkEnabled()); +// } +// }); +// getValidators().put(beanClass, validator); +// } +// return validator; +// } +// +// protected BeanListValidator<Route> getRouteValidator() { +// return getValidator(Route.class); +// } +// +// protected BeanListValidator<Observation> getObservationValidator() { +// return getValidator(Observation.class); +// } protected boolean askConfirmDelete(String label) { return SammoaUtil.askQuestion( @@ -122,4 +134,35 @@ _("sammoa.confirmDialog.validation.deleteByCascade.message", label, cascadeLabel) ); } + + protected void reloadObservations() { + + getModel().setObservationEditBean(null); + + // Reload all observations + getModel().clearObservation(); + List<Observation> observations = + getFlightService().getObservations(getModel().getFlight()); + getModel().addAllObservation(observations); + + getValidModel().cleanUpObservationValid(); + } + + protected void reloadRoutes() { + + Route routeEditBean = getModel().getRouteEditBean(); + getModel().setRouteEditBean(null); + + // Reload all routes + getModel().clearRoute(); + List<Route> routes = getFlightService().getRoutes(getModel().getFlight()); + getModel().addAllRoute(routes); + + // Keep the route selected + if (routeEditBean != null && !routeEditBean.isDeleted()) { + getModel().setRouteEditBean(routeEditBean); + } + + getValidModel().cleanUpRouteValid(); + } } Added: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidFlightAction.java =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidFlightAction.java (rev 0) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidFlightAction.java 2012-09-26 13:12:08 UTC (rev 596) @@ -0,0 +1,123 @@ +package fr.ulr.sammoa.ui.swing.flight.action; +/* + * #%L + * SAMMOA :: UI Swing + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 UMS 3462, Code Lutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import fr.ulr.sammoa.persistence.Flight; +import fr.ulr.sammoa.persistence.Route; +import fr.ulr.sammoa.persistence.TransectFlight; +import fr.ulr.sammoa.persistence.Validables; +import jaxx.runtime.JAXXContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.Action; +import java.awt.event.ActionEvent; +import java.util.List; + +import static org.nuiton.i18n.I18n._; + +/** + * Created: 23/08/12 + * + * @author fdesbois <florian.desbois@codelutin.com> + */ +public class ValidFlightAction extends ValidAction { + + /** Logger. */ + private static final Logger logger = LoggerFactory.getLogger(ValidFlightAction.class); + + private static final long serialVersionUID = 1L; + + protected boolean validatorIsAdjusting; + + public ValidFlightAction(JAXXContext context) { + super(_("sammoa.action.validFlight"), context); + putValue(Action.SHORT_DESCRIPTION, _("sammoa.action.validFlight.tip")); + } + + @Override + public void actionPerformed(ActionEvent e) { + + Flight flight = getModel().getFlight(); + List<TransectFlight> transectFlights = flight.getTransectFlight(); + boolean hasDeletedTransect = Validables.isAnyDeleted(transectFlights); + + if (!hasDeletedTransect + || askConfirmDeleteByCascade(_("sammoa.validable.flight"), + _("sammoa.validable.transect"))) { + + List<Route> routes = getModel().getRoutes(); + + boolean hasDeletedRoute = Validables.isAnyDeleted(routes); + + if (!hasDeletedRoute + || askConfirmDeleteByCascade(_("sammoa.validable.flight"), + _("sammoa.validable.route"))) { + + boolean hasDeletedObservation = Validables.isAnyDeleted(getModel().getObservations()); + + if (!hasDeletedObservation + || askConfirmDeleteByCascade(_("sammoa.validable.flight"), + _("sammoa.validable.observation"))) { + + // Toggle valid value + boolean valid = !getValidModel().getFlightValidFlag(flight); + + getValidationService().validateFlight(flight, routes, valid); + + validatorIsAdjusting = true; + + // Update all transectFlights + for (TransectFlight transectFlight : transectFlights) { + getModel().updateTransectFlight(transectFlight); + } + getValidModel().cleanUpTransectFlightValid(); + + reloadRoutes(); + + reloadObservations(); + + validatorIsAdjusting = false; + } + } + } + } + + @Override + protected boolean checkEnabled() { + boolean result = isEnabled(); + if (!validatorIsAdjusting) { + + Flight flight = getModel().getFlight(); + List<Route> routes = getModel().getRoutes(); + + result = getValidModel().isFlightValid(flight); + + if (logger.isDebugEnabled()) { + logger.debug("Flight is valid : {}", result); + } + } + return result; + } +} Property changes on: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidFlightAction.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidObservationAction.java =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidObservationAction.java 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidObservationAction.java 2012-09-26 13:12:08 UTC (rev 596) @@ -24,8 +24,6 @@ */ import fr.ulr.sammoa.persistence.Observation; -import fr.ulr.sammoa.persistence.Observations; -import fr.ulr.sammoa.ui.swing.flight.FlightUIModel; import jaxx.runtime.JAXXContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,7 +48,6 @@ public ValidObservationAction(JAXXContext context) { super(_("sammoa.action.validObservation"), context); putValue(Action.SHORT_DESCRIPTION, _("sammoa.action.validObservation.tip")); - bindModelProperty(FlightUIModel.PROPERTY_OBSERVATION_EDIT_BEAN, true); } @Override @@ -83,9 +80,9 @@ protected boolean checkEnabled() { Observation observation = getModel().getObservationEditBean(); if (observation != null && logger.isDebugEnabled()) { - logger.debug("Check valid observation : {}", Observations.isValid(observation, getObservationValidator())); + logger.debug("Check valid observation : {}", getValidModel().isObservationValid(observation)); } return observation != null - && Observations.isValid(observation, getObservationValidator()); + && getValidModel().isObservationValid(observation); } } Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidRouteAction.java =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidRouteAction.java 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidRouteAction.java 2012-09-26 13:12:08 UTC (rev 596) @@ -23,11 +23,8 @@ * #L% */ -import fr.ulr.sammoa.application.FlightService; import fr.ulr.sammoa.persistence.Observations; import fr.ulr.sammoa.persistence.Route; -import fr.ulr.sammoa.persistence.Routes; -import fr.ulr.sammoa.ui.swing.flight.FlightUIModel; import jaxx.runtime.JAXXContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,8 +51,6 @@ public ValidRouteAction(JAXXContext context) { super(_("sammoa.action.validRoute"), context); putValue(Action.SHORT_DESCRIPTION, _("sammoa.action.validRoute.tip")); - bindModelProperty(FlightUIModel.PROPERTY_OBSERVATION_EDIT_BEAN, true); - bindModelProperty(FlightUIModel.PROPERTY_ROUTE_EDIT_BEAN, true); } @Override @@ -95,14 +90,8 @@ getModel().setRouteEditBean(routeChanged); - getModel().setObservationEditBean(null); + reloadObservations(); - // Reload all observations - FlightService service = - getSammoaUIContext().getService(FlightService.class); - getModel().clearObservation(); - getModel().addAllObservation(service.getObservations(getModel().getFlight())); - validatorIsAdjusting = false; } } @@ -115,29 +104,8 @@ if (!validatorIsAdjusting) { Route bean = getModel().getRouteEditBean(); result = bean != null - && Routes.isValid(bean, getRouteValidator(), getObservationValidator()); + && getValidModel().isRouteValid(bean); } return result; } - - protected void doValid(Route route) { - - Route routeChanged = getValidationService().validateRoute(route); - getModel().updateRoute(routeChanged); - - validatorIsAdjusting = true; - - getModel().setCurrentRoute(routeChanged); - getModel().setRouteEditBean(routeChanged); - - getModel().setObservationEditBean(null); - - // Reload all observations - FlightService service = - getSammoaUIContext().getService(FlightService.class); - getModel().clearObservation(); - getModel().addAllObservation(service.getObservations(getModel().getFlight())); - - validatorIsAdjusting = false; - } } Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidTransectAction.java =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidTransectAction.java 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/action/ValidTransectAction.java 2012-09-26 13:12:08 UTC (rev 596) @@ -24,14 +24,11 @@ */ import com.google.common.collect.FluentIterable; -import fr.ulr.sammoa.application.FlightService; import fr.ulr.sammoa.persistence.Observations; import fr.ulr.sammoa.persistence.Route; import fr.ulr.sammoa.persistence.Routes; import fr.ulr.sammoa.persistence.TransectFlight; -import fr.ulr.sammoa.persistence.TransectFlights; import fr.ulr.sammoa.persistence.Validables; -import fr.ulr.sammoa.ui.swing.flight.FlightUIModel; import fr.ulr.sammoa.ui.swing.flight.TransectFlightModel; import jaxx.runtime.JAXXContext; import org.slf4j.Logger; @@ -59,9 +56,6 @@ public ValidTransectAction(JAXXContext context) { super(_("sammoa.action.validTransect"), context); putValue(Action.SHORT_DESCRIPTION, _("sammoa.action.validTransect.tip")); - bindModelProperty(FlightUIModel.PROPERTY_OBSERVATION_EDIT_BEAN, true); - bindModelProperty(FlightUIModel.PROPERTY_ROUTE_EDIT_BEAN, true); - bindModelProperty(FlightUIModel.PROPERTY_TRANSECT_FLIGHT_EDIT_BEAN, true); } @Override @@ -118,26 +112,10 @@ validatorIsAdjusting = true; - Route routeEditBean = getModel().getRouteEditBean(); - getModel().setRouteEditBean(null); + reloadRoutes(); - // Reload all routes - FlightService service = - getSammoaUIContext().getService(FlightService.class); - getModel().clearRoute(); - getModel().addAllRoute(service.getRoutes(getModel().getFlight())); + reloadObservations(); - // Keep the route selected - if (routeEditBean != null && !routeEditBean.isDeleted()) { - getModel().setRouteEditBean(routeEditBean); - } - - getModel().setObservationEditBean(null); - - // Reload all observations - getModel().clearObservation(); - getModel().addAllObservation(service.getObservations(getModel().getFlight())); - validatorIsAdjusting = false; } } @@ -150,10 +128,8 @@ boolean result = isEnabled(); if (!validatorIsAdjusting) { TransectFlightModel bean = getModel().getTransectFlightEditBean(); - result = bean != null && - TransectFlights.isValid(bean.getSource(), - getRouteValidator(), - getObservationValidator()); + result = bean != null + && getValidModel().isTransectFlightValid(bean.getSource()); } return result; } Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/validation/ValidationBar.css =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/validation/ValidationBar.css 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/validation/ValidationBar.css 2012-09-26 13:12:08 UTC (rev 596) @@ -26,6 +26,10 @@ text: {dateFormat.format(model.getCurrentRoute().getBeginTime())}; } +#validFlightButton { + _actionName: {"validFlight"}; +} + #validTransectButton { _actionName: {"validTransect"}; } Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/validation/ValidationBar.jaxx =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/validation/ValidationBar.jaxx 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/bar/validation/ValidationBar.jaxx 2012-09-26 13:12:08 UTC (rev 596) @@ -57,6 +57,7 @@ <cell fill='horizontal' weightx='0.2'> <JPanel id='validButtonPanel' layout='{new BoxLayout(validButtonPanel, BoxLayout.X_AXIS)}'> + <JButton id='validFlightButton'/> <JButton id='validTransectButton'/> <JButton id='validRouteButton'/> <JButton id='validObservationButton'/> Modified: trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/effort/EffortPanelHandler.java =================================================================== --- trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/effort/EffortPanelHandler.java 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-ui-swing/src/main/java/fr/ulr/sammoa/ui/swing/flight/effort/EffortPanelHandler.java 2012-09-26 13:12:08 UTC (rev 596) @@ -27,17 +27,13 @@ import com.google.common.base.Objects; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; import fr.ulr.sammoa.application.FlightService; import fr.ulr.sammoa.application.device.DeviceState; import fr.ulr.sammoa.application.device.DeviceStateEvent; import fr.ulr.sammoa.application.device.DeviceStateListener; -import fr.ulr.sammoa.application.device.audio.AudioReader; import fr.ulr.sammoa.application.device.audio.AudioRecorder; import fr.ulr.sammoa.application.device.gps.GpsHandler; import fr.ulr.sammoa.application.flightController.FlightController; -import fr.ulr.sammoa.persistence.GeoPoint; -import fr.ulr.sammoa.persistence.GeoPoints; import fr.ulr.sammoa.persistence.Observation; import fr.ulr.sammoa.persistence.ObservationStatus; import fr.ulr.sammoa.persistence.Observations; @@ -359,33 +355,6 @@ FlightUIModel.PROPERTY_ROUTES, new TableDataChangeListener(table, columnToEditOnInsert) ); - - if (getModel().isValidationMode()) { - - // FlightController # change current route - getModel().addPropertyChangeListener( - FlightUIModel.PROPERTY_ROUTE_EDIT_BEAN, new PropertyChangeListener() { - - @Override - public void propertyChange(PropertyChangeEvent evt) { - onRouteChangedForValidation( - (Route) evt.getOldValue(), - (Route) evt.getNewValue()); - } - }); - - // Refresh matching routes from selected transectFlight - getModel().addPropertyChangeListener( - FlightUIModel.PROPERTY_TRANSECT_FLIGHT_EDIT_BEAN, new PropertyChangeListener() { - - @Override - public void propertyChange(PropertyChangeEvent evt) { - onTransectFlightChangedForValidation( - (TransectFlightModel) evt.getOldValue(), - (TransectFlightModel) evt.getNewValue()); - } - }); - } } BeanListValidator<Route> validator = ui.getRouteValidator(); @@ -569,20 +538,7 @@ } }); - if (getModel().isValidationMode()) { - - getModel().addPropertyChangeListener( - FlightUIModel.PROPERTY_OBSERVATION_EDIT_BEAN, new PropertyChangeListener() { - - @Override - public void propertyChange(PropertyChangeEvent evt) { - onObservationChangedForValidation( - (Observation) evt.getOldValue(), - (Observation) evt.getNewValue()); - } - }); - - } else { + if (!getModel().isValidationMode()) { flightController.getDeviceManager(GpsHandler.class).addDeviceStateListener(this); flightController.getDeviceManager(AudioRecorder.class).addDeviceStateListener(this); } @@ -789,16 +745,6 @@ return getModel().isValidationMode() ? "validation" : "onBoard"; } - protected void setAudioReaderPositionDate(Date date) { - FlightController flightController = getParentUI().getHandler().getFlightController(); - AudioReader audioReader = flightController.getDeviceManager(AudioReader.class); - - // Change position only if AudioReader is ready (not running) - if (DeviceState.READY == audioReader.getState()) { - audioReader.setPositionDate(date); - } - } - protected void fireObservationsUpdated(Route route, boolean scrollToFirst) { Iterable<Observation> observations = Observations.filterInRoute( @@ -810,26 +756,6 @@ scrollToFirst); } - protected void fireRoutesUpdated(TransectFlightModel transectFlight, boolean scrollToFirst) { - - Iterable<Route> routes = Iterables.filter( - getModel().getRoutes(), Routes.withTransectFlight(transectFlight.getSource())); - - SammoaUtil.fireTableRowsUpdated(ui.getRouteTable(), - getModel().getRoutes(), - routes, - scrollToFirst); - } - - protected void selectRouteByObservation(Observation observation) { - - Route route = Routes.findWithObservation( - getModel().getRoutes(), observation, true); - - int routeIndex = getModel().indexOfRoutes(route); - SammoaUtil.selectTableRow(ui.getRouteTable(), routeIndex); - } - private void onRouteChanged(Route oldValue, Route newValue) { if (oldValue != null) { @@ -854,104 +780,6 @@ } } - private void onTransectFlightChangedForValidation(TransectFlightModel oldValue, - TransectFlightModel newValue) { - if (oldValue != null) { - fireRoutesUpdated(oldValue, false); - } - if (newValue != null) { - fireRoutesUpdated(newValue, true); - } - } - - private void onRouteChangedForValidation(Route oldValue, - Route newValue) { - - getParentUI().getHandler().getFlightController().setCurrentRoute(newValue); - - if (oldValue != null) { - oldValue.removePropertyChangeListener( - Route.PROPERTY_BEGIN_TIME, routeTimeChangeListener); - } - - if (newValue == null) { - // no unselect but ensure valid button (a select will cause a loop) - getModel().setObservationEditBean(null); - - } else { - - newValue.addPropertyChangeListener( - Route.PROPERTY_BEGIN_TIME, routeTimeChangeListener); - - // Set audio position - setAudioReaderPositionDate(newValue.getBeginTime()); - - // Remove observationEditBean if not in route - Observation previousObservation = getModel().getObservationEditBean(); - if (previousObservation != null - && !Observations.inRoute(previousObservation, newValue, getModel().getRoutes(), true)) { - - // no unselect but ensure valid button (a select will cause a loop) - getModel().setObservationEditBean(null); - } - } - } - - private void onObservationChangedForValidation(Observation oldValue, - Observation newValue) { - - if (oldValue != null) { - oldValue.removePropertyChangeListener( - Observation.PROPERTY_OBSERVATION_TIME, observationTimeChangeListener); - } - - if (newValue != null) { - newValue.addPropertyChangeListener( - Observation.PROPERTY_OBSERVATION_TIME, observationTimeChangeListener); - - selectRouteByObservation(newValue); - - // Set audio position - setAudioReaderPositionDate(newValue.getObservationTime()); - } - } - - protected GeoPoint ensureGeoPoint(Date date) { - - List<GeoPoint> modelPoints = getModel().getGeoPoints(); - GeoPoint result = Iterables.find(modelPoints, GeoPoints.withDate(date), null); - - if (result == null) { - FlightService service = context.getService(FlightService.class); - result = service.getGeoPoint(getModel().getFlight(), date); - modelPoints.add(result); - } - return result; - } - - private PropertyChangeListener routeTimeChangeListener = new PropertyChangeListener() { - - @Override - public void propertyChange(PropertyChangeEvent evt) { - ensureGeoPoint((Date) evt.getNewValue()); - } - }; - - private PropertyChangeListener observationTimeChangeListener = new PropertyChangeListener() { - - @Override - public void propertyChange(PropertyChangeEvent evt) { - - Observation observation = (Observation) evt.getSource(); - - GeoPoint geoPoint = ensureGeoPoint((Date) evt.getNewValue()); - - getParentUI().getHandler().setObservationGeoPointInMap(observation, geoPoint); - - selectRouteByObservation(observation); - } - }; - private PropertyChangeListener observationSpeciesChangeListener = new PropertyChangeListener() { @Override Modified: trunk/sammoa-ui-swing/src/main/resources/i18n/sammoa-ui-swing_en_GB.properties =================================================================== --- trunk/sammoa-ui-swing/src/main/resources/i18n/sammoa-ui-swing_en_GB.properties 2012-09-25 13:51:43 UTC (rev 595) +++ trunk/sammoa-ui-swing/src/main/resources/i18n/sammoa-ui-swing_en_GB.properties 2012-09-26 13:12:08 UTC (rev 596) @@ -55,6 +55,8 @@ sammoa.action.stop=Stop flight sammoa.action.stop.tip=STOP \: stop the flight. No other actions on routes and sightings could be done after stop. sammoa.action.stopAudio.tip=Stop audio +sammoa.action.validFlight=Flight +sammoa.action.validFlight.tip=Validate the flight, all the transects, routes and observations sammoa.action.validObservation=Sighting sammoa.action.validObservation.tip=Validate the selected sighting sammoa.action.validRoute=Route @@ -271,6 +273,7 @@ sammoa.title.flight=System %1$s - Campaign %2$s - Region %3$s - Flight n°%4$d sammoa.title.home=Home sammoa.title.importApplication=Application import +sammoa.validable.flight=flight sammoa.validable.observation=sighting sammoa.validable.route=route sammoa.validable.transect=transect
participants (1)
-
fdesbois@users.forge.codelutin.com