Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe

Commits:

10 changed files:

Changes:

  • client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/navigation/NavigationTree.java
    ... ... @@ -32,6 +32,7 @@ import org.jdesktop.swingx.JXTree;
    32 32
     import javax.swing.SwingUtilities;
    
    33 33
     import javax.swing.tree.TreeNode;
    
    34 34
     import javax.swing.tree.TreePath;
    
    35
    +import java.util.Arrays;
    
    35 36
     
    
    36 37
     /**
    
    37 38
      * Created on 14/11/16.
    
    ... ... @@ -77,7 +78,7 @@ public class NavigationTree extends JXTree {
    77 78
          * @param node the node to select
    
    78 79
          */
    
    79 80
         public void selectSafeNode(TreeNode node) {
    
    80
    -        log.info("try to select node [" + node + "]");
    
    81
    +        log.info(String.format("try to select safe node [%s]", node));
    
    81 82
             TreePath path = new TreePath(getModel().getPathToRoot(node));
    
    82 83
             getSelectionModel().setSkipCheckPreviousContent(true);
    
    83 84
             try {
    
    ... ... @@ -89,7 +90,7 @@ public class NavigationTree extends JXTree {
    89 90
         }
    
    90 91
     
    
    91 92
         public void reSelectSafeNode(TreeNode node) {
    
    92
    -        log.info("try to select node [" + node + "]");
    
    93
    +        log.info(String.format("try to reselect safe node [%s]", node));
    
    93 94
             TreePath path = new TreePath(getModel().getPathToRoot(node));
    
    94 95
             getSelectionModel().clearSelection();
    
    95 96
             getSelectionModel().setSkipCheckPreviousContent(true);
    
    ... ... @@ -101,6 +102,14 @@ public class NavigationTree extends JXTree {
    101 102
             SwingUtilities.invokeLater(() -> scrollPathToVisible(path));
    
    102 103
         }
    
    103 104
     
    
    105
    +    public boolean isRowSelected(int requiredRow) {
    
    106
    +        int[] selectedRows = getSelectionRows();
    
    107
    +        if (selectedRows != null) {
    
    108
    +            return Arrays.stream(selectedRows).anyMatch(selectedRow -> requiredRow == selectedRow);
    
    109
    +        }
    
    110
    +        return false;
    
    111
    +    }
    
    112
    +
    
    104 113
         /**
    
    105 114
          * Selects the given {@code node} in the registered tree.
    
    106 115
          *
    
    ... ... @@ -111,7 +120,7 @@ public class NavigationTree extends JXTree {
    111 120
                 log.error("Can't load null node.", new NullPointerException());
    
    112 121
                 return;
    
    113 122
             }
    
    114
    -        log.info("try to select node [" + node + "]");
    
    123
    +        log.info(String.format("try to select node [%s]", node));
    
    115 124
             TreePath path = new TreePath(getModel().getPathToRoot(node));
    
    116 125
             setSelectionPath(path);
    
    117 126
             SwingUtilities.invokeLater(() -> scrollPathToVisible(path));
    

  • client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/navigation/NavigationTreeSelectionListenerImpl.java
    ... ... @@ -34,16 +34,21 @@ import fr.ird.observe.dto.ObserveUtil;
    34 34
     import org.apache.logging.log4j.LogManager;
    
    35 35
     import org.apache.logging.log4j.Logger;
    
    36 36
     
    
    37
    +import javax.swing.SwingUtilities;
    
    37 38
     import javax.swing.event.TreeExpansionEvent;
    
    38 39
     import javax.swing.event.TreeSelectionEvent;
    
    39 40
     import javax.swing.event.TreeSelectionListener;
    
    40 41
     import javax.swing.tree.ExpandVetoException;
    
    41 42
     import javax.swing.tree.TreePath;
    
    43
    +import java.awt.Point;
    
    44
    +import java.awt.Rectangle;
    
    45
    +import java.awt.event.MouseEvent;
    
    46
    +import java.awt.event.MouseListener;
    
    42 47
     import java.util.Objects;
    
    43 48
     
    
    44 49
     import static io.ultreia.java4all.i18n.I18n.t;
    
    45 50
     
    
    46
    -class NavigationTreeSelectionListenerImpl implements fr.ird.observe.client.datasource.editor.api.navigation.event.NavigationTreeSelectionListener, TreeSelectionListener {
    
    51
    +class NavigationTreeSelectionListenerImpl implements fr.ird.observe.client.datasource.editor.api.navigation.event.NavigationTreeSelectionListener, TreeSelectionListener, MouseListener {
    
    47 52
         private static final Logger log = LogManager.getLogger(NavigationTreeSelectionListenerImpl.class);
    
    48 53
     
    
    49 54
         private final ClientUIContext clientUIContext;
    
    ... ... @@ -51,6 +56,7 @@ class NavigationTreeSelectionListenerImpl implements fr.ird.observe.client.datas
    51 56
         private final NavigationUI ui;
    
    52 57
         private final DataSourceEditorModel dataSourceEditorModel;
    
    53 58
         private final NavigationTree tree;
    
    59
    +    private int rowToSelect;
    
    54 60
     
    
    55 61
         NavigationTreeSelectionListenerImpl(DataSourceEditorModel dataSourceEditorModel, ContentUIManager contentUIManager, NavigationUI ui, NavigationTree tree) {
    
    56 62
             this.dataSourceEditorModel = Objects.requireNonNull(dataSourceEditorModel);
    
    ... ... @@ -160,4 +166,108 @@ class NavigationTreeSelectionListenerImpl implements fr.ird.observe.client.datas
    160 166
     
    
    161 167
             ObserveUtil.cleanMemory();
    
    162 168
         }
    
    169
    +
    
    170
    +
    
    171
    +    @Override
    
    172
    +    public void mouseClicked(MouseEvent e) {
    
    173
    +        if (!tree.isEnabled()) {
    
    174
    +            return;
    
    175
    +        }
    
    176
    +        if (e.isConsumed()) {
    
    177
    +            return;
    
    178
    +        }
    
    179
    +        boolean rightClick = SwingUtilities.isRightMouseButton(e);
    
    180
    +
    
    181
    +        boolean doubleClick = e.getClickCount() == 2;
    
    182
    +        // get the coordinates of the mouse click
    
    183
    +        Point p = e.getPoint();
    
    184
    +
    
    185
    +        int closestRowForLocation = tree.getClosestRowForLocation(e.getX(), e.getY());
    
    186
    +
    
    187
    +        log.info(String.format("Click on navigation tree: (rightClick? %b, doubleClick? %b) - at row %s (point %s)", rightClick, doubleClick, closestRowForLocation, p));
    
    188
    +
    
    189
    +        if (e.getClickCount() == 1) {
    
    190
    +            // need to compute row to select
    
    191
    +            rowToSelect = -1;
    
    192
    +            if (tree.isRowSelected(closestRowForLocation)) {
    
    193
    +                rowToSelect = closestRowForLocation;
    
    194
    +            } else {
    
    195
    +
    
    196
    +                // try to change selection
    
    197
    +
    
    198
    +                TreePath pathForRow = tree.getPathForRow(closestRowForLocation);
    
    199
    +                if (pathForRow == null) {
    
    200
    +                    e.consume();
    
    201
    +                    return;
    
    202
    +                }
    
    203
    +                Rectangle pathBounds = tree.getPathBounds(pathForRow);
    
    204
    +                if (pathBounds != null && pathBounds.getX() > p.getX()) {
    
    205
    +                    // we never acts when point is before the rectangle, because the arrow button may be used for this...
    
    206
    +                    log.info("Cancel click on tree navigation (before path rectangle (probably on arrow button)");
    
    207
    +                    e.consume();
    
    208
    +                    return;
    
    209
    +                }
    
    210
    +                log.info(String.format("Do select row: %d", closestRowForLocation));
    
    211
    +                tree.setSelectionPath(pathForRow);
    
    212
    +
    
    213
    +                if (tree.isRowSelected(closestRowForLocation)) {
    
    214
    +                    rowToSelect = closestRowForLocation;
    
    215
    +                }
    
    216
    +            }
    
    217
    +        } else {
    
    218
    +
    
    219
    +            // re-use previous rowToSelect
    
    220
    +            if (rowToSelect == -1) {
    
    221
    +                log.info("Cancel double-click, no previous rowToSelect");
    
    222
    +                e.consume();
    
    223
    +                return;
    
    224
    +            }
    
    225
    +        }
    
    226
    +
    
    227
    +        if (rowToSelect == -1) {
    
    228
    +            e.consume();
    
    229
    +            return;
    
    230
    +        }
    
    231
    +
    
    232
    +        // Never apply double click, go instable behaviour with existing code
    
    233
    +//        if (doubleClick) {
    
    234
    +//            TreePath pathForRow = tree.getPathForRow(rowToSelect);
    
    235
    +//            Rectangle pathBounds = tree.getPathBounds(pathForRow);
    
    236
    +//            if (pathBounds != null && pathBounds.getX() < p.getX() && !pathBounds.contains(p)) {
    
    237
    +//                // when after the rectangle of the path, then do the collapse/expand action (tree does not manage this cas)
    
    238
    +//                // we never acts when point is before the rectangle, because the arrow button may be used for this...
    
    239
    +//                boolean expanded = tree.isExpanded(pathForRow);
    
    240
    +//                SwingUtilities.invokeLater(() -> {
    
    241
    +//                    if (expanded) {
    
    242
    +//                        log.info(String.format("do collapse row: %s", pathBounds));
    
    243
    +//                        tree.collapsePath(pathForRow);
    
    244
    +//                    } else {
    
    245
    +//                        log.info(String.format("do expand row: %s", pathBounds));
    
    246
    +//                        tree.expandPath(pathForRow);
    
    247
    +//                    }
    
    248
    +//                });
    
    249
    +//                e.consume();
    
    250
    +//            }
    
    251
    +//        }
    
    252
    +    }
    
    253
    +
    
    254
    +    @Override
    
    255
    +    public void mousePressed(MouseEvent e) {
    
    256
    +        // do nothing
    
    257
    +    }
    
    258
    +
    
    259
    +    @Override
    
    260
    +    public void mouseReleased(MouseEvent e) {
    
    261
    +        // do nothing
    
    262
    +    }
    
    263
    +
    
    264
    +    @Override
    
    265
    +    public void mouseEntered(MouseEvent e) {
    
    266
    +        // do nothing
    
    267
    +    }
    
    268
    +
    
    269
    +    @Override
    
    270
    +    public void mouseExited(MouseEvent e) {
    
    271
    +        // do nothing
    
    272
    +    }
    
    163 273
     }

  • client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/navigation/NavigationTreeShowPopupHandler.java
    ... ... @@ -33,7 +33,6 @@ import javax.swing.AbstractButton;
    33 33
     import javax.swing.JMenuItem;
    
    34 34
     import javax.swing.JPopupMenu;
    
    35 35
     import javax.swing.SwingUtilities;
    
    36
    -import javax.swing.tree.TreePath;
    
    37 36
     import java.awt.Point;
    
    38 37
     import java.awt.Rectangle;
    
    39 38
     import java.awt.event.KeyEvent;
    
    ... ... @@ -68,11 +67,11 @@ public class NavigationTreeShowPopupHandler implements KeyListener, MouseListene
    68 67
     
    
    69 68
         private void showPopup(int row, Point p) {
    
    70 69
     
    
    71
    -        log.info("Will show popup from row: " + row);
    
    70
    +        log.info(String.format("Will show popup from row: %d", row));
    
    72 71
     
    
    73 72
             NavigationNode selectedNode = tree.getNodeForRow(row);
    
    74 73
     
    
    75
    -        log.info("Found selected node: " + selectedNode);
    
    74
    +        log.info(String.format("Found selected node: %s", selectedNode));
    
    76 75
     
    
    77 76
             SwingUtilities.invokeLater(() -> {
    
    78 77
                 beforeOpenPopup(selectedNode);
    
    ... ... @@ -97,7 +96,6 @@ public class NavigationTreeShowPopupHandler implements KeyListener, MouseListene
    97 96
             Arrays.stream(selectedContentUI.getInsertPopup().getSubElements()).forEach(a -> new ContentUIMenuAction(popup, (AbstractButton) a).init());
    
    98 97
             if (popup.getSubElements().length > length) {
    
    99 98
                 popup.addSeparator();
    
    100
    -//            length = popup.getSubElements().length;
    
    101 99
             }
    
    102 100
             Arrays.stream(selectedContentUI.getConfigurePopup().getSubElements()).forEach(a -> new ContentUIMenuAction(popup, (AbstractButton) a).init());
    
    103 101
             length = popup.getSubElements().length;
    
    ... ... @@ -106,22 +104,6 @@ public class NavigationTreeShowPopupHandler implements KeyListener, MouseListene
    106 104
             }
    
    107 105
         }
    
    108 106
     
    
    109
    -    private boolean isRowSelected(int requiredRow) {
    
    110
    -        boolean result = false;
    
    111
    -        int[] selectedRows = tree.getSelectionRows();
    
    112
    -        if (selectedRows != null) {
    
    113
    -            for (int selectedRow : selectedRows) {
    
    114
    -                if (requiredRow == selectedRow) {
    
    115
    -
    
    116
    -                    // match
    
    117
    -                    result = true;
    
    118
    -                    break;
    
    119
    -                }
    
    120
    -            }
    
    121
    -        }
    
    122
    -        return result;
    
    123
    -    }
    
    124
    -
    
    125 107
         private int getLowestSelectedRowCount() {
    
    126 108
             if (tree.isSelectionEmpty()) {
    
    127 109
                 throw new IllegalStateException("Can't have empty selection");
    
    ... ... @@ -141,24 +123,18 @@ public class NavigationTreeShowPopupHandler implements KeyListener, MouseListene
    141 123
             if (!tree.isEnabled()) {
    
    142 124
                 return;
    
    143 125
             }
    
    144
    -
    
    126
    +        if (e.isConsumed()) {
    
    127
    +            return;
    
    128
    +        }
    
    145 129
             if (e.getKeyCode() == KeyEvent.VK_CONTEXT_MENU && !tree.isSelectionEmpty()) {
    
    146
    -
    
    147 130
                 // get the lowest selected row
    
    148 131
                 int lowestRow = getLowestSelectedRowCount();
    
    149
    -
    
    150 132
                 // get the selected column
    
    151 133
                 Rectangle r = tree.getRowBounds(lowestRow);
    
    152
    -
    
    153 134
                 // get the point in the middle lower of the cell
    
    154 135
                 Point p = new Point(r.x + r.width / 2, r.y + r.height);
    
    155
    -
    
    156
    -            if (log.isDebugEnabled()) {
    
    157
    -                log.debug("Row " + lowestRow + " found t point [" + p + "]");
    
    158
    -            }
    
    159
    -
    
    136
    +            log.debug(String.format("Row %d found t point [%s]", lowestRow, p));
    
    160 137
                 showPopup(lowestRow, p);
    
    161
    -
    
    162 138
             }
    
    163 139
         }
    
    164 140
     
    
    ... ... @@ -167,60 +143,33 @@ public class NavigationTreeShowPopupHandler implements KeyListener, MouseListene
    167 143
             if (!tree.isEnabled()) {
    
    168 144
                 return;
    
    169 145
             }
    
    170
    -
    
    146
    +        if (e.isConsumed()) {
    
    147
    +            return;
    
    148
    +        }
    
    171 149
             boolean rightClick = SwingUtilities.isRightMouseButton(e);
    
    172
    -
    
    150
    +        if (!rightClick) {
    
    151
    +            return;
    
    152
    +        }
    
    153
    +        boolean doubleClick = e.getClickCount() == 2;
    
    154
    +        if (doubleClick) {
    
    155
    +            return;
    
    156
    +        }
    
    173 157
             // get the coordinates of the mouse click
    
    174 158
             Point p = e.getPoint();
    
    175
    -
    
    176 159
             int closestRowForLocation = tree.getClosestRowForLocation(e.getX(), e.getY());
    
    160
    +        log.info(String.format("Point of click: (rightClick? %b, doubleClick? %b) - at row %s (point %s)", true, false, closestRowForLocation, p));
    
    177 161
     
    
    178 162
             int rowToSelect = -1;
    
    179 163
     
    
    180
    -        if (isRowSelected(closestRowForLocation)) {
    
    181
    -
    
    164
    +        if (tree.isRowSelected(closestRowForLocation)) {
    
    182 165
                 rowToSelect = closestRowForLocation;
    
    183 166
             }
    
    184 167
     
    
    185
    -        if (rowToSelect == -1) {
    
    186
    -
    
    187
    -            // try to change selection
    
    188
    -
    
    189
    -            TreePath pathForRow = tree.getPathForRow(closestRowForLocation);
    
    190
    -            if (pathForRow == null) {
    
    191
    -                e.consume();
    
    192
    -                return;
    
    193
    -            }
    
    194
    -            tree.setSelectionPath(pathForRow);
    
    195
    -
    
    196
    -            if (isRowSelected(closestRowForLocation)) {
    
    197
    -                rowToSelect = closestRowForLocation;
    
    198
    -            }
    
    199
    -
    
    200
    -        } else {
    
    201
    -            TreePath pathForRow = tree.getPathForRow(rowToSelect);
    
    202
    -
    
    203
    -            Rectangle pathBounds = tree.getPathBounds(pathForRow);
    
    204
    -            if (e.getClickCount() == 2 && pathBounds != null && !pathBounds.contains(e.getPoint())) {
    
    205
    -                SwingUtilities.invokeLater(() -> {
    
    206
    -                    if (tree.isExpanded(pathForRow)) {
    
    207
    -                        tree.collapsePath(pathForRow);
    
    208
    -                    } else {
    
    209
    -                        tree.expandPath(pathForRow);
    
    210
    -                    }
    
    211
    -                });
    
    212
    -                e.consume();
    
    213
    -                return;
    
    214
    -            }
    
    215
    -
    
    216
    -        }
    
    217 168
             if (rowToSelect == -1) {
    
    218 169
                 return;
    
    219 170
             }
    
    220
    -
    
    221
    -        if (rightClick) {
    
    222
    -            showPopup(rowToSelect, p);
    
    223
    -        }
    
    171
    +        showPopup(rowToSelect, p);
    
    172
    +        e.consume();
    
    224 173
         }
    
    225 174
     
    
    226 175
         @Override
    

  • client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/navigation/NavigationUIInitializer.java
    ... ... @@ -123,5 +123,6 @@ class NavigationUIInitializer extends UIInitializerSupport<NavigationUI, UIIniti
    123 123
             editor.addNavigationTreeSelectionListener(selectionListener);
    
    124 124
             editor.addTreeWillExpandListener(selectionListener);
    
    125 125
             editor.addTreeSelectionListener(selectionListener);
    
    126
    +        editor.addMouseListener(selectionListener);
    
    126 127
         }
    
    127 128
     }

  • models/dto/src/main/java/fr/ird/observe/dto/data/ll/common/TripDto.java
    ... ... @@ -22,7 +22,6 @@ package fr.ird.observe.dto.data.ll.common;
    22 22
      * #L%
    
    23 23
      */
    
    24 24
     
    
    25
    -import fr.ird.observe.dto.decoration.I18nDecoratorHelper;
    
    26 25
     import io.ultreia.java4all.bean.spi.GenerateJavaBeanDefinition;
    
    27 26
     import org.nuiton.util.DateUtil;
    
    28 27
     
    
    ... ... @@ -47,11 +46,6 @@ public class TripDto extends GeneratedTripDto {
    47 46
             setNoOfDays(TripDto.createNoOfDay(startDate, endDate));
    
    48 47
         }
    
    49 48
     
    
    50
    -    @Override
    
    51
    -    public String getStartEndDateLabel() {
    
    52
    -        return I18nDecoratorHelper.getStartEndDateLabel(getStartDate(), getEndDate());
    
    53
    -    }
    
    54
    -
    
    55 49
         @Override
    
    56 50
         public void setStartDate(Date startDate) {
    
    57 51
             super.setStartDate(startDate == null ? null : DateUtil.getDay(startDate));
    

  • models/dto/src/main/java/fr/ird/observe/dto/data/ps/common/TripDto.java
    ... ... @@ -55,6 +55,6 @@ public class TripDto extends GeneratedTripDto {
    55 55
             boolean oldValue = isRouteEmpty();
    
    56 56
             super.setRoute(route);
    
    57 57
             //FIXME:Dto should be generated by dto template
    
    58
    -        firePropertyChange("routeEmpty",oldValue, isRouteEmpty());
    
    58
    +        firePropertyChange("routeEmpty", oldValue, isRouteEmpty());
    
    59 59
         }
    
    60 60
     }

  • models/dto/src/main/java/fr/ird/observe/dto/decoration/ObserveI18nLabelsBuilder.java
    ... ... @@ -147,6 +147,15 @@ public class ObserveI18nLabelsBuilder extends BeanPropertyI18nKeyProducerSupport
    147 147
                     .build();
    
    148 148
         }
    
    149 149
     
    
    150
    +    @Override
    
    151
    +    public String getI18nPropertyKey(Class type, String property) {
    
    152
    +        int i = property.indexOf("::");
    
    153
    +        if (i>-1) {
    
    154
    +            property = property.substring(0, i);
    
    155
    +        }
    
    156
    +        return super.getI18nPropertyKey(type, property);
    
    157
    +    }
    
    158
    +
    
    150 159
         @Override
    
    151 160
         protected Map<String, String> createMapping() {
    
    152 161
             String idDtoPrefix = "Id.";
    

  • toolkit/dto/src/main/java/fr/ird/observe/dto/decoration/I18nDecoratorHelper.java
    ... ... @@ -25,6 +25,8 @@ package fr.ird.observe.dto.decoration;
    25 25
     import io.ultreia.java4all.i18n.I18n;
    
    26 26
     import io.ultreia.java4all.i18n.spi.bean.BeanPropertyI18nKeyProducerProvider;
    
    27 27
     
    
    28
    +import java.text.ParseException;
    
    29
    +import java.text.SimpleDateFormat;
    
    28 30
     import java.util.Date;
    
    29 31
     import java.util.Locale;
    
    30 32
     
    
    ... ... @@ -100,6 +102,13 @@ public abstract class I18nDecoratorHelper extends BeanPropertyI18nKeyProducerPro
    100 102
         public static String getDateLabel(Date date) {
    
    101 103
             return String.format("%1$td/%1$tm/%1$tY", date);
    
    102 104
         }
    
    105
    +    public static Date getDate(String date) {
    
    106
    +        try {
    
    107
    +            return new SimpleDateFormat("dd/MM:yy").parse( date);
    
    108
    +        } catch (ParseException e) {
    
    109
    +            return null;
    
    110
    +        }
    
    111
    +    }
    
    103 112
     
    
    104 113
         public static String getTimestampLabel(Date date) {
    
    105 114
             return String.format("%1$td/%1$tm/%1$tY %1$tH:%1$tM", date);
    

  • toolkit/dto/src/main/java/fr/ird/observe/dto/decoration/decorators/DataReferenceDecorator.java
    ... ... @@ -23,7 +23,6 @@ package fr.ird.observe.dto.decoration.decorators;
    23 23
      */
    
    24 24
     
    
    25 25
     
    
    26
    -import fr.ird.observe.dto.WithStartEndDate;
    
    27 26
     import fr.ird.observe.dto.decoration.I18nDecoratorHelper;
    
    28 27
     import fr.ird.observe.dto.reference.DataDtoReference;
    
    29 28
     import fr.ird.observe.dto.reference.DtoReference;
    
    ... ... @@ -51,13 +50,15 @@ public class DataReferenceDecorator<R extends DataDtoReference> extends ObserveD
    51 50
                     return (Comparable) I18nDecoratorHelper.getDateLabel((Date) value2);
    
    52 51
                 }
    
    53 52
                 return value2;
    
    54
    -        }if (token.endsWith(FORMATTER_TIME)) {
    
    53
    +        }
    
    54
    +        if (token.endsWith(FORMATTER_TIME)) {
    
    55 55
                 Comparable value2 = getTokenValue(jxcontext, token.substring(0, token.length() - FORMATTER_TIME.length()));
    
    56 56
                 if (value2 != null && Date.class.isAssignableFrom(value2.getClass())) {
    
    57 57
                     return (Comparable) I18nDecoratorHelper.getTimeLabel((Date) value2);
    
    58 58
                 }
    
    59 59
                 return value2;
    
    60
    -        }if (token.endsWith(FORMATTER_TIMESTAMP)) {
    
    60
    +        }
    
    61
    +        if (token.endsWith(FORMATTER_TIMESTAMP)) {
    
    61 62
                 Comparable value2 = getTokenValue(jxcontext, token.substring(0, token.length() - FORMATTER_TIMESTAMP.length()));
    
    62 63
                 if (value2 != null && Date.class.isAssignableFrom(value2.getClass())) {
    
    63 64
                     return (Comparable) I18nDecoratorHelper.getTimestampLabel((Date) value2);
    
    ... ... @@ -66,27 +67,17 @@ public class DataReferenceDecorator<R extends DataDtoReference> extends ObserveD
    66 67
             }
    
    67 68
             // assume all values are comparable
    
    68 69
             Comparable<Comparable<?>> value;
    
    69
    -
    
    70 70
             Object contextBean = jxcontext.getContextBean();
    
    71
    -
    
    72 71
             if (contextBean instanceof DtoReference) {
    
    73
    -
    
    74 72
                 String[] tokens = token.split("/");
    
    75
    -
    
    76 73
                 value = getValueFromReference(tokens, (DtoReference) contextBean, 0);
    
    77
    -
    
    78 74
                 if (value == null) {
    
    79 75
                     value = (Comparable<Comparable<?>>) getDefaultNullValue(tokens[0]);
    
    80 76
                 }
    
    81
    -
    
    82 77
             } else {
    
    83 78
                 value = super.getTokenValue(jxcontext, token);
    
    84 79
             }
    
    85
    -        if (token.equals(WithStartEndDate.PROPERTY_START_END_DATE_LABEL)) {
    
    86
    -            value = super.getTokenValue(jxcontext, token);
    
    87
    -        }
    
    88 80
             return value;
    
    89
    -
    
    90 81
         }
    
    91 82
     
    
    92 83
         @Override
    
    ... ... @@ -94,4 +85,4 @@ public class DataReferenceDecorator<R extends DataDtoReference> extends ObserveD
    94 85
             String result = super.toString(bean);
    
    95 86
             return result == null ? null : result.trim();
    
    96 87
         }
    
    97
    -}
    88
    +}
    \ No newline at end of file

  • toolkit/dto/src/main/java/fr/ird/observe/dto/decoration/decorators/ObserveDecorator.java
    ... ... @@ -52,11 +52,46 @@ public class ObserveDecorator<E> extends MultiJXPathDecorator<E> implements Clon
    52 52
         private static final Logger log = LogManager.getLogger(ObserveDecorator.class);
    
    53 53
     
    
    54 54
         public ObserveDecorator(Class<E> internalClass, String expression) {
    
    55
    -        super(internalClass, expression, DEFAULT_SEPARATOR, DEFAULT_SEPARATOR_REPLACEMENT);
    
    55
    +        this(internalClass, expression, DEFAULT_SEPARATOR_REPLACEMENT);
    
    56 56
         }
    
    57 57
     
    
    58 58
         public ObserveDecorator(Class<E> internalClass, String expression, String separator) {
    
    59 59
             super(internalClass, expression, DEFAULT_SEPARATOR, separator);
    
    60
    +        if (getNbToken() == 0) {
    
    61
    +            return;
    
    62
    +        }
    
    63
    +        int nbContext = getNbContext();
    
    64
    +        for (int i = 0; i < nbContext; i++) {
    
    65
    +            Context<E> context = contexts[i];
    
    66
    +            String token = context.getFirstProperty();
    
    67
    +            if (token.endsWith("::date") || token.endsWith("::time")) {
    
    68
    +                context.setComparator((o1, o2) -> {
    
    69
    +                    if (o1 == null && o2 == null) {
    
    70
    +                        return 0;
    
    71
    +                    }
    
    72
    +                    if (o1 == null) {
    
    73
    +                        return -1;
    
    74
    +                    }
    
    75
    +                    if (o2 == null) {
    
    76
    +                        return 1;
    
    77
    +                    }
    
    78
    +                    String s1 = o1.toString();
    
    79
    +                    String s2 = o2.toString();
    
    80
    +                    Date d1 = I18nDecoratorHelper.getDate(s1);
    
    81
    +                    Date d2 = I18nDecoratorHelper.getDate(s2);
    
    82
    +                    if (d1 == null && d2 == null) {
    
    83
    +                        return 0;
    
    84
    +                    }
    
    85
    +                    if (d1 == null) {
    
    86
    +                        return -1;
    
    87
    +                    }
    
    88
    +                    if (d2 == null) {
    
    89
    +                        return 1;
    
    90
    +                    }
    
    91
    +                    return d1.compareTo(d2);
    
    92
    +                });
    
    93
    +            }
    
    94
    +        }
    
    60 95
         }
    
    61 96
     
    
    62 97
         @Override
    
    ... ... @@ -73,13 +108,15 @@ public class ObserveDecorator<E> extends MultiJXPathDecorator<E> implements Clon
    73 108
                     return (Comparable) I18nDecoratorHelper.getDateLabel((Date) value2);
    
    74 109
                 }
    
    75 110
                 return value2;
    
    76
    -        }if (token.endsWith(FORMATTER_TIME)) {
    
    111
    +        }
    
    112
    +        if (token.endsWith(FORMATTER_TIME)) {
    
    77 113
                 Comparable value2 = getTokenValue(jxcontext, token.substring(0, token.length() - FORMATTER_TIME.length()));
    
    78 114
                 if (value2 != null && Date.class.isAssignableFrom(value2.getClass())) {
    
    79 115
                     return (Comparable) I18nDecoratorHelper.getTimeLabel((Date) value2);
    
    80 116
                 }
    
    81 117
                 return value2;
    
    82
    -        }if (token.endsWith(FORMATTER_TIMESTAMP)) {
    
    118
    +        }
    
    119
    +        if (token.endsWith(FORMATTER_TIMESTAMP)) {
    
    83 120
                 Comparable value2 = getTokenValue(jxcontext, token.substring(0, token.length() - FORMATTER_TIMESTAMP.length()));
    
    84 121
                 if (value2 != null && Date.class.isAssignableFrom(value2.getClass())) {
    
    85 122
                     return (Comparable) I18nDecoratorHelper.getTimestampLabel((Date) value2);
    
    ... ... @@ -89,58 +126,39 @@ public class ObserveDecorator<E> extends MultiJXPathDecorator<E> implements Clon
    89 126
             // assume all values are comparable
    
    90 127
             Comparable<Comparable<?>> value;
    
    91 128
             try {
    
    92
    -
    
    93 129
                 String[] tokens = token.split("/");
    
    94
    -
    
    95 130
                 Object value0 = jxcontext.getValue(tokens[0]);
    
    96
    -
    
    97 131
                 if (value0 instanceof DtoReference) {
    
    98
    -
    
    99 132
                     value = getValueFromReference(tokens, (DtoReference) value0, 1);
    
    100
    -
    
    101 133
                 } else {
    
    102
    -
    
    103 134
                     value = (Comparable<Comparable<?>>) jxcontext.getValue(token);
    
    104 135
                 }
    
    105
    -
    
    106 136
                 if (value == null) {
    
    107 137
                     value = (Comparable<Comparable<?>>) getDefaultNullValue(token);
    
    108 138
                 }
    
    109
    -
    
    110 139
             } catch (Exception e) {
    
    111 140
                 value = (Comparable<Comparable<?>>) getDefaultUndefinedValue(token);
    
    112 141
             }
    
    113
    -
    
    114 142
             return value;
    
    115 143
         }
    
    116 144
     
    
    117 145
         protected Comparable<Comparable<?>> getValueFromReference(String[] tokens, DtoReference referenceBean, int startIndex) {
    
    118
    -
    
    119 146
             for (int i = startIndex, max = tokens.length - 1; i < max; i++) {
    
    120
    -
    
    121 147
                 if (referenceBean.getPropertyNames().contains(tokens[i])) {
    
    122
    -
    
    123 148
                     Serializable propertyValue = referenceBean.getPropertyValue(tokens[i]);
    
    124
    -
    
    125 149
                     if (!(propertyValue instanceof DtoReference)) {
    
    126
    -
    
    127 150
                         return (Comparable<Comparable<?>>) getDefaultUndefinedValue(StringUtils.join(tokens, "/"));
    
    128
    -
    
    129 151
                     }
    
    130
    -
    
    131 152
                     referenceBean = (DtoReference) propertyValue;
    
    132 153
                 }
    
    133 154
             }
    
    134
    -
    
    135
    -        Comparable<Comparable<?>> value = null;
    
    136
    -
    
    155
    +        Comparable<Comparable<?>> value;
    
    137 156
             String lastToken = tokens[tokens.length - 1];
    
    138 157
             if (referenceBean.getPropertyNames().contains(lastToken)) {
    
    139 158
                 value = referenceBean.getPropertyValue(lastToken);
    
    140 159
             } else {
    
    141 160
                 value = referenceBean.get(lastToken);
    
    142 161
             }
    
    143
    -
    
    144 162
             return value;
    
    145 163
         }
    
    146 164
     
    
    ... ... @@ -157,6 +175,4 @@ public class ObserveDecorator<E> extends MultiJXPathDecorator<E> implements Clon
    157 175
             }
    
    158 176
             return t("observe.common.none");
    
    159 177
         }
    
    160
    -
    
    161
    -
    
    162 178
     }