1 package fr.ifremer.quadrige3.ui.swing;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import com.google.common.collect.Sets;
27 import fr.ifremer.quadrige3.core.dao.technical.Assert;
28 import fr.ifremer.quadrige3.core.exception.QuadrigeTechnicalException;
29 import fr.ifremer.quadrige3.ui.swing.table.state.ExtendedState;
30 import jaxx.runtime.swing.session.State;
31 import org.apache.commons.collections4.MapUtils;
32 import org.apache.commons.lang3.StringUtils;
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35
36 import java.awt.Component;
37 import java.io.File;
38 import java.io.IOException;
39 import java.nio.file.Files;
40 import java.util.Collection;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.Set;
44 import java.util.regex.Pattern;
45 import java.util.stream.Collectors;
46 import java.util.stream.Stream;
47
48
49
50
51
52
53 public class SwingSession extends jaxx.runtime.swing.session.SwingSession {
54
55 private static final Log LOG = LogFactory.getLog(SwingSession.class);
56
57 private final Set<Component> unsavedComponents = Sets.newHashSet();
58
59 private final Set<String> unsavedRootComponentNames = Sets.newHashSet();
60
61 private boolean partialSave;
62
63
64
65
66
67
68
69
70
71 public static SwingSession newSwingSession(File file, boolean autoSave, Map<Class, State> additionalStates) {
72 Assert.notNull(file);
73 patchFile(file);
74 return new SwingSession(file, autoSave, additionalStates);
75 }
76
77
78
79
80
81
82 private static void patchFile(File file) {
83
84 if (!file.exists())
85 return;
86
87 try (Stream<String> lines = Files.lines(file.toPath())) {
88 List<String> replaced = lines
89 .map(line-> line.replaceAll("fr.ifremer.quadrige3.ui.swing.common", "fr.ifremer.quadrige3.ui.swing"))
90 .collect(Collectors.toList());
91 Files.write(file.toPath(), replaced);
92 } catch (IOException ioe) {
93 throw new QuadrigeTechnicalException("something goes wrong when patching file " + file, ioe);
94 }
95
96 }
97
98 private SwingSession(File file, boolean autoSave, Map<Class, State> additionalStates) {
99 super(file, autoSave, additionalStates);
100 }
101
102
103
104
105
106
107 public void restoreState(Component component) {
108 walkThrowComponent("", registeredComponent, new ExtendedRestoreStateAction(component.getName()));
109 }
110
111
112
113
114
115
116
117 public void updateState(Component component, String stateContext) {
118 walkThrowComponent("", registeredComponent, new ExtendedSaveStateAction(component.getName(), stateContext));
119 }
120
121
122
123
124
125
126
127
128
129
130
131
132 public void setPartialSave(boolean partialSave) {
133 this.partialSave = partialSave;
134 }
135
136
137
138
139 @Override
140 public void updateState() {
141 if (partialSave) {
142 return;
143 }
144
145 super.updateState();
146 }
147
148
149
150
151
152
153 @Override
154 protected void walkThrowComponent(String path, Collection<Component> roots, Action action) {
155 if (action instanceof SaveStateAction && !(action instanceof ExtendedSaveStateAction)) {
156 action = new ExtendedSaveStateAction();
157 }
158 if (action instanceof RestoreStateAction && !(action instanceof ExtendedRestoreStateAction)) {
159 action = new ExtendedRestoreStateAction();
160 }
161 super.walkThrowComponent(path, roots, action);
162 }
163
164 @Override
165 protected String getComponentName(Component c) {
166 String name = c.getName();
167 if (name == null) {
168 int n = c.getParent() == null ? -1 : c.getParent().getComponentZOrder(c);
169 if (n >= 0) {
170 Class clazz = c.getClass();
171 name = clazz.getSimpleName();
172 if (StringUtils.isEmpty(name)) {
173 name = "Anonymous" + clazz.getSuperclass().getSimpleName();
174 }
175 name += n;
176 } else {
177 LOG.warn("Couldn't compute pathname for " + c);
178 }
179 }
180 return name;
181 }
182
183
184
185
186
187
188 public void addUnsavedComponent(Component unsavedComponent) {
189 this.unsavedComponents.add(unsavedComponent);
190 }
191
192
193
194
195
196
197 public void addUnsavedComponents(Set<Component> unsavedComponents) {
198 this.unsavedComponents.addAll(unsavedComponents);
199 }
200
201
202
203
204
205
206 public void addUnsavedRootComponentByName(String unsavedRootComponentName) {
207 this.unsavedRootComponentNames.add("/" + unsavedRootComponentName);
208 }
209
210
211
212
213
214
215
216
217 public boolean isComponentToSave(String path, Component c) {
218 if (!unsavedRootComponentNames.isEmpty()) {
219 for (String rootName : unsavedRootComponentNames) {
220 if (path.startsWith(rootName)) {
221 return false;
222 }
223 }
224 }
225 return unsavedComponents.isEmpty() || !unsavedComponents.contains(c);
226 }
227
228
229
230
231
232
233
234 public State findStateByComponentName(String componentNameRegEx) {
235
236 if (MapUtils.isNotEmpty(states)) {
237 Pattern p = Pattern.compile(componentNameRegEx);
238 for (String componentPath : states.keySet()) {
239 if (p.matcher(componentPath).matches()) {
240 return states.get(componentPath);
241 }
242 }
243 }
244 return null;
245 }
246
247 class ExtendedSaveStateAction extends SaveStateAction {
248
249 private final String componentName;
250 private final String stateContext;
251
252 public ExtendedSaveStateAction() {
253 this(null);
254 }
255
256 public ExtendedSaveStateAction(String componentName) {
257 this(componentName, null);
258 }
259
260 public ExtendedSaveStateAction(String componentName, String stateContext) {
261 this.componentName = componentName;
262 this.stateContext = stateContext;
263 }
264
265 @Override
266 public void doAction(jaxx.runtime.swing.session.SwingSession session, String path, Component c) {
267 if (session instanceof SwingSession && !((SwingSession) session).isComponentToSave(path, c)) {
268
269 return;
270 }
271
272 if (componentName != null && !path.endsWith(componentName)) {
273
274 return;
275 }
276
277
278 State manager = session.getStateManager(c.getClass());
279 State state;
280 if (manager instanceof ExtendedState) {
281
282 state = ((ExtendedState) manager).getState(c, session.getStates(path), stateContext);
283 } else {
284 state = manager.getState(c);
285 }
286 session.setStates(path, state);
287 }
288 }
289
290 class ExtendedRestoreStateAction extends RestoreStateAction {
291
292 private final String componentName;
293
294 public ExtendedRestoreStateAction(String componentName) {
295 this.componentName = componentName;
296 }
297
298 public ExtendedRestoreStateAction() {
299 this(null);
300 }
301
302 @Override
303 public void doAction(jaxx.runtime.swing.session.SwingSession session, String path, Component c) {
304 if (session instanceof SwingSession && !((SwingSession) session).isComponentToSave(path, c)) {
305
306 return;
307 }
308
309 if (componentName != null && !path.endsWith(componentName)) {
310
311 return;
312 }
313
314 super.doAction(session, path, c);
315 }
316 }
317 }
318
319