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    package org.crsh.lang.impl.groovy;
020    
021    import groovy.lang.Closure;
022    import groovy.lang.MissingMethodException;
023    import org.codehaus.groovy.runtime.InvokerInvocationException;
024    import org.crsh.command.CommandContext;
025    import org.crsh.command.InvocationContext;
026    import org.crsh.command.RuntimeContext;
027    import org.crsh.lang.impl.groovy.closure.PipeLineClosure;
028    import org.crsh.shell.impl.command.CRaSH;
029    import org.crsh.shell.impl.command.spi.Command;
030    import org.crsh.shell.impl.command.spi.CommandException;
031    import org.crsh.util.SafeCallable;
032    
033    /**
034     * @author Julien Viet
035     */
036    public class Helper {
037    
038      public static Object invokeMethod(RuntimeContext context, String name, Object args, MissingMethodException ex) {
039        if (context instanceof InvocationContext<?>) {
040          SafeCallable executed = Helper.resolveMethodInvocation((InvocationContext)context, name, args);
041          if (executed != null) {
042            return executed.call();
043          }
044        }
045    
046        //
047        Object o = context.getSession().get(name);
048        if (o instanceof Closure) {
049          Closure closure = (Closure)o;
050          if (args instanceof Object[]) {
051            Object[] array = (Object[])args;
052            if (array.length == 0) {
053              return closure.call();
054            } else {
055              return closure.call(array);
056            }
057          } else {
058            return closure.call(args);
059          }
060        } else {
061          throw ex;
062        }
063      }
064    
065      public static PipeLineClosure resolveProperty(final InvocationContext context, final String property) {
066        CRaSH crash = (CRaSH)context.getSession().get("crash");
067        if (crash != null) {
068          try {
069            Command<?> cmd = crash.getCommand(property);
070            if (cmd != null) {
071              return new PipeLineClosure(context, property, cmd);
072            } else {
073              return null;
074            }
075          } catch (CommandException e) {
076            throw new InvokerInvocationException(e);
077          }
078        } else {
079          return null;
080        }
081      }
082    
083      public static SafeCallable resolveMethodInvocation(final InvocationContext context, final String name, final Object args) {
084        CRaSH crash = (CRaSH)context.getSession().get("crash");
085        if (crash != null) {
086          final Command<?> cmd;
087          try {
088            cmd = crash.getCommand(name);
089          }
090          catch (CommandException ce) {
091            throw new InvokerInvocationException(ce);
092          }
093          if (cmd != null) {
094            return new SafeCallable() {
095              @Override
096              public Object call() {
097                PipeLineClosure closure = new PipeLineClosure(context, name, cmd);
098                return closure.call((Object[])args);
099              }
100            };
101          }
102        }
103        return null;
104      }
105    }