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.queryTypes.describe;
21  
22  import cz.zcu.mre.sparkle.Messages;
23  import cz.zcu.mre.sparkle.gui.query.autoComplete.PrefixedNamesAutoCompleteListHandler;
24  import cz.zcu.mre.sparkle.gui.query.helpers.*;
25  import cz.zcu.mre.sparkle.gui.query.other.TypedTextField;
26  import cz.zcu.mre.sparkle.gui.tools.Components;
27  import cz.zcu.mre.sparkle.tools.Changeable;
28  import cz.zcu.mre.sparkle.tools.Saveable;
29  import cz.zcu.mre.sparkle.tools.Utils;
30  import javafx.beans.InvalidationListener;
31  import javafx.beans.property.ObjectProperty;
32  import javafx.beans.property.SimpleObjectProperty;
33  import javafx.event.EventHandler;
34  import javafx.fxml.FXML;
35  import javafx.scene.control.Button;
36  import javafx.scene.layout.HBox;
37  import org.antlr.v4.runtime.tree.ParseTree;
38  import org.w3c.dom.Element;
39  import java.util.Collections;
40  import java.util.HashSet;
41  import java.util.Set;
42  import static cz.zcu.mre.sparkle.tools.sparqlParser.SparqlParserUtils.clearNodeValue;
43  import static cz.zcu.mre.sparkle.tools.sparqlParser.SparqlParserUtils.getFieldType;
44  
45  /**
46   * Kontroler komponenty reprezentující jednu položku klauzule DESCRIBE.
47   *
48   * @author Jan Smucr
49   * @author Klara Hlavacova
50   * @author Petr Vcelak (vcelak@kiv.zcu.cz)
51   */
52  @SuppressWarnings("SimplifyStreamApiCallChains")
53  public final class DescribeClauseItem
54          extends HBox
55          implements PartialQueryGenerator, VariablesGenerator, PrefixesUser, Saveable, VariablesCollector, Changeable {
56  
57      private static final String XML_DESCRIBE_TEXT = "text"; //$NON-NLS-1$
58      private static final String XML_DESCRIBE_TYPE = "type"; //$NON-NLS-1$
59      static final String XML_ELEMENT_NAME = "Describe"; //$NON-NLS-1$
60  
61      @FXML
62      private Button removeButton;
63      @FXML
64      private HBox describeFieldContainer;
65  
66      private final Set<InvalidationListener> observers = new HashSet<>();
67      private final TypedTextField describeField;
68      private final Set<VariablesCollector> variablesCollectors = new HashSet<>();
69  
70      /**
71       * Komponenta nemůže odstranit sama sebe. Požadavek na odstranění je potřeba
72       * předat rodičovskému kontejneru.
73       */
74      private final ObjectProperty<EventHandler<ObjectRelatedActionEvent<DescribeClauseItem>>> onRemovalRequested
75              = new SimpleObjectProperty<>();
76  
77      public DescribeClauseItem(final DescribeQueryFormPane parentQueryPane, final boolean allowRemoval) {
78          Components.load(this);
79  
80          Utils.makeInvisibleUnmanaged(removeButton);
81  
82          if (!allowRemoval) {
83              removeButton.setVisible(false);
84          }
85  
86          describeField
87                  = new TypedTextField(parentQueryPane.getQueryPrefixesStorage(), true, FieldType.Variable, FieldType.IRI,
88                          FieldType.PrefixedName);
89          describeField.setAutoCompleteListHandler(FieldType.Variable,
90                  parentQueryPane.DEFAULT_VARIABLES_AUTOCOMPLETE_LIST_HANDLER);
91          describeField.setAutoCompleteListHandler(FieldType.PrefixedName, new PrefixedNamesAutoCompleteListHandler(
92                  parentQueryPane.getQueryResourcesStorage(), false, false));
93          describeField.addVariablesCollector(this);
94          describeField.setPlaceholder(Messages.getString("DESCRIBE")); //$NON-NLS-1$
95          describeFieldContainer.getChildren().add(describeField);
96  
97          // Sledování změn
98          watch(describeField);
99      }
100 
101     /**
102      * @return Zda je položka vyplněná.
103      */
104     public final boolean isEmpty() {
105         return describeField.isEmpty();
106     }
107 
108     /**
109      * Nastaví obsah položky na proměnnou s daným názvem.
110      *
111      * @param variableName Název proměnné.
112      */
113     public final void describeVariable(final String variableName) {
114         describeField.setFieldType(FieldType.Variable);
115         describeField.setText(variableName);
116     }
117 
118     @SuppressWarnings("unused")
119     @FXML
120     private void removeButtonOnAction() {
121         final EventHandler<ObjectRelatedActionEvent<DescribeClauseItem>> handler = onRemovalRequested.get();
122         if (handler != null) {
123             handler.handle(new ObjectRelatedActionEvent<>(this));
124         }
125     }
126 
127     public final ObjectProperty<EventHandler<ObjectRelatedActionEvent<DescribeClauseItem>>> onRemovalRequestedProperty() {
128         return onRemovalRequested;
129     }
130 
131     public final EventHandler<ObjectRelatedActionEvent<DescribeClauseItem>> getOnRemovalRequested() {
132         return onRemovalRequested.get();
133     }
134 
135     public final void setOnRemovalRequested(final EventHandler<ObjectRelatedActionEvent<DescribeClauseItem>> handler) {
136         onRemovalRequested.set(handler);
137     }
138 
139     @Override
140     public final String getQueryPart() {
141         return describeField.getValue() + " "; //$NON-NLS-1$
142     }
143 
144     @Override
145     public final void notifyVariableRemoved(final String variableName) {
146         variablesCollectors.stream().forEach((collector) -> collector.onVariableRemoved(variableName));
147     }
148 
149     @Override
150     public final void notifyVariableAdded(final String variableName) {
151         variablesCollectors.stream().forEach((collector) -> collector.onVariableAdded(variableName));
152     }
153 
154     @Override
155     public final void addVariablesCollector(final VariablesCollector collector) {
156         variablesCollectors.add(collector);
157     }
158 
159     @Override
160     public final void removeVariablesCollector(final VariablesCollector collector) {
161         variablesCollectors.remove(collector);
162     }
163 
164     @Override
165     public final void notifyVariableChanged(final String oldVariableName, final String newVariableName) {
166         variablesCollectors.stream().forEach((collector) -> collector.onVariableChanged(oldVariableName, newVariableName));
167     }
168 
169     @Override
170     public final Set<String> getVariables() {
171         if (describeField.getFieldType() == FieldType.Variable) {
172             return describeField.getVariables();
173         }
174 
175         return Collections.emptySet();
176     }
177 
178     @Override
179     public final Set<String> getPrefixesUsed(final boolean appendDelimiter) {
180         return describeField.getPrefixesUsed(appendDelimiter);
181     }
182 
183     @Override
184     public final void save(final Element e) {
185         e.setAttribute(XML_DESCRIBE_TYPE, describeField.getFieldType().name().toLowerCase());
186         e.setAttribute(XML_DESCRIBE_TEXT, describeField.getText().trim());
187     }
188 
189     @Override
190     public final void load(final Object e) throws LoadException {
191         FieldType fieldType = null;
192         String descFieldText = null;
193 
194         if (e instanceof Element) {
195             Element eNode = (Element) e;
196             final String fieldTypeString = eNode.getAttribute(XML_DESCRIBE_TYPE);
197             fieldType = FieldType.valueOfIgnoreCase(fieldTypeString);
198             descFieldText = eNode.getAttribute(XML_DESCRIBE_TEXT);
199 
200         } else if (e instanceof ParseTree) {
201             ParseTree eNode = (ParseTree) e;
202             fieldType = getFieldType(eNode);
203             if (fieldType != null) {
204                 descFieldText = clearNodeValue(eNode.getText(), fieldType);
205             }
206         }
207         if (descFieldText == null || descFieldText.isEmpty() || (fieldType == null)
208                 || !fieldType.oneOf(describeField.getAllowedFieldTypes())) {
209             throw new LoadException(XML_ELEMENT_NAME);
210 
211         }
212         describeField.setFieldType(fieldType);
213         describeField.setText(descFieldText);
214     }
215 
216     @Override
217     public final String getXMLElementName() {
218         return XML_ELEMENT_NAME;
219     }
220 
221     @Override
222     public final void requestFocus() {
223         describeField.requestFocus();
224     }
225 
226     @Override
227     public final void onVariableAdded(final String variableName) {
228         notifyVariableAdded(variableName);
229     }
230 
231     @Override
232     public final void onVariableRemoved(final String variableName) {
233         notifyVariableRemoved(variableName);
234     }
235 
236     @Override
237     public final void onVariableChanged(final String oldVariableName, final String newVariableName) {
238         notifyVariableChanged(oldVariableName, newVariableName);
239     }
240 
241     @Override
242     public final Set<InvalidationListener> getObservers() {
243         return observers;
244     }
245 }