Source code: com/xpn/xwiki/XWiki.java
1 /**
2 * ===================================================================
3 *
4 * Copyright (c) 2003-2005 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 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 General Public License for more details, published at
15 * http://www.gnu.org/copyleft/gpl.html or in gpl.txt in the
16 * root folder of this distribution.
17 */
18 package com.xpn.xwiki;
19
20 import com.xpn.xwiki.doc.XWikiAttachment;
21 import com.xpn.xwiki.doc.XWikiDocument;
22 import com.xpn.xwiki.notify.PropertyChangedRule;
23 import com.xpn.xwiki.notify.XWikiDocChangeNotificationInterface;
24 import com.xpn.xwiki.notify.XWikiNotificationManager;
25 import com.xpn.xwiki.notify.XWikiNotificationRule;
26 import com.xpn.xwiki.objects.BaseObject;
27 import com.xpn.xwiki.objects.PropertyInterface;
28 import com.xpn.xwiki.objects.classes.*;
29 import com.xpn.xwiki.objects.meta.MetaClass;
30 import com.xpn.xwiki.plugin.XWikiPluginManager;
31 import com.xpn.xwiki.plugin.XWikiPluginInterface;
32 import com.xpn.xwiki.render.XWikiRenderingEngine;
33 import com.xpn.xwiki.render.XWikiVelocityRenderer;
34 import com.xpn.xwiki.store.XWikiCacheStore;
35 import com.xpn.xwiki.store.XWikiCacheStoreInterface;
36 import com.xpn.xwiki.store.XWikiHibernateStore;
37 import com.xpn.xwiki.store.XWikiStoreInterface;
38 import com.xpn.xwiki.user.api.XWikiAuthService;
39 import com.xpn.xwiki.user.api.XWikiGroupService;
40 import com.xpn.xwiki.user.api.XWikiRightService;
41 import com.xpn.xwiki.user.api.XWikiUser;
42 import com.xpn.xwiki.user.impl.exo.ExoAuthServiceImpl;
43 import com.xpn.xwiki.user.impl.exo.ExoGroupServiceImpl;
44 import com.xpn.xwiki.user.impl.xwiki.XWikiAuthServiceImpl;
45 import com.xpn.xwiki.user.impl.xwiki.XWikiGroupServiceImpl;
46 import com.xpn.xwiki.user.impl.xwiki.XWikiRightServiceImpl;
47 import com.xpn.xwiki.user.impl.LDAP.LDAPAuthServiceImpl;
48 import com.xpn.xwiki.util.Util;
49 import com.xpn.xwiki.web.*;
50 import com.xpn.xwiki.web.includeservletasstring.IncludeServletAsString;
51 import com.xpn.xwiki.stats.api.XWikiStatsService;
52 import com.xpn.xwiki.stats.impl.XWikiStatsServiceImpl;
53 import com.xpn.xwiki.stats.impl.SearchEngineRule;
54 import com.xpn.xwiki.api.Document;
55 import com.xpn.xwiki.api.User;
56 import com.xpn.xwiki.api.Api;
57 import com.xpn.xwiki.cache.api.XWikiCacheService;
58 import com.xpn.xwiki.cache.impl.OSCacheService;
59 import org.hibernate.HibernateException;
60 import org.apache.commons.lang.RandomStringUtils;
61 import org.apache.commons.lang.StringUtils;
62 import org.apache.commons.logging.Log;
63 import org.apache.commons.logging.LogFactory;
64 import org.apache.commons.net.smtp.SMTPClient;
65 import org.apache.commons.net.smtp.SMTPReply;
66 import org.apache.commons.httpclient.HttpClient;
67 import org.apache.commons.httpclient.UsernamePasswordCredentials;
68 import org.apache.commons.httpclient.methods.GetMethod;
69 import org.apache.ecs.Filter;
70 import org.apache.ecs.filter.CharacterFilter;
71 import org.apache.ecs.xhtml.textarea;
72 import org.apache.velocity.VelocityContext;
73 import org.apache.velocity.app.tools.VelocityFormatter;
74 import org.securityfilter.filter.URLPatternMatcher;
75 import org.exoplatform.container.RootContainer;
76 import org.exoplatform.container.PortalContainer;
77
78 import javax.servlet.http.Cookie;
79 import javax.servlet.http.HttpServletRequest;
80 import javax.servlet.http.HttpServletResponse;
81 import java.io.*;
82 import java.lang.reflect.Field;
83 import java.lang.reflect.InvocationTargetException;
84 import java.lang.reflect.Method;
85 import java.lang.Class;
86 import java.net.MalformedURLException;
87 import java.net.URL;
88 import java.net.URLEncoder;
89 import java.util.*;
90 import java.util.zip.ZipOutputStream;
91 import java.text.SimpleDateFormat;
92 import java.text.DateFormatSymbols;
93
94 public class XWiki implements XWikiDocChangeNotificationInterface, XWikiInterface {
95 private static final Log log = LogFactory.getLog(XWiki.class);
96
97 private XWikiConfig config;
98 private XWikiStoreInterface store;
99 private XWikiRenderingEngine renderingEngine;
100 private XWikiPluginManager pluginManager;
101 private XWikiNotificationManager notificationManager;
102 private XWikiAuthService authService;
103 private XWikiRightService rightService;
104 private XWikiGroupService groupService;
105 private XWikiStatsService statsService;
106 private XWikiCacheService cacheService;
107
108 private MetaClass metaclass = MetaClass.getMetaClass();
109 private boolean test = false;
110 private String version = null;
111 private XWikiEngineContext engine_context;
112 private String database;
113 private String fullNameSQL;
114
115 private URLPatternMatcher urlPatternMatcher = new URLPatternMatcher();
116
117 // These are caches in order to improve finding virtual wikis
118 private List virtualWikiList = new ArrayList();
119 private static Map virtualWikiMap = new HashMap();
120 private static Map threadMap = new HashMap();
121
122 private boolean isReadOnly = false;
123
124 public static XWiki getMainXWiki(XWikiContext context) throws XWikiException {
125 String xwikicfg = <font color=red>"/WEB-INF/xwiki.cfg"font>;
126 String xwikiname = <font color=red>"xwiki"font>;
127 XWiki xwiki = null;
128 XWikiEngineContext econtext = context.getEngineContext();
129
130 try {
131 xwiki = (XWiki) econtext.getAttribute(xwikiname);
132 if (xwiki == null) {
133 InputStream xwikicfgis = econtext.getResourceAsStream(xwikicfg);
134 xwiki = new XWiki(xwikicfgis, context, context.getEngineContext());
135 econtext.setAttribute(xwikiname, xwiki);
136 }
137 context.setWiki(xwiki);
138 xwiki.setDatabase(context.getDatabase());
139 return xwiki;
140 } catch (Exception e) {
141 e.printStackTrace();
142 throw new XWikiException(XWikiException.MODULE_XWIKI,
143 XWikiException.ERROR_XWIKI_INIT_FAILED,
144 <font color=red>"Could not initialize main XWiki context"font>, e);
145 }
146 }
147
148 public XWikiHibernateStore getHibernateStore() {
149 XWikiStoreInterface store = getStore();
150 if (store instanceof XWikiHibernateStore)
151 return (XWikiHibernateStore) store;
152 else if (store instanceof XWikiCacheStoreInterface) {
153 store = ((XWikiCacheStoreInterface) store).getStore();
154 if (store instanceof XWikiHibernateStore)
155 return (XWikiHibernateStore) store;
156 else
157 return null;
158 } else
159 return null;
160 }
161
162 public synchronized void updateDatabase(String appname, XWikiContext context) throws HibernateException, XWikiException {
163 updateDatabase(appname, false, context);
164 }
165 public synchronized void updateDatabase(String appname, boolean force, XWikiContext context) throws HibernateException, XWikiException {
166 String database = context.getDatabase()
167 ;
168 try {
169 List wikilist = getVirtualWikiList();
170 context.setDatabase(appname);
171 if (!wikilist.contains(appname)) {
172 wikilist.add(appname);
173 XWikiHibernateStore store = getHibernateStore();
174 if (store != null)
175 store.updateSchema(context, force);
176 }
177
178 // Make sure these classes exists
179 getPrefsClass(context);
180 getUserClass(context);
181 getGroupClass(context);
182 getRightsClass(context);
183 getCommentsClass(context);
184 getSkinClass(context);
185 getGlobalRightsClass(context);
186 getPluginManager().virtualInit(context);
187
188 // Add initdone which will allow to
189 // bypass some initializations
190 context.put(<font color=red>"initdone"font>, <font color=red>"1"font>);
191 } finally {
192 context.setDatabase(database);
193 }
194
195 }
196
197 public List getVirtualWikiList() {
198 return virtualWikiList;
199 }
200
201 public static XWiki getXWiki(XWikiContext context) throws XWikiException {
202 XWiki xwiki = getMainXWiki(context);
203
204 if (xwiki.isVirtual()) {
205 XWikiRequest request = context.getRequest();
206 String host = "";
207 try {
208 URL requestURL = context.getURL();
209 host = requestURL.getHost();
210 } catch (Exception e) {
211 }
212 ;
213
214 if (host.equals(""))
215 return xwiki;
216
217 String appname = findWikiServer(host, context);
218
219 if (appname == null) {
220 String uri = request.getRequestURI();
221 int i1 = host.indexOf(<font color=red>"."font>);
222 String servername = (i1 != -1) ? host.substring(0, i1) : host;
223 appname = uri.substring(1, uri.indexOf(<font color=red>"/"font>, 2));
224 if (<font color=red>"0"font>.equals(xwiki.Param(<font color=red>"xwiki.virtual.autowww"font>))) {
225 appname = servername;
226 } else {
227 if ((servername.equals(<font color=red>"www"font>))
228 || (context.getUtil().match(<font color=red>"m|[0-9]+\\.|[0-9]+\\.[0-9]+\\.[0-9]|"font>, host))) {
229 if (appname.equals(<font color=red>"xwiki"font>))
230 return xwiki;
231 } else {
232 appname = servername;
233 }
234 }
235 }
236
237 // Check if this appname exists in the Database
238 String serverwikipage = getServerWikiPage(appname);
239 XWikiDocument doc = xwiki.getDocument(serverwikipage, context);
240 if (doc.isNew()) {
241 throw new XWikiException(XWikiException.MODULE_XWIKI,
242 XWikiException.ERROR_XWIKI_DOES_NOT_EXIST,
243 <font color=red>"The wiki "font> + appname + <font color=red>" does not exist"font>);
244 }
245
246 // Set the wiki owner
247 String wikiOwner = doc.getStringValue(<font color=red>"XWiki.XWikiServerClass"font>, <font color=red>"owner"font>);
248 if (wikiOwner.indexOf(<font color=red>":"font>) == -1)
249 wikiOwner = xwiki.getDatabase() + <font color=red>":"font> + wikiOwner;
250 context.setWikiOwner(wikiOwner);
251 context.setWikiServer(doc);
252 context.setVirtual(true);
253 context.setDatabase(appname);
254 context.setOriginalDatabase(appname);
255 try {
256 // Let's make sure the virtaul wikis are upgraded to the latest database version
257 xwiki.updateDatabase(appname, false, context);
258 } catch (HibernateException e) {
259 // Just to report it
260 e.printStackTrace();
261 }
262 }
263 return xwiki;
264 }
265
266 public static URL getRequestURL(XWikiRequest request) throws XWikiException {
267 try {
268 StringBuffer requestURL = request.getRequestURL();
269 String qs = request.getQueryString();
270 if ((qs != null) && (!qs.equals("")))
271 return new URL(requestURL.toString() + <font color=red>"?"font> + qs);
272 else
273 return new URL(requestURL.toString());
274 } catch (Exception e) {
275 throw new XWikiException(XWikiException.MODULE_XWIKI_APP,
276 XWikiException.ERROR_XWIKI_APP_URL_EXCEPTION,
277 <font color=red>"Exception while getting URL from request"font>, e);
278 }
279 }
280
281 private static String findWikiServer(String host, XWikiContext context) {
282 String wikiserver = (String) virtualWikiMap.get(host);
283 if (wikiserver != null)
284 return wikiserver;
285
286 String hql = <font color=red>", BaseObject as obj, StringProperty as prop where obj.name="font> + context.getWiki().getFullNameSQL()
287 + <font color=red>" and obj.className='XWiki.XWikiServerClass' and prop.id.id = obj.id "font>
288 + <font color=red>"and prop.id.name = 'server' and prop.value='"font> + host + <font color=red>"'"font>;
289 try {
290 List list = context.getWiki().getStore().searchDocumentsNames(hql, context);
291 if ((list == null) || (list.size() == 0))
292 return null;
293 String docname = (String) list.get(0);
294 if (!docname.startsWith(<font color=red>"XWiki.XWikiServer"font>))
295 return null;
296 wikiserver = docname.substring(<font color=red>"XWiki.XWikiServer"font>.length()).toLowerCase();
297 virtualWikiMap.put(host, wikiserver);
298 return wikiserver;
299 } catch (XWikiException e) {
300 return null;
301 }
302 }
303
304 public static String getServerWikiPage(String servername) {
305 return <font color=red>"XWiki.XWikiServer"font>
306 + servername.substring(0, 1).toUpperCase()
307 + servername.substring(1);
308 }
309
310 public XWiki(XWikiConfig config, XWikiContext context) throws XWikiException {
311 this(config, context, null, false);
312 }
313
314 public XWiki(XWikiConfig config, XWikiContext context, XWikiEngineContext engine_context, boolean noupdate) throws XWikiException {
315 initXWiki(config, context, engine_context, noupdate);
316 }
317
318 /**
319 * @deprecated use {@link #XWiki(XWikiConfig, XWikiContext)} instead
320 */
321 public XWiki(String xwikicfgpath, XWikiContext context) throws XWikiException {
322 this(xwikicfgpath, context, null, false);
323 }
324
325 /**
326 * @deprecated use {@link #XWiki(XWikiConfig, XWikiContext, XWikiEngineContext, boolean)} instead
327 */
328 public XWiki(String xwikicfgpath, XWikiContext context, XWikiEngineContext engine_context, boolean noupdate) throws XWikiException {
329 try {
330 initXWiki(new XWikiConfig(new FileInputStream(xwikicfgpath)), context, engine_context, noupdate);
331 } catch (FileNotFoundException e) {
332 Object[] args = {xwikicfgpath};
333 throw new XWikiException(XWikiException.MODULE_XWIKI_CONFIG,
334 XWikiException.ERROR_XWIKI_CONFIG_FILENOTFOUND,
335 <font color=red>"Configuration file {0} not found"font>, e, args);
336 }
337 }
338
339 /**
340 * @deprecated use {@link #XWiki(XWikiConfig, XWikiContext, XWikiEngineContext, boolean)} instead
341 */
342 public XWiki(InputStream is, XWikiContext context, XWikiEngineContext engine_context) throws XWikiException {
343 initXWiki(new XWikiConfig(is), context, engine_context, true);
344 }
345
346 public void initXWiki(XWikiConfig config, XWikiContext context, XWikiEngineContext engine_context, boolean noupdate) throws XWikiException {
347 setEngineContext(engine_context);
348 context.setWiki(this);
349
350 // Create the notification manager
351 setNotificationManager(new XWikiNotificationManager());
352
353 // Prepare the store
354 XWikiStoreInterface basestore;
355 setConfig(config);
356 String storeclass = Param(<font color=red>"xwiki.store.class"font>, <font color=red>"com.xpn.xwiki.store.XWikiRCSFileStore"font>);
357 try {
358 Class[] classes = new Class[]{this.getClass(), context.getClass()};
359 Object[] args = new Object[]{this, context};
360 basestore = (XWikiStoreInterface) Class.forName(storeclass).getConstructor(classes).newInstance(args);
361 } catch (InvocationTargetException e) {
362 Object[] args = {storeclass};
363 throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
364 XWikiException.ERROR_XWIKI_STORE_CLASSINVOCATIONERROR,
365 <font color=red>"Cannot load store class {0}"font>, e.getTargetException(), args);
366 } catch (Exception e) {
367 Object[] args = {storeclass};
368 throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
369 XWikiException.ERROR_XWIKI_STORE_CLASSINVOCATIONERROR,
370 <font color=red>"Cannot load store class {0}"font>, e, args);
371 }
372
373 // Check if we need to use the cache store..
374 boolean nocache = <font color=red>"0"font>.equals(Param(<font color=red>"xwiki.store.cache"font>, <font color=red>"1"font>));
375 if (!nocache) {
376 XWikiCacheStoreInterface cachestore = new XWikiCacheStore(basestore, context);
377 try {
378 String capacity = Param(<font color=red>"xwiki.store.cache.capacity"font>);
379 if (capacity != null)
380 cachestore.setCacheCapacity(Integer.parseInt(capacity));
381 } catch (Exception e) {
382 }
383 try {
384 String capacity = Param(<font color=red>"xwiki.store.cache.pageexistcapacity"font>);
385 if (capacity != null)
386 cachestore.setPageExistCacheCapacity(Integer.parseInt(capacity));
387 } catch (Exception e) {
388 }
389 setStore(cachestore);
390 } else
391 setStore(basestore);
392
393 // Prepare the Rendering Engine
394 setRenderingEngine(new XWikiRenderingEngine(this, context));
395
396 // Prepare the Plugin Engine
397 preparePlugins(context);
398
399 // Add a notification rule if the preference property plugin is modified
400 getNotificationManager().addNamedRule(<font color=red>"XWiki.XWikiPreferences"font>,
401 new PropertyChangedRule(this, <font color=red>"XWiki.XWikiPreferences"font>, <font color=red>"plugin"font>));
402
403 // Make sure these classes exists
404 if (noupdate) {
405 getPrefsClass(context);
406 getUserClass(context);
407 getGroupClass(context);
408 getRightsClass(context);
409 getCommentsClass(context);
410 getSkinClass(context);
411 getGlobalRightsClass(context);
412 getStatsService(context);
413 }
414
415 String ro = Param (<font color=red>"xwiki.readonly"font>, <font color=red>"no"font>);
416
417 isReadOnly = (<font color=red>"yes"font>.equalsIgnoreCase(ro) || <font color=red>"true"font>.equalsIgnoreCase(ro) || <font color=red>"1"font>.equalsIgnoreCase(ro));
418
419 }
420
421 private void preparePlugins(XWikiContext context) {
422 setPluginManager(new XWikiPluginManager(getXWikiPreference(<font color=red>"plugins"font>, context), context));
423 String plugins = Param(<font color=red>"xwiki.plugins"font>, "");
424 if (!plugins.equals("")) {
425 getPluginManager().addPlugins(StringUtils.split(plugins, <font color=red>" ,"font>), context);
426 }
427 }
428
429 public String getVersion() {
430 if (version == null) {
431 version = Param(<font color=red>"xwiki.version"font>, "");
432 String bnb = null;
433 try {
434 InputStream is = getResourceAsStream(<font color=red>"/WEB-INF/version.properties"font>);
435 XWikiConfig vprop = new XWikiConfig(is);
436 bnb = vprop.getProperty(<font color=red>"build.number"font>);
437 } catch (Exception e) {
438 }
439 if (bnb != null)
440 version = version + <font color=red>"."font> + bnb;
441 }
442 return version;
443 }
444
445 public URL getResource(String s) throws MalformedURLException {
446 return getEngineContext().getResource(s);
447 }
448
449 public InputStream getResourceAsStream(String s) throws MalformedURLException {
450 return getEngineContext().getResourceAsStream(s);
451 }
452
453 public String getResourceContent(String name) throws IOException {
454 InputStream is = null;
455 if (getEngineContext() != null) {
456
457 try {
458 is = getResourceAsStream(name);
459 } catch (Exception e) {
460 }
461 }
462
463 if (is == null)
464 return Util.getFileContent(new File(name));
465
466 return Util.getFileContent(new InputStreamReader(is));
467 }
468
469 public boolean resourceExists(String name) {
470 InputStream ris = null;
471 if (getEngineContext() != null) {
472 try {
473 ris = getResourceAsStream(name);
474 if (ris != null)
475 return true;
476 } catch (IOException e) {
477 }
478 }
479 File file = new File(name);
480 return file.exists();
481 }
482
483 public XWikiConfig getConfig() {
484 return config;
485 }
486
487 public String getRealPath(String path) {
488 return getEngineContext().getRealPath(path);
489 }
490
491 public String Param(String key) {
492 return getConfig().getProperty(key);
493 }
494
495 public String ParamAsRealPath(String key) {
496 String param = Param(key);
497 try {
498
499 return getRealPath(param);
500 } catch (Exception e) {
501 return param;
502 }
503 }
504
505 public String ParamAsRealPath(String key, XWikiContext context) {
506 return ParamAsRealPath(key);
507 }
508
509 public String ParamAsRealPathVerified(String param) {
510 String path;
511 File fpath;
512
513 path = Param(param);
514 if (path == null)
515 return null;
516
517 fpath = new File(path);
518 if (fpath.exists()) {
519 return path;
520 }
521
522 path = getRealPath(path);
523 if (path == null)
524 return null;
525
526 fpath = new File(path);
527 if (fpath.exists()) {
528 return path;
529 } else {
530 }
531 return null;
532 }
533
534 public String Param(String key, String default_value) {
535 return getConfig().getProperty(key, default_value);
536 }
537
538 public long ParamAsLong(String key) {
539 String param = getConfig().getProperty(key);
540 return Long.parseLong(param);
541 }
542
543 public long ParamAsLong(String key, long default_value) {
544 try {
545 return ParamAsLong(key);
546 } catch (NumberFormatException e) {
547 return default_value;
548 }
549 }
550
551 public XWikiStoreInterface getStore() {
552 return store;
553 }
554
555 public void saveDocument(XWikiDocument doc, XWikiContext context) throws XWikiException {
556 getStore().saveXWikiDoc(doc, context);
557 }
558
559 public void saveDocument(XWikiDocument doc, XWikiDocument olddoc, XWikiContext context) throws XWikiException {
560 getStore().saveXWikiDoc(doc, context);
561 getNotificationManager().verify(doc, olddoc, XWikiDocChangeNotificationInterface.EVENT_CHANGE, context);
562 }
563
564 private XWikiDocument getDocument(XWikiDocument doc, XWikiContext context) throws XWikiException {
565 return getStore().loadXWikiDoc(doc, context);
566 }
567
568 public XWikiDocument getDocument(XWikiDocument doc, String revision, XWikiContext context) throws XWikiException {
569 XWikiDocument newdoc;
570 try {
571 if ((revision == null) || revision.equals("")) {
572 newdoc = new XWikiDocument(doc.getWeb(), doc.getName());
573 } else if (revision.equals(doc.getVersion())) {
574 newdoc = doc;
575 } else {
576 newdoc = getStore().loadXWikiDoc(doc, revision, context);
577 }
578 } catch (XWikiException e) {
579 if (revision.equals(<font color=red>"1.1"font>) || revision.equals(<font color=red>"1.0"font>))
580 newdoc = new XWikiDocument(doc.getWeb(), doc.getName());
581 else
582 throw e;
583 }
584 return newdoc;
585 }
586
587 public XWikiDocument getDocument(String fullname, XWikiContext context) throws XWikiException {
588 String server = null, database = null;
589 try {
590 XWikiDocument doc = new XWikiDocument();
591 doc.setFullName(fullname, context);
592 server = doc.getDatabase();
593
594 if (server != null) {
595 database = context.getDatabase();
596 context.setDatabase(server);
597 }
598
599 doc = getDocument(doc, context);
600 return doc;
601 } finally {
602 if ((server != null) && (database != null)) {
603 context.setDatabase(database);
604 }
605 }
606 }
607
608 public XWikiDocument getDocument(String web, String fullname, XWikiContext context) throws XWikiException {
609 int i1 = fullname.lastIndexOf(<font color=red>"."font>);
610 if (i1 != -1) {
611 String web2 = fullname.substring(0, i1);
612 String name = fullname.substring(i1 + 1);
613 if (name.equals(""))
614 name = <font color=red>"WebHome"font>;
615 return getDocument(web2 + <font color=red>"."font> + name, context);
616 } else {
617 return getDocument(web + <font color=red>"."font> + fullname, context);
618 }
619 }
620
621
622 public XWikiDocument getDocumentFromPath(String path, XWikiContext context) throws XWikiException {
623 String web, name;
624 int i1 = path.indexOf(<font color=red>"/"font>, 1);
625 int i2 = path.indexOf(<font color=red>"/"font>, i1 + 1);
626 int i3 = path.indexOf(<font color=red>"/"font>, i2 + 1);
627 web = path.substring(i1 + 1, i2);
628 if (i3 == -1)
629 name = path.substring(i2 + 1);
630 else
631 name = path.substring(i2 + 1, i3);
632 if (name.equals(""))
633 name = <font color=red>"WebHome"font>;
634
635 web = Utils.decode(web, context);
636 name = Utils.decode(name, context);
637 return getDocument(web + <font color=red>"."font> + name, context);
638 }
639
640 public XWikiRenderingEngine getRenderingEngine() {
641 return renderingEngine;
642 }
643
644 public void setRenderingEngine(XWikiRenderingEngine renderingEngine) {
645 this.renderingEngine = renderingEngine;
646 }
647
648 public MetaClass getMetaclass() {
649 return metaclass;
650 }
651
652 public void setMetaclass(MetaClass metaclass) {
653 this.metaclass = metaclass;
654 }
655
656 public static String getFormEncoded(String content) {
657 Filter filter = new CharacterFilter();
658 filter.removeAttribute(<font color=red>"'"font>);
659 String scontent = filter.process(content);
660 return scontent;
661 }
662
663 public static String getURLEncoded(String content) {
664 try {
665 return URLEncoder.encode(content, <font color=red>"UTF-8"font>);
666 } catch (UnsupportedEncodingException e) {
667 return content;
668 }
669 }
670
671
672 public static String getXMLEncoded(String content) {
673 Filter filter = new CharacterFilter();
674 String scontent = filter.process(content);
675 return scontent;
676 }
677
678 public static String getTextArea(String content, XWikiContext context) {
679 Filter filter = new CharacterFilter();
680 filter.removeAttribute(<font color=red>"'"font>);
681 String scontent = filter.process(content);
682
683 textarea textarea = new textarea();
684 textarea.setFilter(filter);
685
686 int rows = 25;
687 try {
688 rows = context.getWiki().getUserPreferenceAsInt(<font color=red>"editbox_height"font>, context);
689 } catch (Exception e) {
690 }
691 textarea.setRows(rows);
692
693 int cols = 80;
694 try {
695 context.getWiki().getUserPreferenceAsInt(<font color=red>"editbox_width"font>, context);
696 } catch (Exception e) {
697 }
698 textarea.setCols(cols);
699 textarea.setName(<font color=red>"content"font>);
700 textarea.addElement(scontent);
701 return textarea.toString();
702 }
703
704 public String getHTMLArea(String content, XWikiContext context) {
705 Filter filter = new CharacterFilter();
706 filter.removeAttribute(<font color=red>"'"font>);
707 String scontent = filter.process(content);
708
709 scontent = context.getUtil().substitute(<font color=red>"s/\\r\\n/<br class=\"htmlarea\"\\/>/g"font>, scontent);
710 textarea textarea = new textarea();
711
712 int rows = 25;
713 try {
714 rows = context.getWiki().getUserPreferenceAsInt(<font color=red>"editbox_height"font>, context);
715 } catch (Exception e) {
716 }
717 textarea.setRows(rows);
718
719 int cols = 80;
720 try {
721 context.getWiki().getUserPreferenceAsInt(<font color=red>"editbox_width"font>, context);
722 } catch (Exception e) {
723 }
724 textarea.setCols(cols);
725 textarea.setFilter(filter);
726 textarea.setName(<font color=red>"content"font>);
727 textarea.setID(<font color=red>"content"font>);
728 textarea.addElement(scontent);
729 return textarea.toString();
730 }
731
732 public List getClassList(XWikiContext context) throws XWikiException {
733 return getStore().getClassList(context);
734 }
735 /*
736 public String[] getClassList() throws XWikiException {
737 List list = store.getClassList();
738 String[] array = new String[list.size()];
739 for (int i=0;i<list.size();i++)
740 array[i] = (String)list.get(i);
741 return array;
742 }
743 */
744
745 public List search(String sql, XWikiContext context) throws XWikiException {
746 return getStore().search(sql, 0, 0, context);
747 }
748
749 public List search(String sql, int nb, int start, XWikiContext context) throws XWikiException {
750 return getStore().search(sql, nb, start, context);
751 }
752
753 public List search(String sql, Object[][] whereParams, XWikiContext context) throws XWikiException {
754 return getStore().search(sql, 0, 0, whereParams, context);
755 }
756
757 public List search(String sql, int nb, int start, Object[][] whereParams, XWikiContext context) throws XWikiException {
758 return getStore().search(sql, nb, start, whereParams, context);
759 }
760
761 public boolean isTest() {
762 return test;
763 }
764
765 public void setTest(boolean test) {
766 this.test = test;
767 }
768
769 public String parseContent(String content, XWikiContext context) {
770 if ((content != null) && (!content.equals("")))
771 // Let's use this template
772 return XWikiVelocityRenderer.evaluate(content, context.getDoc().getFullName(), (VelocityContext) context.get(<font color=red>"vcontext"font>), context);
773 else
774 return "";
775 }
776
777 public String parseTemplate(String template, XWikiContext context) {
778 try {
779 String skin = getSkin(context);
780 String result = parseTemplate(template, skin, context);
781 if (result != null)
782 return result;
783
784 // If we could not find the template in the skin
785 // let's try in the base skin (as long as the base skin is not the same as the skin)
786 String baseskin = getBaseSkin(context);
787 if (!skin.equals(baseskin)) {
788 result = parseTemplate(template, baseskin, context);
789 if (result != null)
790 return result;
791 }
792
793 // If we still could not find the template in the skin or in the base skin
794 // let's try in the base skin (as long as the default base skin is not the same as the skin or the base skin
795 String defaultbaseskin = getDefaultBaseSkin(context);
796 if ((!baseskin.equals(defaultbaseskin)) && (!skin.equals(defaultbaseskin))) {
797 result = parseTemplate(template, defaultbaseskin, context);
798 if (result != null)
799 return result;
800 }
801 } catch (Exception e) {
802 }
803
804 try {
805 String content = getResourceContent(<font color=red>"/templates/"font> + template);
806 return XWikiVelocityRenderer.evaluate(content, "<font color=red>", (VelocityContext) context.get("font>vcontext"), context);
807 } catch (Exception e) {
808 return "";
809 }
810 }
811
812 public String parseTemplate(String template, String skin, XWikiContext context) {
813 try {
814 String path = <font color=red>"/skins/"font> + skin + <font color=red>"/"font> + template;
815 String content = getResourceContent(path);
816 return XWikiVelocityRenderer.evaluate(content, "<font color=red>", (VelocityContext) context.get("font>vcontext"), context);
817 } catch (Exception e) {
818 }
819
820 try {
821 XWikiDocument doc = getDocument(skin, context);
822 if (!doc.isNew()) {
823 BaseObject object = doc.getObject(<font color=red>"XWiki.XWikiSkins"font>, 0);
824 if (object != null) {
825 String content = object.getStringValue(template);
826 if ((content != null) && (!content.equals(""))) {
827 // Let's use this template
828 return XWikiVelocityRenderer.evaluate(content, "<font color=red>", (VelocityContext) context.get("font>vcontext"), context);
829 }
830 }
831 }
832 } catch (Exception e) {
833 }
834
835 return null;
836 }
837
838
839 /**
840 * Designed to include dynamic content, such as Servlets or JSPs, inside Velocity
841 * templates; works by creating a RequestDispatcher, buffering the output,
842 * then returning it as a string.
843 *
844 * @author LBlaze
845 */
846 public String invokeServletAndReturnAsString(String url, XWikiContext xwikiContext) {
847
848 HttpServletRequest servletRequest = xwikiContext.getRequest();
849 HttpServletResponse servletResponse = xwikiContext.getResponse();
850
851 try
852 {
853 return IncludeServletAsString.invokeServletAndReturnAsString(
854 url,
855 servletRequest,
856 servletResponse);
857 }
858 catch(Exception e)
859 {
860 log.warn(<font color=red>"Exception including url: "font>+url, e);
861 return <font color=red>"Exception including \""font>+url+<font color=red>"\", see logs for details."font>;
862 }
863
864 }
865
866
867 public String getSkinFile(String filename, XWikiContext context) {
868 XWikiURLFactory urlf = context.getURLFactory();
869
870 try {
871 String skin = getSkin(context);
872 String result = getSkinFile(filename, skin, context);
873 if (result != null)
874 return result;
875 String baseskin = getBaseSkin(context);
876 if (!skin.equals(baseskin)) {
877 result = getSkinFile(filename, baseskin, context);
878 if (result != null)
879 return result;
880 }
881 URL url = urlf.createSkinURL(filename, <font color=red>"default"font>, context);
882 return urlf.getURL(url, context);
883 } catch (Exception e) {
884 }
885
886 return <font color=red>"../../../skins/default/"font> + filename;
887 }
888
889 public String getSkinFile(String filename, String skin, XWikiContext context) {
890 XWikiURLFactory urlf = context.getURLFactory();
891 try {
892 String path = <font color=red>"skins/"font> + skin + <font color=red>"/"font> + filename;
893 if (resourceExists(path)) {
894 URL url = urlf.createSkinURL(filename, skin, context);
895 return urlf.getURL(url, context);
896 }
897
898 } catch (Exception e) {
899 }
900
901 try {
902 XWikiDocument doc = getDocument(skin, context);
903 if (!doc.isNew()) {
904 BaseObject object = doc.getObject(<font color=red>"XWiki.XWikiSkins"font>, 0);
905 if (object != null) {
906 String content = object.getStringValue(filename);
907 if ((content != null) && (!content.equals(""))) {
908 URL url = urlf.createSkinURL(filename, doc.getWeb(), doc.getName(), context);
909 return urlf.getURL(url, context);
910
911 }
912 }
913
914 // Read XWikiAttachment
915 XWikiAttachment attachment = null;
916 List list = doc.getAttachmentList();
917 String shortname = filename.substring(0, filename.indexOf(<font color=red>"."font>) + 1);
918 attachment = doc.getAttachment(shortname);
919
920 if (attachment != null) {
921 URL url = urlf.createSkinURL(filename, doc.getWeb(), doc.getName(), context);
922 return urlf.getURL(url, context);
923 }
924 }
925 } catch (Exception e) {
926 }
927
928 return null;
929 }
930
931
932 public String getSkin(XWikiContext context) {
933 String skin = "";
934 try {
935 // Try to get it from context
936 skin = (String) context.get(<font color=red>"skin"font>);
937 if (skin != null)
938 return skin;
939
940 // Try to get it from URL
941 if (context.getRequest() != null) {
942 skin = context.getRequest().getParameter(<font color=red>"skin"font>);
943 }
944
945 if ((skin == null) || (skin.equals(""))) {
946 skin = getWebPreference(<font color=red>"skin"font>, "", context);
947 }
948 if (skin.equals("")) {
949 skin = Param(<font color=red>"xwiki.defaultskin"font>, <font color=red>"default"font>);
950 }
951 } catch (Exception e) {
952 skin = <font color=red>"default"font>;
953 }
954 context.put(<font color=red>"skin"font>, skin);
955 return skin;
956 }
957
958
959 public String getDefaultBaseSkin(XWikiContext context) {
960 String defaultbaseskin = Param(<font color=red>"xwiki.defaultbaseskin"font>, "");
961 if (defaultbaseskin.equals("")) {
962 defaultbaseskin = Param(<font color=red>"xwiki.defaultskin"font>, <font color=red>"default"font>);
963 }
964 return defaultbaseskin;
965 }
966
967 public String getBaseSkin(XWikiContext context) {
968 return getBaseSkin(context, false);
969 }
970
971 public String getBaseSkin(XWikiContext context, boolean fromRenderSkin) {
972 String baseskin = "";
973 try {
974 // Try to get it from context
975 baseskin = (String) context.get(<font color=red>"baseskin"font>);
976 if (baseskin != null)
977 return baseskin;
978 else
979 baseskin = "";
980
981 // Let's get the base skin doc itself
982 if (fromRenderSkin) {
983 baseskin = context.getDoc().getStringValue(<font color=red>"XWiki.XWikiSkins"font>, <font color=red>"baseskin"font>);
984 }
985
986 if (baseskin.equals("")) {
987 // Let's get the base skin from the skin itself
988 String skin = getSkin(context);
989 skin = getSkin(context);
990 XWikiDocument doc = getDocument(skin, context);
991 baseskin = doc.getStringValue(<font color=red>"XWiki.XWikiSkins"font>, <font color=red>"baseskin"font>);
992 }
993 if (baseskin.equals("")) {
994 baseskin = getDefaultBaseSkin(context);
995 }
996 } catch (Exception e) {
997 baseskin = <font color=red>"default"font>;
998 }
999 context.put(<font color=red>"baseskin"font>, baseskin);
1000 return baseskin;
1001 }
1002
1003 public String getWebCopyright(XWikiContext context) {
1004 try {
1005 String result = getXWikiPreference(<font color=red>"webcopyright"font>, "", context);
1006 if (!result.trim().equals(""))
1007 return result;
1008 } catch (Exception e) {
1009 }
1010 return <font color=red>"Copyright 2004 (c) Contributing Authors"font>;
1011 }
1012
1013 public String getXWikiPreference(String prefname, XWikiContext context) {
1014 return getXWikiPreference(prefname, "", context);
1015 }
1016
1017 public String getXWikiPreference(String prefname, String default_value, XWikiContext context) {
1018 try {
1019 XWikiDocument doc = getDocument(<font color=red>"XWiki.XWikiPreferences"font>, context);
1020 // First we try to get a translated preference object
1021 BaseObject object = doc.getObject(<font color=red>"XWiki.XWikiPreferences"font>, <font color=red>"language"font>, context.getLanguage(), true);
1022 String result = "";
1023
1024 try {
1025 result = object.getStringValue(prefname);
1026 } catch (Exception e) {
1027 }
1028 // If empty we take it from the default pref object
1029 if (result.equals(""))
1030 result = doc.getxWikiObject().getStringValue(prefname);
1031
1032 if (!result.equals(""))
1033 return result;
1034 } catch (Exception e) {
1035 }
1036 return default_value;
1037 }
1038
1039 public String getWebPreference(String prefname, XWikiContext context) {
1040 return getWebPreference(prefname, "", context);
1041 }
1042
1043 public String getWebPreference(String prefname, String default_value, XWikiContext contex