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 020 package org.crsh.groovy; 021 022 import groovy.lang.GroovyObject; 023 import groovy.lang.MetaClass; 024 import groovy.lang.MissingMethodException; 025 import groovy.lang.MissingPropertyException; 026 import org.codehaus.groovy.runtime.InvokerHelper; 027 import org.crsh.command.BaseCommand; 028 import org.crsh.lang.impl.groovy.Helper; 029 import org.crsh.command.InvocationContext; 030 import org.crsh.command.ScriptException; 031 import org.crsh.lang.impl.groovy.closure.PipeLineClosure; 032 033 /** 034 * The base command for Groovy class based commands. 035 */ 036 public abstract class GroovyCommand extends BaseCommand implements GroovyObject { 037 038 // never persist the MetaClass 039 private transient MetaClass metaClass; 040 041 protected GroovyCommand() { 042 this.metaClass = InvokerHelper.getMetaClass(this.getClass()); 043 } 044 045 public static ScriptException unwrap(groovy.util.ScriptException cause) { 046 // Special handling for groovy.util.ScriptException 047 // which may be thrown by scripts because it is imported by default 048 // by groovy imports 049 String msg = cause.getMessage(); 050 ScriptException translated; 051 if (msg != null) { 052 translated = new ScriptException(msg); 053 } else { 054 translated = new ScriptException(); 055 } 056 translated.setStackTrace(cause.getStackTrace()); 057 return translated; 058 } 059 060 public static Exception unwrap(Exception cause) { 061 if (cause instanceof groovy.util.ScriptException) { 062 return unwrap((groovy.util.ScriptException)cause); 063 } else { 064 return cause; 065 } 066 } 067 068 public final Object invokeMethod(String name, Object args) { 069 try { 070 return getMetaClass().invokeMethod(this, name, args); 071 } 072 catch (MissingMethodException missing) { 073 return Helper.invokeMethod(context, name, args, missing); 074 } 075 } 076 077 public final Object getProperty(String property) { 078 if (context instanceof InvocationContext<?>) { 079 PipeLineClosure ret = Helper.resolveProperty((InvocationContext)context, property); 080 if (ret != null) { 081 return ret; 082 } 083 } 084 try { 085 return getMetaClass().getProperty(this, property); 086 } 087 catch (MissingPropertyException e) { 088 return context.getSession().get(property); 089 } 090 } 091 092 public final void setProperty(String property, Object newValue) { 093 try { 094 getMetaClass().setProperty(this, property, newValue); 095 } 096 catch (MissingPropertyException e) { 097 context.getSession().put(property, newValue); 098 } 099 } 100 101 public MetaClass getMetaClass() { 102 if (metaClass == null) { 103 metaClass = InvokerHelper.getMetaClass(getClass()); 104 } 105 return metaClass; 106 } 107 108 public void setMetaClass(MetaClass metaClass) { 109 this.metaClass = metaClass; 110 } 111 }