Skip to content

Commit 07a7824

Browse files
committed
add references from endpoint uri parameters to their corresponding setters in camel classes (*Endpoint, *Configuration)
1 parent 313b107 commit 07a7824

File tree

5 files changed

+374
-0
lines changed

5 files changed

+374
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.github.cameltooling.idea.reference.endpoint.parameter;
18+
19+
import com.github.cameltooling.idea.reference.endpoint.CamelEndpointPsiReferenceProvider;
20+
import com.github.cameltooling.idea.service.CamelCatalogService;
21+
import com.github.cameltooling.idea.util.CamelIdeaUtils;
22+
import com.github.cameltooling.idea.util.IdeaUtils;
23+
import com.intellij.openapi.project.Project;
24+
import com.intellij.openapi.util.TextRange;
25+
import com.intellij.openapi.util.text.StringUtil;
26+
import com.intellij.patterns.ElementPattern;
27+
import com.intellij.psi.PsiElement;
28+
import com.intellij.psi.PsiReference;
29+
import com.intellij.psi.PsiReferenceContributor;
30+
import com.intellij.psi.PsiReferenceRegistrar;
31+
import com.intellij.util.ProcessingContext;
32+
import org.apache.camel.catalog.CamelCatalog;
33+
import org.jetbrains.annotations.NotNull;
34+
35+
import java.util.List;
36+
import java.util.Map;
37+
import java.util.Objects;
38+
39+
/**
40+
* Contributor for {@link EndpointParameterReference}, which is a reference from endpoint uri query parameter to its setter method in the corresponding camel class
41+
* E.g. from the 'synchronous' substring in endpoint uri "direct:abc?synchronous=true" to {@link org.apache.camel.component.direct.DirectEndpoint#setSynchronous}
42+
*/
43+
public class CamelEndpointParameterReferenceContributor extends PsiReferenceContributor {
44+
45+
@Override
46+
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
47+
List<ElementPattern<? extends PsiElement>> patterns = CamelIdeaUtils.getService().getAllowedEndpointUriLocations();
48+
if (!patterns.isEmpty()) {
49+
CamelEndpointPsiReferenceProvider provider = createProvider();
50+
patterns.forEach(pattern -> {
51+
registrar.registerReferenceProvider(pattern, provider);
52+
});
53+
}
54+
}
55+
56+
@NotNull
57+
private CamelEndpointPsiReferenceProvider createProvider() {
58+
return new CamelEndpointPsiReferenceProvider() {
59+
@Override
60+
protected PsiReference[] getEndpointReferencesByElement(String endpointUri, PsiElement element, ProcessingContext context) {
61+
Project project = element.getProject();
62+
63+
CamelCatalogService catalogService = project.getService(CamelCatalogService.class);
64+
CamelCatalog catalog = catalogService.get();
65+
String component = catalog.endpointComponentName(endpointUri);
66+
if (component == null) {
67+
return PsiReference.EMPTY_ARRAY;
68+
}
69+
70+
Map<String, String> params;
71+
try {
72+
String unescapedUri = IdeaUtils.getService().isXmlLanguage(element) ? StringUtil.unescapeXmlEntities(endpointUri) : endpointUri;
73+
params = catalog.endpointProperties(unescapedUri);
74+
} catch (Exception e) {
75+
return PsiReference.EMPTY_ARRAY;
76+
}
77+
78+
return createParameterReferences(endpointUri, element, component, params);
79+
}
80+
81+
private PsiReference[] createParameterReferences(String endpointUri, PsiElement endpointElement, String component, Map<String, String> params) {
82+
return params.keySet().stream()
83+
.map(param -> {
84+
int paramStartIndex = endpointUri.indexOf(param + "=");
85+
if (paramStartIndex < 0) {
86+
return null;
87+
}
88+
if (endpointElement.getText().startsWith("\"")) {
89+
paramStartIndex++;
90+
}
91+
return new EndpointParameterReference(endpointElement, component, param, new TextRange(paramStartIndex, paramStartIndex + param.length()));
92+
})
93+
.filter(Objects::nonNull)
94+
.toArray(PsiReference[]::new);
95+
}
96+
97+
@Override
98+
protected boolean isEndpoint(String endpointUri) {
99+
return true;
100+
}
101+
};
102+
}
103+
104+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.github.cameltooling.idea.reference.endpoint.parameter;
18+
19+
import com.github.cameltooling.idea.service.CamelCatalogService;
20+
import com.intellij.openapi.project.Project;
21+
import com.intellij.openapi.util.TextRange;
22+
import com.intellij.psi.JavaPsiFacade;
23+
import com.intellij.psi.PsiClass;
24+
import com.intellij.psi.PsiElement;
25+
import com.intellij.psi.PsiMethod;
26+
import com.intellij.psi.PsiReferenceBase;
27+
import com.intellij.psi.search.GlobalSearchScope;
28+
import com.intellij.psi.util.PropertyUtilBase;
29+
import org.apache.camel.catalog.CamelCatalog;
30+
import org.apache.camel.tooling.model.ComponentModel;
31+
import org.jetbrains.annotations.NotNull;
32+
import org.jetbrains.annotations.Nullable;
33+
34+
import java.util.List;
35+
36+
/**
37+
* Reference from an endpoint uri query parameter to its setter method in the corresponding camel class
38+
* E.g. from the 'synchronous' substring in endpoint uri "direct:abc?synchronous=true" to {@link org.apache.camel.component.direct.DirectEndpoint#setSynchronous}
39+
*/
40+
public class EndpointParameterReference extends PsiReferenceBase<PsiElement> {
41+
42+
private static final List<String> CONFIG_CLASS_SUFFIXES = List.of("Endpoint", "Configuration");
43+
44+
private final String component;
45+
private final String parameterName;
46+
47+
public EndpointParameterReference(@NotNull PsiElement element, @NotNull String component, @NotNull String parameterName, TextRange parameterTextRange) {
48+
super(element, parameterTextRange);
49+
this.component = component;
50+
this.parameterName = parameterName;
51+
}
52+
53+
@Override
54+
public @Nullable PsiElement resolve() {
55+
Project project = getElement().getProject();
56+
CamelCatalog catalog = project.getService(CamelCatalogService.class).get();
57+
ComponentModel model = catalog.componentModel(component);
58+
String componentClassName = model.getJavaType();
59+
if (componentClassName.endsWith("Component")) {
60+
String baseClassName = componentClassName.substring(0, componentClassName.length() - "Component".length());
61+
for (String configClassSuffix : CONFIG_CLASS_SUFFIXES) {
62+
String configClassName = baseClassName + configClassSuffix;
63+
PsiClass configClass = JavaPsiFacade.getInstance(project).findClass(configClassName, GlobalSearchScope.allScope(project));
64+
if (configClass != null) {
65+
PsiMethod setter = PropertyUtilBase.findPropertySetter(configClass, parameterName, false, true);
66+
if (setter != null) {
67+
return setter;
68+
}
69+
}
70+
}
71+
}
72+
return null;
73+
}
74+
75+
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
v.1.4.4
1313
<ul>
1414
<li>Only IDEA 2025 onwards is supported</li>
15+
<li>
16+
References from endpoint uri to corresponding setters in camel classes, e.g. from the <code>synchronous</code> substring in endpoint uri <code>"direct:abc?synchronous=true"</code>
17+
to <code>DirectEndpoint#setSynchronous</code>
18+
</li>
1519
</ul>
1620
]]>
1721
</change-notes>
@@ -148,6 +152,9 @@
148152
<psi.referenceContributor implementation="com.github.cameltooling.idea.reference.propertyplaceholder.CamelPropertyPlaceholderReferenceContributor"/>
149153
<psi.referenceContributor implementation="com.github.cameltooling.idea.reference.propertyplaceholder.GenericXmlPropertyPlaceholderReferenceContributor" language="XML"/>
150154
<psi.referenceContributor implementation="com.github.cameltooling.idea.reference.propertyplaceholder.ConfigPropertyPlaceholderReferenceContributor" language="JAVA"/>
155+
<psi.referenceContributor implementation="com.github.cameltooling.idea.reference.endpoint.parameter.CamelEndpointParameterReferenceContributor" language="JAVA" />
156+
<psi.referenceContributor implementation="com.github.cameltooling.idea.reference.endpoint.parameter.CamelEndpointParameterReferenceContributor" language="XML" />
157+
<psi.referenceContributor implementation="com.github.cameltooling.idea.reference.endpoint.parameter.CamelEndpointParameterReferenceContributor" language="yaml" />
151158
<renameHandler implementation="com.github.cameltooling.idea.reference.CamelBeanReferenceRenameHandler"/>
152159
<postFormatProcessor implementation="com.github.cameltooling.idea.formatter.CamelPostFormatProcessor"/>
153160

