svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.swing / org.gvsig.fmap.dal.swing.impl / src / main / java / org / gvsig / fmap / dal / impl / DefaultEditingNotificationManager.java @ 45652
History | View | Annotate | Download (12.4 KB)
1 | 41323 | jjdelcerro | /**
|
---|---|---|---|
2 | * gvSIG. Desktop Geographic Information System.
|
||
3 | *
|
||
4 | * Copyright (C) 2007-2013 gvSIG Association.
|
||
5 | *
|
||
6 | * This program is free software; you can redistribute it and/or
|
||
7 | * modify it under the terms of the GNU General Public License
|
||
8 | * as published by the Free Software Foundation; either version 3
|
||
9 | * of the License, or (at your option) any later version.
|
||
10 | *
|
||
11 | * This program is distributed in the hope that it will be useful,
|
||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
14 | * GNU General Public License for more details.
|
||
15 | *
|
||
16 | * You should have received a copy of the GNU General Public License
|
||
17 | * along with this program; if not, write to the Free Software
|
||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||
19 | * MA 02110-1301, USA.
|
||
20 | *
|
||
21 | * For any additional information, do not hesitate to contact us
|
||
22 | * at info AT gvsig.com, or visit our website www.gvsig.com.
|
||
23 | */
|
||
24 | 42775 | jjdelcerro | package org.gvsig.fmap.dal.impl; |
25 | 41323 | jjdelcerro | |
26 | 45652 | fdiaz | import java.awt.Dimension; |
27 | 41323 | jjdelcerro | import java.util.Arrays; |
28 | import java.util.List; |
||
29 | 45652 | fdiaz | import javax.swing.JComponent; |
30 | 41335 | jjdelcerro | import javax.swing.SwingUtilities; |
31 | 42775 | jjdelcerro | import org.gvsig.featureform.swing.JFeatureForm; |
32 | 41323 | jjdelcerro | import org.gvsig.fmap.dal.DataStore; |
33 | 42775 | jjdelcerro | import org.gvsig.fmap.dal.EditingNotification; |
34 | import org.gvsig.fmap.dal.EditingNotificationManager; |
||
35 | 41335 | jjdelcerro | import org.gvsig.fmap.dal.feature.EditableFeature; |
36 | 41323 | jjdelcerro | import org.gvsig.fmap.dal.feature.EditableFeatureType; |
37 | import org.gvsig.fmap.dal.feature.Feature; |
||
38 | 41335 | jjdelcerro | import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor; |
39 | 41323 | jjdelcerro | import org.gvsig.fmap.dal.feature.FeatureStore; |
40 | 41335 | jjdelcerro | import org.gvsig.fmap.dal.feature.FeatureType; |
41 | 42775 | jjdelcerro | import org.gvsig.fmap.dal.swing.DALSwingLocator; |
42 | 41335 | jjdelcerro | import org.gvsig.tools.ToolsLocator; |
43 | 45133 | jjdelcerro | import org.gvsig.tools.dynobject.DynObjectManager; |
44 | import org.gvsig.tools.dynobject.Tags; |
||
45 | 41323 | jjdelcerro | import org.gvsig.tools.observer.ObservableHelper; |
46 | import org.gvsig.tools.observer.Observer; |
||
47 | 41498 | jjdelcerro | import org.gvsig.tools.observer.BaseNotification; |
48 | 42775 | jjdelcerro | import org.gvsig.tools.swing.api.ToolsSwingLocator; |
49 | import org.gvsig.tools.swing.api.windowmanager.Dialog; |
||
50 | import org.gvsig.tools.swing.api.windowmanager.WindowManager; |
||
51 | import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2; |
||
52 | 41323 | jjdelcerro | import org.slf4j.Logger; |
53 | import org.slf4j.LoggerFactory; |
||
54 | |||
55 | /**
|
||
56 | *
|
||
57 | * Acts as a hub to centralize editing notification events in a single manager.
|
||
58 | *
|
||
59 | * All objects that modify a store notify this manager to reported the actions
|
||
60 | * to the objects interested in knowing when start or end editing, regardless
|
||
61 | * of where the editing work is done.
|
||
62 | *
|
||
63 | */
|
||
64 | 45133 | jjdelcerro | @SuppressWarnings("UseSpecificCatch") |
65 | 41323 | jjdelcerro | public class DefaultEditingNotificationManager implements EditingNotificationManager { |
66 | |||
67 | 45133 | jjdelcerro | private static final Logger LOGGER = LoggerFactory.getLogger(DefaultEditingNotificationManager.class); |
68 | 41323 | jjdelcerro | |
69 | 45133 | jjdelcerro | private static final String TAG_FORCE_SHOW_FORM_ON_INSERT = "forceShowFormOnInsert"; |
70 | |||
71 | 41323 | jjdelcerro | private ObservableHelper helper = null; |
72 | |||
73 | private static final int SOURCE = 1; |
||
74 | private static final int DOCUMENT = 2; |
||
75 | 42775 | jjdelcerro | private static final int AUXDATA = 3; |
76 | 41323 | jjdelcerro | private static final int STORE = 4; |
77 | private static final int FEATURE = 5; |
||
78 | private static final int FEATURETYPE = 6; |
||
79 | |||
80 | private static List cancelableNotifications = null; |
||
81 | |||
82 | |||
83 | |||
84 | 41498 | jjdelcerro | public class DefaultEditingNotification extends BaseNotification implements EditingNotification { |
85 | 41323 | jjdelcerro | |
86 | 41335 | jjdelcerro | private boolean validateTheFeature = true; |
87 | |||
88 | 41323 | jjdelcerro | DefaultEditingNotification(String type) {
|
89 | super(type, 7); |
||
90 | } |
||
91 | |||
92 | 42775 | jjdelcerro | @Override
|
93 | 41323 | jjdelcerro | public Object getSource() { |
94 | return this.getValue(SOURCE); |
||
95 | } |
||
96 | |||
97 | 42775 | jjdelcerro | @Override
|
98 | 41323 | jjdelcerro | public Object getDocument() { |
99 | return this.getValue(DOCUMENT); |
||
100 | } |
||
101 | |||
102 | 45133 | jjdelcerro | @Override
|
103 | 42775 | jjdelcerro | public Object getAuxData() { |
104 | return this.getValue(AUXDATA); |
||
105 | 41323 | jjdelcerro | } |
106 | |||
107 | 42775 | jjdelcerro | @Override
|
108 | 41323 | jjdelcerro | public DataStore getStore() {
|
109 | return (DataStore) this.getValue(STORE); |
||
110 | } |
||
111 | |||
112 | 42775 | jjdelcerro | @Override
|
113 | 41323 | jjdelcerro | public FeatureStore getFeatureStore() {
|
114 | return (FeatureStore) this.getValue(STORE); |
||
115 | } |
||
116 | |||
117 | 42775 | jjdelcerro | @Override
|
118 | 41323 | jjdelcerro | public Feature getFeature() {
|
119 | return (Feature) this.getValue(FEATURE); |
||
120 | } |
||
121 | |||
122 | 42775 | jjdelcerro | @Override
|
123 | 41323 | jjdelcerro | public EditableFeatureType getFeatureType() {
|
124 | return (EditableFeatureType) this.getValue(FEATURETYPE); |
||
125 | } |
||
126 | |||
127 | 42775 | jjdelcerro | @Override
|
128 | 41323 | jjdelcerro | public boolean isCancelable() { |
129 | if( cancelableNotifications==null ) { |
||
130 | String nn[] = new String[] { |
||
131 | 41330 | jjdelcerro | BEFORE_ENTER_EDITING_STORE, |
132 | BEFORE_EXIT_EDITING_STORE, |
||
133 | BEFORE_INSERT_FEATURE, |
||
134 | BEFORE_REMOVE_FEATURE, |
||
135 | BEFORE_UPDATE_FEATURE, |
||
136 | BEFORE_UPDATE_FEATURE_TYPE |
||
137 | 41323 | jjdelcerro | }; |
138 | cancelableNotifications = Arrays.asList(nn);
|
||
139 | } |
||
140 | return cancelableNotifications.contains(this.getType() ); |
||
141 | } |
||
142 | 41335 | jjdelcerro | |
143 | 42775 | jjdelcerro | @Override
|
144 | 41335 | jjdelcerro | public void setSkipFeatureValidation(boolean skipTheFeatureValidation) { |
145 | this.validateTheFeature = !skipTheFeatureValidation;
|
||
146 | } |
||
147 | |||
148 | 42775 | jjdelcerro | @Override
|
149 | 41335 | jjdelcerro | public boolean shouldValidateTheFeature() { |
150 | 41741 | jjdelcerro | return this.validateTheFeature; |
151 | 41335 | jjdelcerro | } |
152 | 41323 | jjdelcerro | } |
153 | |||
154 | public DefaultEditingNotificationManager() {
|
||
155 | this.helper = new ObservableHelper(); |
||
156 | } |
||
157 | |||
158 | 42775 | jjdelcerro | @Override
|
159 | 41323 | jjdelcerro | public void addObserver(Observer o) { |
160 | this.helper.addObserver(o);
|
||
161 | } |
||
162 | |||
163 | 42775 | jjdelcerro | @Override
|
164 | 41323 | jjdelcerro | public void deleteObserver(Observer o) { |
165 | this.helper.deleteObserver(o);
|
||
166 | } |
||
167 | |||
168 | 42775 | jjdelcerro | @Override
|
169 | 41323 | jjdelcerro | public void deleteObservers() { |
170 | this.helper.deleteObservers();
|
||
171 | } |
||
172 | |||
173 | 42775 | jjdelcerro | @Override
|
174 | 41323 | jjdelcerro | public EditingNotification notifyObservers(EditingNotification notification) {
|
175 | try {
|
||
176 | this.helper.notifyObservers(this, notification); |
||
177 | } catch(Exception ex) { |
||
178 | 45133 | jjdelcerro | LOGGER.warn("Problems notifing to observers of DefaultEditingNotificationManager.",ex);
|
179 | 41323 | jjdelcerro | } |
180 | return notification;
|
||
181 | } |
||
182 | |||
183 | 42775 | jjdelcerro | public EditingNotification notifyObservers(Object source, String type, Object document, Object auxdata, DataStore store, Feature feature, EditableFeatureType featureType) { |
184 | 41323 | jjdelcerro | EditingNotification notification = new DefaultEditingNotification(type);
|
185 | notification.setValue(SOURCE,source); |
||
186 | notification.setValue(DOCUMENT,document); |
||
187 | 42775 | jjdelcerro | notification.setValue(AUXDATA,auxdata); |
188 | 41323 | jjdelcerro | notification.setValue(STORE,store); |
189 | notification.setValue(FEATURE,feature); |
||
190 | notification.setValue(FEATURETYPE,featureType); |
||
191 | return this.notifyObservers(notification); |
||
192 | } |
||
193 | |||
194 | 42775 | jjdelcerro | @Override
|
195 | public EditingNotification notifyObservers(Object source, String type, Object document, Object auxdata, DataStore store) { |
||
196 | return this.notifyObservers(source, type, document, auxdata, store, null, null); |
||
197 | 41323 | jjdelcerro | } |
198 | |||
199 | 42775 | jjdelcerro | @Override
|
200 | public EditingNotification notifyObservers(Object source, String type, Object document, Object auxdata) { |
||
201 | return this.notifyObservers(source, type, document, auxdata, null, null, null); |
||
202 | 41323 | jjdelcerro | } |
203 | |||
204 | 42775 | jjdelcerro | @Override
|
205 | 41323 | jjdelcerro | public EditingNotification notifyObservers(Object source, String type, Object document, DataStore store) { |
206 | return this.notifyObservers(source, type, document, null, store, null, null); |
||
207 | } |
||
208 | |||
209 | 42775 | jjdelcerro | @Override
|
210 | 41323 | jjdelcerro | public EditingNotification notifyObservers(Object source, String type, Object document, DataStore store, Feature feature) { |
211 | return this.notifyObservers(source, type, document, null, store, feature, null); |
||
212 | } |
||
213 | |||
214 | 42775 | jjdelcerro | @Override
|
215 | 41323 | jjdelcerro | public EditingNotification notifyObservers(Object source, String type, Object document, DataStore store, EditableFeatureType featureType) { |
216 | return this.notifyObservers(source, type, document, null, store, null, featureType); |
||
217 | } |
||
218 | |||
219 | 42775 | jjdelcerro | @Override
|
220 | public EditingNotification notifyObservers(Object source, String type, Object document, Object auxdata, DataStore store, Feature feature) { |
||
221 | return this.notifyObservers(source, type, document, auxdata, store, feature, null); |
||
222 | 41323 | jjdelcerro | } |
223 | 41335 | jjdelcerro | |
224 | 42775 | jjdelcerro | @Override
|
225 | 41335 | jjdelcerro | public boolean validateFeature(Feature feature) { |
226 | 45133 | jjdelcerro | |
227 | FeatureType featureType = feature.getType(); |
||
228 | Tags tags = featureType.getTags(); |
||
229 | boolean forceShowForm = tags != null && tags.getBoolean(TAG_FORCE_SHOW_FORM_ON_INSERT, false); |
||
230 | 41335 | jjdelcerro | while( true ) { |
231 | 45133 | jjdelcerro | if( !forceShowForm ) {
|
232 | if( !needAskUser(feature) ) {
|
||
233 | // La feature se puede validar y no precisa de intervencion del
|
||
234 | // usuario. Retornamos true.
|
||
235 | return true; |
||
236 | } |
||
237 | 41335 | jjdelcerro | } |
238 | // No se habia podido validar la feature, se piden al
|
||
239 | // usuario los datos que faltan.
|
||
240 | AskRequiredAttributtes ask = new AskRequiredAttributtes();
|
||
241 | ask.showDialog(feature); |
||
242 | if( ask.userCancel() ) {
|
||
243 | // No se habia podido validar la feature, se le han pedido al
|
||
244 | // usuario los datos que faltan y este ha pulsado en cancel,
|
||
245 | // asi que la feature no se puede validar, y retornamos
|
||
246 | // false.
|
||
247 | return false; |
||
248 | } |
||
249 | 45133 | jjdelcerro | forceShowForm = false;
|
250 | 41335 | jjdelcerro | } |
251 | } |
||
252 | 41323 | jjdelcerro | |
253 | 41335 | jjdelcerro | private boolean needAskUser(Feature feature) { |
254 | FeatureType featureType = feature.getType(); |
||
255 | FeatureAttributeDescriptor[] attributeDescriptors = featureType.getAttributeDescriptors();
|
||
256 | |||
257 | 42775 | jjdelcerro | for (FeatureAttributeDescriptor attrDesc : attributeDescriptors) {
|
258 | 41335 | jjdelcerro | if ( attrDesc.isAutomatic() ) {
|
259 | 43362 | jjdelcerro | continue;
|
260 | 41335 | jjdelcerro | } |
261 | if ( (attrDesc.isPrimaryKey() || !attrDesc.allowNull())
|
||
262 | && feature.get(attrDesc.getName()) == null ) {
|
||
263 | return true; |
||
264 | } |
||
265 | } |
||
266 | return false; |
||
267 | } |
||
268 | |||
269 | private class AskRequiredAttributtes { |
||
270 | |||
271 | private boolean userCancelValue = true; |
||
272 | |||
273 | public boolean userCancel() { |
||
274 | return this.userCancelValue; |
||
275 | } |
||
276 | |||
277 | public void showDialog(final Feature feature) { |
||
278 | if ( !SwingUtilities.isEventDispatchThread() ) { |
||
279 | try {
|
||
280 | 45133 | jjdelcerro | SwingUtilities.invokeAndWait(() -> {
|
281 | showDialog(feature); |
||
282 | }); |
||
283 | 41335 | jjdelcerro | } catch (Exception e1) { |
284 | message("Can't show form to fill need data.",e1);
|
||
285 | this.userCancelValue = true; |
||
286 | return;
|
||
287 | } |
||
288 | } |
||
289 | |||
290 | try {
|
||
291 | 42775 | jjdelcerro | JFeatureForm form = DALSwingLocator.getSwingManager().createJFeatureForm(feature); |
292 | 45652 | fdiaz | setPreferredSize(form.asJComponent(), 400, 400); |
293 | 42775 | jjdelcerro | WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager(); |
294 | Dialog dialog = winManager.createDialog(
|
||
295 | form.asJComponent(), |
||
296 | form.getDynForm().getDefinition().getLabel(), |
||
297 | ToolsLocator.getI18nManager().getTranslation("_Fill_the_required_fields"),
|
||
298 | WindowManager_v2.BUTTONS_OK_CANCEL |
||
299 | ); |
||
300 | dialog.show(WindowManager.MODE.DIALOG); |
||
301 | if( dialog.getAction() == WindowManager_v2.BUTTON_OK ) {
|
||
302 | form.fetch((EditableFeature) feature); |
||
303 | 41335 | jjdelcerro | this.userCancelValue = false; |
304 | 43362 | jjdelcerro | } else {
|
305 | this.userCancelValue = true; |
||
306 | 41335 | jjdelcerro | } |
307 | 42775 | jjdelcerro | |
308 | 41335 | jjdelcerro | } catch (Exception ex) { |
309 | message("Can't show form to fill need data.",ex);
|
||
310 | this.userCancelValue = true; |
||
311 | } |
||
312 | } |
||
313 | |||
314 | private void message(String msg, Throwable ex) { |
||
315 | if( ex==null ) { |
||
316 | 45133 | jjdelcerro | LOGGER.warn(msg); |
317 | 41335 | jjdelcerro | } else {
|
318 | 45133 | jjdelcerro | LOGGER.warn(msg,ex); |
319 | 41335 | jjdelcerro | } |
320 | // msg = msg + "\nSee to application log for more information.";
|
||
321 | // ApplicationManager application = ApplicationLocator.getManager();
|
||
322 | // application.message(msg,JOptionPane.WARNING_MESSAGE);
|
||
323 | } |
||
324 | } |
||
325 | 45652 | fdiaz | |
326 | private void setPreferredSize(JComponent c, int width, int height) { |
||
327 | Dimension d = c.getPreferredSize();
|
||
328 | if (d.width < width) {
|
||
329 | d.width = width; |
||
330 | } |
||
331 | if (d.height > height) {
|
||
332 | d.height = height; |
||
333 | } |
||
334 | c.setPreferredSize(d); |
||
335 | } |
||
336 | 41335 | jjdelcerro | |
337 | 45133 | jjdelcerro | public static final void selfRegister() { |
338 | DynObjectManager dynObjectManager = ToolsLocator.getDynObjectManager(); |
||
339 | dynObjectManager.registerTag( |
||
340 | TAG_FORCE_SHOW_FORM_ON_INSERT, |
||
341 | "String value, true/false to force show form on insert features."
|
||
342 | ); |
||
343 | |||
344 | } |
||
345 | 41323 | jjdelcerro | |
346 | 41335 | jjdelcerro | |
347 | 41323 | jjdelcerro | } |