001package conexp.fx.gui.assistent;
002
003/*
004 * #%L
005 * Concept Explorer FX
006 * %%
007 * Copyright (C) 2010 - 2019 Francesco Kriegel
008 * %%
009 * This program is free software: you can redistribute it and/or modify
010 * it under the terms of the GNU General Public License as
011 * published by the Free Software Foundation, either version 3 of the
012 * License, or (at your option) any later version.
013 * 
014 * This program is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017 * GNU General Public License for more details.
018 * 
019 * You should have received a copy of the GNU General Public
020 * License along with this program.  If not, see
021 * <http://www.gnu.org/licenses/gpl-3.0.html>.
022 * #L%
023 */
024
025import java.io.File;
026import java.util.Arrays;
027import java.util.Collections;
028
029import org.openrdf.repository.http.HTTPRepository;
030
031import conexp.fx.core.builder.Request;
032import conexp.fx.core.builder.Requests.Construct.Apposition;
033import conexp.fx.core.builder.Requests.Construct.BiProduct;
034import conexp.fx.core.builder.Requests.Construct.Complement;
035import conexp.fx.core.builder.Requests.Construct.Contrary;
036import conexp.fx.core.builder.Requests.Construct.DirectProduct;
037import conexp.fx.core.builder.Requests.Construct.DirectSum;
038import conexp.fx.core.builder.Requests.Construct.Dual;
039import conexp.fx.core.builder.Requests.Construct.HorizontalSum;
040import conexp.fx.core.builder.Requests.Construct.Quadposition;
041import conexp.fx.core.builder.Requests.Construct.SemiProduct;
042import conexp.fx.core.builder.Requests.Construct.Subposition;
043import conexp.fx.core.builder.Requests.Construct.SubstitutionSum;
044import conexp.fx.core.builder.Requests.Construct.VerticalSum;
045import conexp.fx.core.builder.Requests.Import.ImportCEX;
046import conexp.fx.core.builder.Requests.Import.ImportCFX;
047import conexp.fx.core.builder.Requests.Import.ImportCSVB;
048import conexp.fx.core.builder.Requests.Import.ImportCXT;
049import conexp.fx.core.builder.Requests.Import.ImportSPARQLFromEndpoint;
050import conexp.fx.core.builder.Requests.Import.ImportSPARQLFromFile;
051import conexp.fx.core.builder.Requests.Import.ImportSPARQLFromRepository;
052import conexp.fx.core.builder.Requests.Import.ImportSPARQLFromURL;
053import conexp.fx.core.builder.Requests.New.NewContext;
054import conexp.fx.core.builder.Requests.New.NewOrder;
055import conexp.fx.core.builder.Requests.Scale.BiOrdinalScale;
056import conexp.fx.core.builder.Requests.Scale.BooleanScaleFromInt;
057import conexp.fx.core.builder.Requests.Scale.BooleanScaleFromSetList;
058import conexp.fx.core.builder.Requests.Scale.ContraNominalScaleFromInt;
059import conexp.fx.core.builder.Requests.Scale.ContraNominalScaleFromSetList;
060import conexp.fx.core.builder.Requests.Scale.ContraOrdinalScaleFromInt;
061import conexp.fx.core.builder.Requests.Scale.ContraOrdinalScaleFromOrder;
062import conexp.fx.core.builder.Requests.Scale.ContraOrdinalScaleFromSetList;
063import conexp.fx.core.builder.Requests.Scale.ConvexOrdinalScaleFromInt;
064import conexp.fx.core.builder.Requests.Scale.ConvexOrdinalScaleFromOrder;
065import conexp.fx.core.builder.Requests.Scale.ConvexOrdinalScaleFromSetList;
066import conexp.fx.core.builder.Requests.Scale.DichtomicScale;
067import conexp.fx.core.builder.Requests.Scale.GridScale;
068import conexp.fx.core.builder.Requests.Scale.InterOrdinalScaleFromInt;
069import conexp.fx.core.builder.Requests.Scale.InterOrdinalScaleFromOrder;
070import conexp.fx.core.builder.Requests.Scale.InterOrdinalScaleFromSetList;
071import conexp.fx.core.builder.Requests.Scale.NominalScaleFromInt;
072import conexp.fx.core.builder.Requests.Scale.NominalScaleFromSetList;
073import conexp.fx.core.builder.Requests.Scale.OrdinalScaleFromInt;
074import conexp.fx.core.builder.Requests.Scale.OrdinalScaleFromSetList;
075import conexp.fx.core.builder.Requests.Source;
076import conexp.fx.core.builder.Requests.Type;
077import conexp.fx.core.collections.Pair;
078import conexp.fx.core.collections.setlist.HashSetArrayList;
079import conexp.fx.core.context.MatrixContext;
080import conexp.fx.core.util.FileFormat;
081import conexp.fx.gui.ConExpFX;
082import conexp.fx.gui.dataset.FCADataset;
083import javafx.beans.binding.ObjectBinding;
084import javafx.beans.binding.StringBinding;
085import javafx.beans.property.ObjectProperty;
086import javafx.beans.property.SimpleObjectProperty;
087import javafx.beans.value.ChangeListener;
088import javafx.beans.value.ObservableValue;
089import javafx.collections.FXCollections;
090import javafx.collections.ObservableList;
091import javafx.event.ActionEvent;
092import javafx.event.EventHandler;
093import javafx.geometry.Insets;
094import javafx.geometry.InsetsBuilder;
095import javafx.geometry.Pos;
096import javafx.scene.Node;
097import javafx.scene.control.Accordion;
098import javafx.scene.control.Button;
099import javafx.scene.control.ButtonBuilder;
100import javafx.scene.control.ChoiceBox;
101import javafx.scene.control.ChoiceBoxBuilder;
102import javafx.scene.control.Label;
103import javafx.scene.control.LabelBuilder;
104import javafx.scene.control.TextArea;
105import javafx.scene.control.TextAreaBuilder;
106import javafx.scene.control.TextField;
107import javafx.scene.control.TextFieldBuilder;
108import javafx.scene.control.TitledPane;
109import javafx.scene.layout.ColumnConstraints;
110import javafx.scene.layout.GridPane;
111import javafx.scene.layout.GridPaneBuilder;
112import javafx.scene.layout.HBox;
113import javafx.scene.text.FontBuilder;
114import jfxtras.scene.control.ListSpinner;
115
116@SuppressWarnings("deprecation")
117public class TypePage extends AssistentPage<Request<?, ?>> {
118
119  public final class FileChooseBox extends HBox {
120
121    public final ObjectProperty<Pair<File, FileFormat>> fileProperty =
122        new SimpleObjectProperty<Pair<File, FileFormat>>(null);
123
124    public FileChooseBox(final String title, final FileFormat... fileFormats) {
125      super();
126      this.setAlignment(Pos.BASELINE_LEFT);
127      this.setPadding(new Insets(2));
128      this.setSpacing(8);
129      final Label chosen = LabelBuilder.create().build();
130      chosen.textProperty().bind(new StringBinding() {
131
132        {
133          bind(fileProperty);
134        }
135
136        protected final String computeValue() {
137          if (fileProperty.get() == null)
138            return "unchosen";
139          return fileProperty.get().first().getName();
140        }
141      });
142      final Button choose = ButtonBuilder.create().text("Choose File...").onAction(new EventHandler<ActionEvent>() {
143
144        public final void handle(final ActionEvent event) {
145          fileProperty.set(ConExpFX.instance.showOpenFileDialog(title, fileFormats));
146        }
147      }).build();
148      this.getChildren().addAll(chosen, choose);
149    }
150  }
151
152  private final class SourcePane extends TitledPane {
153
154    protected final ObservableValue<Request<?, ?>> result;
155
156    private SourcePane(final Source src, final Node content, final ObservableValue<Request<?, ?>> result) {
157      super(src.title, content);
158      this.result = result;
159      this.setFont(FontBuilder.create().size(16).build());
160    }
161  }
162
163  private final Type      type;
164  private final Accordion accordion = new Accordion();
165
166  public TypePage(final Type type) {
167    super(type.title, type.description, null, null);
168    this.contentProperty.set(accordion);
169    this.type = type;
170    if (type.sources.contains(Source.NULL))
171      this.resultProperty.set(null);
172    for (Source source : type.sources)
173      this.accordion.getPanes().add(createSourcePane(source));
174    this.accordion.expandedPaneProperty().addListener(new ChangeListener<TitledPane>() {
175
176      public void changed(ObservableValue<? extends TitledPane> observable, TitledPane oldValue, TitledPane newValue) {
177        if (newValue == null) {
178          TypePage.this.resultProperty.unbind();
179          TypePage.this.resultProperty.set(null);
180        } else
181          TypePage.this.resultProperty.bind(((SourcePane) newValue).result);
182      }
183    });
184    this.accordion.setExpandedPane(accordion.getPanes().get(0));
185  }
186
187  private final SourcePane createSourcePane(final Source src) {
188    switch (src) {
189    case NULL:
190      return nullPane();
191    case INT_INT:
192      return intIntPane();
193    case INT:
194      return intPane();
195    case INT_LIST:
196      return intListPane();
197    case STRINGS:
198      return stringsPane();
199    case ORDER:
200      return orderPane();
201    case ORDER_ORDER:
202      return orderOrderPane();
203    case CONTEXT:
204      return contextPane();
205    case CONTEXT_DOUBLE:
206      return contextDoublePane();
207    case CONTEXT_CONTEXT:
208      return contextContextPane();
209    case CONTEXT_CONTEXT_CONTEXT_CONTEXT:
210      return contextContextContextContextPane();
211    case CONTEXT_CONTEXT_OBJECT_OBJECT:
212      return contextContextObjectObjectPane();
213    case CONTEXT_SET_SET:
214      return contextSetSetPane();
215    case FILE:
216      return filePane();
217    case SPARQL_AND_XMLURL:
218      return queryURLPane();
219    case SPARQL_AND_ONTOLOGYFILE:
220      return queryFilePane();
221    case SPARQL_AND_ONTOLOGYURL:
222      return queryURLPane2();
223    case SPARQL_AND_ONTOLOGYREPOSITORY:
224      return queryRepositoryPane();
225    }
226    return null;
227  }
228
229  private GridPane newGridPane() {
230    return GridPaneBuilder
231        .create()
232        .hgap(10)
233        .vgap(10)
234        .maxWidth(480)
235        .padding(InsetsBuilder.create().left(10).right(10).top(10).bottom(10).build())
236        .build();
237  }
238
239  private final SourcePane nullPane() {
240    return new SourcePane(Source.NULL, newGridPane(), new SimpleObjectProperty<Request<?, ?>>(new DichtomicScale()));
241  }
242
243  private final SourcePane intIntPane() {
244    final GridPane pane = newGridPane();
245    final ListSpinner<Integer> objectSpinner = new ListSpinner<Integer>(0, 1024);
246    final ListSpinner<Integer> attributeSpinner = new ListSpinner<Integer>(0, 1024);
247    pane.add(LabelBuilder.create().text("Number of Objects: ").build(), 0, 0);
248    pane.add(objectSpinner, 1, 0);
249    pane.add(LabelBuilder.create().text("Number of Attribute): ").build(), 0, 1);
250    pane.add(attributeSpinner, 1, 1);
251    return new SourcePane(Source.INT_INT, pane, new ObjectBinding<Request<?, ?>>() {
252
253      {
254        bind(objectSpinner.valueProperty(), attributeSpinner.valueProperty());
255      }
256
257      protected final Request<?, ?> computeValue() {
258        return new NewContext(objectSpinner.getValue(), attributeSpinner.getValue());
259      }
260    });
261  }
262
263  private final SourcePane intPane() {
264    final GridPane pane = newGridPane();
265    final ListSpinner<Integer> elementSpinner = new ListSpinner<Integer>(0, 1024);
266    pane.add(LabelBuilder.create().text("Number of Elements: ").build(), 0, 0);
267    pane.add(elementSpinner, 1, 0);
268    return new SourcePane(Source.INT, pane, new ObjectBinding<Request<?, ?>>() {
269
270      {
271        bind(elementSpinner.valueProperty());
272      }
273
274      protected final Request<?, ?> computeValue() {
275        return new NewOrder(elementSpinner.getValue());
276      }
277    });
278  }
279
280  private final SourcePane intListPane() {
281    final GridPane pane = newGridPane();
282    final ListSpinner<Integer> nSpinner = new ListSpinner<Integer>(0, 1024);
283    nSpinner.setMinWidth(100);
284    pane.add(LabelBuilder.create().text("n = ").build(), 0, 0);
285    pane.add(nSpinner, 1, 0);
286    return new SourcePane(Source.INT_LIST, pane, new ObjectBinding<Request<?, ?>>() {
287
288      {
289        bind(nSpinner.valueProperty());
290      }
291
292      protected final Request<?, ?> computeValue() {
293        switch (type) {
294        case BOOLEAN:
295          return new BooleanScaleFromInt(nSpinner.getValue());
296        case NOMINAL:
297          return new NominalScaleFromInt(nSpinner.getValue());
298        case CONTRA_NOMINAL:
299          return new ContraNominalScaleFromInt(nSpinner.getValue());
300        case ORDINAL:
301          return new OrdinalScaleFromInt(nSpinner.getValue());
302        case CONTRA_ORDINAL:
303          return new ContraOrdinalScaleFromInt(nSpinner.getValue());
304        case INTER_ORDINAL:
305          return new InterOrdinalScaleFromInt(nSpinner.getValue());
306        case CONVEX_ORDINAL:
307          return new ConvexOrdinalScaleFromInt(nSpinner.getValue());
308//            case BINARY_RELATIONS_CONTEXT:
309//              return new BinaryRelationsFromInt(nSpinner.getValue());
310        default:
311          return null;
312        }
313      }
314    });
315  }
316
317  private final SourcePane stringsPane() {
318    final GridPane pane = newGridPane();
319    final TextField textField = TextFieldBuilder.create().minWidth(260).maxWidth(260).build();
320    pane.add(LabelBuilder.create().text("Semicolon separated Elements:").build(), 0, 0);
321    pane.add(textField, 1, 0);
322    return new SourcePane(Source.STRINGS, pane, new ObjectBinding<Request<?, ?>>() {
323
324      {
325        bind(textField.textProperty());
326      }
327
328      protected final Request<?, ?> computeValue() {
329        final HashSetArrayList<String> s =
330            new HashSetArrayList<String>(Arrays.asList(textField.textProperty().get().split(";")));
331        switch (type) {
332        case BOOLEAN:
333          return new BooleanScaleFromSetList<String>(s);
334        case NOMINAL:
335          return new NominalScaleFromSetList<String>(s);
336        case CONTRA_NOMINAL:
337          return new ContraNominalScaleFromSetList<String>(s);
338        case ORDINAL:
339          return new OrdinalScaleFromSetList<String>(s);
340        case CONTRA_ORDINAL:
341          return new ContraOrdinalScaleFromSetList<String>(s);
342        case INTER_ORDINAL:
343          return new InterOrdinalScaleFromSetList<String>(s);
344        case CONVEX_ORDINAL:
345          return new ConvexOrdinalScaleFromSetList<String>(s);
346        default:
347          return null;
348        }
349      }
350    });
351  }
352
353  private final SourcePane orderPane() {
354    final GridPane pane = newGridPane();
355    final ChoiceBox<MatrixContext<?, ?>> orderChoice = ChoiceBoxBuilder
356        .<MatrixContext<?, ?>> create()
357        .minWidth(320)
358        .maxWidth(320)
359        .items(ConExpFX.instance.orders)
360        .build();
361    pane.add(LabelBuilder.create().text("Order Context:").build(), 0, 0);
362    pane.add(orderChoice, 1, 0);
363    return new SourcePane(Source.ORDER, pane, new ObjectBinding<Request<?, ?>>() {
364
365      {
366        bind(orderChoice.valueProperty());
367      }
368
369      @SuppressWarnings({ "unchecked", "rawtypes" })
370      protected final Request<?, ?> computeValue() {
371        switch (type) {
372        case CONTRA_ORDINAL:
373          return new ContraOrdinalScaleFromOrder(orderChoice.valueProperty().get());
374        case INTER_ORDINAL:
375          return new InterOrdinalScaleFromOrder(orderChoice.valueProperty().get());
376        case CONVEX_ORDINAL:
377          return new ConvexOrdinalScaleFromOrder(orderChoice.valueProperty().get());
378        default:
379          return null;
380        }
381      }
382    });
383  }
384
385  private final SourcePane orderOrderPane() {
386    final GridPane pane = newGridPane();
387    final ChoiceBox<MatrixContext<?, ?>> order1Choice = ChoiceBoxBuilder
388        .<MatrixContext<?, ?>> create()
389        .minWidth(320)
390        .maxWidth(320)
391        .items(ConExpFX.instance.orders)
392        .build();
393    final ChoiceBox<MatrixContext<?, ?>> order2Choice = ChoiceBoxBuilder
394        .<MatrixContext<?, ?>> create()
395        .minWidth(320)
396        .maxWidth(320)
397        .items(ConExpFX.instance.orders)
398        .build();
399    pane.add(LabelBuilder.create().text("First Order Context:").build(), 0, 0);
400    pane.add(order1Choice, 1, 0);
401    pane.add(LabelBuilder.create().text("Second Order Context:").build(), 0, 1);
402    pane.add(order2Choice, 1, 1);
403    return new SourcePane(Source.ORDER_ORDER, pane, new ObjectBinding<Request<?, ?>>() {
404
405      {
406        bind(order1Choice.valueProperty(), order2Choice.valueProperty());
407      }
408
409      @SuppressWarnings({ "unchecked", "rawtypes" })
410      protected final Request<?, ?> computeValue() {
411        switch (type) {
412        case BI_ORDINAL:
413          return new BiOrdinalScale(order1Choice.valueProperty().get(), order2Choice.valueProperty().get());
414        case GRID:
415          return new GridScale(order1Choice.valueProperty().get(), order2Choice.valueProperty().get());
416        default:
417          return null;
418        }
419      }
420    });
421  }
422
423  private final SourcePane contextPane() {
424    final GridPane pane = newGridPane();
425    final ChoiceBox<MatrixContext<?, ?>> contextChoice = ChoiceBoxBuilder
426        .<MatrixContext<?, ?>> create()
427        .minWidth(320)
428        .maxWidth(320)
429        .items(ConExpFX.instance.contexts)
430        .build();
431    pane.add(LabelBuilder.create().text("Formal Context:").build(), 0, 0);
432    pane.add(contextChoice, 1, 0);
433    return new SourcePane(Source.CONTEXT, pane, new ObjectBinding<Request<?, ?>>() {
434
435      {
436        bind(contextChoice.valueProperty());
437      }
438
439      @SuppressWarnings({ "unchecked", "rawtypes" })
440      protected final Request<?, ?> computeValue() {
441        switch (type) {
442        case COMPLEMENT:
443          return new Complement(contextChoice.valueProperty().get());
444        case DUAL:
445          return new Dual(contextChoice.valueProperty().get());
446        case CONTRARY:
447          return new Contrary(contextChoice.valueProperty().get());
448        default:
449          return null;
450        }
451      }
452    });
453  }
454
455  private final SourcePane contextDoublePane() {
456    final GridPane pane = newGridPane();
457    final ChoiceBox<MatrixContext<?, ?>> contextChoice = ChoiceBoxBuilder
458        .<MatrixContext<?, ?>> create()
459        .minWidth(320)
460        .maxWidth(320)
461        .items(ConExpFX.instance.contexts)
462        .build();
463    pane.add(LabelBuilder.create().text("Formal Context:").build(), 0, 0);
464    pane.add(contextChoice, 1, 0);
465    final ListSpinner<Integer> toleranceSpinner = new ListSpinner<Integer>(0, 100);
466    pane.add(LabelBuilder.create().text("Tolerance (%): ").build(), 0, 1);
467    pane.add(toleranceSpinner, 1, 1);
468    return new SourcePane(Source.CONTEXT_DOUBLE, pane, new ObjectBinding<Request<?, ?>>() {
469
470      {
471        bind(contextChoice.valueProperty(), toleranceSpinner.valueProperty());
472      }
473
474      @SuppressWarnings({ "unchecked", "rawtypes" })
475      protected final Request<?, ?> computeValue() {
476        switch (type) {
477//            case APPROXIMATION_CONTEXT_BY_ATTRIBUTES:
478//              return new AttributeApproximation(contextChoice.valueProperty().get(), toleranceSpinner
479//                  .valueProperty()
480//                  .get() / 100d);
481        default:
482          return null;
483        }
484      }
485    });
486  }
487
488  private final SourcePane contextContextPane() {
489    final GridPane pane = newGridPane();
490    final ChoiceBox<MatrixContext<?, ?>> context1Choice = ChoiceBoxBuilder
491        .<MatrixContext<?, ?>> create()
492        .minWidth(320)
493        .maxWidth(320)
494        .items(ConExpFX.instance.contexts)
495        .build();
496    final ChoiceBox<MatrixContext<?, ?>> context2Choice = ChoiceBoxBuilder
497        .<MatrixContext<?, ?>> create()
498        .minWidth(320)
499        .maxWidth(320)
500        .items(ConExpFX.instance.contexts)
501        .build();
502    pane.add(LabelBuilder.create().text("First Formal Context:").build(), 0, 0);
503    pane.add(context1Choice, 1, 0);
504    pane.add(LabelBuilder.create().text("Second Formal Context:").build(), 0, 1);
505    pane.add(context2Choice, 1, 1);
506    return new SourcePane(Source.CONTEXT_CONTEXT, pane, new ObjectBinding<Request<?, ?>>() {
507
508      {
509        bind(context1Choice.valueProperty(), context2Choice.valueProperty());
510      }
511
512      @SuppressWarnings({ "unchecked", "rawtypes" })
513      protected final Request<?, ?> computeValue() {
514        switch (type) {
515        case APPOSITION:
516          return new Apposition(context1Choice.valueProperty().get(), context2Choice.valueProperty().get());
517        case SUBPOSITION:
518          return new Subposition(context1Choice.valueProperty().get(), context2Choice.valueProperty().get());
519        case HORIZONTAL_SUM:
520          return new HorizontalSum(context1Choice.valueProperty().get(), context2Choice.valueProperty().get());
521        case VERTICAL_SUM:
522          return new VerticalSum(context1Choice.valueProperty().get(), context2Choice.valueProperty().get());
523        case DIRECT_SUM:
524          return new DirectSum(context1Choice.valueProperty().get(), context2Choice.valueProperty().get());
525        case DIRECT_PRODUCT:
526          return new DirectProduct(context1Choice.valueProperty().get(), context2Choice.valueProperty().get());
527        case BI_PRODUCT:
528          return new BiProduct(context1Choice.valueProperty().get(), context2Choice.valueProperty().get());
529        case SEMI_PRODUCT:
530          return new SemiProduct(context1Choice.valueProperty().get(), context2Choice.valueProperty().get());
531        default:
532          return null;
533        }
534      }
535    });
536  }
537
538  private final SourcePane contextContextContextContextPane() {
539    final GridPane pane = newGridPane();
540    final ChoiceBox<MatrixContext<?, ?>> context1Choice = ChoiceBoxBuilder
541        .<MatrixContext<?, ?>> create()
542        .minWidth(320)
543        .maxWidth(320)
544        .items(ConExpFX.instance.contexts)
545        .build();
546    final ChoiceBox<MatrixContext<?, ?>> context2Choice = ChoiceBoxBuilder
547        .<MatrixContext<?, ?>> create()
548        .minWidth(320)
549        .maxWidth(320)
550        .items(ConExpFX.instance.contexts)
551        .build();
552    final ChoiceBox<MatrixContext<?, ?>> context3Choice = ChoiceBoxBuilder
553        .<MatrixContext<?, ?>> create()
554        .minWidth(320)
555        .maxWidth(320)
556        .items(ConExpFX.instance.contexts)
557        .build();
558    final ChoiceBox<MatrixContext<?, ?>> context4Choice = ChoiceBoxBuilder
559        .<MatrixContext<?, ?>> create()
560        .minWidth(320)
561        .maxWidth(320)
562        .items(ConExpFX.instance.contexts)
563        .build();
564    pane.add(LabelBuilder.create().text("First Formal Context:").build(), 0, 0);
565    pane.add(context1Choice, 1, 0);
566    pane.add(LabelBuilder.create().text("Second Formal Context:").build(), 0, 1);
567    pane.add(context2Choice, 1, 1);
568    pane.add(LabelBuilder.create().text("Third Formal Context:").build(), 0, 2);
569    pane.add(context3Choice, 1, 2);
570    pane.add(LabelBuilder.create().text("Fourth Formal Context:").build(), 0, 3);
571    pane.add(context4Choice, 1, 3);
572    return new SourcePane(Source.CONTEXT_CONTEXT_CONTEXT_CONTEXT, pane, new ObjectBinding<Request<?, ?>>() {
573
574      {
575        bind(
576            context1Choice.valueProperty(),
577            context2Choice.valueProperty(),
578            context3Choice.valueProperty(),
579            context4Choice.valueProperty());
580      }
581
582      @SuppressWarnings({ "unchecked", "rawtypes" })
583      protected final Request<?, ?> computeValue() {
584        switch (type) {
585        case QUADPOSITION:
586          return new Quadposition(
587              context1Choice.valueProperty().get(),
588              context2Choice.valueProperty().get(),
589              context3Choice.valueProperty().get(),
590              context4Choice.valueProperty().get());
591        default:
592          return null;
593        }
594      }
595    });
596  }
597
598  @SuppressWarnings({ "rawtypes", "unchecked" })
599  private final SourcePane contextContextObjectObjectPane() {
600    final GridPane pane = newGridPane();
601    final ChoiceBox<MatrixContext<?, ?>> context1Choice = ChoiceBoxBuilder
602        .<MatrixContext<?, ?>> create()
603        .minWidth(320)
604        .maxWidth(320)
605        .items(ConExpFX.instance.contexts)
606        .build();
607    final ChoiceBox<MatrixContext<?, ?>> context2Choice = ChoiceBoxBuilder
608        .<MatrixContext<?, ?>> create()
609        .minWidth(320)
610        .maxWidth(320)
611        .items(ConExpFX.instance.contexts)
612        .build();
613    final ChoiceBox objectChoice = ChoiceBoxBuilder.create().minWidth(320).maxWidth(320).build();
614    final ChoiceBox attributeChoice = ChoiceBoxBuilder.create().minWidth(320).maxWidth(320).build();
615    objectChoice.itemsProperty().bind(new ObjectBinding<ObservableList<?>>() {
616
617      {
618        bind(context1Choice.valueProperty());
619      }
620
621      protected ObservableList<?> computeValue() {
622        if (context1Choice.valueProperty().get() == null)
623          return FXCollections.observableList(Collections.EMPTY_LIST);
624        return FXCollections.observableList(context1Choice.valueProperty().get().rowHeads());
625      }
626    });
627    attributeChoice.itemsProperty().bind(new ObjectBinding<ObservableList<?>>() {
628
629      {
630        bind(context1Choice.valueProperty());
631      }
632
633      protected ObservableList<?> computeValue() {
634        if (context1Choice.valueProperty().get() == null)
635          return FXCollections.observableList(Collections.EMPTY_LIST);
636        return FXCollections.observableList(context1Choice.valueProperty().get().colHeads());
637      }
638    });
639    pane.add(LabelBuilder.create().text("First Formal Context:").build(), 0, 0);
640    pane.add(context1Choice, 1, 0);
641    pane.add(LabelBuilder.create().text("Second Formal Context:").build(), 0, 1);
642    pane.add(context2Choice, 1, 1);
643    pane.add(LabelBuilder.create().text("First Object:").build(), 0, 2);
644    pane.add(objectChoice, 1, 2);
645    pane.add(LabelBuilder.create().text("Second Attribute:").build(), 0, 3);
646    pane.add(attributeChoice, 1, 3);
647    return new SourcePane(Source.CONTEXT_CONTEXT_OBJECT_OBJECT, pane, new ObjectBinding<Request<?, ?>>() {
648
649      {
650        bind(
651            context1Choice.valueProperty(),
652            context2Choice.valueProperty(),
653            objectChoice.valueProperty(),
654            attributeChoice.valueProperty());
655      }
656
657      protected final Request<?, ?> computeValue() {
658        switch (type) {
659        case SUBSTITUTION_SUM:
660          return new SubstitutionSum(
661              context1Choice.valueProperty().get(),
662              context2Choice.valueProperty().get(),
663              objectChoice.valueProperty().get(),
664              attributeChoice.valueProperty().get());
665        default:
666          return null;
667        }
668      }
669    });
670  }
671
672  private final SourcePane contextSetSetPane() {
673    final GridPane pane = newGridPane();
674    final ChoiceBox<MatrixContext<?, ?>> contextChoice = ChoiceBoxBuilder
675        .<MatrixContext<?, ?>> create()
676        .minWidth(320)
677        .maxWidth(320)
678        .items(ConExpFX.instance.contexts)
679        .build();
680    pane.add(LabelBuilder.create().text("Formal Context:").build(), 0, 0);
681    pane.add(contextChoice, 1, 0);
682    // TODO
683    return new SourcePane(Source.CONTEXT_SET_SET, pane, new ObjectBinding<Request<?, ?>>() {
684
685      {
686        bind(contextChoice.valueProperty());
687      }
688
689      @SuppressWarnings({ "unchecked", "rawtypes" })
690      protected final Request<?, ?> computeValue() {
691        switch (type) {
692//            case APPROXIMATION_CONTEXT:
693//              return new Approximation(contextChoice.valueProperty().get(), null, null);
694        default:
695          return null;
696        }
697      }
698    });
699  }
700
701  private final SourcePane filePane() {
702    final GridPane pane = newGridPane();
703    final FileChooseBox fileChooseBox;
704    switch (type) {
705    case IMPORT_CFX_CONTEXT:
706      fileChooseBox = new FileChooseBox("Import Concept Explorer FX File", FileFormat.CFX);
707      break;
708    case IMPORT_CXT_CONTEXT:
709      fileChooseBox = new FileChooseBox("Import Burmeister File", FileFormat.CXT);
710      break;
711    case IMPORT_CEX_CONTEXT:
712      fileChooseBox = new FileChooseBox("Import Concept Explorer File", FileFormat.CEX);
713      break;
714    case IMPORT_CSV_CONTEXT:
715      fileChooseBox = new FileChooseBox("Import Binary CSV File", FileFormat.CSVB);
716      break;
717    default:
718      fileChooseBox = null;
719      break;
720    }
721    pane.add(LabelBuilder.create().text("Concept Explorer File: ").build(), 0, 0);
722    pane.add(fileChooseBox, 1, 0);
723    return new SourcePane(Source.FILE, pane, new ObjectBinding<Request<?, ?>>() {
724
725      {
726        bind(fileChooseBox.fileProperty);
727      }
728
729      protected final Request<?, ?> computeValue() {
730        if (fileChooseBox.fileProperty.get() == null)
731          return null;
732        switch (type) {
733        case IMPORT_CFX_CONTEXT:
734          return new ImportCFX(fileChooseBox.fileProperty.get().first());
735        case IMPORT_CXT_CONTEXT:
736          return new ImportCXT(fileChooseBox.fileProperty.get().first());
737        case IMPORT_CEX_CONTEXT:
738          return new ImportCEX(fileChooseBox.fileProperty.get().first());
739        case IMPORT_CSV_CONTEXT:
740          return new ImportCSVB(fileChooseBox.fileProperty.get().first());
741        default:
742          return null;
743        }
744      }
745    });
746  }
747
748  private final SourcePane queryURLPane() {
749    final GridPane pane = newGridPane();
750    pane.getColumnConstraints().add(0, new ColumnConstraints(80));
751    final ChoiceBox<String> sampleURLChoice = ChoiceBoxBuilder
752        .<String> create()
753        .items(FXCollections.observableArrayList("FactForge.net", "LinkedLifeData.com"))
754        .build();
755    final TextField urlField = TextFieldBuilder
756        .create()
757        .text(
758            "http://factforge.net/sparql.xml?query=<QUERY>&_implicit=false&implicit=true&_equivalent=false&_form=%2Fsparql")
759        .build();
760    final TextArea queryArea = TextAreaBuilder.create().minHeight(230).build();
761    sampleURLChoice.valueProperty().addListener(new ChangeListener<String>() {
762
763      public final void
764          changed(final ObservableValue<? extends String> observable, final String oldValue, final String newValue) {
765        switch (newValue) {
766        case "FactForge.net":
767          urlField.setText(
768              "http://factforge.net/sparql.xml?query=<QUERY>&_implicit=false&implicit=true&_equivalent=false&_form=%2Fsparql");
769          break;
770        case "LinkedLifeData.com":
771          urlField.setText(
772              "http://linkedlifedata.com/sparql.xml?query=<QUERY>&_implicit=false&implicit=true&_form=%2Fsparql");
773          break;
774        }
775      }
776    });
777    pane.add(
778        LabelBuilder
779            .create()
780            .wrapText(true)
781            .text(
782                "Enter an URL that computes a SPARQL XML Result. Specify the position of the SPARQL Query with the variable <QUERY>. Within the Query, use the variables ?object and ?attribute to indicate the elements of the constructed formal context. Furthermore use numbered variables, e.g. ?object1, ?object2, ..., if tuples should be created.")
783            .build(),
784        1,
785        0);
786    pane.add(sampleURLChoice, 1, 1);
787    pane.add(LabelBuilder.create().text("URL: ").build(), 0, 2);
788    pane.add(urlField, 1, 2);
789    pane.add(LabelBuilder.create().text("SPARQL Query: ").build(), 0, 3);
790    pane.add(queryArea, 1, 3);
791    return new SourcePane(Source.SPARQL_AND_XMLURL, pane, new ObjectBinding<Request<?, ?>>() {
792
793      {
794        bind(urlField.textProperty(), queryArea.textProperty());
795      }
796
797      protected final Request<?, ?> computeValue() {
798        return new ImportSPARQLFromEndpoint(urlField.textProperty().get(), queryArea.textProperty().get());
799      }
800    });
801  }
802
803  private final SourcePane queryURLPane2() {
804    final GridPane pane = newGridPane();
805    pane.getColumnConstraints().add(0, new ColumnConstraints(80));
806    final TextField urlField = TextFieldBuilder.create().build();
807    final TextArea queryArea = TextAreaBuilder.create().minHeight(230).build();
808    pane.add(
809        LabelBuilder
810            .create()
811            .wrapText(true)
812            .text(
813                "Enter an URL of an ontology on the web. Within the Query, use the variables ?object and ?attribute to indicate the elements of the constructed formal context. Furthermore use numbered variables, e.g. ?object1, ?object2, ..., if tuples should be created.")
814            .build(),
815        1,
816        0);
817    pane.add(LabelBuilder.create().text("URL: ").build(), 0, 1);
818    pane.add(urlField, 1, 1);
819    pane.add(LabelBuilder.create().text("SPARQL Query: ").build(), 0, 2);
820    pane.add(queryArea, 1, 2);
821    return new SourcePane(Source.SPARQL_AND_ONTOLOGYURL, pane, new ObjectBinding<Request<?, ?>>() {
822
823      {
824        bind(urlField.textProperty(), queryArea.textProperty());
825      }
826
827      protected final Request<?, ?> computeValue() {
828        return new ImportSPARQLFromURL(urlField.textProperty().get(), queryArea.textProperty().get());
829      }
830    });
831  }
832
833  private final SourcePane queryFilePane() {
834    final GridPane pane = newGridPane();
835    pane.getColumnConstraints().add(0, new ColumnConstraints(80));
836    final FileChooseBox fileChooseBox = new FileChooseBox("Select Ontology File", FileFormat.ANY);
837    final TextArea queryArea = TextAreaBuilder.create().minHeight(230).build();
838    pane.add(
839        LabelBuilder
840            .create()
841            .wrapText(true)
842            .text(
843                "Choose a local ontology file. Within the Query, use the variables ?object and ?attribute to indicate the elements of the constructed formal context. Furthermore use numbered variables, e.g. ?object1, ?object2, ..., if tuples should be created.")
844            .build(),
845        1,
846        0);
847    pane.add(LabelBuilder.create().text("Ontology File: ").build(), 0, 1);
848    pane.add(fileChooseBox, 1, 1);
849    pane.add(LabelBuilder.create().text("SPARQL Query: ").build(), 0, 2);
850    pane.add(queryArea, 1, 2);
851    return new SourcePane(Source.SPARQL_AND_ONTOLOGYFILE, pane, new ObjectBinding<Request<?, ?>>() {
852
853      {
854        bind(fileChooseBox.fileProperty, queryArea.textProperty());
855      }
856
857      protected final Request<?, ?> computeValue() {
858        if (fileChooseBox.fileProperty.get() == null)
859          return null;
860        return new ImportSPARQLFromFile(fileChooseBox.fileProperty.get().first(), queryArea.textProperty().get());
861      }
862    });
863  }
864
865  private final SourcePane queryRepositoryPane() {
866    final GridPane pane = newGridPane();
867    pane.getColumnConstraints().add(0, new ColumnConstraints(105));
868    final TextField urlField = TextFieldBuilder.create().build();
869    final TextField repositoryField = TextFieldBuilder.create().build();
870    final TextArea queryArea = TextAreaBuilder.create().minHeight(230).build();
871    pane.add(
872        LabelBuilder
873            .create()
874            .wrapText(true)
875            .text(
876                "Enter an URL of a Sesame Server and a name of a Repository. Within the Query, use the variables ?object and ?attribute to indicate the elements of the constructed formal context. Furthermore use numbered variables, e.g. ?object1, ?object2, ..., if tuples should be created.")
877            .build(),
878        1,
879        0);
880    pane.add(LabelBuilder.create().text("Sesame Server URL: ").build(), 0, 1);
881    pane.add(urlField, 1, 1);
882    pane.add(LabelBuilder.create().text("Repository Name: ").build(), 0, 2);
883    pane.add(repositoryField, 1, 2);
884    pane.add(LabelBuilder.create().text("SPARQL Query: ").build(), 0, 3);
885    pane.add(queryArea, 1, 3);
886    return new SourcePane(Source.SPARQL_AND_ONTOLOGYREPOSITORY, pane, new ObjectBinding<Request<?, ?>>() {
887
888      {
889        bind(urlField.textProperty(), repositoryField.textProperty(), queryArea.textProperty());
890      }
891
892      protected final Request<?, ?> computeValue() {
893        return new ImportSPARQLFromRepository(
894            new HTTPRepository(urlField.textProperty().get(), repositoryField.textProperty().get()),
895            queryArea.textProperty().get());
896      }
897    });
898  }
899
900  protected final void onNext() {
901    ConExpFX.instance.treeView.addDataset(new FCADataset(null, resultProperty.get()));
902  }
903}