You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by js...@apache.org on 2013/05/24 11:24:36 UTC
git commit: provide an implementation of CAMEL-6391 so that we can
use completion when entering the endpoint path values. for example for file
components,
we can use bash style completion on the available directory/file names from a
karaf command, CLI to
Updated Branches:
refs/heads/master ca35a4d7b -> 4cc51e1c6
provide an implementation of CAMEL-6391 so that we can use completion when entering the endpoint path values. for example for file components, we can use bash style completion on the available directory/file names from a karaf command, CLI tool, IDE or web based tool
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/4cc51e1c
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/4cc51e1c
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/4cc51e1c
Branch: refs/heads/master
Commit: 4cc51e1c6ed20787cf98888241e2909e72d05331
Parents: ca35a4d
Author: James Strachan <ja...@gmail.com>
Authored: Fri May 24 10:23:13 2013 +0100
Committer: James Strachan <ja...@gmail.com>
Committed: Fri May 24 10:23:13 2013 +0100
----------------------------------------------------------------------
.../org/apache/camel/ComponentConfiguration.java | 15 +++
.../management/mbean/ManagedCamelContextMBean.java | 22 ++++
.../apache/camel/component/file/FileComponent.java | 56 ++++++++++-
.../camel/impl/ComponentConfigurationSupport.java | 9 ++
.../management/mbean/ManagedCamelContext.java | 19 ++++
.../org/apache/camel/spi/EndpointCompleter.java | 41 ++++++++
.../camel/management/EndpointCompletionTest.java | 78 +++++++++++++++
7 files changed, 239 insertions(+), 1 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/4cc51e1c/camel-core/src/main/java/org/apache/camel/ComponentConfiguration.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/ComponentConfiguration.java b/camel-core/src/main/java/org/apache/camel/ComponentConfiguration.java
index 91ac7cf..4873ad4 100644
--- a/camel-core/src/main/java/org/apache/camel/ComponentConfiguration.java
+++ b/camel-core/src/main/java/org/apache/camel/ComponentConfiguration.java
@@ -17,6 +17,7 @@
package org.apache.camel;
import java.net.URISyntaxException;
+import java.util.List;
import java.util.Map;
import java.util.SortedMap;
@@ -134,5 +135,19 @@ public interface ComponentConfiguration {
*/
void setEndpointParameter(Endpoint endpoint, String name, Object value) throws RuntimeCamelException;
+ /**
+ * A helper method for tools such as CLIs, IDEs or web tools that provides a completion list for Endpoint Paths
+ * rather like bash tab completion or Karaf attribute or option completion handers.
+ *
+ * So given the current configuration data, return a list of completions given the specified text.
+ *
+ * e.g. return the files in a directory, the matching queues in a message broker, the database tables in a database component etc
+ *
+ * @param completionText the prefix text used to complete on (usually a matching bit of text)
+ *
+ * @return a list of matches
+ * @return a list of matches
+ */
+ List<String> completeEndpointPath(String completionText);
}
http://git-wip-us.apache.org/repos/asf/camel/blob/4cc51e1c/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java b/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
index 002f556..ea4e8b9 100644
--- a/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
+++ b/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
@@ -16,6 +16,7 @@
*/
package org.apache.camel.api.management.mbean;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
@@ -172,6 +173,15 @@ public interface ManagedCamelContextMBean extends ManagedPerformanceCounterMBean
Map<String, Properties> findComponents() throws Exception;
/**
+ * Find the names of all the Camel components available in the classpath and {@link org.apache.camel.spi.Registry}.
+ *
+ * @return a list with the names of the camel components
+ * @throws Exception is thrown if error occurred
+ */
+ @ManagedOperation(description = "Find all Camel components names available in the classpath")
+ List<String> findComponentNames() throws Exception;
+
+ /**
* Resets all the performance counters.
*
* @param includeRoutes whether to reset all routes as well.
@@ -180,4 +190,16 @@ public interface ManagedCamelContextMBean extends ManagedPerformanceCounterMBean
@ManagedOperation(description = "Reset counters")
void reset(boolean includeRoutes) throws Exception;
+
+ /**
+ * Helper method for tooling which returns the completion list of the endpoint path
+ * from the given endpoint name, properties and current path expression.
+ *
+ * For example if using the file endpoint, this should complete a list of files (rather like bash completion)
+ * or for an ActiveMQ component this should complete the list of queues or topics.
+ *
+ */
+ @ManagedOperation(description = "Returns the list of available endpoint paths for the given component name, endpoint properties and completion text")
+ List<String> completeEndpointPath(String componentName, Map<String,Object> endpointParameters, String completionText) throws Exception;
+
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/4cc51e1c/camel-core/src/main/java/org/apache/camel/component/file/FileComponent.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/file/FileComponent.java b/camel-core/src/main/java/org/apache/camel/component/file/FileComponent.java
index 8db964a..8ec22df 100644
--- a/camel-core/src/main/java/org/apache/camel/component/file/FileComponent.java
+++ b/camel-core/src/main/java/org/apache/camel/component/file/FileComponent.java
@@ -17,15 +17,20 @@
package org.apache.camel.component.file;
import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
+import org.apache.camel.ComponentConfiguration;
+import org.apache.camel.spi.EndpointCompleter;
import org.apache.camel.util.FileUtil;
+import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.StringHelper;
/**
* File component.
*/
-public class FileComponent extends GenericFileComponent<File> {
+public class FileComponent extends GenericFileComponent<File> implements EndpointCompleter {
/**
* GenericFile property on Camel Exchanges.
@@ -60,4 +65,53 @@ public class FileComponent extends GenericFileComponent<File> {
protected void afterPropertiesSet(GenericFileEndpoint<File> endpoint) throws Exception {
// noop
}
+
+ public List<String> completeEndpointPath(ComponentConfiguration configuration, String completionText) {
+ boolean empty = ObjectHelper.isEmpty(completionText);
+ String pattern = completionText;
+ File file = new File(completionText);
+ String prefix = completionText;
+ if (file.exists()) {
+ pattern = "";
+ } else {
+ String startPath = ".";
+ if (!empty) {
+ int idx = completionText.lastIndexOf('/');
+ if (idx >= 0) {
+ startPath = completionText.substring(0, idx);
+ if (startPath.length() == 0) {
+ startPath = "/";
+ }
+ pattern = completionText.substring(idx + 1);
+ }
+ }
+ file = new File(startPath);
+ prefix = startPath;
+ }
+ if (prefix.length() > 0 && !prefix.endsWith("/")) {
+ prefix += "/";
+ }
+ if (prefix.equals("./")) {
+ prefix = "";
+ }
+ File[] list = file.listFiles();
+ List<String> answer = new ArrayList<String>();
+ for (File aFile : list) {
+ String name = aFile.getName();
+ if (pattern.length() == 0 || name.contains(pattern)) {
+ if (isValidEndpointCompletion(configuration, completionText, aFile)) {
+ answer.add(prefix + name);
+ }
+ }
+ }
+ return answer;
+ }
+
+ /**
+ * Returns true if this is a valid file for completion. By default we should ignore files that start with a "."
+ */
+ protected boolean isValidEndpointCompletion(ComponentConfiguration configuration, String completionText,
+ File file) {
+ return !file.getName().startsWith(".");
+ }
}
http://git-wip-us.apache.org/repos/asf/camel/blob/4cc51e1c/camel-core/src/main/java/org/apache/camel/impl/ComponentConfigurationSupport.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/ComponentConfigurationSupport.java b/camel-core/src/main/java/org/apache/camel/impl/ComponentConfigurationSupport.java
index c529148..027a610 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/ComponentConfigurationSupport.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/ComponentConfigurationSupport.java
@@ -27,6 +27,7 @@ import java.util.Set;
import org.apache.camel.Component;
import org.apache.camel.ComponentConfiguration;
import org.apache.camel.Endpoint;
+import org.apache.camel.spi.EndpointCompleter;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.URISupport;
import org.apache.camel.util.UnsafeUriCharactersEncoder;
@@ -154,6 +155,14 @@ public abstract class ComponentConfigurationSupport implements ComponentConfigur
return getParameterConfigurationMap().get(name);
}
+ public List<String> completeEndpointPath(String completionText) {
+ if (component instanceof EndpointCompleter) {
+ EndpointCompleter completer = (EndpointCompleter) component;
+ return completer.completeEndpointPath(this, completionText);
+ }
+ return new ArrayList<String>();
+ }
+
/**
* Allow implementations to validate whether a property name is valid
* and either throw an exception or log a warning of an unknown property being used
http://git-wip-us.apache.org/repos/asf/camel/blob/4cc51e1c/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java b/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
index 4d58660..cc6c10e 100644
--- a/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
+++ b/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
@@ -17,6 +17,7 @@
package org.apache.camel.management.mbean;
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
@@ -29,6 +30,8 @@ import javax.management.MBeanServerInvocationHandler;
import javax.management.ObjectName;
import org.apache.camel.CamelContext;
+import org.apache.camel.Component;
+import org.apache.camel.ComponentConfiguration;
import org.apache.camel.Endpoint;
import org.apache.camel.ManagementStatisticsLevel;
import org.apache.camel.ProducerTemplate;
@@ -336,6 +339,22 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
return CamelContextHelper.findComponents(context);
}
+ public List<String> findComponentNames() throws Exception {
+ Map<String, Properties> map = findComponents();
+ return new ArrayList<String>(map.keySet());
+ }
+
+ public List<String> completeEndpointPath(String componentName, Map<String, Object> endpointParameters,
+ String completionText) throws Exception {
+ if (completionText == null) {
+ completionText = "";
+ }
+ Component component = context.getComponent(componentName);
+ ComponentConfiguration configuration = component.createComponentConfiguration();
+ configuration.setParameters(endpointParameters);
+ return configuration.completeEndpointPath(completionText);
+ }
+
public void reset(boolean includeRoutes) throws Exception {
reset();
http://git-wip-us.apache.org/repos/asf/camel/blob/4cc51e1c/camel-core/src/main/java/org/apache/camel/spi/EndpointCompleter.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/spi/EndpointCompleter.java b/camel-core/src/main/java/org/apache/camel/spi/EndpointCompleter.java
new file mode 100644
index 0000000..2fd34ec
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/spi/EndpointCompleter.java
@@ -0,0 +1,41 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.spi;
+
+import java.util.List;
+
+import org.apache.camel.ComponentConfiguration;
+
+/**
+ * A helper interface used by the {@link org.apache.camel.ComponentConfiguration#completeEndpointPath(String)} method
+ * to allow endpoint paths to be completed.
+ *
+ * {@link org.apache.camel.Component} implementations should try to implement this API to make your component
+ * behave nicer in command line, IDE and web based tools.
+ */
+public interface EndpointCompleter {
+ /**
+ * Given the configuration and completion text, return a list of possible completion values
+ * for a command line, IDE or web based tool.
+ *
+ * @returns the list of completion values if any (rather like bash completion, prefix values can be returned
+ * - such as just the directories in the current path rather than returning every possible file name on a disk).
+ */
+ List<String> completeEndpointPath(ComponentConfiguration configuration,
+ String completionText);
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/4cc51e1c/camel-core/src/test/java/org/apache/camel/management/EndpointCompletionTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/management/EndpointCompletionTest.java b/camel-core/src/test/java/org/apache/camel/management/EndpointCompletionTest.java
new file mode 100644
index 0000000..fff57b8
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/management/EndpointCompletionTest.java
@@ -0,0 +1,78 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.management;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+
+import com.sun.javafx.tools.packager.Log;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EndpointCompletionTest extends ManagementTestSupport {
+ private static final transient Logger LOG = LoggerFactory.getLogger(EndpointCompletionTest.class);
+
+ @SuppressWarnings("unchecked")
+ public void testEndpointCompletion() throws Exception {
+ MBeanServer mbeanServer = getMBeanServer();
+ ObjectName on = ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=context,name=\"camel-1\"");
+ assertNotNull(on);
+ mbeanServer.isRegistered(on);
+
+ String componentName = "file";
+ HashMap<String, Object> properties = new HashMap<String, Object>();
+ List<String> completions = assertCompletion(mbeanServer, on, componentName, properties, "");
+ completions = assertCompletion(mbeanServer, on, componentName, properties, "po");
+ completions = assertCompletion(mbeanServer, on, componentName, properties, "/");
+ completions = assertCompletion(mbeanServer, on, componentName, properties, "/usr/local");
+ completions = assertCompletion(mbeanServer, on, componentName, properties, "/usr/local/");
+ completions = assertCompletion(mbeanServer, on, componentName, properties, "/usr/local/b");
+
+ }
+
+ private List<String> assertCompletion(MBeanServer mbeanServer, ObjectName on, String componentName,
+ HashMap<String, Object> properties, String completionText)
+ throws InstanceNotFoundException, MBeanException, ReflectionException {
+ Object[] params = {componentName, properties, completionText};
+ String[] signature = { "java.lang.String", "java.util.Map", "java.lang.String" };
+
+ List completions = assertIsInstanceOf(List.class,
+ mbeanServer.invoke(on, "completeEndpointPath", params, signature));
+
+ LOG.info("Component " + componentName + " with '" + completionText + "' Returned: " + completions);
+ return completions;
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ }
+ };
+ }
+
+}