Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe
Commits:
-
342a2670
by Tony Chemit at 2021-01-04T11:21:21+01:00
-
18699c34
by Tony Chemit at 2021-01-04T11:21:21+01:00
10 changed files:
- client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/navigation/NavigationTree.java
- client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/navigation/NavigationTreeSelectionListenerImpl.java
- client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/navigation/NavigationTreeShowPopupHandler.java
- client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/navigation/NavigationUIInitializer.java
- models/dto/src/main/java/fr/ird/observe/dto/data/ll/common/TripDto.java
- models/dto/src/main/java/fr/ird/observe/dto/data/ps/common/TripDto.java
- models/dto/src/main/java/fr/ird/observe/dto/decoration/ObserveI18nLabelsBuilder.java
- toolkit/dto/src/main/java/fr/ird/observe/dto/decoration/I18nDecoratorHelper.java
- toolkit/dto/src/main/java/fr/ird/observe/dto/decoration/decorators/DataReferenceDecorator.java
- toolkit/dto/src/main/java/fr/ird/observe/dto/decoration/decorators/ObserveDecorator.java
Changes:
| ... | ... | @@ -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));
|
| ... | ... | @@ -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 |
}
|
| ... | ... | @@ -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
|
| ... | ... | @@ -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 |
}
|
| ... | ... | @@ -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));
|
| ... | ... | @@ -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 |
}
|
| ... | ... | @@ -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.";
|
| ... | ... | @@ -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);
|
| ... | ... | @@ -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 |
| ... | ... | @@ -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 |
}
|