View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.jetspeed.ajax;
18  
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.io.InputStreamReader;
22  import java.io.Reader;
23  import java.io.StringWriter;
24  import java.lang.reflect.Method;
25  import java.util.Iterator;
26  import java.util.List;
27  import java.util.Map;
28  import java.util.Properties;
29  
30  import javax.servlet.ServletOutputStream;
31  import javax.servlet.http.HttpServletResponse;
32  
33  import org.apache.velocity.VelocityContext;
34  import org.apache.velocity.app.VelocityEngine;
35  import org.apache.velocity.context.Context;
36  import org.springframework.beans.BeansException;
37  import org.springframework.beans.factory.BeanFactory;
38  import org.springframework.beans.factory.BeanFactoryAware;
39  
40  /***
41   * Performs invocation of the actual AJAX request and returns
42   * a result object to converted into XML.
43   * 
44   * @author <href a="mailto:weaver@apache.org">Scott T. Weaver</a>
45   *
46   */
47  public class AJAXServiceImpl implements AJAXService, BeanFactoryAware
48  {
49      private Map serviceToBeans;
50      private Map serviceToTemplates;
51  
52      private BeanFactory beanFactory;
53      private VelocityEngine engine;
54  
55      public AJAXServiceImpl(Map serviceToBeans)
56      {
57          this.serviceToBeans = serviceToBeans;        
58      }
59  
60      public AJAXServiceImpl(Map serviceToBeans, VelocityEngine engine, Map serviceToTemplates)
61      {
62          this.serviceToBeans = serviceToBeans; 
63          this.engine = engine;
64          this.serviceToTemplates = serviceToTemplates;
65      }
66  
67      public AJAXResponse processRequest(AJAXRequest request)
68              throws AJAXException
69      {
70          final String serviceName = request.getServiceName();
71          final String methodName = request.getMethodName();
72   //       final String templateName = request.getServletRequest().getServletPath();
73  
74          final String mappedServiceName = (serviceName+"."+methodName).trim();
75          try
76          {
77              if(engine == null)
78              {
79                  engine = new VelocityEngine();
80                  Properties props = new Properties();
81                  props.load(request.getContext().getResourceAsStream("/WEB-INF/velocity.properties"));
82                  props.setProperty("file.resource.loader.path", request.getContext().getRealPath("/"));
83                  engine.init();
84              }
85              
86              
87              if(!serviceToBeans.containsKey(mappedServiceName))
88              {
89                  throw new AJAXException("There is no AJAX service named '"+mappedServiceName+"' defined.  "+ 
90                          "Please make sure that your ajax.xml is set up correctly.");
91              }
92              
93              String beanId = ((String)serviceToBeans.get(mappedServiceName)).trim();
94              Object targetService = beanFactory.getBean(beanId);
95              final List parameters = request.getParameters();
96              Method method = targetService.getClass().getMethod(methodName, getTypes(parameters));
97              Object result = method.invoke(targetService, getValues(parameters));
98              Context context = new VelocityContext();
99              context.put("ajaxRequest", request);
100             context.put("result", result);            
101    
102             String templateName =  ((String)serviceToTemplates.get(mappedServiceName)).trim();
103             final InputStream templateResource = request.getContext().getResourceAsStream(templateName);
104             
105             if(templateResource == null)
106             {
107                 request.getServletResponse().sendError(404, templateName+" ajax template could not be found.");
108                 throw new IOException(templateName+" does not exist");
109             }
110             Reader template = new InputStreamReader(templateResource);
111             
112             StringWriter stringWriter = new StringWriter();
113 
114             AJAXResponse ajaxResponse = new AJAXResponseImpl(context, engine, template, stringWriter);            
115             ajaxResponse.complete();
116     
117             String buffer = stringWriter.getBuffer().toString();
118 
119             // Put the response XML on the response object            
120             HttpServletResponse response = request.getServletResponse();
121             ServletOutputStream sos = response.getOutputStream();
122             sos.print(buffer);
123             sos.flush();
124             return ajaxResponse;
125         }
126         catch(AJAXException ae)
127         {
128             throw ae;
129         }
130         catch (Exception e)
131         {
132             throw new AJAXException("Unable to process service" + mappedServiceName + ": " + e.getMessage(), e);
133         }
134 
135     }
136 
137     /*
138      * (non-Javadoc)
139      * 
140      * @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)
141      */
142     public void setBeanFactory(BeanFactory beanFactory) throws BeansException
143     {
144         this.beanFactory = beanFactory;
145     }
146 
147     protected Class[] getTypes(List objects)
148     {
149         Class[] args = new Class[objects.size()];
150         Iterator itr = objects.iterator();
151         int i = 0;
152         while (itr.hasNext())
153         {
154             args[i] = ((AJAXRequestImpl.AJAXParameter)itr.next()).getValue().getClass();
155             i++;
156         }
157         return args;
158     }
159     
160     protected Object[] getValues(List objects)
161     {
162         Object[] args = new Object[objects.size()];
163         Iterator itr = objects.iterator();
164         int i = 0;
165         while (itr.hasNext())
166         {
167             args[i] = ((AJAXRequestImpl.AJAXParameter)itr.next()).getValue();
168             i++;
169         }
170         return args;
171     }
172 
173 }