View Javadoc
1   /*
2    * Copyright 2013-2023 Medical Information Systems Research Group (https://medical.zcu.cz),
3    * Department of Computer Science and Engineering, University of West Bohemia.
4    * Address: Univerzitni 8, 306 14 Plzen, Czech Republic.
5    *
6    * This file is part of Sparkle project.
7    *
8    * Sparkle is free software: you can redistribute it and/or modify
9    * it under the terms of the GNU General Public License as published by
10   * the Free Software Foundation, either version 3 of the License.
11   *
12   * Sparkle is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License
18   * along with Sparkle. If not, see <http://www.gnu.org/licenses/>.
19   */
20  package cz.zcu.mre.sparkle.gui.query.autoComplete;
21  
22  import cz.zcu.mre.sparkle.data.PrefixesStorage;
23  import cz.zcu.mre.sparkle.data.resourceStorage.ResourcesStorage;
24  import cz.zcu.mre.sparkle.gui.query.QueryFormPane;
25  import cz.zcu.mre.sparkle.gui.query.other.TypedTextField;
26  import cz.zcu.mre.sparkle.gui.query.triplePane.TriplePane;
27  import cz.zcu.mre.sparkle.tools.Definitions;
28  import cz.zcu.mre.sparkle.tools.Utils;
29  import javafx.collections.FXCollections;
30  import javafx.collections.ObservableList;
31  import javafx.scene.control.TextField;
32  import org.slf4j.Logger;
33  import org.slf4j.LoggerFactory;
34  
35  /**
36   * Handler pro seznam návrhů využitelný s {@link TypedTextField} nastaveným pro
37   * zápis zkráceného IRI.
38   *
39   * @author Jan Smucr
40   * @author Klara Hlavacova
41   * @author Petr Vcelak (vcelak@kiv.zcu.cz)
42   */
43  public final class PrefixedNamesAutoCompleteListHandler
44          implements AutoCompleteListHandler {
45  
46      private static final Logger LOG = LoggerFactory.getLogger(PrefixedNamesAutoCompleteListHandler.class);
47  
48      private final ResourcesStorage resourcesStorage;
49      private final boolean propertiesOnly;
50      private final boolean includeBlankNodesPrefix;
51      private final QueryFormPane<?> parentQueryFormPane;
52      private final String RDFS = "rdfs"; //$NON-NLS-1$
53      private final TriplePane parentTriplePane;
54  
55      public PrefixedNamesAutoCompleteListHandler(final QueryFormPane<?> parentQueryFormPane,
56              final boolean propertiesOnly,
57              final boolean includeBlankNodesPrefix, final TriplePane parentTriplePane) {
58  
59          this.resourcesStorage = parentQueryFormPane.getQueryResourcesStorage();
60          this.propertiesOnly = propertiesOnly;
61          this.includeBlankNodesPrefix = includeBlankNodesPrefix;
62          this.parentQueryFormPane = parentQueryFormPane;
63          this.parentTriplePane = parentTriplePane;
64      }
65  
66      public PrefixedNamesAutoCompleteListHandler(final ResourcesStorage termsStorage, final boolean propertiesOnly,
67              final boolean includeBlankNodesPrefix) {
68          this.resourcesStorage = termsStorage;
69          this.propertiesOnly = propertiesOnly;
70          this.includeBlankNodesPrefix = includeBlankNodesPrefix;
71          this.parentQueryFormPane = null;
72          this.parentTriplePane = null;
73      }
74  
75      @Override
76      public PrefixesStorage getPrefixesStorage() {
77          return this.resourcesStorage.getPrefixesStorage();
78      }
79  
80      @Override
81      public final ObservableList<Object> getAutoCompleteList(final TextField textField) {
82          final String textFieldContent = getTextFieldContent(textField);
83  
84          if ((textFieldContent == null) || (textFieldContent.isEmpty())) {
85              return getAllResources();
86          }
87  
88          // Proposal of the prefix terms before the cursor
89          final int delimiterIndex = textFieldContent.indexOf(Definitions.PREFIXED_NAME_PREFIX_DELIMITER);
90          ObservableList<Object> unfilteredList;
91  
92          if (delimiterIndex > -1) {
93              unfilteredList = getResourcesWithPrefix(textFieldContent, delimiterIndex);
94          } else {
95              unfilteredList = getPrefixes();
96          }
97          //unfilteredList.sort(Utils::compareResourceEntryByIri);
98  
99          return unfilteredList.filtered((t) -> Utils
100                 .stringStartsWithIgnoreCase(AutoCompleteWrapper.getIRI(t, getPrefixesStorage()),
101                         textFieldContent));
102     }
103 
104     /**
105      * Vrati seznam prefixu
106      *
107      * @return seznam prefixu
108      */
109     private ObservableList<Object> getPrefixes() {
110         ObservableList<Object> unfilteredList;
111         unfilteredList
112                 = FXCollections.observableArrayList(resourcesStorage.getPrefixesStorage()
113                         .getPrefixesUsed(true));
114 
115         if (includeBlankNodesPrefix) {
116             unfilteredList.add(Definitions.BLANK_NODE_PREFIX);
117 
118         }
119 
120         return unfilteredList;
121     }
122 
123     /**
124      * Vrati seznam zdroju s prefixem, jejichz jmena zacinaji danym textem
125      *
126      * @param textFieldContent obsah pole
127      * @param delimiterIndex index konce prefixu
128      *
129      * @return seznam zdroju, jejichz jmena zacinaji danym textem
130      */
131     private ObservableList<Object> getResourcesWithPrefix(String textFieldContent, int delimiterIndex) {
132         ObservableList<Object> unfilteredList;
133         final String prefix = textFieldContent.substring(0, delimiterIndex);
134 
135         unfilteredList = propertiesOnly
136                 ? resourcesStorage.getPropertiesByPrefix(prefix)
137                 : resourcesStorage.getResourcesByPrefix(prefix);
138         /*
139             // It loads RDFS:LABEL values
140             if (prefix.equals(RDFS) && this.parentQueryFormPane != null) {
141                 unfilteredList.addAll(getRDFSLabelValues(textField.getCaretPosition()));
142             }
143          */
144         return unfilteredList;
145     }
146 
147     /**
148      * Vrati seznam dostupnych zdroju
149      *
150      * @return seznam zdroju
151      */
152     private ObservableList<Object> getAllResources() {
153         final ObservableList<String> list
154                 = FXCollections.observableArrayList(resourcesStorage.getPrefixesStorage()
155                         .getPrefixesUsed(true));
156 
157         if (includeBlankNodesPrefix) {
158             list.add(Definitions.BLANK_NODE_PREFIX);
159         }
160         list.sort(String.CASE_INSENSITIVE_ORDER);
161 
162         return Utils.getObjectList(list);
163     }
164 
165     /**
166      * It obtains the prefixed name that is editing.
167      *
168      * @param textField TextField containing prefixed names.
169      *
170      * @return Just edited name.
171      */
172     private String getTextFieldContent(final TextField textField) {
173         final String originalText = textField.getText();
174         final int caretPosition = textField.getCaretPosition();
175         int leftSlash = originalText.substring(0, caretPosition).lastIndexOf(Definitions.PROPERTY_PATH_DELIMITER);
176         int rightSlash = originalText.substring(caretPosition).indexOf(Definitions.PROPERTY_PATH_DELIMITER);
177 
178         if (leftSlash > -1 && rightSlash > -1) {
179             return originalText.substring(++leftSlash, rightSlash + caretPosition);
180 
181         } else if (leftSlash > -1) {
182             return originalText.substring(++leftSlash);
183 
184         } else if (rightSlash > -1) {
185             return originalText.substring(0, rightSlash + caretPosition);
186 
187         } else {
188             return originalText;
189         }
190     }
191 
192     /*
193      * It obtains RDFS:LABEL values (including their data types).
194      *
195      * @return ObservableList of RDFS:LABEL values.
196      */
197  /*private ObservableList<String> getRDFSLabelValues(final int caretPosition) {
198         final Window window = this.parentQueryFormPane.getMainForm().getMainTabPane().getScene().getWindow();
199         final SimpleBooleanProperty cancelled = new SimpleBooleanProperty(false);
200         final ObservableList<String> results;
201         try {
202             results = ProgressDialog.performTask(window, new Task<ObservableList<String>>() {
203                 @Override
204                 protected final ObservableList<String> call() throws Exception {
205                     updateMessage(Messages.getString("SEARCHING")); //$NON-NLS-1$
206                     return resourcesStorage.getLabels(parentQueryFormPane.getDataAgent(), parentQueryFormPane.getQueryPart(), parentTriplePane.getQueryPart(), parentQueryFormPane.getMainForm().getSelectedLang(), caretPosition, cancelled);
207                 }
208 
209                 @Override
210                 protected final void cancelled() {
211                     cancelled.set(true);
212                 }
213             });
214         } catch (InterruptedException | ExecutionException e) {
215             ErrorDialog.open(window, Messages.getString("ERROR"), Messages.getString("SEARCHING_PATHS_FAILED"), e); //$NON-NLS-1$ //$NON-NLS-2$
216             LOG.log(Level.SEVERE, "Exception: ", e); //$NON-NLS-1$
217             return FXCollections.<String>emptyObservableList();
218         }
219         if (cancelled.get()) {
220             return FXCollections.<String>emptyObservableList();
221         }
222         return results;
223     }*/
224 }