001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jetspeed.ajax;
018:
019: import java.io.IOException;
020: import java.io.InputStream;
021: import java.io.InputStreamReader;
022: import java.io.Reader;
023: import java.io.StringWriter;
024: import java.lang.reflect.Method;
025: import java.util.Iterator;
026: import java.util.List;
027: import java.util.Map;
028: import java.util.Properties;
029:
030: import javax.servlet.ServletOutputStream;
031: import javax.servlet.http.HttpServletResponse;
032:
033: import org.apache.velocity.VelocityContext;
034: import org.apache.velocity.app.VelocityEngine;
035: import org.apache.velocity.context.Context;
036: import org.springframework.beans.BeansException;
037: import org.springframework.beans.factory.BeanFactory;
038: import org.springframework.beans.factory.BeanFactoryAware;
039:
040: /**
041: * Performs invocation of the actual AJAX request and returns
042: * a result object to converted into XML.
043: *
044: * @author <href a="mailto:weaver@apache.org">Scott T. Weaver</a>
045: *
046: */
047: public class AJAXServiceImpl implements AJAXService, BeanFactoryAware {
048: private Map serviceToBeans;
049: private Map serviceToTemplates;
050:
051: private BeanFactory beanFactory;
052: private VelocityEngine engine;
053:
054: public AJAXServiceImpl(Map serviceToBeans) {
055: this .serviceToBeans = serviceToBeans;
056: }
057:
058: public AJAXServiceImpl(Map serviceToBeans, VelocityEngine engine,
059: Map serviceToTemplates) {
060: this .serviceToBeans = serviceToBeans;
061: this .engine = engine;
062: this .serviceToTemplates = serviceToTemplates;
063: }
064:
065: public AJAXResponse processRequest(AJAXRequest request)
066: throws AJAXException {
067: final String serviceName = request.getServiceName();
068: final String methodName = request.getMethodName();
069: // final String templateName = request.getServletRequest().getServletPath();
070:
071: final String mappedServiceName = (serviceName + "." + methodName)
072: .trim();
073: try {
074: if (engine == null) {
075: engine = new VelocityEngine();
076: Properties props = new Properties();
077: props.load(request.getContext().getResourceAsStream(
078: "/WEB-INF/velocity.properties"));
079: props.setProperty("file.resource.loader.path", request
080: .getContext().getRealPath("/"));
081: engine.init();
082: }
083:
084: if (!serviceToBeans.containsKey(mappedServiceName)) {
085: throw new AJAXException(
086: "There is no AJAX service named '"
087: + mappedServiceName
088: + "' defined. "
089: + "Please make sure that your ajax.xml is set up correctly.");
090: }
091:
092: String beanId = ((String) serviceToBeans
093: .get(mappedServiceName)).trim();
094: Object targetService = beanFactory.getBean(beanId);
095: final List parameters = request.getParameters();
096: Method method = targetService.getClass().getMethod(
097: methodName, getTypes(parameters));
098: Object result = method.invoke(targetService,
099: getValues(parameters));
100: Context context = new VelocityContext();
101: context.put("ajaxRequest", request);
102: context.put("result", result);
103:
104: String templateName = ((String) serviceToTemplates
105: .get(mappedServiceName)).trim();
106: final InputStream templateResource = request.getContext()
107: .getResourceAsStream(templateName);
108:
109: if (templateResource == null) {
110: request.getServletResponse().sendError(
111: 404,
112: templateName
113: + " ajax template could not be found.");
114: throw new IOException(templateName + " does not exist");
115: }
116: Reader template = new InputStreamReader(templateResource);
117:
118: StringWriter stringWriter = new StringWriter();
119:
120: AJAXResponse ajaxResponse = new AJAXResponseImpl(context,
121: engine, template, stringWriter);
122: ajaxResponse.complete();
123:
124: String buffer = stringWriter.getBuffer().toString();
125:
126: // Put the response XML on the response object
127: HttpServletResponse response = request.getServletResponse();
128: ServletOutputStream sos = response.getOutputStream();
129: sos.print(buffer);
130: sos.flush();
131: return ajaxResponse;
132: } catch (AJAXException ae) {
133: throw ae;
134: } catch (Exception e) {
135: throw new AJAXException("Unable to process service"
136: + mappedServiceName + ": " + e.getMessage(), e);
137: }
138:
139: }
140:
141: /*
142: * (non-Javadoc)
143: *
144: * @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)
145: */
146: public void setBeanFactory(BeanFactory beanFactory)
147: throws BeansException {
148: this .beanFactory = beanFactory;
149: }
150:
151: protected Class[] getTypes(List objects) {
152: Class[] args = new Class[objects.size()];
153: Iterator itr = objects.iterator();
154: int i = 0;
155: while (itr.hasNext()) {
156: args[i] = ((AJAXRequestImpl.AJAXParameter) itr.next())
157: .getValue().getClass();
158: i++;
159: }
160: return args;
161: }
162:
163: protected Object[] getValues(List objects) {
164: Object[] args = new Object[objects.size()];
165: Iterator itr = objects.iterator();
166: int i = 0;
167: while (itr.hasNext()) {
168: args[i] = ((AJAXRequestImpl.AJAXParameter) itr.next())
169: .getValue();
170: i++;
171: }
172: return args;
173: }
174:
175: }
|