1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package cz.zcu.mre.sparkle.gui.query.modifiers;
21
22 import cz.zcu.mre.sparkle.gui.query.helpers.PartialQueryGenerator;
23 import cz.zcu.mre.sparkle.gui.tools.Components;
24 import cz.zcu.mre.sparkle.gui.tools.ReferenceKeeper;
25 import cz.zcu.mre.sparkle.tools.Changeable;
26 import cz.zcu.mre.sparkle.tools.Saveable;
27 import cz.zcu.mre.sparkle.tools.SparqlParser;
28 import javafx.beans.InvalidationListener;
29 import javafx.fxml.FXML;
30 import javafx.scene.control.CheckBox;
31 import javafx.scene.control.TextField;
32 import javafx.scene.layout.FlowPane;
33 import org.w3c.dom.Element;
34 import java.util.HashSet;
35 import java.util.Set;
36 import static cz.zcu.mre.sparkle.tools.sparqlParser.SparqlParserUtils.LIMIT_VALUE;
37 import static cz.zcu.mre.sparkle.tools.sparqlParser.SparqlParserUtils.OFFSET_VALUE;
38
39
40
41
42
43
44
45 public final class LimitOffsetClausePane
46 extends FlowPane
47 implements PartialQueryGenerator, Saveable, Changeable {
48
49 private static final String XML_OFFSET = "offset";
50 private static final String XML_LIMIT = "limit";
51 private static final String XML_ELEMENT_NAME = "LimitOffset";
52 @FXML
53 private CheckBox limitCheckBox, offsetCheckBox;
54 @FXML
55 private TextField limitTextField, offsetTextField;
56
57 private final ReferenceKeeper keeper = new ReferenceKeeper();
58 private final Set<InvalidationListener> observers = new HashSet<>();
59
60 public LimitOffsetClausePane() {
61 Components.load(this);
62
63 limitTextField.disableProperty().bind(limitCheckBox.selectedProperty().not());
64 offsetTextField.disableProperty().bind(offsetCheckBox.selectedProperty().not());
65
66 limitTextField.setText("0");
67 offsetTextField.setText("0");
68
69 createFieldTextListeners(limitTextField);
70 createFieldTextListeners(offsetTextField);
71
72
73 watch(limitCheckBox.selectedProperty());
74 watch(limitTextField.textProperty());
75 watch(offsetCheckBox.selectedProperty());
76 watch(offsetTextField.textProperty());
77 }
78
79 private static boolean isValidValue(final String value) {
80 try {
81 final int intValue = Integer.parseInt(value);
82 return intValue >= 0;
83 } catch (final NumberFormatException e) {
84 return false;
85 }
86 }
87
88 private void createFieldTextListeners(final TextField field) {
89 field.focusedProperty().addListener(keeper.toWeak((observable, oldValue, newValue)
90 -> {
91 if (newValue) {
92 return;
93 }
94 if (!isValidValue(field.getText())) {
95 field.setText("0");
96 }
97 }));
98
99 field.textProperty().addListener(keeper.toWeak((observable, oldValue, newValue)
100 -> {
101 if (!oldValue.isEmpty()) {
102 if (!isValidValue(oldValue)) {
103 oldValue = "0";
104 }
105 }
106 if (newValue.isEmpty()) {
107 return;
108 }
109 if (!isValidValue(newValue)) {
110 field.setText(oldValue);
111 }
112 }));
113 }
114
115 @Override
116 public final String getQueryPart() {
117 return (limitCheckBox.isSelected() ? "LIMIT "
118 + limitTextField.getText() + " "
119 : "")
120 + (offsetCheckBox.isSelected() ? "OFFSET "
121 + offsetTextField.getText() + " "
122 : "");
123 }
124
125 @Override
126 public final void save(final Element e) {
127 if (limitCheckBox.isSelected()) {
128 e.setAttribute(XML_LIMIT, limitTextField.getText().trim());
129 }
130 if (offsetCheckBox.isSelected()) {
131 e.setAttribute(XML_OFFSET, offsetTextField.getText().trim());
132 }
133 }
134
135 @Override
136 public final void load(final Object e) throws LoadException {
137 String limitString = null;
138 String offsetString = null;
139 if (e instanceof Element) {
140 Element eNode = (Element) e;
141 if (eNode.hasAttribute(XML_LIMIT)) {
142 limitString = eNode.getAttribute(XML_LIMIT);
143 if (!isValidValue(limitString)) {
144 throw new LoadException(eNode, XML_LIMIT);
145 }
146 }
147 if (eNode.hasAttribute(XML_OFFSET)) {
148 offsetString = eNode.getAttribute(XML_OFFSET);
149 if (!isValidValue(offsetString)) {
150 throw new LoadException(eNode, XML_OFFSET);
151 }
152 }
153 if (limitString == null) {
154 limitCheckBox.setSelected(false);
155 } else {
156 limitCheckBox.setSelected(true);
157 limitTextField.setText(limitString);
158 }
159 if (offsetString == null) {
160 offsetCheckBox.setSelected(false);
161 } else {
162 offsetCheckBox.setSelected(true);
163 offsetTextField.setText(offsetString);
164 }
165 } else if (e instanceof SparqlParser.LimitClauseContext) {
166 SparqlParser.LimitClauseContext eNode = (SparqlParser.LimitClauseContext) e;
167 String limitValue = eNode.INTEGER().getText();
168 if (limitValue != null) {
169 limitCheckBox.setSelected(true);
170 limitTextField.setText(limitValue);
171 } else {
172 throw new LoadException(eNode, LIMIT_VALUE);
173 }
174 } else if (e instanceof SparqlParser.OffsetClauseContext) {
175 SparqlParser.OffsetClauseContext eNode = (SparqlParser.OffsetClauseContext) e;
176 String offsetValue = eNode.INTEGER().getText();
177 if (offsetValue != null) {
178 offsetCheckBox.setSelected(true);
179 offsetTextField.setText(offsetValue);
180 } else {
181 throw new LoadException(eNode, OFFSET_VALUE);
182 }
183 }
184 }
185
186 @Override
187 public final String getXMLElementName() {
188 return XML_ELEMENT_NAME;
189 }
190
191 @Override
192 public final Set<InvalidationListener> getObservers() {
193 return observers;
194 }
195 }