7df44925 by Ean Schuessler

New component for DirectControlServlet

0 parents
1 <?xml version="1.0"?>
2 <!--
3 Licensed to the Apache Software Foundation (ASF) under one
4 or more contributor license agreements. See the NOTICE file
5 distributed with this work for additional information
6 regarding copyright ownership. The ASF licenses this file
7 to you under the Apache License, Version 2.0 (the
8 "License"); you may not use this file except in compliance
9 with the License. You may obtain a copy of the License at
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 Unless required by applicable law or agreed to in writing,
14 software distributed under the License is distributed on an
15 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 KIND, either express or implied. See the License for the
17 specific language governing permissions and limitations
18 under the License.
19 -->
20
21 <project name="direct-control" default="jar" basedir=".">
22 <first id="possible.ofbiz.home.common.xml">
23 <resources>
24 <fileset dir="..">
25 <include name="ofbiz/common.xml"/>
26 </fileset>
27 <fileset dir="/">
28 <include name="srv/ofbiz-upstream/common.xml"/>
29 <include name="opt/ofbiz-upstream/common.xml"/>
30 <include name="job/ofbiz-upstream/common.xml"/>
31 </fileset>
32 </resources>
33 </first>
34 <dirname property="possible.ofbiz.home.dir" file="${toString:possible.ofbiz.home.common.xml}"/>
35 <property name="ofbiz.home.dir" value="${possible.ofbiz.home.dir}"/>
36 <import file="${ofbiz.home.dir}/common.xml"/>
37
38 <!-- ================================================================== -->
39 <!-- Initialization of all property settings -->
40 <!-- ================================================================== -->
41
42 <property name="desc" value="direct-control"/>
43 <property name="name" value="direct-control"/>
44
45 <path id="local.class.path">
46 <!--<fileset dir="${lib.dir}" includes="*.jar"/>-->
47 <fileset dir="${ofbiz.home.dir}/framework/webapp/lib" includes="*.jar"/>
48 <fileset dir="${ofbiz.home.dir}/framework/webapp/build/lib" includes="*.jar"/>
49 <fileset dir="${ofbiz.home.dir}/framework/base/lib" includes="*.jar"/>
50 <fileset dir="${ofbiz.home.dir}/framework/base/lib/commons" includes="*.jar"/>
51 <fileset dir="${ofbiz.home.dir}/framework/base/lib/scripting" includes="*.jar"/>
52 <fileset dir="${ofbiz.home.dir}/framework/base/lib/j2eespecs" includes="*.jar"/>
53 <fileset dir="${ofbiz.home.dir}/framework/base/build/lib" includes="*.jar"/>
54 <fileset dir="${ofbiz.home.dir}/framework/entity/lib" includes="*.jar"/>
55 <fileset dir="${ofbiz.home.dir}/framework/entity/build/lib" includes="*.jar"/>
56 <fileset dir="${ofbiz.home.dir}/framework/security/build/lib" includes="*.jar"/>
57 <fileset dir="${ofbiz.home.dir}/framework/service/lib" includes="*.jar"/>
58 <fileset dir="${ofbiz.home.dir}/framework/service/build/lib" includes="*.jar"/>
59 <fileset dir="${ofbiz.home.dir}/framework/minilang/build/lib" includes="*.jar"/>
60 <fileset dir="${ofbiz.home.dir}/framework/common/build/lib" includes="*.jar"/>
61 <fileset dir="${ofbiz.home.dir}/framework/webapp/build/lib" includes="*.jar"/>
62 <fileset dir="${ofbiz.home.dir}/applications/party/build/lib" includes="*.jar"/>
63 <fileset dir="${ofbiz.home.dir}/applications/product/build/lib" includes="*.jar"/>
64 <fileset dir="${ofbiz.home.dir}/applications/marketing/build/lib" includes="*.jar"/>
65 <fileset dir="${ofbiz.home.dir}/applications/order/build/lib" includes="*.jar"/>
66 <fileset dir="${ofbiz.home.dir}/applications/accounting/build/lib" includes="*.jar"/>
67 <fileset dir="${ofbiz.home.dir}/applications/securityext/build/lib" includes="*.jar"/>
68
69 <fileset dir="${ofbiz.home.dir}/framework/start/build/lib" includes="*.jar"/>
70 <fileset dir="${ofbiz.home.dir}/framework/catalina/lib" includes="*.jar"/>
71 </path>
72 </project>
1 <?xml version="1.0" encoding="UTF-8"?>
2 <ofbiz-component name="direct-api"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:noNamespaceSchemaLocation="http://www.ofbiz.org/dtds/ofbiz-component.xsd">
5 <resource-loader name="main" type="component"/>
6 <classpath type="dir" location="config"/>
7 <classpath type="jar" location="lib/*"/>
8 <classpath type="jar" location="build/lib/*"/>
9
10 </ofbiz-component>
11
1 package com.brainfood.ofbiz;
2
3 import java.io.IOException;
4 import java.io.PrintWriter;
5 import java.io.BufferedReader;
6 import java.io.StringReader;
7 import java.io.InputStreamReader;
8 import java.io.InputStream;
9 import java.util.Collections;
10 import java.util.Collection;
11 import java.util.Map;
12 import java.net.URL;
13 import java.net.MalformedURLException;
14 import java.util.Set;
15 import java.util.concurrent.CopyOnWriteArraySet;
16 import java.util.HashMap;
17 import java.util.HashSet;
18 import java.util.Enumeration;
19 import java.util.Locale;
20 import java.util.TimeZone;
21
22 import javolution.util.FastList;
23
24 import javax.script.ScriptContext;
25 import javax.servlet.RequestDispatcher;
26 import javax.servlet.ServletConfig;
27 import javax.servlet.ServletContext;
28 import javax.servlet.ServletException;
29 import javax.servlet.http.HttpServlet;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32 import javax.servlet.http.HttpSession;
33
34 import org.ofbiz.base.util.Debug;
35 import org.ofbiz.base.util.GroovyUtil;
36 import org.ofbiz.base.util.ScriptHelper;
37 import org.ofbiz.base.util.ScriptUtil;
38 import org.ofbiz.base.util.StringUtil;
39 import org.ofbiz.base.util.UtilHttp;
40 import org.ofbiz.base.util.UtilMisc;
41 import org.ofbiz.base.util.UtilProperties;
42
43 import org.ofbiz.entity.Delegator;
44 import org.ofbiz.entity.DelegatorFactory;
45 import org.ofbiz.entity.GenericValue;
46 import org.ofbiz.entity.util.EntityUtil;
47 import org.ofbiz.entity.condition.EntityOperator;
48 import org.ofbiz.entity.condition.EntityCondition;
49 import org.ofbiz.service.LocalDispatcher;
50 import org.ofbiz.service.ServiceContainer;
51
52 import groovy.lang.GroovyClassLoader;
53 import groovy.lang.Script;
54 import org.codehaus.groovy.runtime.InvokerHelper;
55
56 import org.ofbiz.base.json.JSON;
57 import org.ofbiz.base.json.ParseException;
58 import net.sf.json.JSONObject;
59
60 public class DirectControlServlet extends HttpServlet {
61 public static final String module = DirectControlServlet.class.getName();
62 public static final Map<String, String> serviceURLMappings = new HashMap<String, String>();
63
64 public void init(ServletConfig config) throws ServletException {
65 // get the mapping file for this webapp
66 ServletContext context = config.getServletContext();
67 String mappingFile = context.getInitParameter("serviceURLMappings");
68 Debug.logError("Mapping file: " + mappingFile, module);
69
70 if (mappingFile == null) {
71 Debug.logError("No mapping file configured", module);
72 } else {
73 try {
74 BufferedReader in = new BufferedReader(new InputStreamReader(context.getResourceAsStream(mappingFile)));
75 String line;
76 while ((line = in.readLine()) != null) {
77 String[] confItem = line.split("=");
78 serviceURLMappings.put(confItem[0], confItem[1]);
79 }
80 } catch (IOException ex) {
81 Debug.logError("Could not read mapping file " + mappingFile, module);
82 throw new ServletException("Could not read mapping file " + mappingFile);
83 }
84 }
85 }
86
87 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
88 doPost(request, response);
89 }
90
91 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
92 String method = "";
93 Debug.logInfo("request.getPathInfo: " + request.getPathInfo(), module);
94 Debug.logInfo("request.getContentType: " + request.getContentType(), module);
95
96 String pathInfo = request.getPathInfo();
97 if (pathInfo == null || pathInfo.length() == 0) {
98 return;
99 }
100 pathInfo = pathInfo.substring(1).replaceAll(":", ".");
101
102 try {
103 Delegator delegator = getDelegator(request.getServletContext());
104 LocalDispatcher dispatcher = getDispatcher(request.getServletContext());
105
106 // Build context
107 Map<String, Object> context = new HashMap<String, Object>();
108 String authToken = null;
109
110 // Handle if this is a form post
111 String contentType = request.getContentType();
112 if (contentType != null && contentType.indexOf("application/x-www-form-urlencoded") != -1) {
113 method = request.getParameter("_method");
114 // If this is a backbone PUT/DELETE emulated call then handle it
115 Debug.logInfo("Method: " + method, module);
116 if ("PUT".equals(method) || "DELETE".equals(method) || "CALL".equals(method)) {
117 if (!"CALL".equals(method)) context.put("_method", method);
118 JSON json = new JSON(new StringReader(request.getParameter("model")));
119 Map<String,Object> items = json.JSONObject();
120 authToken = (String) items.get("_AUTHTOKEN");
121 for (String key : items.keySet()) {
122 if (!"_AUTHTOKEN".equals(key)) {
123 context.put(key, items.get(key));
124 Debug.logInfo("parameter '" + key + "'=" + items.get(key), module);
125 }
126 }
127 } else {
128 authToken = request.getParameter("_AUTHTOKEN");
129 for (Enumeration<String> params = request.getParameterNames(); params.hasMoreElements();) {
130 String param = params.nextElement();
131 Object[] values = request.getParameterValues(param);
132 if (!"_AUTHTOKEN".equals(param)) {
133 context.put(param, values.length == 1 ? values[0] : values);
134 Debug.logInfo("parameter '" + param + "'=" + context.get(param), module);
135 }
136 }
137 }
138 } else {
139 Debug.logError("Unsupported form encoding", module);
140 }
141
142 // If there is a mapping for this pathInfo, run the corresponding service
143 // otherwise, return an error
144 String serviceName = serviceURLMappings.get(pathInfo) + "#" + method;
145 if (serviceName == null) {
146 serviceName = serviceURLMappings.get(pathInfo);
147 if (serviceName == null) {
148 response.setStatus(400);
149
150 PrintWriter writer = response.getWriter();
151 writer.println("No mapping found for URL \"" + pathInfo + "\"");
152 writer.flush();
153 writer.close();
154 return;
155 }
156 }
157
158 // If the _AUTHTOKEN parameter is set, attempt to look up the corresponding
159 // UserLogin and apply it to the service context
160 if (authToken != null) {
161 GenericValue authTokenEntity = EntityUtil.getFirst(
162 delegator.findList("Visit",
163 EntityCondition.makeCondition("cookie",
164 EntityOperator.EQUALS, authToken),
165 null, null, null, true));
166
167 if (authTokenEntity != null &&
168 authTokenEntity.get("userLoginId") != null) {
169 GenericValue userLogin = EntityUtil.getFirst(
170 delegator.findList("UserLogin",
171 EntityCondition.makeCondition("userLoginId",
172 EntityOperator.EQUALS,
173 authTokenEntity.get("userLoginId")),
174 null, null, null, true));
175 if (userLogin != null) {
176 context.put("userLogin", userLogin);
177 }
178 }
179 }
180
181 // some needed info for when running the service
182 Locale locale = UtilHttp.getLocale(request);
183 TimeZone timeZone = UtilHttp.getTimeZone(request);
184
185 Map<String, Object> result = dispatcher.runSync(serviceName, context);
186
187 System.err.println("RESULT:" + result);
188
189 result.remove("responseMessage");
190
191 if (result.get("errorMessage") != null) {
192 response.setStatus(400);
193 }
194
195 response.setContentType("application/x-json");
196
197 PrintWriter writer = response.getWriter();
198
199 JSONObject json = JSONObject.fromObject(result);
200 String jsonStr = json.toString();
201 response.setContentLength(jsonStr.getBytes("UTF8").length);
202 writer.write(jsonStr);
203 Debug.logWarning("JSON result [%s]", module, jsonStr);
204
205 writer.flush();
206 writer.close();
207 } catch (Throwable t) {
208 response.setStatus(400);
209 PrintWriter writer = response.getWriter();
210 while (t != null) {
211 t.printStackTrace(writer);
212 t = t.getCause();
213 }
214 writer.flush();
215 writer.close();
216 }
217 }
218
219 protected static LocalDispatcher getDispatcher(ServletContext servletContext) {
220 LocalDispatcher dispatcher = (LocalDispatcher) servletContext.getAttribute("dispatcher");
221 if (dispatcher == null) {
222 Delegator delegator = getDelegator(servletContext);
223 dispatcher = makeWebappDispatcher(servletContext, delegator);
224 servletContext.setAttribute("dispatcher", dispatcher);
225 }
226 return dispatcher;
227 }
228
229 /** This method only sets up a dispatcher for the current webapp and passed in delegator, it does not save it to the ServletContext or anywhere else, just returns it */
230 public static LocalDispatcher makeWebappDispatcher(ServletContext servletContext, Delegator delegator) {
231 if (delegator == null) {
232 Debug.logError("[ContextFilter.init] ERROR: delegator not defined.", module);
233 return null;
234 }
235 // get the unique name of this dispatcher
236 String dispatcherName = servletContext.getInitParameter("localDispatcherName");
237
238 if (dispatcherName == null) {
239 Debug.logError("No localDispatcherName specified in the web.xml file", module);
240 dispatcherName = delegator.getDelegatorName();
241 }
242
243 LocalDispatcher dispatcher = ServiceContainer.getLocalDispatcher(dispatcherName, delegator);
244 if (dispatcher == null) {
245 Debug.logError("[ContextFilter.init] ERROR: dispatcher could not be initialized.", module);
246 }
247
248 return dispatcher;
249 }
250
251 protected static Delegator getDelegator(ServletContext servletContext) {
252 Delegator delegator = (Delegator) servletContext.getAttribute("delegator");
253 if (delegator == null) {
254 String delegatorName = servletContext.getInitParameter("entityDelegatorName");
255
256 if (delegatorName == null || delegatorName.length() <= 0) {
257 delegatorName = "default";
258 }
259 if (Debug.verboseOn()) Debug.logVerbose("Setup Entity Engine Delegator with name " + delegatorName, module);
260 delegator = DelegatorFactory.getDelegator(delegatorName);
261 servletContext.setAttribute("delegator", delegator);
262 if (delegator == null) {
263 Debug.logError("[ContextFilter.init] ERROR: delegator factory returned null for delegatorName \"" + delegatorName + "\"", module);
264 }
265 }
266 return delegator;
267 }
268 }