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 */
019
020package org.crsh.lang.script;
021
022import org.crsh.command.CommandCreationException;
023import org.crsh.command.CommandInvoker;
024import org.crsh.command.ShellCommand;
025import org.crsh.command.SyntaxException;
026import org.crsh.repl.REPLSession;
027import org.crsh.command.pipeline.PipeLine;
028import org.crsh.shell.ErrorType;
029import org.crsh.text.Chunk;
030
031import java.util.LinkedList;
032import java.util.regex.Pattern;
033
034/**
035 * A factory for a pipeline.
036 */
037public class PipeLineFactory {
038
039  /** . */
040  final String line;
041
042  /** . */
043  final String name;
044
045  /** . */
046  final String rest;
047
048  /** . */
049  final PipeLineFactory next;
050
051  public PipeLineFactory(String line, PipeLineFactory next) throws SyntaxException {
052    Pattern p = Pattern.compile("^\\s*(\\S+)");
053    java.util.regex.Matcher m = p.matcher(line);
054    if (m.find()) {
055      this.name = m.group(1);
056      this.rest = line.substring(m.end());
057      this.line = line;
058      this.next = next;
059    } else {
060      throw new SyntaxException("Empty name");
061    }
062  }
063
064  public String getLine() {
065    return line;
066  }
067
068  public PipeLineFactory getNext() {
069    return next;
070  }
071
072  public CommandInvoker<Void, Chunk> create(REPLSession session) throws CommandCreationException {
073    LinkedList<CommandInvoker> pipes = new LinkedList<CommandInvoker>();
074    for (PipeLineFactory current = this;current != null;current = current.next) {
075      ShellCommand command = session.getCommand(current.name);
076      if (command == null) {
077        throw new CommandCreationException(current.name, ErrorType.EVALUATION, "Unknown command");
078      }
079      CommandInvoker commandInvoker = command.resolveInvoker(current.rest);
080      if (commandInvoker == null) {
081        throw new CommandCreationException(current.name, ErrorType.EVALUATION, "Command " + current.rest + " cannot not be invoked");
082      }
083      pipes.add(commandInvoker);
084    }
085    return new PipeLine(pipes.toArray(new CommandInvoker[pipes.size()]));
086  }
087
088  public PipeLineFactory getLast() {
089    if (next != null) {
090      return next.getLast();
091    }
092    return this;
093  }
094}