1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.scripting.ruby;
16  
17  import com.liferay.portal.kernel.scripting.ExecutionException;
18  import com.liferay.portal.kernel.scripting.ScriptingException;
19  import com.liferay.portal.kernel.scripting.ScriptingExecutor;
20  import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
21  import com.liferay.portal.kernel.util.StringPool;
22  
23  import java.util.ArrayList;
24  import java.util.HashMap;
25  import java.util.Map;
26  import java.util.Set;
27  
28  import org.jruby.Ruby;
29  import org.jruby.RubyInstanceConfig;
30  import org.jruby.exceptions.RaiseException;
31  import org.jruby.internal.runtime.GlobalVariables;
32  import org.jruby.javasupport.JavaEmbedUtils;
33  
34  /**
35   * <a href="RubyExecutor.java.html"><b><i>View Source</i></b></a>
36   *
37   * @author Alberto Montero
38   */
39  public class RubyExecutor implements ScriptingExecutor {
40  
41      public static final String LANGUAGE = "ruby";
42  
43      public RubyExecutor() {
44          RubyInstanceConfig rubyInstanceConfig = new RubyInstanceConfig();
45  
46          rubyInstanceConfig.setLoader(PortalClassLoaderUtil.getClassLoader());
47  
48          _ruby = JavaEmbedUtils.initialize(
49              new ArrayList<String>(), rubyInstanceConfig);
50      }
51  
52      public void clearCache() {
53      }
54  
55      public String getLanguage() {
56          return LANGUAGE;
57      }
58  
59      public Map<String, Object> eval(
60              Set<String> allowedClasses, Map<String, Object> inputObjects,
61              Set<String> outputNames, String script)
62          throws ScriptingException {
63  
64          if (allowedClasses != null) {
65              throw new ExecutionException(
66                  "Constrained execution not supported for Ruby");
67          }
68  
69          try {
70              GlobalVariables globalVariables = _ruby.getGlobalVariables();
71  
72              for (Map.Entry<String, Object> entry : inputObjects.entrySet()) {
73                  String inputName = entry.getKey();
74                  Object inputObject = entry.getValue();
75  
76                  if (!inputName.startsWith(StringPool.DOLLAR)) {
77                      inputName = StringPool.DOLLAR + inputName;
78                  }
79  
80                  BeanGlobalVariable beanGlobalVariable = new BeanGlobalVariable(
81                      _ruby, inputObject, inputObject.getClass());
82  
83                  globalVariables.define(inputName, beanGlobalVariable);
84              }
85  
86              _ruby.evalScriptlet(script);
87  
88              if (outputNames == null) {
89                  return null;
90              }
91  
92              Map<String, Object> outputObjects = new HashMap<String, Object>();
93  
94              for (String outputName : outputNames) {
95                  outputObjects.put(outputName, globalVariables.get(outputName));
96              }
97  
98              return outputObjects;
99          }
100         catch (RaiseException re) {
101             throw new ScriptingException(
102                 re.getException().message.asJavaString() + "\n\n", re);
103         }
104         finally {
105             JavaEmbedUtils.terminate(_ruby);
106         }
107     }
108 
109     private Ruby _ruby;
110 
111 }