src/test/java/com/github/cameltooling/idea/CamelLightCodeInsightFixtureTestCaseIT.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ public abstract class CamelLightCodeInsightFixtureTestCaseIT extends LightJavaCo
6767
protected static String CAMEL_CORE_MODEL_MAVEN_ARTIFACT = "org.apache.camel:camel-core-model:%s";
6868
protected static String CAMEL_API_MAVEN_ARTIFACT = "org.apache.camel:camel-api:%s";
6969
protected static String CAMEL_ENDPOINTDSL_MAVEN_ARTIFACT = "org.apache.camel:camel-endpointdsl:%s";
70+
protected static String CAMEL_TIMER_MAVEN_ARTIFACT = "org.apache.camel:camel-timer:%s";
71+
protected static String CAMEL_FTP_MAVEN_ARTIFACT = "org.apache.camel:camel-ftp:%s";
7072

7173

7274
static {
@@ -79,6 +81,8 @@ public abstract class CamelLightCodeInsightFixtureTestCaseIT extends LightJavaCo
7981
CAMEL_API_MAVEN_ARTIFACT = String.format(CAMEL_API_MAVEN_ARTIFACT, CAMEL_VERSION);
8082
CAMEL_CORE_MODEL_MAVEN_ARTIFACT = String.format(CAMEL_CORE_MODEL_MAVEN_ARTIFACT, CAMEL_VERSION);
8183
CAMEL_ENDPOINTDSL_MAVEN_ARTIFACT = String.format(CAMEL_ENDPOINTDSL_MAVEN_ARTIFACT, CAMEL_VERSION);
84+
CAMEL_TIMER_MAVEN_ARTIFACT = String.format(CAMEL_TIMER_MAVEN_ARTIFACT, CAMEL_VERSION);
85+
CAMEL_FTP_MAVEN_ARTIFACT = String.format(CAMEL_FTP_MAVEN_ARTIFACT, CAMEL_VERSION);
8286
} catch (IOException e) {
8387
throw new UncheckedIOException(e);
8488
}

0 commit comments

Comments
 (0)