001: package org.osbl.client.wings.form;
002:
003: import org.osbl.client.action.*;
004: import org.osbl.client.wings.*;
005: import org.osbl.client.wings.shell.*;
006: import org.osbl.client.ClientServiceProvider;
007: import org.osbl.*;
008: import org.osbl.plugin.*;
009: import org.hibernate.ObjectNotFoundException;
010: import org.apache.commons.logging.LogFactory;
011:
012: import javax.swing.*;
013: import java.awt.event.ActionEvent;
014: import java.awt.event.ActionListener;
015: import java.util.*;
016:
017: /**
018: * A generic base class, that implements basic ObjectEditor functionality.
019: * It coordinates ObjectList and ObjectForm.
020: */
021: public abstract class GenericObjectEditor implements ObjectEditor,
022: ObjectContextAware {
023: private static org.apache.commons.logging.Log LOG = LogFactory
024: .getLog(GenericObjectEditor.class);
025:
026: protected Environment environment = new DelegateEnvironment(true);
027: protected List<Tool> tools = new ArrayList<Tool>();
028:
029: protected ObjectList objectList;
030: protected ObjectForm objectForm;
031: private boolean editing;
032: private Object object;
033:
034: protected AddAction addAction = new AddAction(base());
035: protected EditAction editAction = new EditAction(base());
036: protected PreviousAction previousAction = new PreviousAction(base());
037: protected NextAction nextAction = new NextAction(base());
038: protected ListAction listAction = new ListAction(base());
039: protected SaveAction saveAction = new SaveAction(base());
040: protected DeleteObjectAction deleteObjectAction = new DeleteObjectAction(
041: base());
042: protected GenericObjectForm.DelegateObjectAction formDeleteAction = new GenericObjectForm.DelegateObjectAction(
043: deleteObjectAction);
044: protected GenericObjectList.DelegateObjectAction listDeleteAction = new GenericObjectList.DelegateObjectAction(
045: deleteObjectAction);
046: protected ObjectContext context;
047:
048: public GenericObjectEditor() {
049: initializeTools();
050: initializeEditor();
051: environment.setActive(true);
052: }
053:
054: protected void initializeTools() {
055: PluginManager pluginManager = (PluginManager) ClientServiceProvider
056: .getInstance().getService("ClientPluginManager");
057: final ExtensionPoint extensionPoint = new ExtensionPoint(
058: "org.osbl.client.wings.form.editorTools",
059: EditorTool.class);
060: final List<Extension> list = pluginManager
061: .getExtensions(extensionPoint);
062:
063: for (Extension extension : list) {
064: final Class<EditorTool> toolClass = (Class<EditorTool>) extension
065: .getImplementation();
066: try {
067: EditorTool tool = toolClass.newInstance();
068: tool.setEditor(this );
069: tools.add(tool);
070: } catch (Exception e) {
071: throw new RuntimeException(e);
072: }
073: }
074: }
075:
076: public ObjectContext getContext() {
077: if (context == null) {
078: context = new ObjectContext();
079: }
080: return context;
081: }
082:
083: public void setContext(ObjectContext context) {
084: this .context = context;
085: }
086:
087: public Environment getEnvironment() {
088: return environment;
089: }
090:
091: public void showList() {
092: editing = false;
093:
094: getList();
095:
096: if (objectForm != null) {
097: objectForm.getEnvironment().setActive(false);
098: objectForm.setObject(null);
099: }
100: objectList.getEnvironment().setActive(true);
101:
102: objectList.refresh();
103: }
104:
105: public void showForm() {
106: editing = true;
107:
108: getForm();
109:
110: if (objectList != null)
111: objectList.getEnvironment().setActive(false);
112: objectForm.getEnvironment().setActive(true);
113:
114: objectForm.setObject(object);
115: }
116:
117: /**
118: * Initializations like installing global object actions go here.
119: * Override this method for your own initializations.
120: */
121: protected void initializeEditor() {
122: }
123:
124: public ObjectForm getForm() {
125: if (objectForm == null) {
126: objectForm = initializeForm();
127: if (objectForm instanceof ObjectContextAware)
128: ((ObjectContextAware) objectForm)
129: .setContext(getContext());
130: formControls(objectForm.getEnvironment());
131: formTools(objectForm.getEnvironment());
132: objectForm.getEnvironment().setDelegate(environment);
133: formDeleteAction.setForm(objectForm);
134: }
135: return objectForm;
136: }
137:
138: protected void formControls(Environment environment) {
139: environment.addControl(new XButton(listAction));
140: environment.addControl(new XButton(previousAction));
141: environment.addControl(new XButton(nextAction));
142: environment.addControl(new XButton(saveAction));
143: environment.addControl(new XButton(formDeleteAction));
144: }
145:
146: protected void formTools(Environment environment) {
147: for (Tool tool : tools)
148: environment.addTool(tool);
149: }
150:
151: /**
152: * Create and initialize the conform component.
153: * @return the conform component
154: */
155: protected abstract ObjectForm initializeForm();
156:
157: public ObjectList getList() {
158: if (objectList == null) {
159: objectList = initializeList();
160: if (objectList instanceof ObjectContextAware)
161: ((ObjectContextAware) objectList)
162: .setContext(getContext());
163: listControls(objectList.getEnvironment());
164: listTools(objectList.getEnvironment());
165: objectList.getEnvironment().setDelegate(environment);
166: listDeleteAction.setList(objectList);
167:
168: objectList.setLinkAction(linkPropertyName(),
169: new AbstractObjectAction() {
170: public void actionPerformed(
171: ObjectActionEvent event) {
172: Object object = event.getTargets()[0];
173: try {
174: revertObject(object);
175: objectList.setCurrent(object);
176: setObject(object);
177:
178: if (editAction.isEnabled())
179: editAction
180: .actionPerformed(new ActionEvent(
181: GenericObjectEditor.this ,
182: 0, "edit"));
183: } catch (Exception e) {
184: LOG.warn(e);
185: String name = Client
186: .getInstance()
187: .getResourceProvider()
188: .getMessage(getType().getName());
189: String message = Client
190: .getInstance()
191: .getResourceProvider()
192: .getMessage(
193: "businessobject.messages.doesNotExist",
194: name);
195: XOptionPane.showMessageDialog(null,
196: message, name,
197: XOptionPane.ERROR_MESSAGE,
198: new ActionListener() {
199: public void actionPerformed(
200: ActionEvent e) {
201: objectList.refresh();
202: }
203: });
204: }
205: }
206: });
207: }
208: return objectList;
209: }
210:
211: protected String linkPropertyName() {
212: return "key";
213: }
214:
215: protected void listControls(Environment environment) {
216: environment.addControl(new XButton(addAction));
217: environment.addControl(new XButton(listDeleteAction));
218: }
219:
220: protected void listTools(Environment environment) {
221: for (Tool tool : tools)
222: environment.addTool(tool);
223: }
224:
225: /**
226: * Create and initialize the list component.
227: * @return the list component
228: */
229: protected abstract ObjectList initializeList();
230:
231: public Object getObject() {
232: return object;
233: }
234:
235: public void setObject(Object object) {
236: this .object = object;
237: }
238:
239: public void setSelectionMode(int selectionMode) {
240: getList().setSelectionMode(selectionMode);
241: }
242:
243: public void setSelectedObject(Object object) {
244: getList().setSelectedObject(object);
245: }
246:
247: public Object getSelectedObject() {
248: return getList().getSelectedObject();
249: }
250:
251: public List getSelectedObjects() {
252: return getList().getSelectedObjects();
253: }
254:
255: public void setSelectedObjects(List objects) {
256: getList().setSelectedObjects(objects);
257: }
258:
259: public abstract Class getType();
260:
261: public abstract void saveObject(Object object);
262:
263: public abstract void deleteObject(Object object);
264:
265: public abstract void revertObject(Object object);
266:
267: /**
268: * Provide the ChooseAction and append the object list actions if any.
269: * @return a list of actions, displayed along with the list.
270: */
271: protected List<Action> getListActions() {
272: return null;
273: }
274:
275: /**
276: * Provide the ListAction, PreviousAction, NextAction and SaveAction and append the object conform actions if any.
277: * @return a list of actions, displayed along with the conform.
278: */
279: protected List<Action> getFormActions() {
280: return null;
281: }
282:
283: protected String base() {
284: return getType().getName();
285: }
286:
287: protected String unsavedChangesMessage(String name) {
288: String message = Client.getInstance().getResourceProvider()
289: .getMessage("businessobject.messages.unsavedChanges",
290: name);
291: if (objectForm instanceof GenericObjectForm) {
292: GenericObjectForm genericObjectForm = (GenericObjectForm) objectForm;
293: String changes = genericObjectForm.getChangeStatus()
294: .composeMessageDetail();
295: message = message + "\n\n" + changes;
296: }
297: return message;
298: }
299:
300: protected class ListAction extends AbstractAction {
301: public ListAction(String base) {
302: putValue(Action.ACTION_COMMAND_KEY, base + ".buttons.list");
303: }
304:
305: public void actionPerformed(ActionEvent e) {
306: if (objectForm.hasChanges()) {
307: String name = Client.getInstance()
308: .getResourceProvider().getMessage(
309: getType().getName());
310: String message = unsavedChangesMessage(name);
311: XOptionPane.showConfirmDialog(null, message, name,
312: new ActionListener() {
313: public void actionPerformed(ActionEvent e) {
314: if (XOptionPane.YES_ACTION == e
315: .getActionCommand())
316: showList();
317: }
318: });
319: } else
320: showList();
321: }
322:
323: public void setEnabled(boolean newValue) {
324: }
325: }
326:
327: protected class NextAction extends AbstractAction {
328: public NextAction(String base) {
329: putValue(Action.ACTION_COMMAND_KEY, base + ".buttons.next");
330: setEnabled(false);
331: }
332:
333: public void actionPerformed(ActionEvent e) {
334: if (objectForm.hasChanges()) {
335: String name = Client.getInstance()
336: .getResourceProvider().getMessage(
337: objectForm.getType().getName());
338: String message = unsavedChangesMessage(name);
339: XOptionPane.showConfirmDialog(null, message, name,
340: new ActionListener() {
341: public void actionPerformed(ActionEvent e) {
342: if (XOptionPane.YES_ACTION == e
343: .getActionCommand())
344: next();
345: }
346: });
347: } else
348: next();
349: }
350:
351: private void next() {
352: objectList.next();
353: setObject(objectList.getCurrent());
354: showForm();
355: previousAction.setEnabled(objectList.hasPrevious());
356: nextAction.setEnabled(objectList.hasNext());
357: if (formDeleteAction != null)
358: formDeleteAction.setEnabled(true);
359: }
360: }
361:
362: protected class PreviousAction extends AbstractAction {
363: public PreviousAction(String base) {
364: putValue(Action.ACTION_COMMAND_KEY, base
365: + ".buttons.previous");
366: setEnabled(false);
367: }
368:
369: public void actionPerformed(ActionEvent e) {
370: if (objectForm.hasChanges()) {
371: String name = Client.getInstance()
372: .getResourceProvider().getMessage(
373: getType().getName());
374: String message = unsavedChangesMessage(name);
375: XOptionPane.showConfirmDialog(null, message, name,
376: new ActionListener() {
377: public void actionPerformed(ActionEvent e) {
378: if (XOptionPane.YES_ACTION == e
379: .getActionCommand())
380: previous();
381: }
382: });
383: } else
384: previous();
385: }
386:
387: private void previous() {
388: objectList.previous();
389: setObject(objectList.getCurrent());
390: showForm();
391: previousAction.setEnabled(objectList.hasPrevious());
392: nextAction.setEnabled(objectList.hasNext());
393: if (formDeleteAction != null)
394: formDeleteAction.setEnabled(true);
395: }
396: }
397:
398: protected class AddAction extends AbstractAction {
399: public AddAction(String base) {
400: putValue(Action.ACTION_COMMAND_KEY, base + ".buttons.add");
401: putValue(AuthorizedAction.PERMISSION_KEY, base + "[w]");
402: }
403:
404: public void actionPerformed(ActionEvent e) {
405: setObject(null);
406: showForm();
407: objectList.setSelectedObject(null);
408: previousAction.setEnabled(false);
409: nextAction.setEnabled(false);
410: if (formDeleteAction != null)
411: formDeleteAction.setEnabled(false);
412: }
413: }
414:
415: protected class EditAction extends AbstractAction {
416: public EditAction(String base) {
417: putValue(Action.ACTION_COMMAND_KEY, base + ".buttons.edit");
418: putValue(AuthorizedAction.PERMISSION_KEY, base + "[w]");
419: }
420:
421: public void actionPerformed(ActionEvent e) {
422: showForm();
423: previousAction.setEnabled(objectList.hasPrevious());
424: nextAction.setEnabled(objectList.hasNext());
425: if (formDeleteAction != null)
426: formDeleteAction.setEnabled(true);
427: }
428: }
429:
430: protected class SaveAction extends AbstractAction {
431: public SaveAction(String base) {
432: putValue(Action.ACTION_COMMAND_KEY, base + ".buttons.save");
433: putValue(AuthorizedAction.PERMISSION_KEY, base + "[w]");
434: }
435:
436: public void actionPerformed(ActionEvent event) {
437: if (objectForm.hasValidationIssues())
438: return;
439:
440: try {
441: saveObject(objectForm.getObject());
442: String name = Client.getInstance()
443: .getResourceProvider().getMessage(
444: getType().getName());
445: String message = Client.getInstance()
446: .getResourceProvider().getMessage(
447: "businessobject.messages.saved", name);
448: objectForm.setObject(objectForm.getObject());
449: getEnvironment().setStatusMessage(
450: new Client.Message(Client.Message.TYPE_INFO,
451: message));
452: } catch (Exception e) {
453: getEnvironment().setStatusMessage(
454: new Client.Message(Client.Message.TYPE_ERROR, e
455: .getMessage()));
456: e.printStackTrace();
457: }
458:
459: getList().refresh();
460: objectList.setSelectedObject(objectForm.getObject());
461: }
462: }
463:
464: protected class DeleteObjectAction extends AbstractObjectAction {
465: public DeleteObjectAction(String base) {
466: putValue(Action.ACTION_COMMAND_KEY, base
467: + ".buttons.delete");
468: putValue(AuthorizedAction.PERMISSION_KEY, base + "[w]");
469: }
470:
471: public void actionPerformed(ObjectActionEvent event) {
472: try {
473: final Object[] objects = event.getTargets();
474: final ReferenceCheckers referenceCheckers = (ReferenceCheckers) ServiceProvider
475: .getInstance().getService("ReferenceCheckers");
476: List references = referenceCheckers.referenceChecks(
477: getType(), Arrays.asList(objects));
478:
479: if (references == null || references.size() == 0) {
480: String name = Client.getInstance()
481: .getResourceProvider().getMessage(
482: getType().getName());
483: String message = Client
484: .getInstance()
485: .getResourceProvider()
486: .getMessage(
487: "businessobject.messages.reallyDelete",
488: name, objects.length);
489:
490: XOptionPane.showConfirmDialog(null, message, name,
491: new ActionListener() {
492: public void actionPerformed(
493: ActionEvent e) {
494: if (XOptionPane.YES_ACTION == e
495: .getActionCommand()) {
496: for (Object object : objects)
497: deleteObject(object);
498:
499: String name = Client
500: .getInstance()
501: .getResourceProvider()
502: .getMessage(
503: getType()
504: .getName());
505: String message = Client
506: .getInstance()
507: .getResourceProvider()
508: .getMessage(
509: "businessobject.messages.deleted",
510: name,
511: objects.length);
512: getEnvironment()
513: .setStatusMessage(
514: new Client.Message(
515: Client.Message.TYPE_INFO,
516: message));
517:
518: if (editing)
519: showList();
520: else
521: getList().refresh();
522: }
523: }
524: });
525: } else {
526: String name = Client.getInstance()
527: .getResourceProvider().getMessage(
528: getType().getName());
529: String message = Client
530: .getInstance()
531: .getResourceProvider()
532: .getMessage(
533: "businessobject.messages.reallyDeletePartially",
534: name, objects.length);
535:
536: XOptionPane.showConfirmDialog(null, message, name,
537: new ActionListener() {
538: public void actionPerformed(
539: ActionEvent e) {
540: if (XOptionPane.YES_ACTION == e
541: .getActionCommand()) {
542: int i = 0;
543: for (Object object : objects) {
544: List references = referenceCheckers
545: .referenceChecks(
546: getType(),
547: Collections
548: .singleton(object));
549: if (references == null
550: || references
551: .size() == 0) {
552: deleteObject(object);
553: i++;
554: }
555: }
556:
557: String name = Client
558: .getInstance()
559: .getResourceProvider()
560: .getMessage(
561: getType()
562: .getName());
563: String message = Client
564: .getInstance()
565: .getResourceProvider()
566: .getMessage(
567: "businessobject.messages.partiallyDeleted",
568: name, i,
569: objects.length);
570: getEnvironment()
571: .setStatusMessage(
572: new Client.Message(
573: Client.Message.TYPE_INFO,
574: message));
575:
576: if (editing)
577: showList();
578: else
579: getList().refresh();
580: }
581: }
582: });
583: }
584: } catch (Exception e) {
585: getEnvironment().setStatusMessage(
586: new Client.Message(Client.Message.TYPE_ERROR, e
587: .getMessage()));
588: e.printStackTrace();
589: }
590: }
591: }
592: }
|