Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/xpn/xwiki/web/Utils.java


1   /**
2    * ===================================================================
3    *
4    * Copyright (c) 2003,2004 Ludovic Dubost, All rights reserved.
5    *
6    * This program is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public License
8    * as published by the Free Software Foundation; either version 2
9    * of the License, or (at your option) any later version.
10   *
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU Lesser General Public License for more details, published at 
15   * http://www.gnu.org/copyleft/lesser.html or in lesser.txt in the
16   * root folder of this distribution.
17  
18   * Created by
19   * User: Ludovic Dubost
20   * Date: 19 mai 2004
21   * Time: 13:36:16
22   */
23  package com.xpn.xwiki.web;
24  
25  import com.xpn.xwiki.XWiki;
26  import com.xpn.xwiki.XWikiContext;
27  import com.xpn.xwiki.XWikiException;
28  import com.xpn.xwiki.xmlrpc.XWikiXMLRPCRequest;
29  import com.xpn.xwiki.xmlrpc.XWikiXMLRPCURLFactory;
30  import com.novell.ldap.util.Base64;
31  import org.apache.commons.fileupload.DefaultFileItem;
32  import org.apache.log4j.MDC;
33  import org.apache.ecs.Filter;
34  import org.apache.ecs.filter.CharacterFilter;
35  
36  import java.io.IOException;
37  import java.io.InputStream;
38  import java.io.UnsupportedEncodingException;
39  import java.net.URL;
40  import java.net.URLEncoder;
41  import java.net.URLDecoder;
42  import java.util.Date;
43  import java.util.HashMap;
44  import java.util.List;
45  import java.util.Map;
46  
47  public class Utils {
48  
49      public static void parseTemplate(String template, XWikiContext context) throws XWikiException {
50          parseTemplate(template, true, context);
51      }
52  
53      public static void parseTemplate(String template, boolean write, XWikiContext context) throws XWikiException {
54          XWikiResponse response = context.getResponse();
55  
56          // Set content-type and encoding (this can be changed in the future by pages themselves)
57          if (context.getResponse() instanceof XWikiPortletResponse) {
58              response.setContentType("text/html");
59          }
60          else {
61              response.setContentType("text/html; charset=" + context.getWiki().getEncoding());
62          }
63  
64          if ("view".equals(context.getAction())) {
65              if (context.getResponse() instanceof XWikiServletResponse) {
66                  // Add a last modified to tell when the page was last updated
67                  if (context.getWiki().getXWikiPreferenceAsLong("headers_lastmodified", 1, context)!=0) {
68                      if (context.getDoc()!=null)
69                       response.setDateHeader("Last-Modified", context.getDoc().getDate().getTime());
70                  }
71                  // Set a nocache to make sure the page is reloaded after an edit
72                  if (context.getWiki().getXWikiPreferenceAsLong("headers_nocache", 1, context)!=0) {
73                      response.setHeader("Pragma", "no-cache");
74                      response.setHeader("Cache-Control","no-cache");
75                  }
76                  // Set an expires in one month
77                  long expires = context.getWiki().getXWikiPreferenceAsLong("headers_expires", -1, context);
78                  if (expires==-1) {
79                      response.setDateHeader("Expires", -1);
80                  } else if (expires!=0) {
81                      response.setDateHeader("Expires", (new Date()).getTime() + 30*24*3600*1000L);
82                  }
83  
84              }
85          }
86  
87          String content = context.getWiki().parseTemplate(template + ".vm", context);
88          content = content.trim();
89  
90          if (!context.isFinished()) {
91              if (context.getResponse() instanceof XWikiServletResponse) {
92                  response.setContentLength(content.length());
93              }
94  
95              try {
96                  if (write)
97                      response.getWriter().write(content);
98              } catch (IOException e) {
99                  throw new XWikiException(XWikiException.MODULE_XWIKI_APP,
100                         XWikiException.ERROR_XWIKI_APP_SEND_RESPONSE_EXCEPTION,
101                         "Exception while sending response", e);
102             }
103         }
104 
105         try {
106              response.getWriter().flush();
107         } catch (Throwable e) {
108         }
109     }
110 
111     public static String getRedirect(XWikiRequest request, String defaultRedirect) {
112         String redirect;
113         redirect = request.getParameter("xredirect");
114         if ((redirect == null)||(redirect.equals("")))
115             redirect = defaultRedirect;
116         return redirect;
117     }
118 
119     public static String getRedirect(String action, XWikiContext context) {
120         String redirect;
121         redirect = context.getRequest().getParameter("xredirect");
122         if ((redirect == null)||(redirect.equals("")))
123            redirect = context.getDoc().getURL(action, true, context);
124         return redirect;
125     }
126 
127     public static String getPage(XWikiRequest request, String defaultpage) {
128         String page;
129         page = request.getParameter("xpage");
130         if ((page == null)||(page.equals("")))
131             page = defaultpage;
132         return page;
133     }
134 
135 
136     public static String getFileName(List filelist, String name) {
137         DefaultFileItem  fileitem = null;
138         for (int i=0;i<filelist.size();i++) {
139             DefaultFileItem item = (DefaultFileItem) filelist.get(i);
140             if (name.equals(item.getFieldName())) {
141                 fileitem = item;
142                 break;
143             }
144         }
145 
146         if (fileitem==null)
147             return null;
148 
149         return fileitem.getName();
150     }
151 
152     public static byte[] getContent(List filelist, String name) throws XWikiException {
153         DefaultFileItem  fileitem = null;
154         for (int i=0;i<filelist.size();i++) {
155             DefaultFileItem item = (DefaultFileItem) filelist.get(i);
156             if (name.equals(item.getFieldName())) {
157                 fileitem = item;
158                 break;
159             }
160         }
161 
162         if (fileitem==null)
163             return null;
164 
165         byte[] data = new byte[(int)fileitem.getSize()];
166         InputStream fileis = null;
167         try {
168             fileis = fileitem.getInputStream();
169             fileis.read(data);
170             fileis.close();
171         } catch (IOException e) {
172             throw new XWikiException(XWikiException.MODULE_XWIKI_APP,
173                     XWikiException.ERROR_XWIKI_APP_UPLOAD_FILE_EXCEPTION,
174                     "Exception while reading uploaded parsed file", e);
175         }
176         return data;
177     }
178 
179     public static XWikiContext prepareContext(String action, XWikiRequest request, XWikiResponse response,
180                                               XWikiEngineContext engine_context) throws XWikiException {
181         // Test works with xwiki-test.cfg instead of xwiki.cfg
182         XWikiContext context = new XWikiContext();
183         String dbname = "xwiki";
184 
185         URL url = XWiki.getRequestURL(request);
186         context.setURL(url);
187         // Push the URL into the Log4j NDC context
188         MDC.put("url", url);
189 
190         context.setEngineContext(engine_context);
191         context.setRequest(request);
192         context.setResponse(response);
193         context.setAction(action);
194         context.setDatabase(dbname);
195 
196 
197         if (request instanceof XWikiXMLRPCRequest) {
198          context.setMode(XWikiContext.MODE_XMLRPC);
199          XWikiURLFactory urlf = new XWikiXMLRPCURLFactory(context);
200          context.setURLFactory(urlf);
201         }
202         else if (request instanceof XWikiServletRequest) {
203          context.setMode(XWikiContext.MODE_SERVLET);
204          XWikiURLFactory urlf = new XWikiServletURLFactory(context);
205          context.setURLFactory(urlf);
206         }
207         else if (request instanceof XWikiPortletRequest) {
208          context.setMode(XWikiContext.MODE_PORTLET);
209          XWikiURLFactory urlf = new XWikiPortletURLFactory(context);
210          context.setURLFactory(urlf);
211         }
212 
213         return context;
214     }
215 
216     /**
217      * Append request parameters from the specified String to the specified
218      * Map.  It is presumed that the specified Map is not accessed from any
219      * other thread, so no synchronization is performed.
220      * <p>
221      * <strong>IMPLEMENTATION NOTE</strong>:  URL decoding is performed
222      * individually on the parsed name and value elements, rather than on
223      * the entire query string ahead of time, to properly deal with the case
224      * where the name or value includes an encoded "=" or "&" character
225      * that would otherwise be interpreted as a delimiter.
226      *
227      * @param data Input string containing request parameters
228      *
229      * @exception IllegalArgumentException if the data is malformed
230      *
231      *  Code borrowed from Apache Tomcat 5.0
232      */
233     public static Map parseParameters(String data, String encoding)
234         throws UnsupportedEncodingException {
235 
236         if ((data != null) && (data.length() > 0)) {
237 
238             // use the specified encoding to extract bytes out of the
239             // given string so that the encoding is not lost. If an
240             // encoding is not specified, let it use platform default
241             byte[] bytes = null;
242             try {
243                 if (encoding == null) {
244                     bytes = data.getBytes();
245                 } else {
246                     bytes = data.getBytes(encoding);
247                 }
248             } catch (UnsupportedEncodingException uee) {
249             }
250 
251             return parseParameters(bytes, encoding);
252         }
253 
254         return new HashMap();
255     }
256 
257     /**
258      * Append request parameters from the specified String to the specified
259      * Map.  It is presumed that the specified Map is not accessed from any
260      * other thread, so no synchronization is performed.
261      * <p>
262      * <strong>IMPLEMENTATION NOTE</strong>:  URL decoding is performed
263      * individually on the parsed name and value elements, rather than on
264      * the entire query string ahead of time, to properly deal with the case
265      * where the name or value includes an encoded "=" or "&" character
266      * that would otherwise be interpreted as a delimiter.
267      *
268      * NOTE: byte array data is modified by this method.  Caller beware.
269      *
270      * @param data Input string containing request parameters
271      * @param encoding Encoding to use for converting hex
272      *
273      * @exception UnsupportedEncodingException if the data is malformed
274      *
275      *  Code borrowed from Apache Tomcat 5.0
276      */
277     public static Map parseParameters(byte[] data, String encoding)
278         throws UnsupportedEncodingException {
279 
280         Map map = new HashMap();
281 
282         if (data != null && data.length > 0) {
283             int    pos = 0;
284             int    ix = 0;
285             int    ox = 0;
286             String key = null;
287             String value = null;
288             while (ix < data.length) {
289                 byte c = data[ix++];
290                 switch ((char) c) {
291                 case '&':
292                     value = new String(data, 0, ox, encoding);
293                     if (key != null) {
294                         putMapEntry(map, key, value);
295                         key = null;
296                     }
297                     ox = 0;
298                     break;
299                 case '=':
300                     if (key == null) {
301                         key = new String(data, 0, ox, encoding);
302                         ox = 0;
303                     } else {
304                         data[ox++] = c;
305                     }
306                     break;
307                 case '+':
308                     data[ox++] = (byte)' ';
309                     break;
310                 case '%':
311                     data[ox++] = (byte)((convertHexDigit(data[ix++]) << 4)
312                                     + convertHexDigit(data[ix++]));
313                     break;
314                 default:
315                     data[ox++] = c;
316                 }
317             }
318             //The last value does not end in '&'.  So save it now.
319             if (key != null) {
320                 value = new String(data, 0, ox, encoding);
321                 putMapEntry(map, key, value);
322             }
323         }
324         return map;
325     }
326 
327     /**
328      * Convert a byte character value to hexidecimal digit value.
329      *
330      * @param b the character value byte
331      *
332      *  Code borrowed from Apache Tomcat 5.0
333      */
334     private static byte convertHexDigit( byte b ) {
335         if ((b >= '0') && (b <= '9')) return (byte)(b - '0');
336         if ((b >= 'a') && (b <= 'f')) return (byte)(b - 'a' + 10);
337         if ((b >= 'A') && (b <= 'F')) return (byte)(b - 'A' + 10);
338         return 0;
339     }
340 
341     /**
342      * Put name value pair in map.
343      *
344      * Put name and value pair in map.  When name already exist, add value
345      * to array of values.
346      *
347      * Code borrowed from Apache Tomcat 5.0
348      */
349     private static void putMapEntry( Map map, String name, String value) {
350         String[] newValues = null;
351         String[] oldValues = (String[]) map.get(name);
352         if (oldValues == null) {
353             newValues = new String[1];
354             newValues[0] = value;
355         } else {
356             newValues = new String[oldValues.length + 1];
357             System.arraycopy(oldValues, 0, newValues, 0, oldValues.length);
358             newValues[oldValues.length] = value;
359         }
360         map.put(name, newValues);
361     }
362 
363     public static String formEncode(String value) {
364         Filter filter = new CharacterFilter();
365         filter.removeAttribute("'");
366         String svalue = filter.process(value);
367         return svalue;
368     }
369 
370     public static String SQLFilter(String text) {
371         try {
372             return text.replaceAll("'","''");
373         } catch (Exception e) {
374             return text;
375         }
376     }
377 
378     public static String encode(String name, XWikiContext context) {
379         try {
380             //byte[] bytes = name.getBytes("UTF-8");
381             ///String result = new String(bytes);
382             return URLEncoder.encode(name, context.getWiki().getEncoding());
383         } catch (Exception e) {
384          return name;
385         }
386     }
387 
388     public static String decode(String name, XWikiContext context) {
389         try {
390             // Make sure + is considered as a space
391             String result = name.replace('+',' ');
392 
393             // It seems Internet Explorer can send us back UTF-8
394             // instead of ISO-8859-1 for URLs
395              if (Base64.isValidUTF8(result.getBytes(), false))
396                result = new String(result.getBytes(), "UTF-8");
397 
398             // Still need to decode URLs
399             return URLDecoder.decode(result, context.getWiki().getEncoding());
400         } catch (Exception e) {
401          return name;
402         }
403     }
404 
405 }