summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline')
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/CompositeURICompletor.java76
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/ICURICompletor.java49
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/InstallCompletor.java123
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/JLine.java80
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/RemoteNodeCompletor.java51
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/ServiceCompletor.java57
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/ServiceOperationCompletor.java89
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/TShellCompletor.java181
8 files changed, 706 insertions, 0 deletions
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/CompositeURICompletor.java b/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/CompositeURICompletor.java
new file mode 100644
index 0000000000..fe40a4051a
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/CompositeURICompletor.java
@@ -0,0 +1,76 @@
+/*
+ * 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.tuscany.sca.shell.jline;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jline.SimpleCompletor;
+
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.contribution.Artifact;
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.monitor.ValidationException;
+import org.apache.tuscany.sca.shell.Shell;
+
+/**
+ * A Completor that uses the composite URIs within a Contribution
+ * Will only work if the argument before the composite URI is a contribution URI
+ */
+public class CompositeURICompletor extends SimpleCompletor {
+
+ private Shell shell;
+
+ public CompositeURICompletor(Shell shell) {
+ super("");
+ this.shell = shell;
+ }
+
+ @Override
+ public int complete(final String buffer, final int cursor, final List clist) {
+ if (shell.getNode() == null) {
+ return -1;
+ }
+ Contribution c;
+ try {
+ c = shell.getNode().getContribution(getContributionURI());
+ } catch (Exception e) {
+ return super.complete(buffer, cursor, clist);
+ }
+ if (c == null) {
+ return -1;
+ }
+
+ List<String> cus = new ArrayList<String>();
+ for (Artifact a : c.getArtifacts()) {
+ if (a.getModel() instanceof Composite) {
+ cus.add(((Composite)a.getModel()).getURI());
+ }
+ }
+ setCandidateStrings(cus.toArray(new String[cus.size()]));
+ return super.complete(buffer, cursor, clist);
+ }
+
+ protected String getContributionURI() {
+ /* A little hacky to use a static but i can't see how else to get the contribution URI */
+ return TShellCompletor.lastArg;
+ }
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/ICURICompletor.java b/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/ICURICompletor.java
new file mode 100644
index 0000000000..a596725971
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/ICURICompletor.java
@@ -0,0 +1,49 @@
+/*
+ * 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.tuscany.sca.shell.jline;
+
+import java.util.List;
+
+import jline.SimpleCompletor;
+
+import org.apache.tuscany.sca.shell.Shell;
+
+/**
+ * An Installed Contribution URI Completor
+ */
+public class ICURICompletor extends SimpleCompletor {
+
+ private Shell shell;
+
+ public ICURICompletor(Shell shell) {
+ super("");
+ this.shell = shell;
+ }
+
+ @Override
+ public int complete(final String buffer, final int cursor, final List clist) {
+ if (shell.getNode() != null) {
+ List<String> ics = shell.getNode().getInstalledContributionURIs();
+ setCandidateStrings(ics.toArray(new String[ics.size()]));
+ }
+ return super.complete(buffer, cursor, clist);
+ }
+
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/InstallCompletor.java b/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/InstallCompletor.java
new file mode 100644
index 0000000000..f615fe610b
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/InstallCompletor.java
@@ -0,0 +1,123 @@
+/*
+ * 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.tuscany.sca.shell.jline;
+
+import java.io.File;
+import java.util.List;
+
+import jline.FileNameCompletor;
+
+import org.apache.tuscany.sca.shell.Shell;
+
+/**
+ * A Completor for the install command.
+ * The command format is: install [<uri>] <contributionURL> [-start] [-metadata <url>] [-duris <uri,uri,...>]
+ *
+ * TODO: doesn't seem to complete the -xxx parameters properly yet
+ *
+ */
+public class InstallCompletor extends FileNameCompletor {
+
+ ICURICompletor icuriCompletor;
+
+ public InstallCompletor(Shell shell) {
+ icuriCompletor = new ICURICompletor(shell);
+ }
+
+ public int complete(final String buf, final int cursor,
+ final List candidates) {
+
+// System.err.println("buf:" + buf);
+// System.err.println("candidates:" + candidates);
+
+ if ("-duris".equals(TShellCompletor.lastArg)) {
+ return icuriCompletor.complete(buf, cursor, candidates);
+ }
+ if ("-metadata".equals(TShellCompletor.lastArg)) {
+ return super.complete(buf, cursor, candidates);
+ }
+
+ return super.complete(buf, cursor, candidates);
+ }
+
+ @Override
+ public int matchFiles(String buffer, String translated, File[] entries,
+ List candidates) {
+ if (entries == null) {
+ return -1;
+ }
+
+ int matches = 0;
+
+ // first pass: just count the matches
+ for (int i = 0; i < entries.length; i++) {
+ if (entries[i].getAbsolutePath().startsWith(translated)) {
+ matches++;
+ }
+ }
+ if ("-metadata".startsWith(buffer)) {
+ matches++;
+ }
+ if ("-duris".startsWith(buffer)) {
+ matches++;
+ }
+ if ("-start".startsWith(buffer)) {
+ matches++;
+ }
+
+ // green - executable
+ // blue - directory
+ // red - compressed
+ // cyan - symlink
+ for (int i = 0; i < entries.length; i++) {
+ if (entries[i].getAbsolutePath().startsWith(translated)) {
+ String name =
+ entries[i].getName()
+ + (((matches == 1) && entries[i].isDirectory())
+ ? File.separator : " ");
+
+ /*
+ if (entries [i].isDirectory ())
+ {
+ name = new ANSIBuffer ().blue (name).toString ();
+ }
+ */
+ candidates.add(name);
+ }
+ }
+
+ if ("-metadata".startsWith(buffer) && !TShellCompletor.allArgs.contains("-metadata")) {
+ candidates.add("-metadata" + (matches == 1 ? " " : ""));
+ }
+ if ("-duris".startsWith(buffer) && !TShellCompletor.allArgs.contains("-duris")) {
+ candidates.add("-duris" + (matches == 1 ? " " : ""));
+ }
+ if ("-start".startsWith(buffer) && !TShellCompletor.allArgs.contains("-start")) {
+ candidates.add("-start" + (matches == 1 ? " " : ""));
+ }
+
+ final int index = buffer.lastIndexOf(File.separator);
+
+ int x= index + File.separator.length();
+// System.out.println("x="+x);
+ return x;
+// return index + File.separator.length();
+ }
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/JLine.java b/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/JLine.java
new file mode 100644
index 0000000000..e8fcd627e2
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/JLine.java
@@ -0,0 +1,80 @@
+/*
+ * 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.tuscany.sca.shell.jline;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.LinkedList;
+import java.util.List;
+
+import jline.Completor;
+import jline.ConsoleReader;
+
+import org.apache.tuscany.sca.shell.Shell;
+
+/**
+ * Keep all the JLine specific code out of the Shell class so that it runs ok
+ * when jline isn't on the classpath.
+ */
+public class JLine {
+
+ public static String readLine(Object r) throws IOException {
+ return ((ConsoleReader)r).readLine();
+ }
+
+ public static Object createJLineReader(final Shell shell) throws IOException {
+ ConsoleReader reader = new ConsoleReader();
+ fixCtrlC(reader);
+ // Add a Ctrl-c listener
+ reader.addTriggeredAction((char)3, new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ shell.bye();
+ System.exit(0);
+ }
+ });
+ reader.setBellEnabled(false);
+ // TODO: write a Completor specific to this that can handle the individual command arguments
+ List<Completor> completors = new LinkedList<Completor>();
+// completors.add(new SimpleCompletor(Shell.COMMANDS));
+// completors.add(new ICURICompletor(shell.node));
+// completors.add(new FileNameCompletor());
+// reader.addCompletor(new ArgumentCompletor(completors));
+ reader.addCompletor(new TShellCompletor(shell));
+ return reader;
+ }
+
+ /**
+ * The windowsbindings.properties shipped inside jline maps ctrl-c to INSERT
+ * with the comment "(frankly, I wasn't sure where to bind this)". That does not
+ * seem a great choice as it disables ctrl-c interupt so this resets that binding.
+ */
+ private static void fixCtrlC(ConsoleReader reader) {
+ try {
+ Field f = ConsoleReader.class.getDeclaredField("keybindings");
+ f.setAccessible(true);
+ short[] keybindings = (short[])f.get(reader);
+ if (keybindings[3] == -48) keybindings[3] = 3;
+ } catch (Exception e) {
+ e.printStackTrace(); // shouldnt happen
+ }
+ }
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/RemoteNodeCompletor.java b/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/RemoteNodeCompletor.java
new file mode 100644
index 0000000000..6cc7577fee
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/RemoteNodeCompletor.java
@@ -0,0 +1,51 @@
+/*
+ * 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.tuscany.sca.shell.jline;
+
+import java.util.List;
+
+import jline.SimpleCompletor;
+
+import org.apache.tuscany.sca.shell.Shell;
+
+/**
+ * A Completor for the names of the remote nodes in the domain
+ */
+public class RemoteNodeCompletor extends SimpleCompletor {
+
+ private Shell shell;
+
+ public RemoteNodeCompletor(Shell shell) {
+ super("");
+ this.shell = shell;
+ }
+
+ @Override
+ public int complete(final String buffer, final int cursor, final List clist) {
+ if (shell.getNode() == null) {
+ return -1;
+ }
+
+ List<String> nodes = shell.getNode().getNodeNames();
+ nodes.remove(shell.getNode().getLocalNodeName());
+ setCandidateStrings(nodes.toArray(new String[nodes.size()]));
+ return super.complete(buffer, cursor, clist);
+ }
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/ServiceCompletor.java b/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/ServiceCompletor.java
new file mode 100644
index 0000000000..4f86b1d1b3
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/ServiceCompletor.java
@@ -0,0 +1,57 @@
+/*
+ * 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.tuscany.sca.shell.jline;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jline.SimpleCompletor;
+
+import org.apache.tuscany.sca.assembly.Endpoint;
+import org.apache.tuscany.sca.impl.NodeImpl;
+import org.apache.tuscany.sca.runtime.DomainRegistry;
+import org.apache.tuscany.sca.shell.Shell;
+
+/**
+ * A Completor for available services
+ */
+public class ServiceCompletor extends SimpleCompletor {
+
+ private Shell shell;
+
+ public ServiceCompletor(Shell shell) {
+ super("");
+ this.shell = shell;
+ }
+
+ @Override
+ public int complete(final String buffer, final int cursor, final List clist) {
+ if (shell.getNode() != null) {
+ List<String> services = new ArrayList<String>();
+ DomainRegistry reg = ((NodeImpl)shell.getNode()).getEndpointRegistry();
+ for (Endpoint endpoint : reg.getEndpoints()) {
+ services.add(endpoint.getComponent().getURI() + "/" + endpoint.getService().getName());
+ }
+ setCandidateStrings(services.toArray(new String[services.size()]));
+ }
+ return super.complete(buffer, cursor, clist);
+ }
+
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/ServiceOperationCompletor.java b/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/ServiceOperationCompletor.java
new file mode 100644
index 0000000000..c61e8cf4ca
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/ServiceOperationCompletor.java
@@ -0,0 +1,89 @@
+/*
+ * 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.tuscany.sca.shell.jline;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import jline.SimpleCompletor;
+
+import org.apache.tuscany.sca.assembly.Endpoint;
+import org.apache.tuscany.sca.impl.NodeImpl;
+import org.apache.tuscany.sca.runtime.DomainRegistry;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.shell.Shell;
+import org.oasisopen.sca.NoSuchServiceException;
+
+/**
+ * A Completor for available service operations
+ */
+public class ServiceOperationCompletor extends SimpleCompletor {
+
+ private Shell shell;
+ private static final List<String> EXCLUDED_OPS = Arrays.asList(new String[] {"equals", "getClass",
+ "getInvocationHandler",
+ "getProxyClass", "hashCode",
+ "isProxyClass", "newProxyInstance",
+ "notify", "notifyAll", "toString",
+ "wait", "CGLIB$SET_STATIC_CALLBACKS",
+ "CGLIB$SET_THREAD_CALLBACKS",
+ "CGLIB$findMethodProxy",
+ "getCallback", "getCallbacks",
+ "newInstance", "setCallback",
+ "setCallbacks"});
+
+ public ServiceOperationCompletor(Shell shell) {
+ super("");
+ this.shell = shell;
+ }
+
+ @Override
+ public int complete(final String buffer, final int cursor, final List clist) {
+ String service = TShellCompletor.lastArg;
+// DomainRegistry reg = ((NodeImpl)shell.getNode()).getEndpointRegistry();
+// List<Endpoint> endpoints = reg.findEndpoint(service);
+// if (endpoints.size() < 1) {
+// return -1;
+// }
+// String serviceName = null;
+// if (service.contains("/")) {
+// int i = service.indexOf("/");
+// if (i < service.length()-1) {
+// serviceName = service.substring(i+1);
+// }
+// }
+// Object proxy = ((RuntimeComponent)endpoints.get(0).getComponent()).getServiceReference(null, serviceName).getService();
+ try {
+ Object proxy = shell.getNode().getService(null, service);
+ Method[] ms = proxy.getClass().getMethods();
+ List<String> ops = new ArrayList<String>();
+ for (Method m : ms) {
+ if (!EXCLUDED_OPS.contains(m.getName())) {
+ ops.add(m.getName());
+ }
+ }
+ setCandidateStrings(ops.toArray(new String[ops.size()]));
+ } catch (NoSuchServiceException e) {
+ }
+ return super.complete(buffer, cursor, clist);
+ }
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/TShellCompletor.java b/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/TShellCompletor.java
new file mode 100644
index 0000000000..3f38caf1e5
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/shell/src/main/java/org/apache/tuscany/sca/shell/jline/TShellCompletor.java
@@ -0,0 +1,181 @@
+/*
+ * 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.tuscany.sca.shell.jline;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import jline.ArgumentCompletor;
+import jline.Completor;
+import jline.ConsoleReader;
+import jline.FileNameCompletor;
+import jline.NullCompletor;
+import jline.SimpleCompletor;
+
+import org.apache.tuscany.sca.shell.Command;
+import org.apache.tuscany.sca.shell.Shell;
+
+/**
+ * A Completor thats specific to the Tuscany Shell that knows about
+ * each command and has an argument specific Completor for each command argument.
+ */
+public class TShellCompletor extends ArgumentCompletor {
+
+ Map<String, Completor[]> completors;
+ final Completor commandCompletor;
+ final ArgumentDelimiter delim = new WhitespaceArgumentDelimiter();
+ final Shell shell;
+
+ static String lastArg;
+ static List<String> allArgs;
+
+ public TShellCompletor(Shell shell) {
+ super((Completor)null);
+ this.shell = shell;
+ this.commandCompletor = new SimpleCompletor(shell.getCommandNames());
+
+ completors = new HashMap<String, Completor[]>();
+ completors.put("help", new Completor[]{commandCompletor, commandCompletor, new NullCompletor()});
+ completors.put("install", new Completor[]{commandCompletor, new InstallCompletor(shell)});
+ completors.put("installed", new Completor[]{commandCompletor, new ICURICompletor(shell), new NullCompletor()});
+ completors.put("invoke", new Completor[]{commandCompletor, new ServiceCompletor(shell), new ServiceOperationCompletor(shell), new NullCompletor()});
+ completors.put("load", new Completor[]{commandCompletor, new FileNameCompletor(), new NullCompletor()});
+ completors.put("remove", new Completor[]{commandCompletor, new ICURICompletor(shell), new NullCompletor()});
+ completors.put("run", new Completor[]{commandCompletor, new FileNameCompletor(), new NullCompletor()});
+ completors.put("save", new Completor[]{commandCompletor, new FileNameCompletor(), new NullCompletor()});
+ completors.put("start", new Completor[]{commandCompletor, new ICURICompletor(shell), new CompositeURICompletor(shell), new RemoteNodeCompletor(shell), new NullCompletor()});
+ completors.put("started", new Completor[]{commandCompletor, new ICURICompletor(shell), new CompositeURICompletor(shell), new NullCompletor()});
+ completors.put("stop", new Completor[]{commandCompletor, new ICURICompletor(shell), new CompositeURICompletor(shell), new NullCompletor()});
+
+ for (Command c : shell.getCommands().values()) {
+ List<Completor> compleors = new ArrayList<Completor>();
+ compleors.add(commandCompletor);
+ compleors.addAll(Arrays.asList(c.getCompletors()));
+ completors.put(c.getName(), compleors.toArray(new Completor[]{}));
+ }
+ }
+
+ @Override
+ /**
+ * Copied from JLine ArgumentCompletor class. The only change is to
+ * get the completors by using the getCompletors method and setting the lastArg static.
+ */
+ public int complete(final String buffer, final int cursor,
+ final List candidates) {
+
+ ArgumentList list = delim.delimit(buffer, cursor);
+ int argpos = list.getArgumentPosition();
+ int argIndex = list.getCursorArgumentIndex();
+
+ if (argIndex < 0) {
+ return -1;
+ }
+
+ if (argIndex > 0) {
+ /* set the last argument in a static for the CompositeURICompletor */
+ lastArg = list.getArguments()[argIndex-1];
+ if (lastArg != null) lastArg = lastArg.trim();
+ }
+ allArgs = Arrays.asList(list.getArguments());
+
+ final Completor comp;
+
+ Completor[] completors = getCompletors(buffer);
+
+ // if we are beyond the end of the completors, just use the last one
+ if (argIndex >= completors.length) {
+ comp = completors[completors.length - 1];
+ } else {
+ comp = completors[argIndex];
+ }
+
+ // ensure that all the previous completors are successful before
+ // allowing this completor to pass (only if strict is true).
+ for (int i = 0; getStrict() && (i < argIndex); i++) {
+ Completor sub =
+ completors[(i >= completors.length) ? (completors.length - 1) : i];
+ String[] args = list.getArguments();
+ String arg = ((args == null) || (i >= args.length)) ? "" : args[i];
+
+ List subCandidates = new LinkedList();
+
+ if (sub.complete(arg, arg.length(), subCandidates) == -1) {
+ return -1;
+ }
+
+ if (subCandidates.size() == 0) {
+ return -1;
+ }
+ }
+
+ int ret = comp.complete(list.getCursorArgument(), argpos, candidates);
+
+ if (ret == -1) {
+ return -1;
+ }
+
+ int pos = ret + (list.getBufferPosition() - argpos);
+
+ /**
+ * Special case: when completing in the middle of a line, and the
+ * area under the cursor is a delimiter, then trim any delimiters
+ * from the candidates, since we do not need to have an extra
+ * delimiter.
+ *
+ * E.g., if we have a completion for "foo", and we
+ * enter "f bar" into the buffer, and move to after the "f"
+ * and hit TAB, we want "foo bar" instead of "foo bar".
+ */
+ if ((cursor != buffer.length()) && delim.isDelimiter(buffer, cursor)) {
+ for (int i = 0; i < candidates.size(); i++) {
+ String val = candidates.get(i).toString();
+
+ while ((val.length() > 0)
+ && delim.isDelimiter(val, val.length() - 1)) {
+ val = val.substring(0, val.length() - 1);
+ }
+
+ candidates.set(i, val);
+ }
+ }
+
+ ConsoleReader.debug("Completing " + buffer + "(pos=" + cursor + ") "
+ + "with: " + candidates + ": offset=" + pos);
+
+ return pos;
+ }
+
+ protected Completor[] getCompletors(String buffer) {
+ StringBuilder sb = new StringBuilder();
+ for (int i=0; i<buffer.length(); i++) {
+ if (Character.isWhitespace(buffer.charAt(i))) {
+ break;
+ }
+ sb.append(buffer.charAt(i));
+ }
+ String command = sb.toString();
+ Completor[] comps = completors.get(command);
+ return comps == null ? new Completor[]{commandCompletor} : comps;
+ }
+}