001: /**
002: * LibreSource
003: * Copyright (C) 2004-2008 Artenum SARL / INRIA
004: * http://www.libresource.org - contact@artenum.com
005: *
006: * This file is part of the LibreSource software,
007: * which can be used and distributed under license conditions.
008: * The license conditions are provided in the LICENSE.TXT file
009: * at the root path of the packaging that enclose this file.
010: * More information can be found at
011: * - http://dev.libresource.org/home/license
012: *
013: * Initial authors :
014: *
015: * Guillaume Bort / INRIA
016: * Francois Charoy / Universite Nancy 2
017: * Julien Forest / Artenum
018: * Claude Godart / Universite Henry Poincare
019: * Florent Jouille / INRIA
020: * Sebastien Jourdain / INRIA / Artenum
021: * Yves Lerumeur / Artenum
022: * Pascal Molli / Universite Henry Poincare
023: * Gerald Oster / INRIA
024: * Mariarosa Penzi / Artenum
025: * Gerard Sookahet / Artenum
026: * Raphael Tani / INRIA
027: *
028: * Contributors :
029: *
030: * Stephane Bagnier / Artenum
031: * Amadou Dia / Artenum-IUP Blois
032: * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
033: */package org.libresource.web.config;
034:
035: import org.jaxen.XPath;
036:
037: import org.jaxen.dom.DOMXPath;
038:
039: import org.libresource.Libresource;
040: import org.libresource.LibresourceResourceValue;
041:
042: import org.libresource.core.CoreConstants;
043: import org.libresource.core.interfaces.LibresourceCoreService;
044:
045: import org.libresource.kernel.KernelConstants;
046: import org.libresource.kernel.interfaces.KernelService;
047:
048: import org.libresource.membership.MembershipConstants;
049: import org.libresource.membership.ejb.model.ProfileResourceValue;
050: import org.libresource.membership.interfaces.MembershipService;
051:
052: import org.libresource.web.Controller;
053: import org.libresource.web.NoControllerFound;
054: import org.libresource.web.Skin;
055: import org.libresource.web.Tab;
056:
057: import org.w3c.dom.Attr;
058: import org.w3c.dom.Document;
059: import org.w3c.dom.Element;
060:
061: import java.io.File;
062: import java.io.FileInputStream;
063: import java.io.InputStream;
064:
065: import java.net.URI;
066:
067: import java.util.ArrayList;
068: import java.util.Collection;
069: import java.util.Hashtable;
070: import java.util.Iterator;
071: import java.util.Locale;
072: import java.util.TimeZone;
073: import java.util.Vector;
074:
075: import javax.servlet.ServletContext;
076:
077: import javax.xml.parsers.DocumentBuilderFactory;
078:
079: public class Config {
080: private static Config instance;
081: private Document document = null;
082: private ServletContext servletContext;
083: private KernelService kernelService;
084: private MembershipService membershipService;
085: private LibresourceCoreService libresourceCoreService;
086: private Hashtable controllers = new Hashtable();
087: private Hashtable types = new Hashtable();
088: private Hashtable names = new Hashtable();
089: private Vector skins;
090: private Hashtable skinsWithKey;
091: private Vector langs;
092: private Hashtable langsWithKey;
093: private Vector units;
094: private Vector additionalTab;
095:
096: // resource macro cycle detection
097: private String wikiChain;
098:
099: private Config(ServletContext context) throws Exception {
100: this .servletContext = context;
101:
102: if (context != null) {
103: String specificConf = Libresource
104: .getLibresourceConfiguration("libresource.web.conf");
105:
106: if ((specificConf == null)
107: || (specificConf.trim().length() == 0)
108: || !new File(specificConf).exists()) {
109: // Standard mode no custom config
110: InputStream is = context
111: .getResourceAsStream("/WEB-INF/libresource-web.xml");
112: document = DocumentBuilderFactory.newInstance()
113: .newDocumentBuilder().parse(is);
114: is.close();
115: } else {
116: // Custom config
117: InputStream is = new FileInputStream(specificConf);
118: document = DocumentBuilderFactory.newInstance()
119: .newDocumentBuilder().parse(is);
120: is.close();
121: }
122: }
123:
124: kernelService = (KernelService) Libresource
125: .getService(KernelConstants.SERVICE);
126: membershipService = (MembershipService) Libresource
127: .getService(MembershipConstants.SERVICE);
128: libresourceCoreService = (LibresourceCoreService) Libresource
129: .getService(CoreConstants.SERVICE);
130: }
131:
132: public synchronized static Config getInstance(ServletContext context)
133: throws Exception {
134: if (instance == null) {
135: instance = new Config(context);
136: }
137:
138: return instance;
139: }
140:
141: public Controller getController(LibresourceResourceValue resource,
142: String action) throws Exception {
143: String service = "*";
144: String type = "*";
145:
146: if ((resource != null) && !resource.getIsEmpty()) {
147: service = resource.getLibresourceResourceIdentifier()
148: .getService();
149: type = resource.getLibresourceResourceIdentifier()
150: .getResourceType();
151: }
152:
153: if (controllers.get(service + "/" + type + "/" + action) != null) {
154: return (Controller) controllers.get(service + "/" + type
155: + "/" + action);
156: }
157:
158: XPath xpath = new DOMXPath("//resource[@type='" + type
159: + "'][@service='" + service + "']/action[@name='"
160: + action + "']/@controller");
161: ArrayList al = (ArrayList) xpath.evaluate(document);
162: String className = null;
163:
164: if (al.size() > 0) {
165: className = ((Attr) al.get(0)).getNodeValue();
166: } else {
167: xpath = new DOMXPath(
168: "//resource[@type='*'][@service='*']/action[@name='"
169: + action + "']/@controller");
170: al = (ArrayList) xpath.evaluate(document);
171:
172: if (al.size() > 0) {
173: className = ((Attr) (al).get(0)).getNodeValue();
174: }
175: }
176:
177: if (className == null) {
178: throw new NoControllerFound(
179: "No controller found for action " + action
180: + " with resource " + resource);
181: }
182:
183: Controller c = (Controller) Class.forName(className)
184: .newInstance();
185: controllers.put(service + "/" + type + "/" + action, c);
186:
187: return c;
188: }
189:
190: public String getResourceType(LibresourceResourceValue resource)
191: throws Exception {
192: String service = resource.getLibresourceResourceIdentifier()
193: .getService();
194: String type = resource.getLibresourceResourceIdentifier()
195: .getResourceType();
196:
197: if (types.get(service + "/" + type) != null) {
198: return (String) types.get(service + "/" + type);
199: }
200:
201: XPath xpath = new DOMXPath("//resource[@type='" + type
202: + "'][@service='" + service + "']/@key");
203: ArrayList al = (ArrayList) xpath.evaluate(document);
204: String className = null;
205:
206: if (al.size() > 0) {
207: String r = ((Attr) al.get(0)).getNodeValue();
208: types.put(service + "/" + type, r);
209:
210: return r;
211: }
212:
213: types.put(service + "/" + type, "Generic");
214:
215: return "Generic";
216: }
217:
218: public String getResourceTypeName(LibresourceResourceValue resource)
219: throws Exception {
220: String service = resource.getLibresourceResourceIdentifier()
221: .getService();
222: String type = resource.getLibresourceResourceIdentifier()
223: .getResourceType();
224:
225: if (names.get(service + "/" + type) != null) {
226: return (String) names.get(service + "/" + type);
227: }
228:
229: XPath xpath = new DOMXPath("//resource[@type='" + type
230: + "'][@service='" + service + "']/@name");
231: ArrayList al = (ArrayList) xpath.evaluate(document);
232: String className = null;
233:
234: if (al.size() > 0) {
235: String r = ((Attr) al.get(0)).getNodeValue();
236: names.put(service + "/" + type, r);
237:
238: return r;
239: }
240:
241: names.put(service + "/" + type, "Generic");
242:
243: return "Generic";
244: }
245:
246: public String getResourceTypeName(String key) throws Exception {
247: XPath xpath = new DOMXPath("//resource[@key='" + key
248: + "']/@name");
249: ArrayList al = (ArrayList) xpath.evaluate(document);
250: String className = null;
251:
252: if (al.size() > 0) {
253: String r = ((Attr) al.get(0)).getNodeValue();
254:
255: return r;
256: }
257:
258: return null;
259: }
260:
261: public Collection listResourceTypeForCreation() throws Exception {
262: XPath xpath = new DOMXPath(
263: "//resource[action/@name='create']/@key");
264: ArrayList al = (ArrayList) xpath.evaluate(document);
265: Vector result = new Vector();
266:
267: for (Iterator i = al.iterator(); i.hasNext();) {
268: String key = ((Attr) i.next()).getNodeValue();
269: result.add(key);
270: }
271:
272: return result;
273: }
274:
275: public Collection listResourceTypeForSearchFilter()
276: throws Exception {
277: Collection result = listResourceTypeForCreation();
278: result.add("Profile");
279:
280: return result;
281: }
282:
283: public Controller getCreateController(String type) throws Exception {
284: XPath xpath = new DOMXPath("//resource[@key='" + type
285: + "']/action[@name='create']/@controller");
286: ArrayList al = (ArrayList) xpath.evaluate(document);
287: String className = null;
288:
289: if (al.size() > 0) {
290: className = ((Attr) al.get(0)).getNodeValue();
291: }
292:
293: if (className == null) {
294: throw new Exception("No controller found");
295: }
296:
297: return (Controller) Class.forName(className).newInstance();
298: }
299:
300: public Vector listSkins() throws Exception {
301: if (skins == null) {
302: skins = new Vector();
303: skinsWithKey = new Hashtable();
304:
305: XPath xpath = new DOMXPath("//skin");
306: ArrayList al = (ArrayList) xpath.evaluate(document);
307:
308: for (Iterator i = al.iterator(); i.hasNext();) {
309: Element element = (Element) i.next();
310: Skin skin = new Skin(element.getAttribute("key"),
311: element.getAttribute("name"), element
312: .getAttribute("css"), element
313: .getAttribute("platforms"));
314: skins.add(skin);
315: skinsWithKey.put(skin.getKey(), skin);
316: }
317: }
318:
319: return skins;
320: }
321:
322: public Skin getSkin(String key) throws Exception {
323: listSkins();
324:
325: return (Skin) skinsWithKey.get(key);
326: }
327:
328: public Vector listLangs() throws Exception {
329: if (langs == null) {
330: langs = new Vector();
331: langsWithKey = new Hashtable();
332:
333: XPath xpath = new DOMXPath("//lang");
334: ArrayList al = (ArrayList) xpath.evaluate(document);
335:
336: for (Iterator i = al.iterator(); i.hasNext();) {
337: Element element = (Element) i.next();
338: String[] lang = new String[2];
339: lang[0] = element.getAttribute("key");
340: lang[1] = element.getAttribute("name");
341: langs.add(lang);
342: langsWithKey.put(element.getAttribute("key"), element
343: .getAttribute("name"));
344: }
345: }
346:
347: return langs;
348: }
349:
350: public String getLang(String key) throws Exception {
351: listLangs();
352:
353: return (String) langsWithKey.get(key);
354: }
355:
356: public Locale getLocale() throws Exception {
357: String locale = null;
358: ProfileResourceValue profile = null;
359:
360: try {
361: profile = membershipService.getProfile();
362: } catch (Exception e) {
363: }
364:
365: if (profile != null) {
366: locale = (String) profile.getInfos().get(
367: "libresource-web.lang");
368: }
369:
370: if ((locale == null) || (locale.trim().length() == 0)) {
371: locale = "en";
372: }
373:
374: return new Locale(locale);
375: }
376:
377: public String getTimeZone() throws Exception {
378: String timeZone = null;
379: ProfileResourceValue profile = null;
380:
381: try {
382: profile = membershipService.getProfile();
383: } catch (Exception e) {
384: }
385:
386: if (profile != null) {
387: timeZone = (String) profile.getInfos().get(
388: "libresource-web.time-zone");
389: }
390:
391: if ((timeZone == null) || (timeZone.trim().length() == 0)) {
392: timeZone = TimeZone.getDefault().getID();
393: }
394:
395: return timeZone;
396: }
397:
398: public Vector listUnits() throws Exception {
399: if (units == null) {
400: units = new Vector();
401:
402: String[] octet = new String[2];
403: octet[0] = "Octet";
404: octet[1] = "o";
405: units.add(octet);
406:
407: String[] bytes = new String[2];
408: bytes[0] = "Byte";
409: bytes[1] = "B";
410: units.add(bytes);
411: }
412:
413: return units;
414: }
415:
416: public File getLsWebBuffer() throws Exception {
417: return new File(libresourceCoreService
418: .getDistributedFileSystem());
419: }
420:
421: public boolean canRegisterUser() throws Exception {
422: if (kernelService.isSuperUser()) {
423: return true;
424: }
425:
426: // get property
427: String registerProperty = kernelService.getProperty(
428: kernelService.getServerConfigURI(), "register-users");
429:
430: if ((registerProperty == null)
431: || (registerProperty.trim().length() == 0)) {
432: return false;
433: }
434:
435: URI allowedUsers = new URI(registerProperty);
436:
437: if (allowedUsers.getPath().equals(
438: new URI(membershipService.getUsersRootURI() + "/"
439: + membershipService.getUnauthentifiedUserId())
440: .getPath())) {
441: return true;
442: }
443:
444: try {
445: membershipService.getGroup(allowedUsers);
446:
447: if (membershipService.isUserInGroup(allowedUsers,
448: kernelService.getConnectedResource())) {
449: return true;
450: }
451: } catch (Exception e) {
452: return false;
453: }
454:
455: return false;
456: }
457:
458: public String getWkiHelp() throws Exception {
459: StringBuffer wikiHelp = new StringBuffer();
460: wikiHelp.append("1 Wiki Syntax\n\n");
461: wikiHelp.append("1.1 Simple text filters\n\n");
462: wikiHelp.append("{table}\n");
463: wikiHelp.append("Mnemonic|Rendering|Comment\n");
464: wikiHelp
465: .append("1 Title| |a style 1 heading (major heading)\n");
466: wikiHelp
467: .append("1.1 Title| |a style 1.1 heading (minor heading)\n");
468: wikiHelp
469: .append("- text| |a list item (with -), several lines create a single list\n");
470: wikiHelp.append("* text| |a list item (with *)\n");
471: wikiHelp.append("1. text| |an enumerated list\n");
472: wikiHelp.append("\\_\\_bold\\_\\_|__bold__|simple bold text\n");
473: wikiHelp
474: .append("\\~\\~italics\\~\\~|~~italics~~|simple italic text\n");
475: wikiHelp
476: .append("\\-\\-strike\\-\\-|--strike--|strike through text\n");
477: wikiHelp.append("(empty line)| |produces a new paragraph\n");
478: wikiHelp
479: .append("\\\\\\\\\\\\\\\\| |creates a line break, please use sparingly!\n");
480: wikiHelp
481: .append("\\[/documentation\\] or \\[../documentation\\] or \\[/documentation\\|Doc\\]|Like a standard link|internal link to another document\n");
482: wikiHelp
483: .append("http\\://www.libresource.org/|http://www.libresource.org/|creates a link to an external resource, special characters that come after the URL and are not part of it must be separated with a space.\n");
484: wikiHelp
485: .append("\\\\\\\\X|X|escape special character X (i.e. \\{)\n");
486: wikiHelp.append("\\-\\-\\-\\-| |creates a horizontal rule\n");
487: wikiHelp.append("{table}\n\n");
488:
489: wikiHelp.append("1.1 Macros List\n\n");
490: wikiHelp
491: .append("__Macro syntaxe:__ \\{macroName:key1=param1|key2=param2|...\\}\n\n");
492: wikiHelp.append("{list-of-macros}\n\n");
493:
494: wikiHelp.append("1.1 Smiley\n");
495: wikiHelp.append("{table}\n");
496: wikiHelp
497: .append(":-) | :-( | ;-) | :-P | :-D | :-[ | :-/ | :-* | >:o | 8-) | :-$ | :-! | :'( | :-X =-O \n");
498: wikiHelp
499: .append("\\:\\-) | \\:-( | \\;\\-) | \\:-P | \\:-D | \\:-[ | \\:-/ | \\:-* | \\>\\:o | \\8\\-) | \\:-$ | \\:-! | \\:'( | \\:-X \\=-O\n");
500: wikiHelp.append("{table}\n\n");
501:
502: return wikiHelp.toString();
503: }
504:
505: public ServletContext getServletContext() {
506: return servletContext;
507: }
508:
509: // resource macro cycle detection
510: public synchronized String getWikiChain() {
511: return wikiChain;
512: }
513:
514: public synchronized void setWikiChain(String wikiChain) {
515: this .wikiChain = wikiChain;
516: }
517:
518: // Custom web add-on
519: public Collection getAdditionalTab() throws Exception {
520: if (additionalTab == null) {
521: additionalTab = new Vector();
522:
523: XPath xpath = new DOMXPath("//tab");
524: ArrayList al = (ArrayList) xpath.evaluate(document);
525:
526: for (Iterator i = al.iterator(); i.hasNext();) {
527: Element element = (Element) i.next();
528: Tab tab = new Tab(element.getAttribute("path"), element
529: .getAttribute("label"));
530: additionalTab.add(tab);
531: }
532: }
533:
534: return additionalTab;
535: }
536: }
|