001/*
002 * Copyright (C) 2012 eXo Platform SAS.
003 *
004 * This is free software; you can redistribute it and/or modify it
005 * under the terms of the GNU Lesser General Public License as
006 * published by the Free Software Foundation; either version 2.1 of
007 * the License, or (at your option) any later version.
008 *
009 * This software is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public
015 * License along with this software; if not, write to the Free
016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018 */
019package org.crsh.shell.impl.command.system;
020
021import org.crsh.cli.Argument;
022import org.crsh.cli.Command;
023import org.crsh.cli.Usage;
024import org.crsh.cli.descriptor.ParameterDescriptor;
025import org.crsh.cli.spi.Completion;
026import org.crsh.command.BaseCommand;
027import org.crsh.command.InvocationContext;
028import org.crsh.command.ScriptException;
029import org.crsh.lang.spi.Language;
030import org.crsh.lang.impl.script.ScriptRepl;
031import org.crsh.lang.spi.Repl;
032import org.crsh.shell.impl.command.ShellSession;
033import org.crsh.text.Color;
034import org.crsh.text.Decoration;
035import org.crsh.text.Style;
036import org.crsh.text.ui.LabelElement;
037import org.crsh.text.ui.TableElement;
038
039import java.util.LinkedHashMap;
040import java.util.Map;
041
042/** @author Julien Viet */
043public class repl extends BaseCommand implements ReplCompleter {
044
045  @Usage("list the repl or change the current repl")
046  @Command
047  public void main(
048      InvocationContext<Object> context,
049      @Argument(completer = ReplCompleter.class)
050      @Usage("the optional repl name")
051      String name) throws Exception {
052    ShellSession session = (ShellSession)context.getSession();
053    Repl current = session.getRepl();
054    if (name != null) {
055      if (name.equals(current.getLanguage().getName())) {
056        context.provide("Using repl " + name);
057      } else {
058        Repl found = null;
059        for (Language lang : session.getContext().getPlugins(Language.class)) {
060          if (lang.getName().equals(name)) {
061            if (lang.isActive()) {
062              found = lang.getRepl();
063              if (found != null) {
064                break;
065              } else {
066                throw new ScriptException("Language " + name + " does not provide a repl");
067              }
068            } else {
069              throw new ScriptException("Language " + name + " not active");
070            }
071          }
072        }
073        if (found != null) {
074          session.setRepl(found);
075          context.provide("Using repl " + name);
076        } else {
077          throw new ScriptException("Repl " + name + " not found");
078        }
079      }
080    } else {
081
082      //
083      LinkedHashMap<Repl, Boolean> repls = new LinkedHashMap<Repl, Boolean>();
084      repls.put(ScriptRepl.getInstance(), true);
085      for (Language lang : session.getContext().getPlugins(Language.class)) {
086        Repl repl = lang.getRepl();
087        if (repl != null) {
088          repls.put(repl, lang.isActive());
089        }
090      }
091
092      //
093      TableElement table = new TableElement().rightCellPadding(1);
094      table.row(
095        new LabelElement("NAME").style(Style.style(Decoration.bold)),
096        new LabelElement("DISPLAY NAME"),
097        new LabelElement("DESCRIPTION"),
098        new LabelElement("ACTIVE")
099      );
100      for (Map.Entry<Repl, Boolean> entry : repls.entrySet()) {
101        Boolean active = entry.getValue();
102        String langDescription = entry.getKey().getDescription();
103        String langDisplayName = entry.getKey().getLanguage().getDisplayName();
104        String langName = entry.getKey().getLanguage().getName();
105        table.row(
106          new LabelElement(langName).style(Style.style(Color.red)),
107          new LabelElement(langDisplayName != null ? langDisplayName : ""),
108          new LabelElement(langDescription != null ? langDescription : ""),
109          new LabelElement(active)
110        );
111      }
112
113      //
114      context.provide(new LabelElement("Current repl is " + current.getLanguage().getName() + "available repl are:\n"));
115      context.provide(table);
116    }
117  }
118
119  @Override
120  public Completion complete(ParameterDescriptor parameter, String prefix) throws Exception {
121    ShellSession session = (ShellSession)context.getSession();
122    Completion.Builder builder = Completion.builder(prefix);
123    for (Language lang : session.getContext().getPlugins(Language.class)) {
124      if (lang.isActive()) {
125        if (lang.getRepl() != null) {
126          String name = lang.getName();
127          if (name.startsWith(prefix)) {
128            builder.add(name.substring(prefix.length()), true);
129          }
130        }
131      }
132    }
133    return builder.build();
134  }
135}