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;
034:
035: import org.libresource.kernel.KernelConstants;
036: import org.libresource.kernel.interfaces.KernelService;
037:
038: import org.libresource.search.LibresourceIndexableContent;
039: import org.libresource.search.LibresourceResourceDocument;
040: import org.libresource.search.LibresourceSearch;
041:
042: import java.lang.reflect.Method;
043:
044: import java.net.URI;
045:
046: import java.security.Principal;
047: import java.security.acl.Group;
048:
049: import java.text.ParseException;
050: import java.text.SimpleDateFormat;
051:
052: import java.util.Date;
053: import java.util.Hashtable;
054: import java.util.Properties;
055: import java.util.Vector;
056:
057: import javax.jms.Message;
058: import javax.jms.Topic;
059: import javax.jms.TopicConnection;
060: import javax.jms.TopicConnectionFactory;
061: import javax.jms.TopicPublisher;
062: import javax.jms.TopicSession;
063:
064: import javax.mail.Session;
065:
066: import javax.naming.Context;
067: import javax.naming.InitialContext;
068: import javax.naming.NameClassPair;
069: import javax.naming.NamingEnumeration;
070: import javax.naming.NamingException;
071:
072: import javax.rmi.PortableRemoteObject;
073:
074: import javax.security.auth.callback.CallbackHandler;
075:
076: import javax.sql.DataSource;
077:
078: /**
079: * LibreSource
080: *
081: * @author <a href="mailto:bort@loria.fr">Guillaume Bort</a> - <a
082: * href="http://www.inria.fr">INRIA Lorraine</a>
083: */
084: public class Libresource {
085: public final static String ID_REGEXP = "[^A-Za-z0-9-_]+";
086: private final static String SERVER_NAME = "libresource.server";
087: private final static String SERVER_NAME_JONAS = "jonas";
088: private final static String SERVER_NAME_JBOSS = "jboss";
089: static private Context jndi;
090: static private Hashtable homesCache = new Hashtable();
091: static private Hashtable proxy = new Hashtable();
092: static private Hashtable references = new Hashtable();
093: private static Topic eventsTopic;
094: private static Topic indexationTopic;
095: private static TopicConnectionFactory connectionFactory;
096: private static DataSource dataSource;
097: private static SimpleDateFormat dateFormater;
098:
099: //
100: private static Properties lsConfig;
101:
102: static private Context getJndiContext() throws NamingException {
103: if (jndi == null) {
104: jndi = new InitialContext();
105: }
106:
107: return jndi;
108: }
109:
110: static public LibresourceResourceLocal findResource(
111: LibresourceResourceIdentifier resourceIdentifier)
112: throws LibresourceException {
113: try {
114: if (references.get(resourceIdentifier.serialize()) != null) {
115: return (LibresourceResourceLocal) references
116: .get(resourceIdentifier.serialize());
117: }
118:
119: String jndiName = LibresourceNamingConvention
120: .getJndiNameForResource(resourceIdentifier
121: .getService(), resourceIdentifier
122: .getResourceType());
123:
124: if (homesCache.get(jndiName) == null) {
125: LibresourceResourceLocalHome resourceLocalHome = (LibresourceResourceLocalHome) getJndiContext()
126: .lookup(jndiName);
127: homesCache.put(jndiName, resourceLocalHome);
128: }
129:
130: LibresourceResourceLocalHome resourceLocalHome = (LibresourceResourceLocalHome) homesCache
131: .get(jndiName);
132:
133: Class[] types = { Class.forName("java.lang.String") };
134: Object[] params = { resourceIdentifier.getResourceId() };
135: Method method = resourceLocalHome.getClass().getMethod(
136: "findByPrimaryKey", types);
137: LibresourceResourceLocal resourceLocal = (LibresourceResourceLocal) method
138: .invoke(resourceLocalHome, params);
139:
140: references.put(resourceIdentifier.serialize(),
141: resourceLocal);
142:
143: return resourceLocal;
144: } catch (NamingException e) {
145: throw new LibresourceException("Can't find resource "
146: + resourceIdentifier, e);
147: } catch (Exception e) {
148: throw new LibresourceException("Can't find resource "
149: + resourceIdentifier, e);
150: }
151: }
152:
153: static public LibresourceResourceLocal findResource(
154: LibresourceResourceIdentifier resourceIdentifier,
155: Class localInterfaceType) throws LibresourceException {
156: checkType(resourceIdentifier, localInterfaceType);
157:
158: return findResource(resourceIdentifier);
159: }
160:
161: static public String[] listAvailablesPermissions(
162: LibresourceResourceIdentifier resourceIdentifier)
163: throws LibresourceException {
164: try {
165: if (resourceIdentifier == null) {
166: return null;
167: }
168:
169: return getService(resourceIdentifier.getService())
170: .listAvailablesPermissions(resourceIdentifier);
171: } catch (Exception e) {
172: throw new LibresourceException(e);
173: }
174: }
175:
176: static public String[] listAvailablesEvents(
177: LibresourceResourceIdentifier resourceIdentifier)
178: throws LibresourceException {
179: try {
180: if (resourceIdentifier == null) {
181: return null;
182: }
183:
184: return getService(resourceIdentifier.getService())
185: .listAvailablesEvents(resourceIdentifier);
186: } catch (Exception e) {
187: throw new LibresourceException(e);
188: }
189: }
190:
191: static public String getShortName(URI uri)
192: throws LibresourceException {
193: try {
194: return ((KernelService) getService(KernelConstants.SERVICE))
195: .getShortName(uri);
196:
197: // return getShortName(((KernelService)
198: // getService("Kernel")).systemLookup(uri));
199: } catch (Exception e) {
200: throw new LibresourceException(e);
201: }
202: }
203:
204: static public LibresourceService getService(String serviceName)
205: throws LibresourceException {
206: try {
207: if (proxy.get(serviceName) != null) {
208: return (LibresourceService) proxy.get(serviceName);
209: }
210:
211: String jndiName = LibresourceNamingConvention
212: .getJndiNameForService(serviceName);
213:
214: if (homesCache.get(jndiName) == null) {
215: homesCache.put(jndiName, getJndiContext().lookup(
216: jndiName));
217: }
218:
219: LibresourceServiceHome libresourceServiceHome;
220: Object homeStub = homesCache.get(jndiName);
221: libresourceServiceHome = (LibresourceServiceHome) PortableRemoteObject
222: .narrow(homeStub, LibresourceServiceHome.class);
223:
224: LibresourceService libresourceService = libresourceServiceHome
225: .create();
226: proxy.put(serviceName, libresourceService);
227:
228: return libresourceService;
229: } catch (NamingException e) {
230: throw new LibresourceException("Can't find service "
231: + serviceName, e);
232: } catch (Exception e) {
233: throw new LibresourceException("Can't create service "
234: + serviceName, e);
235: }
236: }
237:
238: static public void checkType(
239: LibresourceResourceIdentifier resourceIdentifier,
240: Class localInterface) throws LibresourceException {
241: if (!LibresourceResourceLocal.class
242: .isAssignableFrom(localInterface)) {
243: throw new LibresourceException(localInterface
244: + " is not of type LibresourceResourceLocal");
245: }
246:
247: try {
248: if (!resourceIdentifier.getService().equals(
249: localInterface.getField(
250: "LIBRESOURCE_RESOURCE_SERVICE").get(null))
251: || !resourceIdentifier.getResourceType().equals(
252: localInterface.getField(
253: "LIBRESOURCE_RESOURCE_TYPE").get(
254: null))) {
255: throw new LibresourceException("Resource ["
256: + resourceIdentifier
257: + "] is not of type "
258: + localInterface.getField(
259: "LIBRESOURCE_RESOURCE_SERVICE").get(
260: null)
261: + "/"
262: + localInterface.getField(
263: "LIBRESOURCE_RESOURCE_TYPE").get(null));
264: }
265: } catch (LibresourceException e) {
266: throw e;
267: } catch (Exception e) {
268: e.printStackTrace();
269: throw new LibresourceException("ERROR : " + e);
270: }
271: }
272:
273: static public String[] listServices() throws LibresourceException {
274: try {
275: NamingEnumeration enumeration = getJndiContext().list("");
276: Vector result = new Vector();
277:
278: while (enumeration.hasMoreElements()) {
279: String service = LibresourceNamingConvention
280: .extractServiceName(((NameClassPair) enumeration
281: .next()).getName());
282:
283: if (service != null) {
284: result.add(service);
285: }
286: }
287:
288: String[] resultS = new String[result.size()];
289:
290: for (int i = 0; i < result.size(); i++) {
291: resultS[i] = (String) result.get(i);
292: }
293:
294: return resultS;
295: } catch (Exception e) {
296: throw new LibresourceException("Can't list services", e);
297: }
298: }
299:
300: static public void throwEvent(LibresourceEvent event)
301: throws LibresourceException {
302: try {
303: TopicConnectionFactory factory = getConnectionFactory();
304: Topic topic = getEventsTopic();
305: TopicConnection topicConnection = factory
306: .createTopicConnection();
307: TopicSession topicSession = topicConnection
308: .createTopicSession(true,
309: javax.jms.Session.AUTO_ACKNOWLEDGE);
310: TopicPublisher topicPublisher = topicSession
311: .createPublisher(topic);
312: Message message = topicSession.createMessage();
313: event.toMessage(message);
314: topicPublisher.publish(message);
315: topicPublisher.close();
316: topicSession.close();
317: topicConnection.close();
318: } catch (Exception e) {
319: }
320: }
321:
322: static public void index(URI uri) throws LibresourceException {
323: try {
324: TopicConnectionFactory factory = getConnectionFactory();
325: Topic topic = getIndexationTopic();
326: TopicConnection topicConnection = factory
327: .createTopicConnection();
328: TopicSession topicSession = topicConnection
329: .createTopicSession(true,
330: javax.jms.Session.AUTO_ACKNOWLEDGE);
331: TopicPublisher topicPublisher = topicSession
332: .createPublisher(topic);
333: Message message = topicSession.createMessage();
334: message.setStringProperty("action", "index");
335: message.setStringProperty("uri", uri.toString());
336: topicPublisher.publish(message);
337: topicPublisher.close();
338: topicSession.close();
339: topicConnection.close();
340: } catch (Exception e) {
341: throw new LibresourceException("Error in index", e);
342: }
343: }
344:
345: static public void removeFromIndex(URI uri)
346: throws LibresourceException {
347: try {
348: TopicConnectionFactory factory = getConnectionFactory();
349: Topic topic = getIndexationTopic();
350: TopicConnection topicConnection = factory
351: .createTopicConnection();
352: TopicSession topicSession = topicConnection
353: .createTopicSession(true,
354: javax.jms.Session.AUTO_ACKNOWLEDGE);
355: TopicPublisher topicPublisher = topicSession
356: .createPublisher(topic);
357: Message message = topicSession.createMessage();
358: message.setStringProperty("action", "delete");
359: message.setStringProperty("uri", uri.toString());
360: topicPublisher.publish(message);
361: topicPublisher.close();
362: topicSession.close();
363: topicConnection.close();
364: } catch (Exception e) {
365: throw new LibresourceException("Error in removeFromIndex",
366: e);
367: }
368: }
369:
370: public static Topic getEventsTopic() throws NamingException {
371: if (eventsTopic == null) {
372: eventsTopic = (Topic) new InitialContext()
373: .lookup(getLibresourceConfiguration("event.topic.lookup"));
374: }
375:
376: return eventsTopic;
377: }
378:
379: public static Topic getIndexationTopic() throws NamingException {
380: if (indexationTopic == null) {
381: indexationTopic = (Topic) new InitialContext()
382: .lookup(getLibresourceConfiguration("indexation.topic.lookup"));
383: }
384:
385: return indexationTopic;
386: }
387:
388: public static TopicConnectionFactory getConnectionFactory()
389: throws NamingException {
390: if (connectionFactory == null) {
391: connectionFactory = (TopicConnectionFactory) new InitialContext()
392: .lookup(getLibresourceConfiguration("topic.connection.factory"));
393: }
394:
395: return connectionFactory;
396: }
397:
398: public static DataSource getDatasource() throws NamingException {
399: if (dataSource == null) {
400: dataSource = (DataSource) new InitialContext()
401: .lookup(getLibresourceConfiguration("libresource.datasource"));
402: }
403:
404: return dataSource;
405: }
406:
407: public static String formatDate(Date date) {
408: if (dateFormater == null) {
409: dateFormater = new SimpleDateFormat("dd-MM-yy HH:mm:ss");
410: }
411:
412: if (date == null) {
413: return dateFormater.format(new Date());
414: }
415:
416: return dateFormater.format(date);
417: }
418:
419: public static Date parseDate(String date) throws ParseException {
420: if (dateFormater == null) {
421: dateFormater = new SimpleDateFormat("dd-MM-yy HH:mm:ss");
422: }
423:
424: if ((date == null) || (date.trim().length() == 0)) {
425: return new Date();
426: }
427:
428: try {
429: return dateFormater.parse(date);
430: } catch (Exception e) {
431: System.out.println("Impossible de parser la date: " + date);
432:
433: return new Date();
434: }
435: }
436:
437: public static String getLibresourceConfiguration(String key) {
438: if (lsConfig == null) {
439: synchronized (Libresource.class) {
440: if (lsConfig == null) {
441: try {
442: // Try for Jonas first
443: lsConfig = ((Session) PortableRemoteObject
444: .narrow(new InitialContext()
445: .lookup("libresourceConfig"),
446: Session.class)).getProperties();
447: } catch (Exception eJonas) {
448: try {
449: // Try for JBoss
450: lsConfig = ((Session) PortableRemoteObject
451: .narrow(
452: new InitialContext()
453: .lookup("java:/libresourceConfig"),
454: Session.class))
455: .getProperties();
456: } catch (Exception eJBoss) {
457: throw new RuntimeException(
458: "Unable to load the LibreSource configuration file.");
459: }
460: }
461: }
462: }
463: }
464:
465: return lsConfig.getProperty(key);
466: }
467:
468: public static URI getAbsoluteURI(URI contextUri,
469: String uriToTransform) throws Exception {
470: uriToTransform = uriToTransform.trim();
471:
472: URI workingURI = new URI(uriToTransform).normalize();
473: String query = workingURI.getQuery();
474: String path = null;
475:
476: if ((contextUri == null)
477: || ((uriToTransform.length() != 0) && uriToTransform
478: .startsWith("/"))) {
479: path = new URI(uriToTransform).normalize().getPath();
480: } else {
481: path = new URI(contextUri.getPath() + "/" + uriToTransform)
482: .normalize().getPath();
483: }
484:
485: if (path.endsWith("/")) {
486: path = path.substring(0, path.length() - 1);
487: }
488:
489: if (query != null) {
490: return new URI(path + "?" + query);
491: }
492:
493: return new URI(path);
494: }
495:
496: public static String convertStringToId(String name) {
497: return name.replaceAll(ID_REGEXP, "_");
498: }
499:
500: public static CallbackHandler buildCallBackHandler(String login,
501: String password) {
502: CallbackHandler result = null;
503:
504: try {
505: if (getLibresourceConfiguration(SERVER_NAME).equals(
506: SERVER_NAME_JONAS)) {
507: result = (CallbackHandler) Class
508: .forName(
509: "org.objectweb.jonas.security.auth.callback.NoInputCallbackHandler")
510: .getConstructor(
511: new Class[] { String.class,
512: String.class }).newInstance(
513: new Object[] { login, password });
514: } else { // if
515:
516: // (getLibresourceConfiguration("libresource.server").equals("jboss"))
517: // {
518: result = (CallbackHandler) Class
519: .forName(
520: "org.jboss.security.auth.callback.AppCallbackHandler")
521: .getConstructor(
522: new Class[] { String.class,
523: char[].class }).newInstance(
524: new Object[] { login,
525: password.toCharArray() });
526: }
527: } catch (Exception e) {
528: e.printStackTrace();
529: }
530:
531: return result;
532: }
533:
534: public static Principal buildPrincipal(String principal) {
535: Principal result = null;
536:
537: try {
538: if (getLibresourceConfiguration(SERVER_NAME).equals(
539: SERVER_NAME_JONAS)) {
540: result = (Principal) Class.forName(
541: "org.objectweb.jonas.security.auth.JPrincipal")
542: .getConstructor(new Class[] { String.class })
543: .newInstance(new Object[] { principal });
544: } else { // if
545:
546: // (getLibresourceConfiguration("libresource.server").equals("jboss"))
547: // {
548: result = (Principal) Class.forName(
549: "org.jboss.security.NestablePrincipal")
550: .getConstructor(new Class[] { String.class })
551: .newInstance(new Object[] { principal });
552: }
553: } catch (Exception e) {
554: e.printStackTrace();
555: }
556:
557: return result;
558: }
559:
560: public static Group buildGroup(String role) {
561: Group result = null;
562:
563: try {
564: if (getLibresourceConfiguration(SERVER_NAME).equals(
565: SERVER_NAME_JONAS)) {
566: result = (Group) Class.forName(
567: "org.objectweb.jonas.security.auth.JGroup")
568: .getConstructor(new Class[] { String.class })
569: .newInstance(new Object[] { role });
570: } else { // if
571:
572: // (getLibresourceConfiguration("libresource.server").equals("jboss"))
573: // {
574: result = (Group) Class.forName(
575: "org.jboss.security.NestableGroup")
576: .getConstructor(new Class[] { String.class })
577: .newInstance(new Object[] { role });
578: }
579: } catch (Exception e) {
580: e.printStackTrace();
581: }
582:
583: return result;
584: }
585: }
|