Skip to content

Commit f190cbc

Browse files
authored
Add support for validating JQ (#1170)
* #1168: Add camel-jq language validation * #1168: Add camel-jq language validation
1 parent 13237bc commit f190cbc

8 files changed

Lines changed: 179 additions & 33 deletions

File tree

src/main/java/com/github/cameltooling/idea/annotator/CamelJSonPathAnnotator.java renamed to src/main/java/com/github/cameltooling/idea/annotator/CamelLanguageAnnotator.java

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,49 +33,51 @@
3333
import org.jetbrains.annotations.NotNull;
3434

3535
/**
36-
* Validate JSonPath expression and annotated the specific jsonpath expression to highlight the error in the editor
36+
* Validate language expression such as JSonPath/JQ to highlight the error in the editor
3737
*/
38-
public class CamelJSonPathAnnotator extends AbstractCamelAnnotator {
38+
public class CamelLanguageAnnotator extends AbstractCamelAnnotator {
3939

4040
private static final Logger LOG = Logger.getInstance(CamelEndpointAnnotator.class);
4141

4242
@Override
4343
boolean isEnabled() {
44-
return CamelPreferenceService.getService().isRealTimeJSonPathValidation();
44+
return CamelPreferenceService.getService().isRealTimeJSonPathValidation() || CamelPreferenceService.getService().isRealTimeJQValidation();
4545
}
4646

4747
/**
48-
* Validate jsonpath expression. eg jsonpath("$.store.book[?(@.price < 10)]")
49-
* if the expression is not valid a error annotation is created and highlight the invalid value.
48+
* Validate language expression, such as jsonpath("$.store.book[?(@.price < 10)]")
49+
* if the expression is not valid an error annotation is created and highlight the invalid value.
5050
*/
5151
void validateText(@NotNull PsiElement element, @NotNull AnnotationHolder holder, @NotNull String text) {
52-
5352
final CamelIdeaUtils camelIdeaUtils = CamelIdeaUtils.getService();
54-
// only validate if the element is jsonpath element
55-
if (camelIdeaUtils.isCamelExpression(element, "jsonpath")) {
53+
54+
boolean json = CamelPreferenceService.getService().isRealTimeJSonPathValidation() && camelIdeaUtils.isCamelExpression(element, "jsonpath");
55+
boolean jq = CamelPreferenceService.getService().isRealTimeJQValidation() && camelIdeaUtils.isCamelExpression(element, "jq");
56+
if (json || jq) {
5657
Project project = element.getProject();
5758
CamelCatalog catalogService = project.getService(CamelCatalogService.class).get();
5859
CamelService camelService = project.getService(CamelService.class);
5960

60-
// must have camel-json library
61-
boolean jsonLib = camelService.containsLibrary("camel-jsonpath", false);
62-
if (!jsonLib) {
63-
camelService.showMissingJSonPathJarNotification();
61+
// must have the supporting library
62+
String lib = json ? "camel-jsonpath" : "camel-jq";
63+
if (!camelService.containsLibrary(lib, false)) {
64+
camelService.showMissingLanguageJarNotification(lib);
6465
return;
6566
}
6667

68+
String lan = json ? "jsonpath" : "jq";
6769
try {
6870
// need to use the classloader that can load classes from the project
6971
ClassLoader loader = camelService.getProjectClassloader();
7072
if (loader != null) {
7173
LanguageValidationResult result;
72-
boolean predicate = camelIdeaUtils.isCamelExpressionUsedAsPredicate(element, "jsonpath");
74+
boolean predicate = camelIdeaUtils.isCamelExpressionUsedAsPredicate(element, lan);
7375
if (predicate) {
74-
LOG.debug("Inspecting jsonpath predicate: " + text);
75-
result = catalogService.validateLanguagePredicate(loader, "jsonpath", text);
76+
LOG.debug("Inspecting " + lan + " predicate: " + text);
77+
result = catalogService.validateLanguagePredicate(loader, lan, text);
7678
} else {
77-
LOG.debug("Inspecting jsonpath expression: " + text);
78-
result = catalogService.validateLanguageExpression(loader, "jsonpath", text);
79+
LOG.debug("Inspecting " + lan + " expression: " + text);
80+
result = catalogService.validateLanguageExpression(loader, lan, text);
7981
}
8082
if (!result.isSuccess()) {
8183
String error = result.getShortError();
@@ -95,7 +97,7 @@ void validateText(@NotNull PsiElement element, @NotNull AnnotationHolder holder,
9597
}
9698
}
9799
} catch (Throwable e) {
98-
LOG.warn("Error inspecting Camel jsonpath: " + text, e);
100+
LOG.warn("Error inspecting Camel " + lan + ": " + text, e);
99101
}
100102
}
101103
}

src/main/java/com/github/cameltooling/idea/preference/annotator/CamelAnnotatorPage.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public class CamelAnnotatorPage implements SearchableConfigurable, Configurable.
3737
private JBCheckBox highlightCustomOptionsCheckBox;
3838
private JBCheckBox realTimeSimpleValidationCatalogCheckBox;
3939
private JBCheckBox realTimeJSonPathValidationCatalogCheckBox;
40+
private JBCheckBox realTimeJQValidationCatalogCheckBox;
4041
private JBCheckBox realTimeIdReferenceTypeValidationCheckBox;
4142
private JBCheckBox realTimeBeanMethodValidationCheckBox;
4243
private JPanel result;
@@ -52,6 +53,7 @@ public JComponent createComponent() {
5253
highlightCustomOptionsCheckBox = new JBCheckBox("Highlight custom endpoint options as warnings in editor");
5354
realTimeSimpleValidationCatalogCheckBox = new JBCheckBox("Real time validation of Camel simple language in editor");
5455
realTimeJSonPathValidationCatalogCheckBox = new JBCheckBox("Real time validation of Camel JSonPath language in editor");
56+
realTimeJQValidationCatalogCheckBox = new JBCheckBox("Real time validation of Camel JQ language in editor");
5557
realTimeIdReferenceTypeValidationCheckBox = new JBCheckBox("Real time type validation when referencing beans");
5658
realTimeBeanMethodValidationCheckBox = new JBCheckBox("Real time validation of call bean method in editor");
5759

@@ -63,6 +65,7 @@ public JComponent createComponent() {
6365
jPanel.add(highlightCustomOptionsCheckBox, "span 2");
6466
jPanel.add(realTimeSimpleValidationCatalogCheckBox, "span 2");
6567
jPanel.add(realTimeJSonPathValidationCatalogCheckBox, "span 2");
68+
jPanel.add(realTimeJQValidationCatalogCheckBox, "span 2");
6669
jPanel.add(realTimeIdReferenceTypeValidationCheckBox, "span 2");
6770
jPanel.add(realTimeBeanMethodValidationCheckBox, "span 2");
6871

@@ -79,6 +82,7 @@ public void apply() {
7982
camelPreferenceService.setHighlightCustomOptions(highlightCustomOptionsCheckBox.isSelected());
8083
camelPreferenceService.setRealTimeSimpleValidation(realTimeSimpleValidationCatalogCheckBox.isSelected());
8184
camelPreferenceService.setRealTimeJSonPathValidation(realTimeJSonPathValidationCatalogCheckBox.isSelected());
85+
camelPreferenceService.setRealTimeJQValidation(realTimeJQValidationCatalogCheckBox.isSelected());
8286
camelPreferenceService.setRealTimeIdReferenceTypeValidation(realTimeIdReferenceTypeValidationCheckBox.isSelected());
8387
camelPreferenceService.setRealTimeBeanMethodValidationCheckBox(realTimeBeanMethodValidationCheckBox.isSelected());
8488
}
@@ -91,6 +95,7 @@ public boolean isModified() {
9195
|| camelPreferenceService.isHighlightCustomOptions() != highlightCustomOptionsCheckBox.isSelected()
9296
|| camelPreferenceService.isRealTimeSimpleValidation() != realTimeSimpleValidationCatalogCheckBox.isSelected()
9397
|| camelPreferenceService.isRealTimeJSonPathValidation() != realTimeJSonPathValidationCatalogCheckBox.isSelected()
98+
|| camelPreferenceService.isRealTimeJQValidation() != realTimeJQValidationCatalogCheckBox.isSelected()
9499
|| camelPreferenceService.isRealTimeIdReferenceTypeValidation() != realTimeIdReferenceTypeValidationCheckBox.isSelected()
95100
|| camelPreferenceService.isRealTimeBeanMethodValidationCheckBox() != realTimeBeanMethodValidationCheckBox.isSelected();
96101
return b1;
@@ -103,6 +108,7 @@ public void reset() {
103108
highlightCustomOptionsCheckBox.setSelected(camelPreferenceService.isHighlightCustomOptions());
104109
realTimeSimpleValidationCatalogCheckBox.setSelected(camelPreferenceService.isRealTimeSimpleValidation());
105110
realTimeJSonPathValidationCatalogCheckBox.setSelected(camelPreferenceService.isRealTimeJSonPathValidation());
111+
realTimeJQValidationCatalogCheckBox.setSelected(camelPreferenceService.isRealTimeJQValidation());
106112
realTimeIdReferenceTypeValidationCheckBox.setSelected(camelPreferenceService.isRealTimeIdReferenceTypeValidation());
107113
realTimeBeanMethodValidationCheckBox.setSelected(camelPreferenceService.isRealTimeBeanMethodValidationCheckBox());
108114
}
@@ -113,6 +119,7 @@ public void disposeUIResources() {
113119
highlightCustomOptionsCheckBox = null;
114120
realTimeSimpleValidationCatalogCheckBox = null;
115121
realTimeJSonPathValidationCatalogCheckBox = null;
122+
realTimeJQValidationCatalogCheckBox = null;
116123
realTimeIdReferenceTypeValidationCheckBox = null;
117124
realTimeBeanMethodValidationCheckBox = null;
118125

@@ -150,6 +157,10 @@ JBCheckBox getRealTimeJSonPathValidationCatalogCheckBox() {
150157
return realTimeJSonPathValidationCatalogCheckBox;
151158
}
152159

160+
public JBCheckBox getRealTimeJQValidationCatalogCheckBox() {
161+
return realTimeJQValidationCatalogCheckBox;
162+
}
163+
153164
JBCheckBox getRealTimeIdReferenceTypeValidationCheckBox() {
154165
return realTimeIdReferenceTypeValidationCheckBox;
155166
}

src/main/java/com/github/cameltooling/idea/service/CamelPreferenceService.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public class CamelPreferenceService implements PersistentStateComponent<CamelPre
6666
private boolean realTimeEndpointValidation = true;
6767
private boolean realTimeSimpleValidation = true;
6868
private boolean realTimeJSonPathValidation = true;
69+
private boolean realTimeJQValidation = true;
6970
private boolean realTimeIdReferenceTypeValidation = true;
7071
private boolean realTimeBeanMethodValidationCheckBox = true;
7172
private boolean highlightCustomOptions = true;
@@ -124,6 +125,14 @@ public void setRealTimeJSonPathValidation(boolean realTimeJSonPathValidation) {
124125
this.realTimeJSonPathValidation = realTimeJSonPathValidation;
125126
}
126127

128+
public boolean isRealTimeJQValidation() {
129+
return realTimeJQValidation;
130+
}
131+
132+
public void setRealTimeJQValidation(boolean realTimeJQValidation) {
133+
this.realTimeJQValidation = realTimeJQValidation;
134+
}
135+
127136
public boolean isRealTimeIdReferenceTypeValidation() {
128137
return realTimeIdReferenceTypeValidation;
129138
}
@@ -222,6 +231,7 @@ public boolean equals(Object o) {
222231
return realTimeEndpointValidation == that.realTimeEndpointValidation
223232
&& realTimeSimpleValidation == that.realTimeSimpleValidation
224233
&& realTimeJSonPathValidation == that.realTimeJSonPathValidation
234+
&& realTimeJQValidation == that.realTimeJQValidation
225235
&& realTimeIdReferenceTypeValidation == that.realTimeIdReferenceTypeValidation
226236
&& downloadCatalog == that.downloadCatalog
227237
&& scanThirdPartyComponents == that.scanThirdPartyComponents
@@ -233,7 +243,7 @@ public boolean equals(Object o) {
233243

234244
@Override
235245
public int hashCode() {
236-
return Objects.hash(realTimeEndpointValidation, realTimeSimpleValidation, realTimeJSonPathValidation,
246+
return Objects.hash(realTimeEndpointValidation, realTimeSimpleValidation, realTimeJSonPathValidation, realTimeJQValidation,
237247
realTimeIdReferenceTypeValidation, downloadCatalog, scanThirdPartyComponents,
238248
ignorePropertyList, excludePropertyFiles, xmlPropertyPlaceholders);
239249
}

src/main/java/com/github/cameltooling/idea/service/CamelService.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public class CamelService implements Disposable {
8787
private volatile boolean camelPresent;
8888
private volatile Notification camelVersionNotification;
8989
private volatile Notification camelMissingJSonSchemaNotification;
90-
private volatile Notification camelMissingJSonPathJarNotification;
90+
private volatile Notification camelMissingLanguageJarNotification;
9191

9292
/**
9393
* The project in which the service is registered.
@@ -118,9 +118,9 @@ public synchronized void dispose() {
118118
camelMissingJSonSchemaNotification.expire();
119119
camelMissingJSonSchemaNotification = null;
120120
}
121-
if (camelMissingJSonPathJarNotification != null) {
122-
camelMissingJSonPathJarNotification.expire();
123-
camelMissingJSonPathJarNotification = null;
121+
if (camelMissingLanguageJarNotification != null) {
122+
camelMissingLanguageJarNotification.expire();
123+
camelMissingLanguageJarNotification = null;
124124
}
125125
if (camelCoreClassloader != null) {
126126
try {
@@ -345,12 +345,12 @@ synchronized ClassLoader getProjectCompleteClassloader() {
345345
return projectCompleteClassloader;
346346
}
347347

348-
public void showMissingJSonPathJarNotification() {
349-
if (camelMissingJSonPathJarNotification == null) {
348+
public void showMissingLanguageJarNotification(String lib) {
349+
if (camelMissingLanguageJarNotification == null) {
350350
Icon icon = CamelPreferenceService.getService().getCamelIcon();
351-
camelMissingJSonPathJarNotification = CAMEL_NOTIFICATION_GROUP.createNotification("camel-jsonpath is not on classpath. Cannot perform real time JSonPath validation.",
351+
camelMissingLanguageJarNotification = CAMEL_NOTIFICATION_GROUP.createNotification(lib + " is not on classpath. Cannot perform real time validation.",
352352
NotificationType.WARNING).setImportant(true).setIcon(icon);
353-
camelMissingJSonPathJarNotification.notify(project);
353+
camelMissingLanguageJarNotification.notify(project);
354354
}
355355
}
356356

src/main/java/com/github/cameltooling/idea/service/extension/camel/JavaCamelIdeaUtils.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,14 @@ public boolean isCamelExpression(PsiElement element, String language) {
246246
methods = new String[]{"simple", "log"};
247247
} else if ("jsonpath".equals(language)) {
248248
methods = new String[]{"jsonpath"};
249+
} else if ("jq".equals(language)) {
250+
methods = new String[]{"jq"};
251+
}
252+
if (methods != null) {
253+
return IdeaUtils.getService().isFromJavaMethodCall(element, true, methods);
254+
} else {
255+
return false;
249256
}
250-
return IdeaUtils.getService().isFromJavaMethodCall(element, true, methods);
251257
}
252258

253259
@Override

src/main/resources/META-INF/plugin.xml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,18 +126,18 @@
126126
<annotator language="JAVA" implementationClass="com.github.cameltooling.idea.annotator.CamelSimpleAnnotator"/>
127127
<annotator language="XML" implementationClass="com.github.cameltooling.idea.annotator.CamelSimpleAnnotator"/>
128128
<annotator language="yaml" implementationClass="com.github.cameltooling.idea.annotator.CamelSimpleAnnotator"/>
129-
<!-- annotator to validate jsonpath language -->
130-
<annotator language="JAVA" implementationClass="com.github.cameltooling.idea.annotator.CamelJSonPathAnnotator"/>
131-
<annotator language="XML" implementationClass="com.github.cameltooling.idea.annotator.CamelJSonPathAnnotator"/>
132-
<annotator language="yaml" implementationClass="com.github.cameltooling.idea.annotator.CamelJSonPathAnnotator"/>
129+
<!-- annotator to validate json/jq language(s) -->
130+
<annotator language="JAVA" implementationClass="com.github.cameltooling.idea.annotator.CamelLanguageAnnotator"/>
131+
<annotator language="XML" implementationClass="com.github.cameltooling.idea.annotator.CamelLanguageAnnotator"/>
132+
<annotator language="yaml" implementationClass="com.github.cameltooling.idea.annotator.CamelLanguageAnnotator"/>
133133
<!-- annotator to validate bean references by type -->
134134
<annotator language="JAVA" implementationClass="com.github.cameltooling.idea.annotator.BeanReferenceTypeAnnotator"/>
135135
<annotator language="XML" implementationClass="com.github.cameltooling.idea.annotator.BeanReferenceTypeAnnotator"/>
136136
<!-- annotator to validate bean method calls language -->
137137
<annotator language="JAVA" implementationClass="com.github.cameltooling.idea.annotator.CamelBeanMethodAnnotator"/>
138138

139139
<!-- inspection to validate endpoints -->
140-
<localInspection displayName="Camel inspection" groupName="Camel" implementationClass="com.github.cameltooling.idea.inspection.CamelInspection"/>
140+
<localInspection language="" displayName="Camel Inspection" groupName="Camel" implementationClass="com.github.cameltooling.idea.inspection.CamelInspection"/>
141141

142142
<!-- preference -->
143143
<applicationConfigurable id="camel" groupId="language" displayName="Apache Camel" instance="com.github.cameltooling.idea.preference.CamelPreferenceEntryPage"/>

0 commit comments

Comments
 (0)