001
014
015 package com.liferay.portal.scripting;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
018 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
019 import com.liferay.portal.kernel.scripting.Scripting;
020 import com.liferay.portal.kernel.scripting.ScriptingException;
021 import com.liferay.portal.kernel.scripting.ScriptingExecutor;
022 import com.liferay.portal.kernel.scripting.UnsupportedLanguageException;
023 import com.liferay.portal.kernel.util.StringBundler;
024 import com.liferay.portal.kernel.util.StringPool;
025
026 import java.io.IOException;
027 import java.io.LineNumberReader;
028
029 import java.util.HashMap;
030 import java.util.Map;
031 import java.util.Set;
032 import java.util.concurrent.ConcurrentHashMap;
033
034 import javax.portlet.ActionRequest;
035 import javax.portlet.ActionResponse;
036 import javax.portlet.PortletConfig;
037 import javax.portlet.PortletContext;
038 import javax.portlet.PortletRequest;
039 import javax.portlet.PortletResponse;
040 import javax.portlet.RenderRequest;
041 import javax.portlet.RenderResponse;
042 import javax.portlet.ResourceRequest;
043 import javax.portlet.ResourceResponse;
044
045 import org.python.core.Py;
046 import org.python.core.PyFile;
047 import org.python.core.PySyntaxError;
048
049
053 public class ScriptingImpl implements Scripting {
054
055 public void addScriptionExecutor(
056 String language, ScriptingExecutor scriptingExecutor) {
057
058 _scriptingExecutors.put(language, scriptingExecutor);
059 }
060
061 public void clearCache(String language) throws ScriptingException {
062 ScriptingExecutor scriptingExecutor = _scriptingExecutors.get(language);
063
064 if (scriptingExecutor == null) {
065 throw new UnsupportedLanguageException(language);
066 }
067
068 scriptingExecutor.clearCache();
069 }
070
071 public Map<String, Object> eval(
072 Set<String> allowedClasses, Map<String, Object> inputObjects,
073 Set<String> outputNames, String language, String script)
074 throws ScriptingException {
075
076 ScriptingExecutor scriptingExecutor = _scriptingExecutors.get(language);
077
078 if (scriptingExecutor == null) {
079 throw new UnsupportedLanguageException(language);
080 }
081
082 try {
083 return scriptingExecutor.eval(
084 allowedClasses, inputObjects, outputNames, script);
085 }
086 catch (Exception e) {
087 throw new ScriptingException(getErrorMessage(script, e), e);
088 }
089 }
090
091 public void exec(
092 Set<String> allowedClasses, Map<String, Object> inputObjects,
093 String language, String script)
094 throws ScriptingException {
095
096 eval(allowedClasses, inputObjects, null, language, script);
097 }
098
099 public Map<String, Object> getPortletObjects(
100 PortletConfig portletConfig, PortletContext portletContext,
101 PortletRequest portletRequest, PortletResponse portletResponse) {
102
103 Map<String, Object> objects = new HashMap<String, Object>();
104
105 objects.put("portletConfig", portletConfig);
106 objects.put("portletContext", portletContext);
107 objects.put("preferences", portletRequest.getPreferences());
108
109 if (portletRequest instanceof ActionRequest) {
110 objects.put("actionRequest", portletRequest);
111 }
112 else if (portletRequest instanceof RenderRequest) {
113 objects.put("renderRequest", portletRequest);
114 }
115 else if (portletRequest instanceof ResourceRequest) {
116 objects.put("resourceRequest", portletRequest);
117 }
118 else {
119 objects.put("portletRequest", portletRequest);
120 }
121
122 if (portletResponse instanceof ActionResponse) {
123 objects.put("actionResponse", portletResponse);
124 }
125 else if (portletResponse instanceof RenderResponse) {
126 objects.put("renderResponse", portletResponse);
127 }
128 else if (portletResponse instanceof ResourceResponse) {
129 objects.put("resourceResponse", portletResponse);
130 }
131 else {
132 objects.put("portletResponse", portletResponse);
133 }
134
135 objects.put(
136 "userInfo", portletRequest.getAttribute(PortletRequest.USER_INFO));
137
138 return objects;
139 }
140
141 public Set<String> getSupportedLanguages() {
142 return _scriptingExecutors.keySet();
143 }
144
145 public void setScriptingExecutors(
146 Map<String, ScriptingExecutor> scriptingExecutors) {
147
148 for (Map.Entry<String, ScriptingExecutor> entry :
149 scriptingExecutors.entrySet()) {
150
151 _scriptingExecutors.put(entry.getKey(), entry.getValue());
152 }
153 }
154
155 protected String getErrorMessage(Exception e) {
156 String message = e.getMessage();
157
158 if (e instanceof PySyntaxError) {
159 PySyntaxError pySyntaxError = (PySyntaxError)e;
160
161 UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
162 new UnsyncByteArrayOutputStream();
163
164 Py.displayException(
165 pySyntaxError.type, pySyntaxError.value,
166 pySyntaxError.traceback,
167 new PyFile(unsyncByteArrayOutputStream));
168
169 message = unsyncByteArrayOutputStream.toString();
170 }
171
172 return message;
173 }
174
175 protected String getErrorMessage(String script, Exception e) {
176 StringBundler sb = new StringBundler();
177
178 sb.append(getErrorMessage(e));
179 sb.append(StringPool.NEW_LINE);
180
181 try{
182 LineNumberReader lineNumberReader = new LineNumberReader(
183 new UnsyncStringReader(script));
184
185 while (true) {
186 String line = lineNumberReader.readLine();
187
188 if (line == null) {
189 break;
190 }
191
192 sb.append("Line ");
193 sb.append(lineNumberReader.getLineNumber());
194 sb.append(": ");
195 sb.append(line);
196 sb.append(StringPool.NEW_LINE);
197 }
198 }
199 catch (IOException ioe) {
200 sb.setIndex(0);
201
202 sb.append(getErrorMessage(e));
203 sb.append(StringPool.NEW_LINE);
204 sb.append(script);
205 }
206
207 return sb.toString();
208 }
209
210 private Map<String, ScriptingExecutor> _scriptingExecutors =
211 new ConcurrentHashMap<String, ScriptingExecutor>();
212
213 }