source: VirtualCollectionRegistry/trunk/VirtualCollectionRegistry/src/main/java/eu/clarin/cmdi/virtualcollectionregistry/gui/wizard/CreateVirtualCollectionWizard.java @ 5541

Last change on this file since 5541 was 5541, checked in by Twan Goosen, 10 years ago

Added a confirmation pop-up before completing the editing of a public collection
Refs #600

  • Property svn:eol-style set to native
File size: 35.4 KB
Line 
1package eu.clarin.cmdi.virtualcollectionregistry.gui.wizard;
2
3import eu.clarin.cmdi.virtualcollectionregistry.gui.ApplicationSession;
4import eu.clarin.cmdi.virtualcollectionregistry.gui.TooltipBehavior;
5import eu.clarin.cmdi.virtualcollectionregistry.gui.VolatileEntityModel;
6import eu.clarin.cmdi.virtualcollectionregistry.gui.dialog.ConfirmationDialog;
7import eu.clarin.cmdi.virtualcollectionregistry.gui.pages.ReferenceLinkPanel;
8import eu.clarin.cmdi.virtualcollectionregistry.model.Creator;
9import eu.clarin.cmdi.virtualcollectionregistry.model.Resource;
10import eu.clarin.cmdi.virtualcollectionregistry.model.VirtualCollection;
11import eu.clarin.cmdi.virtualcollectionregistry.service.CreatorProvider;
12import java.util.Arrays;
13import java.util.Iterator;
14import java.util.List;
15import org.apache.wicket.Component;
16import org.apache.wicket.ResourceReference;
17import org.apache.wicket.Session;
18import org.apache.wicket.ajax.AjaxRequestTarget;
19import org.apache.wicket.ajax.markup.html.AjaxLink;
20import org.apache.wicket.behavior.AttributeAppender;
21import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
22import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
23import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
24import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable;
25import org.apache.wicket.extensions.markup.html.repeater.data.table.HeaderlessColumn;
26import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
27import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
28import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
29import org.apache.wicket.extensions.wizard.dynamic.DynamicWizardModel;
30import org.apache.wicket.extensions.wizard.dynamic.DynamicWizardStep;
31import org.apache.wicket.extensions.wizard.dynamic.IDynamicWizardStep;
32import org.apache.wicket.markup.ComponentTag;
33import org.apache.wicket.markup.html.WebMarkupContainer;
34import org.apache.wicket.markup.html.basic.Label;
35import org.apache.wicket.markup.html.form.DropDownChoice;
36import org.apache.wicket.markup.html.form.EnumChoiceRenderer;
37import org.apache.wicket.markup.html.form.Form;
38import org.apache.wicket.markup.html.form.FormComponent;
39import org.apache.wicket.markup.html.form.RequiredTextField;
40import org.apache.wicket.markup.html.form.TextArea;
41import org.apache.wicket.markup.html.form.TextField;
42import org.apache.wicket.markup.html.form.validation.AbstractFormValidator;
43import org.apache.wicket.markup.html.internal.HtmlHeaderContainer;
44import org.apache.wicket.markup.html.list.ListItem;
45import org.apache.wicket.markup.html.list.ListView;
46import org.apache.wicket.markup.html.list.OddEvenListItem;
47import org.apache.wicket.markup.html.panel.Panel;
48import org.apache.wicket.markup.html.resources.JavascriptResourceReference;
49import org.apache.wicket.markup.repeater.Item;
50import org.apache.wicket.model.AbstractReadOnlyModel;
51import org.apache.wicket.model.CompoundPropertyModel;
52import org.apache.wicket.model.IModel;
53import org.apache.wicket.model.Model;
54import org.apache.wicket.model.PropertyModel;
55import org.apache.wicket.model.StringResourceModel;
56import org.apache.wicket.spring.injection.annot.SpringBean;
57import org.apache.wicket.validation.validator.StringValidator;
58import org.apache.wicket.validation.validator.UrlValidator;
59import org.odlabs.wiquery.core.commons.CoreJavaScriptResourceReference;
60
61@SuppressWarnings("serial")
62public abstract class CreateVirtualCollectionWizard extends WizardBase {
63
64    @SpringBean
65    private CreatorProvider creatorProvider;
66   
67    private final static ResourceReference TOOLTIP_JAVASCRIPT_REFERENCE = 
68            new JavascriptResourceReference(CreateVirtualCollectionWizard.class, "wizardhelp.js");
69
70    @Override
71    public void renderHead(HtmlHeaderContainer container) {
72        super.renderHead(container);
73        // Javascript dependencies for this page (jQuery tooltips)
74        container.getHeaderResponse().renderJavascriptReference(CoreJavaScriptResourceReference.get());
75        container.getHeaderResponse().renderJavascriptReference(TooltipBehavior.QTIP_JAVASCRIPT_RESOURCE);
76        container.getHeaderResponse().renderJavascriptReference(TOOLTIP_JAVASCRIPT_REFERENCE);
77    }
78   
79    private final class GeneralStep extends DynamicWizardStep {
80
81        private final class DeleteKeywordDialog extends ConfirmationDialog {
82
83            private String keyword;
84
85            public DeleteKeywordDialog(String id,
86                    final Component updateComponent) {
87                super(id, updateComponent);
88            }
89
90            @Override
91            public void onConfirm(AjaxRequestTarget target) {
92                vc.getObject().getKeywords().remove(keyword);
93            }
94
95            public void show(AjaxRequestTarget target, String keyword) {
96                this.keyword = keyword;
97                super.show(target, new StringResourceModel("keywords.deleteconfirm", null, new Object[]{keyword}));
98            }
99        } // class CreateVirtualCollectionWizard.GeneralStep.DeleteKeywordDialog
100
101        private final class KeywordsList extends WebMarkupContainer {
102
103            private final ListView<String> itemsView;
104
105            public KeywordsList(String id, final IModel<List<String>> itemsModel) {
106                super(id);
107                setOutputMarkupId(true);
108
109                itemsView = new ListView<String>("keywords", itemsModel) {
110                    @Override
111                    protected void populateItem(final ListItem<String> item) {
112                        final IModel<String> model = item.getModel();
113                        item.add(new Label("itemText", model.getObject()));
114                        item.add(new AjaxLink<String>("itemRemove") {
115                            @Override
116                            public void onClick(AjaxRequestTarget target) {
117                                deleteKeywordDialog.show(target,
118                                        model.getObject());
119                            }
120                        });
121                    }
122
123                    @Override
124                    protected ListItem<String> newItem(int index) {
125                        final IModel<String> model
126                                = getListItemModel(getModel(), index);
127                        return new OddEvenListItem<String>(index, model) {
128                            @Override
129                            protected void onComponentTag(ComponentTag tag) {
130                                super.onComponentTag(tag);
131                                if (getIndex() == 0) {
132                                    tag.append("class", "first", " ");
133                                }
134                            }
135                        };
136                    }
137                };
138                add(itemsView);
139            }
140        } // class CreateVirtualCollectionWizard.GeneralStep.KeywordsList
141
142        private final AddKeywordDialog addKeywordDialog;
143        private final DeleteKeywordDialog deleteKeywordDialog;
144
145        public GeneralStep() {
146            super(null, "General", null, vc);
147            setDefaultModel(new CompoundPropertyModel<VirtualCollection>(vc));
148            final TextField<String> nameField
149                    = new RequiredTextField<String>("name");
150            nameField.add(new StringValidator.MaximumLengthValidator(255));
151            add(nameField);
152           
153            final DropDownChoice<VirtualCollection.Type> typeChoice
154                    = new DropDownChoice<VirtualCollection.Type>("type",
155                            Arrays.asList(VirtualCollection.Type.values()),
156                            new EnumChoiceRenderer<VirtualCollection.Type>(this));
157            typeChoice.setRequired(true);
158//            typeChoice.add(new TooltipBehavior(new StringResourceModel("type.tooltip", CreateVirtualCollectionWizard.this, null)));
159            add(typeChoice);
160           
161            add(new TextArea<String>("description"));
162            final DropDownChoice<VirtualCollection.Purpose> purposeChoice
163                    = new DropDownChoice<VirtualCollection.Purpose>("purpose",
164                            Arrays.asList(VirtualCollection.Purpose.values()),
165                            new EnumChoiceRenderer<VirtualCollection.Purpose>(this));
166            add(purposeChoice);
167            final DropDownChoice<VirtualCollection.Reproducibility> reproducibilityChoice
168                    = new DropDownChoice<VirtualCollection.Reproducibility>("reproducibility",
169                            Arrays.asList(VirtualCollection.Reproducibility.values()),
170                            new EnumChoiceRenderer<VirtualCollection.Reproducibility>(this));
171            add(reproducibilityChoice);
172            final TextArea<String> reproducibilityNoticeArea
173                    = new TextArea<String>("reproducibilityNotice");
174            add(reproducibilityNoticeArea);
175
176            final KeywordsList keywordList
177                    = new KeywordsList("keywordsList",
178                            new PropertyModel<List<String>>(vc, "keywords"));
179            add(keywordList);
180            add(new AjaxLink<String>("keywordsAdd") {
181                @Override
182                public void onClick(AjaxRequestTarget target) {
183                    addKeywordDialog.show(target);
184                }
185            });
186
187            addKeywordDialog = new AddKeywordDialog("addKeywordDialog") {
188                @Override
189                public void onSubmit(AjaxRequestTarget target, String keyword) {
190                    final List<String> keywords = vc.getObject().getKeywords();
191                    if (!keywords.contains(keyword)) {
192                        keywords.add(keyword);
193                    }
194                    target.addComponent(keywordList);
195                }
196            };
197            add(addKeywordDialog);
198
199            deleteKeywordDialog
200                    = new DeleteKeywordDialog("deleteKeywordDialog", keywordList);
201            add(deleteKeywordDialog);
202        }
203
204        @Override
205        public boolean isLastStep() {
206            return false;
207        }
208
209        @Override
210        public IDynamicWizardStep next() {
211            return new CreatorsStep(this);
212        }
213
214        @Override
215        public void applyState() {
216            super.applyState();
217            switch (vc.getObject().getType()) {
218                case EXTENSIONAL:
219                    vc.getObject().setGeneratedBy(null);
220                    break;
221                case INTENSIONAL:
222                    vc.getObject().getResources().clear();
223                    break;
224            }
225        }
226    } // class CreateVirtualCollectionWizard.GeneralStep
227
228    private final class CreatorsStep extends DynamicWizardStep {
229
230        private final class ActionsPanel extends Panel {
231
232            public ActionsPanel(String id, final IModel<Creator> model) {
233                super(id, model);
234                setRenderBodyOnly(true);
235                final AjaxLink<Creator> editLink
236                        = new AjaxLink<Creator>("edit") {
237                            @Override
238                            public void onClick(AjaxRequestTarget target) {
239                                editCreatorDialog.show(target, model);
240                            }
241                        };
242                add(editLink);
243                final AjaxLink<Creator> deleteLink
244                        = new AjaxLink<Creator>("delete") {
245                            @Override
246                            public void onClick(AjaxRequestTarget target) {
247                                deleteCreatorDialog.showCreator(target, model);
248                            }
249                        };
250                add(deleteLink);
251            }
252        } // class CreateVirtualCollectionWizard.CreatorsStep.ActionsPanel
253
254        private final class DeleteCreatorDialog extends ConfirmationDialog {
255
256            private IModel<Creator> creator;
257
258            public DeleteCreatorDialog(String id,
259                    final Component updateComponent) {
260                super(id, updateComponent);
261                setInitialWidth(400);
262            }
263
264            @Override
265            public void onConfirm(AjaxRequestTarget target) {
266                if (creator != null) {
267                    vc.getObject().getCreators().remove(creator.getObject());
268                }
269            }
270
271            public void showCreator(AjaxRequestTarget target, IModel<Creator> creator) {
272                this.creator = creator;
273                super.show(target,
274                        new StringResourceModel("creators.deleteconfirm",
275                                creator));
276            }
277        } // class CreateVirtualCollectionWizard.CreatorsStep.DeleteCreatorDialog
278
279        private final EditCreatorDialog editCreatorDialog;
280        private final DeleteCreatorDialog deleteCreatorDialog;
281
282        public CreatorsStep(IDynamicWizardStep previousStep) {
283            super(previousStep, "Creators", null, vc);
284            final DataTable<Creator> creatorsTable
285                    = new AjaxFallbackDefaultDataTable<Creator>("creatorsTable",
286                            createColumns(),
287                            new SortableDataProvider<Creator>() {
288                                @Override
289                                public Iterator<? extends Creator>
290                                iterator(int first, int count) {
291                                    return vc.getObject().getCreators().listIterator(first);
292                                }
293
294                                @Override
295                                public IModel<Creator> model(Creator creator) {
296                                    return new VolatileEntityModel<Creator>(creator);
297                                }
298
299                                @Override
300                                public int size() {
301                                    return vc.getObject().getCreators().size();
302                                }
303                            },
304                            8);
305            creatorsTable.setOutputMarkupId(true);
306            add(creatorsTable);
307
308            editCreatorDialog = new EditCreatorDialog("editCreatorDialog") {
309                @Override
310                public void onSubmit(AjaxRequestTarget target, Creator creator) {
311                    // create a copy first because retrieving the creators may
312                    // reset the state of the object
313                    final Creator copy = creator.getCopy();
314                    final List<Creator> creators = vc.getObject().getCreators();
315                    if (creators.contains(creator)) {
316                        // update existig creator (needed since we're dealing with a volatile instance)
317                        creator.setValuesFrom(copy);
318                    } else {
319                        // new entry, add
320                        creators.add(creator);
321                    }
322                    target.addComponent(creatorsTable);
323                }
324            };
325            add(editCreatorDialog);
326
327            deleteCreatorDialog
328                    = new DeleteCreatorDialog("deleteCreatorDialog", creatorsTable);
329            add(deleteCreatorDialog);
330
331            add(new AjaxLink<Object>("add") {
332                @Override
333                public void onClick(AjaxRequestTarget target) {
334                    editCreatorDialog.show(target);
335                }
336            });
337            add(new AjaxLink("addme") {
338
339                @Override
340                public void onClick(AjaxRequestTarget target) {
341                    final Creator creator = creatorProvider.getCreator(ApplicationSession.get().getPrincipal());
342                    if (creator.getPerson() == null) {
343                        Session.get().error("Could not retrieve required user information");
344                        setResponsePage(getPage());
345                    } else {
346                        vc.getObject().getCreators().add(creator);
347                        target.addComponent(creatorsTable);
348                    }
349                }
350            });
351        }
352
353        @Override
354        public boolean isLastStep() {
355            return false;
356        }
357
358        @Override
359        public IDynamicWizardStep next() {
360            switch (vc.getObject().getType()) {
361                case EXTENSIONAL:
362                    return new ResourcesStep(this);
363                case INTENSIONAL:
364                    return new GeneratedByStep(this);
365                default:
366                    throw new InternalError("bad vc type");
367            } // switch
368        }
369
370        @SuppressWarnings("unchecked")
371        private IColumn<Creator>[] createColumns() {
372            final IColumn<?>[] columns = new IColumn<?>[]{
373                new PropertyColumn<Creator>(new Model<String>("Person"),
374                "person"),
375                new PropertyColumn<Creator>(new Model<String>("EMail"),
376                "email"),
377                new PropertyColumn<Creator>(new Model<String>(
378                "Organisation"), "organisation"),
379                new HeaderlessColumn<Creator>() {
380                    @Override
381                    public void populateItem(Item<ICellPopulator<Creator>> item, String compontentId, IModel<Creator> model) {
382                        item.add(new ActionsPanel(compontentId, model));
383                    }
384
385                    @Override
386                    public String getCssClass() {
387                        return "action";
388                    }
389                }
390            };
391            return (IColumn<Creator>[]) columns;
392        }
393    } // class CreateVirtualCollectionWizard.CreatorsStep
394
395    private final class ResourcesStep extends DynamicWizardStep {
396
397        private final WebMarkupContainer resourcesContainer;
398
399        private final class ActionsPanel extends Panel {
400
401            public ActionsPanel(String id, final IModel<Resource> model) {
402                super(id, model);
403                setRenderBodyOnly(true);
404                final AjaxLink<Resource> editLink
405                        = new AjaxLink<Resource>("edit") {
406                            @Override
407                            public void onClick(AjaxRequestTarget target) {
408                                editResourceDialog.show(target, model);
409                            }
410
411                            @Override
412                            protected void onConfigure() {
413                                // only allow when not moving
414                                setVisible(movingResource.getObject() == null);
415                            }
416                        };
417                add(editLink);
418                final AjaxLink<Resource> deleteLink
419                        = new AjaxLink<Resource>("delete") {
420                            @Override
421                            public void onClick(AjaxRequestTarget target) {
422                                deleteResourceDialog.showResource(target, model);
423                            }
424
425                            @Override
426                            protected void onConfigure() {
427                                // only allow when not moving
428                                setVisible(movingResource.getObject() == null);
429                            }
430                        };
431                add(deleteLink);
432            }
433
434        }
435
436        private final class MoveItemPanel extends Panel {
437
438            public MoveItemPanel(String id, final IModel<Resource> model) {
439                super(id, model);
440
441                final AjaxLink<Resource> moveLink
442                        = new AjaxLink<Resource>("move") {
443
444                            @Override
445                            public void onClick(AjaxRequestTarget target) {
446                                movingResource.setObject(model.getObject());
447                                target.addComponent(resourcesContainer);
448                            }
449
450                            @Override
451                            protected void onConfigure() {
452                                // only allow to start moving when not moving
453                                setVisible(movingResource.getObject() == null);
454                            }
455
456                        };
457                add(moveLink);
458
459                final AjaxLink<Resource> cancelLink
460                        = new AjaxLink<Resource>("cancel") {
461
462                            @Override
463                            public void onClick(AjaxRequestTarget target) {
464                                movingResource.setObject(null);
465                                target.addComponent(resourcesContainer);
466                            }
467
468                            @Override
469                            protected void onConfigure() {
470                                // only allow cancelling resource being moved
471                                setVisible(model.getObject().equals(movingResource.getObject())
472                                );
473                            }
474
475                        };
476                add(cancelLink);
477
478                final AjaxLink<Resource> targetLink
479                        = new AjaxLink<Resource>("target") {
480
481                            @Override
482                            public void onClick(AjaxRequestTarget target) {
483                                final List<Resource> resources = vc.getObject().getResources();
484                                final Resource toMove = movingResource.getObject();
485                                try {
486                                    if (resources.remove(toMove)) {
487                                        final int targetIndex = resources.indexOf(model.getObject());
488                                        if (targetIndex >= 0) {
489                                            resources.add(targetIndex, toMove);
490                                            return;
491                                        }
492                                    }
493                                    Session.get().warn("Could not move reference");
494
495                                } finally {
496                                    movingResource.setObject(null);
497                                    target.addComponent(resourcesContainer);
498                                }
499                            }
500
501                            @Override
502                            protected void onConfigure() {
503                                final Resource toMove = movingResource.getObject();
504                                // only allow to drop when moving
505                                setVisible(toMove != null
506                                        && !toMove.equals(model.getObject())
507                                );
508                            }
509
510                        };
511
512                add(targetLink);
513            }
514        } // class CreateVirtualCollectionWizard.ResourcesStep.ActionsPanel
515
516        private final class DeleteResourceDialog extends ConfirmationDialog {
517
518            private IModel<Resource> resource;
519
520            public DeleteResourceDialog(String id,
521                    final Component updateComponenet) {
522                super(id, updateComponenet);
523                setInitialWidth(400);
524            }
525
526            @Override
527            public void onConfirm(AjaxRequestTarget target) {
528                if (resource != null) {
529                    vc.getObject().getResources().remove(resource.getObject());
530                }
531            }
532
533            public void showResource(AjaxRequestTarget target, IModel<Resource> resource) {
534                this.resource = resource;
535                super.show(target,
536                        new StringResourceModel("resources.deleteconfirm",
537                                resource));
538            }
539        } // class CreateVirtualCollectionWizard.CreatorsStep.DeleteResourceDialog
540
541        private final EditResourceDialog editResourceDialog;
542        private final DeleteResourceDialog deleteResourceDialog;
543
544        private IModel<Resource> movingResource = new Model<>();
545
546        public ResourcesStep(IDynamicWizardStep previousStep) {
547            super(previousStep, "Resources", null, vc);
548            resourcesContainer = new WebMarkupContainer("resourcesContainer");
549            resourcesContainer.setOutputMarkupId(true);
550            add(resourcesContainer);
551            final DataTable<Resource> resourcesTable
552                    = new AjaxFallbackDefaultDataTable<Resource>("resourcesTable",
553                            createColumns(),
554                            new SortableDataProvider<Resource>() {
555                                @Override
556                                public Iterator<? extends Resource>
557                                iterator(int first, int count) {
558                                    return vc.getObject().getResources().listIterator(first);
559                                }
560
561                                @Override
562                                public IModel<Resource> model(Resource resource) {
563                                    return new VolatileEntityModel<Resource>(resource);
564                                }
565
566                                @Override
567                                public int size() {
568                                    return vc.getObject().getResources().size();
569                                }
570                            },
571                            64) {
572
573                        @Override
574                        protected Item<Resource> newRowItem(String id, int index, final IModel<Resource> model) {
575                            final Item<Resource> item = super.newRowItem(id, index, model);
576                            // mark the row that is being moved
577                            item.add(new AttributeAppender("class", new AbstractReadOnlyModel<String>() {
578
579                                @Override
580                                public String getObject() {
581                                    if (model.getObject().equals(movingResource.getObject())) {
582                                        return "moving";
583                                    } else {
584                                        return "";
585                                    }
586                                }
587                            }, " "));
588                            return item;
589                        }
590
591                    };
592            resourcesTable.setOutputMarkupId(true);
593
594            // add 'moving' class if table is in moving mode
595            resourcesTable.add(new AttributeAppender("class", new AbstractReadOnlyModel<String>() {
596
597                @Override
598                public String getObject() {
599                    return movingResource.getObject() == null ? "" : "moving";
600                }
601            }, " "));
602            resourcesContainer.add(resourcesTable);
603
604            editResourceDialog = new EditResourceDialog("editResourceDialog") {
605                @Override
606                public void onSubmit(AjaxRequestTarget target,
607                        Resource resource) {
608                    // create a copy first because retrieving the resources may
609                    // reset the state of the object
610                    final Resource copy = resource.getCopy();
611                    final List<Resource> resources = vc.getObject().getResources();
612                    if (resources.contains(resource)) {
613                        // update existig resource (needed since we're dealing with a volatile instance)
614                        resource.valuesFrom(copy);
615                    } else {
616                        // new entry, add
617                        resources.add(resource);
618                    }
619                    target.addComponent(resourcesTable);
620                }
621            };
622            add(editResourceDialog);
623
624            deleteResourceDialog = new DeleteResourceDialog(
625                    "deleteResourceDialog", resourcesTable);
626            add(deleteResourceDialog);
627
628            final AddResourcesDialog addResourcesDialog
629                    = new AddResourcesDialog("addResourcesDialog") {
630                        @Override
631                        public void onSubmit(AjaxRequestTarget target,
632                                Resource[] resources) {
633                            for (Resource resource : resources) {
634                                if (!vc.getObject().getResources().contains(resource)) {
635                                    vc.getObject().getResources().add(resource);
636                                }
637                            }
638                            target.addComponent(resourcesTable);
639                        }
640
641                    };
642            add(addResourcesDialog);
643
644            resourcesContainer.add(new AjaxLink<Object>("add") {
645                @Override
646                public void onClick(AjaxRequestTarget target) {
647                    editResourceDialog.show(target);
648                }
649            });
650
651            resourcesContainer.add(new AjaxLink<Object>("addMore") {
652                @Override
653                public void onClick(AjaxRequestTarget target) {
654                    addResourcesDialog.show(target);
655                }
656            });
657
658            add(new AbstractFormValidator() {
659                @Override
660                public FormComponent<?>[] getDependentFormComponents() {
661                    return null;
662                }
663
664                @Override
665                public void validate(Form<?> form) {
666                    if (vc.getObject().getResources().isEmpty()) {
667                        form.error("An extensional collection requires at "
668                                + "least one resource.");
669                    }
670                }
671            });
672        }
673
674        @Override
675        public boolean isLastStep() {
676            return true;
677        }
678
679        @Override
680        public IDynamicWizardStep next() {
681            return null;
682        }
683
684        @SuppressWarnings("unchecked")
685        private IColumn<Resource>[] createColumns() {
686            final IColumn<?>[] columns = new IColumn<?>[]{
687                new AbstractColumn<Resource>(new Model<String>("Type")) {
688                    @Override
689                    public void populateItem(
690                            Item<ICellPopulator<Resource>> item,
691                            String componentId, IModel<Resource> model) {
692                        switch (model.getObject().getType()) {
693                            case METADATA:
694                                item.add(new Label(componentId, "Metadata"));
695                                break;
696                            case RESOURCE:
697                                item.add(new Label(componentId, "Resource"));
698                                break;
699                        }
700                    }
701
702                    @Override
703                    public String getCssClass() {
704                        return "type";
705                    }
706                },
707                new PropertyColumn<Resource>(
708                new Model<String>("Reference"), "ref") {
709
710                    @Override
711                    public void populateItem(Item<ICellPopulator<Resource>> item, String componentId, IModel<Resource> rowModel) {
712                        item.add(new ReferenceLinkPanel(componentId, rowModel));
713                    }
714
715                },
716                new HeaderlessColumn<Resource>() {
717                    @Override
718                    public void populateItem(
719                            Item<ICellPopulator<Resource>> item,
720                            String compontentId, IModel<Resource> model) {
721                        item.add(new ActionsPanel(compontentId, model));
722                    }
723
724                    @Override
725                    public String getCssClass() {
726                        return "action";
727                    }
728                },
729                new HeaderlessColumn<Resource>() {
730
731                    @Override
732                    public void populateItem(Item<ICellPopulator<Resource>> item, String componentId, IModel<Resource> model) {
733                        item.add(new MoveItemPanel(componentId, model));
734                    }
735
736                    @Override
737                    public String getCssClass() {
738                        return "move";
739                    }
740
741                }
742            };
743            return (IColumn<Resource>[]) columns;
744        }
745    } // class CreateVirtualCollectionWizard.ResourcesStep
746
747    private final class GeneratedByStep extends DynamicWizardStep {
748
749        public GeneratedByStep(IDynamicWizardStep previousStep) {
750            super(previousStep, "Intensional Collection Query", null, vc);
751            setDefaultModel(new CompoundPropertyModel<VirtualCollection>(vc));
752            final TextArea<String> descriptionArea
753                    = new TextArea<String>("generatedBy.description");
754            descriptionArea.setRequired(true);
755            add(descriptionArea);
756            final TextField<String> uriField
757                    = new TextField<String>("generatedBy.uri");
758            uriField.add(new StringValidator.MaximumLengthValidator(255));
759            uriField.add(new UrlValidator(UrlValidator.NO_FRAGMENTS));
760            add(uriField);
761            final TextField<String> queryProfileField
762                    = new TextField<String>("generatedBy.query.profile");
763            add(queryProfileField);
764            final TextArea<String> queryValueArea
765                    = new TextArea<String>("generatedBy.query.value");
766            add(queryValueArea);
767
768            add(new AbstractFormValidator() {
769                @Override
770                public FormComponent<?>[] getDependentFormComponents() {
771                    return new FormComponent[]{queryProfileField,
772                        queryValueArea};
773                }
774
775                @Override
776                public void validate(Form<?> form) {
777                    final String profile = queryProfileField.getInput();
778                    final String value = queryValueArea.getInput();
779                    if (profile.isEmpty() && !value.isEmpty()) {
780                        form.error("profile is required with value");
781                        queryProfileField.invalid();
782                    }
783                    if (!profile.isEmpty() && value.isEmpty()) {
784                        form.error("value is required with profile");
785                        queryValueArea.invalid();
786                    }
787                    if (profile.isEmpty() && value.isEmpty()) {
788                        /*
789                         * XXX: clear Query object as side-effect. This is
790                         * more a hack than a clean solution.
791                         */
792                        if (vc.getObject().getGeneratedBy() != null) {
793                            vc.getObject().getGeneratedBy().setQuery(null);
794                        }
795                    }
796                }
797            });
798        }
799
800        @Override
801        public boolean isLastStep() {
802            return true;
803        }
804
805        @Override
806        public IDynamicWizardStep next() {
807            return null;
808        }
809    } // class CreateVirtualCollectionWizard.GeneratedByStep
810
811    private final IModel<VirtualCollection> vc;
812
813    public CreateVirtualCollectionWizard(String id, IModel<VirtualCollection> vc) {
814        super(id);
815        if (vc == null) {
816            throw new IllegalArgumentException("vc == null");
817        }
818        this.vc = vc;
819        setDefaultModel(new CompoundPropertyModel<VirtualCollection>(this));
820        init(new DynamicWizardModel(new GeneralStep()));
821    }
822
823    public IModel<VirtualCollection> getVirtualCollectionModel() {
824        return vc;
825    }
826
827    @Override
828    public final void onCancel() {
829        onCancelWizard();
830    }
831
832    @Override
833    public final void onFinish() {
834        onFinishWizard(vc);
835    }
836
837    @Override
838    public void detachModels() {
839        super.detachModels();
840        vc.detach();
841    }
842
843    protected abstract void onCancelWizard();
844
845    protected abstract void onFinishWizard(IModel<VirtualCollection> vc);
846
847} // class CreateVirtualCollectionWizard
Note: See TracBrowser for help on using the repository browser.