1 | package eu.clarin.cmdi.virtualcollectionregistry.gui.wizard; |
---|
2 | |
---|
3 | import eu.clarin.cmdi.virtualcollectionregistry.gui.ApplicationSession; |
---|
4 | import eu.clarin.cmdi.virtualcollectionregistry.gui.TooltipBehavior; |
---|
5 | import eu.clarin.cmdi.virtualcollectionregistry.gui.VolatileEntityModel; |
---|
6 | import eu.clarin.cmdi.virtualcollectionregistry.gui.dialog.ConfirmationDialog; |
---|
7 | import eu.clarin.cmdi.virtualcollectionregistry.gui.pages.ReferenceLinkPanel; |
---|
8 | import eu.clarin.cmdi.virtualcollectionregistry.model.Creator; |
---|
9 | import eu.clarin.cmdi.virtualcollectionregistry.model.Resource; |
---|
10 | import eu.clarin.cmdi.virtualcollectionregistry.model.VirtualCollection; |
---|
11 | import eu.clarin.cmdi.virtualcollectionregistry.service.CreatorProvider; |
---|
12 | import java.util.Arrays; |
---|
13 | import java.util.Iterator; |
---|
14 | import java.util.List; |
---|
15 | import org.apache.wicket.Component; |
---|
16 | import org.apache.wicket.ResourceReference; |
---|
17 | import org.apache.wicket.Session; |
---|
18 | import org.apache.wicket.ajax.AjaxRequestTarget; |
---|
19 | import org.apache.wicket.ajax.markup.html.AjaxLink; |
---|
20 | import org.apache.wicket.behavior.AttributeAppender; |
---|
21 | import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable; |
---|
22 | import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; |
---|
23 | import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn; |
---|
24 | import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable; |
---|
25 | import org.apache.wicket.extensions.markup.html.repeater.data.table.HeaderlessColumn; |
---|
26 | import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; |
---|
27 | import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn; |
---|
28 | import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider; |
---|
29 | import org.apache.wicket.extensions.wizard.dynamic.DynamicWizardModel; |
---|
30 | import org.apache.wicket.extensions.wizard.dynamic.DynamicWizardStep; |
---|
31 | import org.apache.wicket.extensions.wizard.dynamic.IDynamicWizardStep; |
---|
32 | import org.apache.wicket.markup.ComponentTag; |
---|
33 | import org.apache.wicket.markup.html.WebMarkupContainer; |
---|
34 | import org.apache.wicket.markup.html.basic.Label; |
---|
35 | import org.apache.wicket.markup.html.form.DropDownChoice; |
---|
36 | import org.apache.wicket.markup.html.form.EnumChoiceRenderer; |
---|
37 | import org.apache.wicket.markup.html.form.Form; |
---|
38 | import org.apache.wicket.markup.html.form.FormComponent; |
---|
39 | import org.apache.wicket.markup.html.form.RequiredTextField; |
---|
40 | import org.apache.wicket.markup.html.form.TextArea; |
---|
41 | import org.apache.wicket.markup.html.form.TextField; |
---|
42 | import org.apache.wicket.markup.html.form.validation.AbstractFormValidator; |
---|
43 | import org.apache.wicket.markup.html.internal.HtmlHeaderContainer; |
---|
44 | import org.apache.wicket.markup.html.list.ListItem; |
---|
45 | import org.apache.wicket.markup.html.list.ListView; |
---|
46 | import org.apache.wicket.markup.html.list.OddEvenListItem; |
---|
47 | import org.apache.wicket.markup.html.panel.Panel; |
---|
48 | import org.apache.wicket.markup.html.resources.JavascriptResourceReference; |
---|
49 | import org.apache.wicket.markup.repeater.Item; |
---|
50 | import org.apache.wicket.model.AbstractReadOnlyModel; |
---|
51 | import org.apache.wicket.model.CompoundPropertyModel; |
---|
52 | import org.apache.wicket.model.IModel; |
---|
53 | import org.apache.wicket.model.Model; |
---|
54 | import org.apache.wicket.model.PropertyModel; |
---|
55 | import org.apache.wicket.model.StringResourceModel; |
---|
56 | import org.apache.wicket.spring.injection.annot.SpringBean; |
---|
57 | import org.apache.wicket.validation.validator.StringValidator; |
---|
58 | import org.apache.wicket.validation.validator.UrlValidator; |
---|
59 | import org.odlabs.wiquery.core.commons.CoreJavaScriptResourceReference; |
---|
60 | |
---|
61 | @SuppressWarnings("serial") |
---|
62 | public 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 |
---|