KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jetspeed > services > psmlmanager > CastorPsmlManagerService


1 /*
2  * Copyright 2000-2001,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.jetspeed.services.psmlmanager;
18
19 //Jetspeed stuff
20
import org.apache.jetspeed.om.profile.ProfileLocator;
21 import org.apache.jetspeed.om.profile.QueryLocator;
22 import org.apache.jetspeed.util.FileCopy;
23 import org.apache.jetspeed.util.DirectoryUtils;
24 import org.apache.jetspeed.services.Profiler;
25 import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
26 import org.apache.jetspeed.services.logging.JetspeedLogger;
27 import org.apache.jetspeed.services.JetspeedSecurity;
28 import org.apache.jetspeed.services.resources.JetspeedResources;
29
30 //Castor defined API
31
import org.apache.jetspeed.om.profile.Portlets;
32 import org.apache.jetspeed.om.profile.*;
33
34 //turbine stuff
35
import org.apache.turbine.services.TurbineBaseService;
36 import org.apache.turbine.services.InitializationException;
37 import org.apache.turbine.services.TurbineServices;
38 import org.apache.turbine.services.servlet.TurbineServlet;
39 import org.apache.turbine.services.resources.ResourceService;
40 import org.apache.turbine.services.servlet.ServletService;
41
42 import org.apache.jetspeed.om.security.JetspeedUser;
43 import org.apache.jetspeed.om.security.Role;
44 import org.apache.jetspeed.om.security.JetspeedRoleFactory;
45 import org.apache.jetspeed.om.security.Group;
46 import org.apache.jetspeed.om.security.JetspeedGroupFactory;
47 import org.apache.jetspeed.om.security.JetspeedUserFactory;
48
49 //castor support
50
import org.exolab.castor.xml.MarshalException;
51 import org.exolab.castor.xml.Unmarshaller;
52 import org.exolab.castor.xml.Marshaller;
53 import org.exolab.castor.xml.ValidationException;
54 import org.exolab.castor.mapping.Mapping;
55 import org.exolab.castor.mapping.MappingException;
56 import org.xml.sax.InputSource JavaDoc;
57 import org.xml.sax.SAXException JavaDoc;
58 import org.w3c.dom.Document JavaDoc;
59 import org.w3c.dom.Node JavaDoc;
60
61 // serialization support
62
import org.apache.xml.serialize.Serializer;
63 import org.apache.xml.serialize.XMLSerializer;
64 import org.apache.xml.serialize.OutputFormat;
65
66 //standard java stuff
67
import java.io.File JavaDoc;
68 import java.io.Reader JavaDoc;
69 import java.io.FileReader JavaDoc;
70 import java.io.Writer JavaDoc;
71 import java.io.FileOutputStream JavaDoc;
72 import java.io.OutputStreamWriter JavaDoc;
73 import java.io.IOException JavaDoc;
74 import java.util.Iterator JavaDoc;
75 import java.util.List JavaDoc;
76 import java.util.LinkedList JavaDoc;
77 import javax.servlet.ServletConfig JavaDoc;
78 import javax.xml.parsers.DocumentBuilder JavaDoc;
79 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
80 import javax.xml.parsers.ParserConfigurationException JavaDoc;
81
82 import org.apache.jetspeed.cache.FileCache;
83 import org.apache.jetspeed.cache.FileCacheEventListener;
84 import org.apache.jetspeed.cache.FileCacheEntry;
85
86
87 /**
88  * This service is responsible for loading and saving PSML documents.
89  *
90  * @author <a HREF="mailto:raphael@apache.org">Raphaël Luta</a>
91  * @author <a HREF="mailto:taylor@apache.org">David Sean Taylor</a>
92  * @author <a HREF="mailto:sgala@apache.org">Santiago Gala</a>
93  * @version $Id: CastorPsmlManagerService.java,v 1.44 2004/03/31 00:23:02 jford Exp $
94  */

95 public class CastorPsmlManagerService extends TurbineBaseService
96                                       implements FileCacheEventListener,
97                                                  PsmlManagerService
98 {
99     /**
100      * Static initialization of the logger for this class
101      */

102     private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(CastorPsmlManagerService.class.getName());
103     
104     // resource path constants
105
protected static final String JavaDoc PATH_GROUP = "group";
106     protected static final String JavaDoc PATH_ROLE = "role";
107     protected static final String JavaDoc PATH_USER = "user";
108
109     // configuration keys
110
protected final static String JavaDoc CONFIG_ROOT = "root";
111     protected final static String JavaDoc CONFIG_EXT = "ext";
112     protected final static String JavaDoc CONFIG_SCAN_RATE = "scanRate";
113     protected final static String JavaDoc CONFIG_CACHE_SIZE = "cacheSize";
114
115     // default configuration values
116
public final static String JavaDoc DEFAULT_ROOT = "/WEB-INF/psml";
117     public final static String JavaDoc DEFAULT_EXT = ".psml";
118
119     // default resource
120
public final static String JavaDoc DEFAULT_RESOURCE = "default.psml";
121
122     // the root psml resource directory
123
protected String JavaDoc root;
124     // base store directory
125
protected File JavaDoc rootDir = null;
126     // file extension
127
protected String JavaDoc ext;
128
129     /** The documents loaded by this manager */
130     protected FileCache documents = null;
131
132     /** the output format for pretty printing when saving registries */
133     protected OutputFormat format = null;
134
135     /** the base refresh rate for documents */
136     protected long scanRate = 1000 * 60; // every minute
137

138     /** the default cache size */
139     protected int cacheSize = 100;
140
141     /** the import/export consumer service **/
142     protected PsmlManagerService consumer = null;
143     protected boolean importFlag = false;
144
145     // castor mapping
146
public static final String JavaDoc DEFAULT_MAPPING = "${webappRoot}/WEB-INF/conf/psml-mapping.xml";
147     protected String JavaDoc mapFile = null;
148
149     /** the Castor mapping file name */
150     protected Mapping mapping = null;
151
152     /** The default encoding used to serialize PSML files to disk */
153     protected String JavaDoc defaultEncoding = JetspeedResources.getString(JetspeedResources.CONTENT_ENCODING_KEY, "utf-8");
154
155     /**
156      * This is the early initialization method called by the
157      * Turbine <code>Service</code> framework
158      */

159     public void init( ServletConfig JavaDoc conf ) throws InitializationException
160     {
161         if (getInit())
162         {
163             return;
164         }
165
166         //Ensure that the servlet service is initialized
167
TurbineServices.getInstance().initService(ServletService.SERVICE_NAME, conf);
168
169         // get configuration parameters from Jetspeed Resources
170
ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
171                                                      .getResources(PsmlManagerService.SERVICE_NAME);
172         // get the PSML Root Directory
173
this.root = serviceConf.getString( CONFIG_ROOT, DEFAULT_ROOT );
174         this.rootDir = new File JavaDoc(root);
175
176         //If the rootDir does not exist, treat it as context relative
177
if ( !rootDir.exists() )
178         {
179             try
180             {
181                 this.rootDir = new File JavaDoc(conf.getServletContext().getRealPath(root));
182             }
183             catch (Exception JavaDoc e)
184             {
185                 // this.rootDir = new File("./webapp" + this.rootDir.toString());
186
}
187         }
188         //If it is still missing, try to create it
189
if (!rootDir.exists())
190         {
191             try
192             {
193                 rootDir.mkdirs();
194             }
195             catch (Exception JavaDoc e)
196             {
197             }
198         }
199
200         // get default extension
201
this.ext = serviceConf.getString( CONFIG_EXT, DEFAULT_EXT );
202
203         // create the serializer output format
204
this.format = new OutputFormat();
205         format.setIndenting(true);
206         format.setIndent(4);
207         format.setLineWidth(0);
208
209         // psml castor mapping file
210
mapFile = serviceConf.getString("mapping",DEFAULT_MAPPING);
211         mapFile = TurbineServlet.getRealPath( mapFile );
212         loadMapping();
213
214         this.scanRate = serviceConf.getLong(CONFIG_SCAN_RATE, this.scanRate);
215         this.cacheSize= serviceConf.getInt(CONFIG_CACHE_SIZE, this.cacheSize);
216
217         documents = new FileCache(this.scanRate, this.cacheSize);
218         documents.addListener(this);
219         documents.startFileScanner();
220
221
222         //Mark that we are done
223
setInit(true);
224
225         // Test
226
//testCases();
227

228     }
229
230
231     /** Late init method from Turbine Service model */
232     public void init() throws InitializationException
233     {
234         while( !getInit() )
235         {
236             //Not yet...
237
try
238             {
239                 Thread.sleep( 500 );
240             }
241             catch (InterruptedException JavaDoc ie )
242             {
243                 logger.error("Exception", ie);
244             }
245         }
246     }
247
248
249     /**
250      * This is the shutdown method called by the
251      * Turbine <code>Service</code> framework
252      */

253     public void shutdown()
254     {
255         documents.stopFileScanner();
256     }
257
258     /**
259      * Returns a PSML document of the given name.
260      * For this implementation, the name must be the document
261      * URL or absolute filepath
262      *
263      * @deprecated
264      * @param name the name of the document to retrieve
265      */

266     public PSMLDocument getDocument( String JavaDoc name )
267     {
268         if (name == null)
269         {
270             String JavaDoc message = "PSMLManager: Must specify a name";
271             logger.error( message );
272             throw new IllegalArgumentException JavaDoc( message );
273         }
274
275         if (logger.isDebugEnabled())
276         {
277             logger.debug( "PSMLManager: asked for " + name );
278         }
279
280         PSMLDocument doc = null;
281
282         doc = (PSMLDocument)documents.getDocument(name);
283
284         if (doc == null)
285         {
286             doc = loadDocument(name);
287
288             synchronized (documents)
289             {
290                 // store the document in the hash and reference it to the watcher
291
try
292                 {
293                     documents.put(name, doc);
294                 }
295                 catch (java.io.IOException JavaDoc e)
296                 {
297                     logger.error("Error putting document", e);
298                 }
299             }
300         }
301
302         return doc;
303     }
304
305     /**
306      * Returns a cached PSML document for the given locator
307      *
308      * @param locator The locator descriptor of the document to be retrieved.
309      * @return PSML document from cache (or disk if not yet cached)
310      */

311     public PSMLDocument getDocument( ProfileLocator locator)
312     {
313         return getDocument(locator, true);
314     }
315
316     /**
317      * Returns a PSML document for the given locator
318      *
319      * @param locator The locator descriptor of the document to be retrieved.
320      * @param getCached Look in the cache (true) or umarshall a fresh copy from disk (false)
321      * @return
322      */

323     protected PSMLDocument getDocument( ProfileLocator locator, boolean getCached )
324     {
325         if (locator == null)
326         {
327             String JavaDoc message = "PSMLManager: Must specify a name";
328             logger.error( message );
329             throw new IllegalArgumentException JavaDoc( message );
330         }
331         File JavaDoc base = this.rootDir;
332         String JavaDoc path = mapLocatorToFile(locator);
333         File JavaDoc file = new File JavaDoc(base, path);
334         String JavaDoc name = null;
335
336         try
337         {
338             name = file.getCanonicalPath();
339         }
340         catch (IOException JavaDoc e)
341         {
342             logger.error("PSMLManager: unable to resolve file path for "+ file);
343         }
344
345         if (logger.isDebugEnabled())
346         {
347             logger.debug("PSMLManager: calculated resource:" + path + ". Base: " + base + " File: " + name);
348         }
349
350         PSMLDocument doc = null;
351         Profile profile = null;
352
353         if (getCached == true)
354         {
355             profile = (Profile)documents.getDocument(name);
356         }
357
358         if (profile == null)
359         {
360             doc = loadDocument(name);
361             if (null == doc)
362             {
363                 if (logger.isWarnEnabled())
364                 {
365                     logger.warn( "PSMLManager: " + name + " not found, returning null document" );
366                 }
367                 return null;
368             }
369
370             synchronized (documents)
371             {
372                 // store the document in the hash and reference it to the watcher
373
Profile newProfile = createProfile(locator);
374                 newProfile.setDocument(doc);
375                 try
376                 {
377                     documents.put(name, newProfile);
378                 }
379                 catch (IOException JavaDoc e)
380                 {
381                     logger.error("Error putting document", e);
382                 }
383             }
384         }
385         else
386         {
387             doc = profile.getDocument();
388         }
389
390         return doc;
391     }
392
393     /**
394      * Loads a PSML document from disk bypassing the cache
395      *
396      * @param locator
397      * @return PSML document from disk
398      */

399     public PSMLDocument refresh(ProfileLocator locator)
400     {
401         if (logger.isDebugEnabled())
402         {
403             logger.debug("CastorPsmlManagerService: psml document refreshed from disk: " + locator.getPath());
404         }
405         return getDocument(locator, false);
406     }
407
408     /**
409      * Load a PSMLDOcument from disk
410      *
411      * @param fileOrUrl a String representing either an absolute URL or an
412      * absolute filepath
413      */

414     protected PSMLDocument loadDocument(String JavaDoc fileOrUrl)
415     {
416         PSMLDocument doc = null;
417
418         if (fileOrUrl!=null)
419         {
420             if (!fileOrUrl.endsWith(DEFAULT_EXT))
421             {
422                 fileOrUrl = fileOrUrl.concat(DEFAULT_EXT);
423             }
424
425             // load the document and add it to the watcher
426
// we'll assume the name is the the location of the file
427

428             File JavaDoc f = getFile(fileOrUrl);
429             if (null == f)
430                 return null;
431
432             doc = new BasePSMLDocument();
433             doc.setName(fileOrUrl);
434
435             // now that we have a file reference, try to load the serialized PSML
436
Portlets portlets = null;
437             try
438             {
439                 DocumentBuilderFactory JavaDoc dbfactory = DocumentBuilderFactory.newInstance();
440                 DocumentBuilder JavaDoc builder = dbfactory.newDocumentBuilder();
441
442                 Document JavaDoc d = builder.parse(f);
443
444                 Unmarshaller unmarshaller = new Unmarshaller(this.mapping);
445                 portlets = (Portlets)unmarshaller.unmarshal((Node JavaDoc) d);
446
447                 doc.setPortlets(portlets);
448
449             }
450             catch (IOException JavaDoc e)
451             {
452                 logger.error("PSMLManager: Could not load the file "+f.getAbsolutePath(), e);
453                 doc = null;
454             }
455             catch (MarshalException e)
456             {
457                 logger.error("PSMLManager: Could not unmarshal the file "+f.getAbsolutePath(), e);
458                 doc = null;
459             }
460             catch (MappingException e)
461             {
462                 logger.error("PSMLManager: Could not unmarshal the file "+f.getAbsolutePath(), e);
463                 doc = null;
464             }
465             catch (ValidationException e)
466             {
467                 logger.error("PSMLManager: document "+f.getAbsolutePath()+" is not valid", e);
468                 doc = null;
469             }
470             catch (ParserConfigurationException JavaDoc e)
471             {
472                 logger.error("PSMLManager: Could not load the file "+f.getAbsolutePath(), e);
473                 doc = null;
474             }
475             catch (SAXException JavaDoc e)
476             {
477                 logger.error("PSMLManager: Could not load the file "+f.getAbsolutePath(), e);
478                 doc = null;
479             }
480         }
481
482         return doc;
483     }
484
485     /** Store the PSML document on disk, using its locator
486      *
487      * @param profile the profile locator description.
488      * @return true if the operation succeeded
489      */

490     public boolean store(Profile profile)
491     {
492         PSMLDocument doc = profile.getDocument();
493
494         File JavaDoc base = this.rootDir;
495         String JavaDoc path = mapLocatorToFile(profile);
496
497         File JavaDoc file = new File JavaDoc(base, path);
498         String JavaDoc fullpath = null;
499
500         try
501         {
502             fullpath = file.getCanonicalPath();
503         }
504         catch (IOException JavaDoc e)
505         {
506             logger.error("PSMLManager: unable to resolve file path for "+ file);
507         }
508
509         boolean ok = saveDocument(fullpath, doc);
510
511         // update it in cache
512
synchronized (documents)
513         {
514             try
515             {
516                 documents.put(fullpath, profile);
517             }
518             catch (IOException JavaDoc e)
519             {
520                 logger.error("Error storing document", e);
521             }
522         }
523
524         return ok;
525     }
526
527     /** Save the PSML document on disk, using its name as filepath
528      * @deprecated
529      * @param doc the document to save
530      */

531     public boolean saveDocument(PSMLDocument doc)
532     {
533         return saveDocument(doc.getName(), doc);
534     }
535
536     /** Save the PSML document on disk to the specififed fileOrUrl
537      *
538      * @param fileOrUrl a String representing either an absolute URL
539      * or an absolute filepath
540      * @param doc the document to save
541      */

542     public boolean saveDocument(String JavaDoc fileOrUrl, PSMLDocument doc)
543     {
544         boolean success = false;
545
546         if (doc == null) return false;
547         File JavaDoc f = getFile(fileOrUrl);
548         if (f == null)
549         {
550             f = new File JavaDoc(fileOrUrl);
551         }
552
553         OutputStreamWriter JavaDoc writer = null;
554         FileOutputStream JavaDoc fos = null;
555         try
556         {
557             String JavaDoc encoding = this.defaultEncoding;
558             fos = new FileOutputStream JavaDoc(f);
559             writer = new OutputStreamWriter JavaDoc(fos, encoding);
560
561             save(writer, doc.getPortlets());
562             success = true;
563         }
564         catch (MarshalException e)
565         {
566             logger.error("PSMLManager: Could not marshal the file "+f.getAbsolutePath(), e);
567         }
568         catch (MappingException e)
569         {
570             logger.error("PSMLManager: Could not marshal the file "+f.getAbsolutePath(), e);
571         }
572         catch (ValidationException e)
573         {
574             logger.error("PSMLManager: document "+f.getAbsolutePath()+" is not valid", e);
575         }
576         catch (IOException JavaDoc e)
577         {
578             logger.error("PSMLManager: Could not save the file "+f.getAbsolutePath(), e);
579         }
580         catch (Exception JavaDoc e)
581         {
582             logger.error("PSMLManager: Error while saving "+f.getAbsolutePath(), e);
583         }
584         finally
585         {
586             try { writer.close(); } catch (IOException JavaDoc e) {}
587             try { if(fos != null) { fos.close(); } } catch (IOException JavaDoc e) {}
588         }
589
590         return success;
591     }
592
593     /** Deserializes a PSML structure read from the reader using Castor
594      * XML unmarshaller
595      *
596      * @param reader the reader to load the PSML from
597      * @param the loaded portlets structure or null
598      */

599     protected Portlets load(Reader JavaDoc reader)
600         throws IOException JavaDoc, MarshalException, ValidationException, MappingException
601     {
602         Unmarshaller unmarshaller = new Unmarshaller(this.mapping);
603         Portlets portlets = (Portlets)unmarshaller.unmarshal(reader);
604         return portlets;
605     }
606
607     protected void loadMapping()
608         throws InitializationException
609     {
610         // test the mapping file and create the mapping object
611

612         if (mapFile != null)
613         {
614             File JavaDoc map = new File JavaDoc(mapFile);
615             if (logger.isDebugEnabled())
616             {
617                 logger.debug("PSMLManager: Loading psml mapping file "+mapFile);
618             }
619             if (map.exists() && map.isFile() && map.canRead())
620             {
621                 try
622                 {
623                     mapping = new Mapping();
624                     InputSource JavaDoc is = new InputSource JavaDoc( new FileReader JavaDoc(map) );
625                     is.setSystemId( mapFile );
626                     mapping.loadMapping( is );
627                 }
628                 catch (Exception JavaDoc e)
629                 {
630                     logger.error("PSMLManager: Error in psml mapping creation", e);
631                     throw new InitializationException("Error in mapping",e);
632                 }
633             }
634             else
635             {
636                 throw new InitializationException("PSML Mapping not found or not a file or unreadable: "+mapFile);
637             }
638         }
639     }
640
641     /** Serializes a PSML structure using the specified writer with Castor
642      * XML marshaller and a Xerces serializer for pretty printing
643      *
644      * @param writer the writer to use for serialization
645      * @param portlets the structure to save
646      */

647     protected void save(Writer JavaDoc writer, Portlets portlets)
648         throws IOException JavaDoc, MarshalException, ValidationException, MappingException
649     {
650         String JavaDoc encoding = this.defaultEncoding;
651
652         if (portlets != null)
653         {
654             format.setEncoding(encoding);
655             Serializer serializer = new XMLSerializer(writer, format);
656             Marshaller marshaller = new Marshaller(serializer.asDocumentHandler());
657             marshaller.setMapping(this.mapping);
658             marshaller.marshal(portlets);
659         }
660     }
661
662     /** Tests wether the passed argument is an URL string or a file name
663      * and returns the corresponding file object, using diskcache for
664      * remote URLs
665      *
666      * @param fileOrUrl the URL string or file path
667      * @return a File object. This file may not exist on disk.
668      */

669     protected File JavaDoc getFile(String JavaDoc fileOrUrl)
670     {
671         File JavaDoc f = null;
672
673         f = new File JavaDoc(fileOrUrl);
674
675         if (f.exists())
676         {
677             return f;
678         }
679
680         return null;
681     }
682
683     /** Create a new document.
684      *
685      * @param profile The description and default value for the new document.
686      * @return The newly created document;
687      */

688     public PSMLDocument createDocument( Profile profile )
689     {
690         File JavaDoc base = this.rootDir;
691         String JavaDoc path = mapLocatorToFile((ProfileLocator)profile);
692
693         if (logger.isDebugEnabled())
694         {
695             logger.debug("PSMLManager: Create document for profile " + profile +", calculated path: " + path);
696         }
697
698         File JavaDoc file = new File JavaDoc(base, path);
699         String JavaDoc name = null;
700
701         try
702         {
703             name = file.getCanonicalPath();
704         }
705         catch (IOException JavaDoc e)
706         {
707             logger.error("PSMLManager: unable to resolve file path for "+ file);
708         }
709
710         PSMLDocument template = profile.getDocument();
711         PSMLDocument doc = new BasePSMLDocument( name, template.getPortlets() );
712         try
713         {
714             String JavaDoc parent = file.getParent();
715             File JavaDoc filePath = new File JavaDoc(parent);
716             filePath.mkdirs();
717             if (template.getName() != null)
718             {
719                 try
720                 {
721                     File JavaDoc source = new File JavaDoc(template.getName());
722                     if (source.exists())
723                     {
724                         FileCopy.copy( template.getName(), name );
725                     }
726                 }
727                 catch (Exception JavaDoc e)
728                 {}
729             }
730             else
731             {
732                 doc.setName(name);
733             }
734             saveDocument(doc);
735         }
736         catch (Exception JavaDoc e)
737         {
738             logger.error("PSMLManager: Failed to save document: " , e);
739         }
740         return doc;
741     }
742
743     /** Given a ordered list of locators, find the first document matching
744      * a profile locator, starting from the beginning of the list and working
745      * to the end.
746      *
747      * @param locator The ordered list of profile locators.
748      */

749     public PSMLDocument getDocument( List JavaDoc locators )
750     {
751         PSMLDocument doc=null;
752
753         Iterator JavaDoc i = locators.iterator();
754         while ((doc==null)&&(i.hasNext()))
755         {
756             doc=getDocument((ProfileLocator)i.next());
757         }
758
759         return doc;
760     }
761
762     /** Removes a document.
763      *
764      * @param locator The description of the profile resource to be removed.
765      */

766     public void removeDocument( ProfileLocator locator )
767     {
768         // remove a single document
769
String JavaDoc fileName = mapLocatorToFile(locator);
770
771         File JavaDoc base = this.rootDir;
772         File JavaDoc file = new File JavaDoc(base, fileName);
773         String JavaDoc name = null;
774
775         try
776         {
777             name = file.getCanonicalPath();
778         }
779         catch (IOException JavaDoc e)
780         {
781             logger.error("PSMLManager: unable to resolve file path for "+ file);
782         }
783
784
785         synchronized (documents)
786         {
787             documents.remove(name);
788         }
789
790         file.delete();
791
792     }
793
794     /** Removes all documents for a given user.
795      *
796      * @param user The user object.
797      */

798     public void removeUserDocuments( JetspeedUser user )
799     {
800         ProfileLocator locator = Profiler.createLocator();
801         locator.setUser(user);
802         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
803         buffer.append(PATH_USER);
804         String JavaDoc name = user.getUserName();
805         if (null != name && name.length() > 0)
806         {
807             buffer.append(File.separator)
808                 .append(name);
809         }
810         else
811             return; // don't delete the entire user directories
812

813         String JavaDoc path = buffer.toString();
814         File JavaDoc base = this.rootDir;
815         File JavaDoc file = new File JavaDoc(base, path);
816
817         try
818         {
819             name = file.getCanonicalPath();
820         }
821         catch (IOException JavaDoc e)
822         {
823             logger.error("PSMLManager: unable to resolve file path for "+ file);
824         }
825
826
827         synchronized (documents)
828         {
829             DirectoryUtils.rmdir(name);
830             Iterator JavaDoc it = documents.getIterator();
831             while (it.hasNext())
832             {
833                 FileCacheEntry entry = (FileCacheEntry)it.next();
834                 if (null == entry)
835                 {
836                     continue;
837                 }
838                 Profile profile = (Profile)entry.getDocument();
839                 if (null == profile)
840                 {
841                     continue;
842                 }
843                 JetspeedUser pUser = profile.getUser();
844                 if (null != pUser && pUser.getUserName().equals(user.getUserName()))
845                 {
846                     documents.remove(profile.getDocument().getName());
847                 }
848             }
849         }
850
851     }
852
853     /** Removes all documents for a given role.
854      *
855      * @param role The role object.
856      */

857     public void removeRoleDocuments( Role role )
858     {
859         ProfileLocator locator = Profiler.createLocator();
860         locator.setRole(role);
861         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
862         buffer.append(PATH_ROLE);
863         String JavaDoc name = role.getName();
864         if (null != name && name.length() > 0)
865         {
866             buffer.append(File.separator)
867                 .append(name);
868         }
869         else
870             return; // don't delete the entire role directories
871

872         String JavaDoc path = buffer.toString();
873         File JavaDoc base = this.rootDir;
874         File JavaDoc file = new File JavaDoc(base, path);
875
876         try
877         {
878             name = file.getCanonicalPath();
879         }
880         catch (IOException JavaDoc e)
881         {
882             logger.error("PSMLManager: unable to resolve file path for "+ file);
883         }
884
885
886         synchronized (documents)
887         {
888             DirectoryUtils.rmdir(name);
889             Iterator JavaDoc it = documents.getIterator();
890             while (it.hasNext())
891             {
892                 FileCacheEntry entry = (FileCacheEntry)it.next();
893                 if (null == entry)
894                 {
895                     continue;
896                 }
897                 Profile profile = (Profile)entry.getDocument();
898                 if (null == profile)
899                 {
900                     continue;
901                 }
902                 Role pRole = profile.getRole();
903                 if (null != pRole && pRole.getName().equals(role.getName()))
904                 {
905                     documents.remove(profile.getDocument().getName());
906                 }
907             }
908         }
909     }
910
911     /** Removes all documents for a given group.
912      *
913      * @param group The group object.
914      */

915     public void removeGroupDocuments( Group group )
916     {
917         ProfileLocator locator = Profiler.createLocator();
918         locator.setGroup(group);
919         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
920         buffer.append(PATH_GROUP);
921         String JavaDoc name = group.getName();
922         if (null != name && name.length() > 0)
923         {
924             buffer.append(File.separator)
925                 .append(name);
926         }
927         else
928             return; // don't delete the entire group directories
929

930         String JavaDoc path = buffer.toString();
931         File JavaDoc base = this.rootDir;
932         File JavaDoc file = new File JavaDoc(base, path);
933
934         try
935         {
936             name = file.getCanonicalPath();
937         }
938         catch (IOException JavaDoc e)
939         {
940             logger.error("PSMLManager: unable to resolve file path for "+ file);
941         }
942
943
944         synchronized (documents)
945         {
946             DirectoryUtils.rmdir(name);
947             Iterator JavaDoc it = documents.getIterator();
948             while (it.hasNext())
949             {
950                 FileCacheEntry entry = (FileCacheEntry)it.next();
951                 if (null == entry)
952                 {
953                     continue;
954                 }
955                 Profile profile = (Profile)entry.getDocument();
956                 if (null == profile)
957                 {
958                     continue;
959                 }
960                 Group pGroup = profile.getGroup();
961                 if (null != pGroup && pGroup.getName().equals(group.getName()))
962                 {
963                     documents.remove(profile.getDocument().getName());
964                 }
965             }
966         }
967
968     }
969
970
971     /**
972      * Maps a ProfileLocator to a file.
973      *
974      * @param locator The profile locator describing the PSML resource to be found.
975      * @return the String path of the file.
976      */

977     protected String JavaDoc mapLocatorToFile(ProfileLocator locator)
978     {
979         StringBuffer JavaDoc path = new StringBuffer JavaDoc();
980
981         // move the base dir is either user or role is specified
982
Role role = locator.getRole();
983         Group group = locator.getGroup();
984         JetspeedUser user = locator.getUser();
985
986         if (user != null)
987         {
988             path.append(PATH_USER);
989             String JavaDoc name = user.getUserName();
990             if (null != name && name.length() > 0)
991             {
992                 path.append(File.separator)
993                     .append(name);
994             }
995         }
996         else if (group != null)
997         {
998             path.append(PATH_GROUP);
999             String JavaDoc name = group.getName();
1000            if (null != name && name.length() > 0)
1001            {
1002                path.append(File.separator)
1003                    .append(name);
1004            }
1005        }
1006        else if (null != role)
1007        {
1008            path.append(PATH_ROLE);
1009            String JavaDoc name = role.getName();
1010            if (null != name && name.length() > 0)
1011            {
1012                path.append(File.separator)
1013                    .append(name);
1014            }
1015        }
1016
1017        // Media
1018
if (null != locator.getMediaType())
1019        {
1020            path.append(File.separator)
1021                .append(locator.getMediaType());
1022        }
1023        // Language
1024
if (null != locator.getLanguage() && (! locator.getLanguage().equals("-1")))
1025        {
1026            path.append(File.separator)
1027                .append(locator.getLanguage());
1028        }
1029        // Country
1030
if (null != locator.getCountry() && (! locator.getCountry().equals("-1")))
1031        {
1032            path.append(File.separator)
1033                .append(locator.getCountry());
1034        }
1035        // Resource Name
1036
if (null != locator.getName())
1037        {
1038            if (!(locator.getName().endsWith(CastorPsmlManagerService.DEFAULT_EXT)))
1039            {
1040                path.append(File.separator)
1041                    .append(locator.getName()).append(CastorPsmlManagerService.DEFAULT_EXT);
1042            }
1043            else
1044            {
1045                path.append(File.separator)
1046                    .append(locator.getName());
1047            }
1048        }
1049        else
1050        {
1051            path.append(File.separator)
1052                .append(DEFAULT_RESOURCE);
1053        }
1054
1055        return path.toString();
1056    }
1057
1058    protected static int STATE_INIT = 0;
1059    protected static int STATE_BASE = 1;
1060    protected static int STATE_NAME = 2;
1061    protected static int STATE_MEDIA = 3;
1062    protected static int STATE_LANGUAGE = 4;
1063    protected static int STATE_COUNTRY = 5;
1064
1065    /** Query for a collection of profiles given a profile locator criteria.
1066     *
1067     * @param locator The profile locator criteria.
1068     */

1069    public Iterator JavaDoc query( QueryLocator locator )
1070    {
1071        List JavaDoc list = new LinkedList JavaDoc();
1072
1073        Role role = locator.getRole();
1074        Group group = locator.getGroup();
1075        JetspeedUser user = locator.getUser();
1076
1077        // search thru anonymous directories?
1078
int qm = locator.getQueryMode();
1079        if ((qm & QueryLocator.QUERY_USER) == QueryLocator.QUERY_USER)
1080        {
1081            Profile profile = createProfile();
1082            StringBuffer JavaDoc path = new StringBuffer JavaDoc();
1083            path.append(PATH_USER);
1084            String JavaDoc name = null;
1085            int state = STATE_INIT;
1086            if (null != user)
1087            {
1088                name = user.getUserName();
1089                profile.setUser( user );
1090                if (null != name)
1091                {
1092                    path.append(File.separator).append(name);
1093                    state = STATE_BASE;
1094                }
1095            }
1096            File JavaDoc base = this.rootDir;
1097            File JavaDoc file = new File JavaDoc(base, path.toString());
1098            String JavaDoc absPath = file.getAbsolutePath();
1099            QueryState qs = new QueryState( QUERY_BY_USER,
1100                                             profile,
1101                                             locator,
1102                                             list,
1103                                             name,
1104                                             state);
1105            subQuery(qs, absPath);
1106        }
1107        if ((qm & QueryLocator.QUERY_ROLE) == QueryLocator.QUERY_ROLE)
1108        {
1109            Profile profile = createProfile();
1110            StringBuffer JavaDoc path = new StringBuffer JavaDoc();
1111            path.append(PATH_ROLE);
1112            String JavaDoc name = null;
1113            int state = STATE_INIT;
1114            if (null != role)
1115            {
1116                name = role.getName();
1117                profile.setRole( role );
1118                if (null != name)
1119                {
1120                    path.append(File.separator).append(name);
1121                    state = STATE_BASE;
1122                }
1123            }
1124            File JavaDoc base = this.rootDir;
1125            File JavaDoc file = new File JavaDoc(base, path.toString());
1126            String JavaDoc absPath = null;
1127
1128            try
1129            {
1130                absPath = file.getCanonicalPath();
1131            }
1132            catch (IOException JavaDoc e)
1133            {
1134                logger.error("PSMLManager: unable to resolve file path for "+ file);
1135            }
1136
1137            QueryState qs = new QueryState( QUERY_BY_ROLE,
1138                                             profile,
1139                                             locator,
1140                                             list,
1141                                             name,
1142                                             state);
1143            subQuery(qs, absPath);
1144        }
1145        if ((qm & QueryLocator.QUERY_GROUP) == QueryLocator.QUERY_GROUP)
1146        {
1147            Profile profile = createProfile();
1148            StringBuffer JavaDoc path = new StringBuffer JavaDoc();
1149            path.append(PATH_GROUP);
1150            String JavaDoc name = null;
1151            int state = STATE_INIT;
1152            if (null != group)
1153            {
1154                name = group.getName();
1155                profile.setGroup( group );
1156                if (null != name)
1157                {
1158                    path.append(File.separator).append(name);
1159                    state = STATE_BASE;
1160                }
1161            }
1162            File JavaDoc base = this.rootDir;
1163            File JavaDoc file = new File JavaDoc(base, path.toString());
1164            String JavaDoc absPath = null;
1165
1166            try
1167            {
1168                absPath = file.getCanonicalPath();
1169            }
1170            catch (IOException JavaDoc e)
1171            {
1172                logger.error("PSMLManager: unable to resolve file path for "+ file);
1173            }
1174
1175            QueryState qs = new QueryState( QUERY_BY_GROUP,
1176                                             profile,
1177                                             locator,
1178                                             list,
1179                                             name,
1180                                             state);
1181            subQuery(qs, absPath);
1182        }
1183
1184        return list.iterator();
1185    }
1186
1187    /** Create a profile based on import flag.
1188     *
1189     */

1190    protected Profile createProfile()
1191    {
1192        if (importFlag)
1193            return new ImportProfile(this, this.consumer);
1194        else
1195            return Profiler.createProfile();
1196    }
1197
1198    protected Profile createProfile(ProfileLocator locator)
1199    {
1200        if (importFlag)
1201            return new ImportProfile(this, this.consumer, locator);
1202        else
1203            return Profiler.createProfile(locator);
1204    }
1205
1206    /** Query for a collection of profiles given a profile locator criteria.
1207     * This method should be used when importing or exporting profiles between services.
1208     *
1209     * @param locator The profile locator criteria.
1210     * @return The count of profiles exported.
1211     */

1212    public int export(PsmlManagerService consumer, QueryLocator locator)
1213    {
1214        importFlag = true;
1215        Iterator JavaDoc profiles = null;
1216        int count = 0;
1217        try
1218        {
1219            this.consumer = consumer;
1220            profiles = query(locator);
1221
1222            while (profiles.hasNext() )
1223            {
1224                Profile profile = (Profile)profiles.next();
1225                //dumpProfile(profile);
1226
try
1227                {
1228                    consumer.createDocument(profile);
1229                    count++;
1230                }
1231                catch (Exception JavaDoc ex)
1232                {
1233                    try
1234                    {
1235                        consumer.store(profile);
1236                        count++;
1237                    }
1238                    catch (Exception JavaDoc e)
1239                    {
1240                        logger.error("PSMLManager: Failed to export profiles to DB: " + profile, ex );
1241                    }
1242                }
1243            }
1244        }
1245        catch(Exception JavaDoc e)
1246        {
1247            e.printStackTrace();
1248            logger.error("PSMLManager: Failed to export profiles to DB: " , e );
1249
1250        }
1251        finally
1252        {
1253            importFlag = false;
1254        }
1255        return count;
1256    }
1257
1258
1259    /** Query for a collection of profiles given a profile locator criteria.
1260     * To specify 'all' - use '*' in the criteria
1261     *
1262     * @param locator The profile locator criteria.
1263     */

1264    protected void subQuery(QueryState qs, String JavaDoc path)
1265    {
1266        File JavaDoc file = new File JavaDoc(path);
1267        if (file.isFile())
1268        {
1269            try
1270            {
1271                String JavaDoc filename = file.getName();
1272                if (!filename.endsWith(this.ext))
1273                    return;
1274
1275                Profile clone = (Profile)qs.profile.clone();
1276                clone.setName(filename);
1277                qs.list.add( clone );
1278            }
1279            catch (Exception JavaDoc e)
1280            {
1281                logger.error("PSMLManager: Failed to clone profile: " + path + " : " + e, e);
1282            }
1283        }
1284        else if (file.isDirectory())
1285        {
1286            String JavaDoc dirName = file.getName();
1287            qs.state++;
1288
1289            // filter out based on name, mediatype, language, country
1290
if (qs.state == STATE_NAME)
1291            {
1292                if (null != qs.name)
1293                {
1294                    if (!dirName.equals(qs.name))
1295                        return;
1296                }
1297                try
1298                {
1299                    if (QUERY_BY_USER == qs.queryBy)
1300                    {
1301                        JetspeedUser user = (JetspeedUser)qs.profile.getUser();
1302                        if (null == user)
1303                        {
1304                            user = JetspeedUserFactory.getInstance();
1305                            user.setUserName(file.getName());
1306                            qs.profile.setUser(user);
1307                            qs.clearName = true;
1308                        }
1309                    }
1310                    else if (QUERY_BY_ROLE == qs.queryBy)
1311                    {
1312                        Role role = qs.profile.getRole();
1313                        if (null == role)
1314                        {
1315                            role = JetspeedRoleFactory.getInstance();
1316                            role.setName(file.getName());
1317                            qs.profile.setRole(role);
1318                            qs.clearName = true;
1319                        }
1320                    }
1321                    else if (QUERY_BY_GROUP == qs.queryBy)
1322                    {
1323                        Group group = qs.profile.getGroup();
1324                        if (null == group)
1325                        {
1326                            group = JetspeedGroupFactory.getInstance();
1327                            group.setName(file.getName());
1328                            qs.profile.setGroup(group);
1329                            qs.clearName = true;
1330                        }
1331                    }
1332                }
1333                catch (Exception JavaDoc e)
1334                {}
1335
1336
1337            }
1338            else if (qs.state == STATE_MEDIA)
1339            {
1340                String JavaDoc media = qs.locator.getMediaType();
1341                if (null != media)
1342                {
1343                    if (!dirName.equals(media))
1344                        return;
1345                }
1346                else
1347                {
1348                    qs.profile.setMediaType(dirName);
1349                    qs.clearMedia = true;
1350                }
1351            }
1352            else if (qs.state == STATE_LANGUAGE)
1353            {
1354                String JavaDoc language = qs.locator.getLanguage();
1355                if (null != language)
1356                {
1357                    if (!dirName.equals(language))
1358                        return;
1359                }
1360                else
1361                {
1362                    qs.profile.setLanguage(dirName);
1363                    qs.clearLanguage = true;
1364                }
1365            }
1366            else if (qs.state == STATE_COUNTRY)
1367            {
1368                String JavaDoc country = qs.locator.getCountry();
1369                if (null != country)
1370                {
1371                    if (!dirName.equals(country))
1372                        return;
1373                }
1374                else
1375                {
1376                    qs.profile.setCountry(dirName);
1377                    qs.clearCountry = true;
1378                }
1379            }
1380
1381            if (!path.endsWith(File.separator))
1382                path += File.separator;
1383
1384            String JavaDoc files[] = file.list();
1385
1386
1387            // Process all files recursivly
1388
for(int ix = 0; files != null && ix < files.length; ix++)
1389            {
1390                subQuery(qs, path + files[ix]);
1391            }
1392
1393            // clear state
1394
if (qs.state == STATE_NAME && true == qs.clearName)
1395            {
1396                if (QUERY_BY_USER == qs.queryBy)
1397                    qs.profile.setUser(null);
1398                else if (QUERY_BY_ROLE == qs.queryBy)
1399                    qs.profile.setRole(null);
1400                else if (QUERY_BY_GROUP == qs.queryBy)
1401                    qs.profile.setGroup(null);
1402                qs.clearName = false;
1403            }
1404            else if (qs.state == STATE_MEDIA && true == qs.clearMedia)
1405            {
1406                qs.profile.setMediaType(null);
1407                qs.clearMedia = false;
1408            }
1409            else if (qs.state == STATE_LANGUAGE && true == qs.clearLanguage)
1410            {
1411                qs.profile.setLanguage(null);
1412                qs.clearLanguage = false;
1413            }
1414            else if (qs.state == STATE_COUNTRY && true == qs.clearCountry)
1415            {
1416                qs.profile.setCountry(null);
1417                qs.clearCountry = false;
1418            }
1419
1420            qs.state--;
1421
1422        }
1423
1424    }
1425
1426     static int QUERY_BY_USER = 0;
1427     static int QUERY_BY_ROLE = 1;
1428     static int QUERY_BY_GROUP = 2;
1429
1430    protected class QueryState
1431    {
1432
1433        QueryState( int queryBy,
1434                    Profile profile,
1435                    ProfileLocator locator,
1436                    List JavaDoc list,
1437                    String JavaDoc name,
1438                    int state)
1439        {
1440            this.queryBy = queryBy;
1441            this.profile = profile;
1442            this.locator = locator;
1443            this.list = list;
1444            this.name = name;
1445            this.state = state;
1446        }
1447
1448        protected int queryBy;
1449        protected Profile profile;
1450        protected ProfileLocator locator;
1451        protected List JavaDoc list;
1452        protected String JavaDoc name;
1453        protected int state;
1454
1455        protected boolean clearName = false;
1456        protected boolean clearMedia = false;
1457        protected boolean clearLanguage = false;
1458        protected boolean clearCountry = false;
1459
1460    }
1461
1462    protected void testCases()
1463    {
1464        try
1465        {
1466            QueryLocator locator = new QueryLocator( QueryLocator.QUERY_USER );
1467            Iterator JavaDoc x1 = query( locator );
1468            dump( x1 );
1469
1470            QueryLocator locator2 = new QueryLocator( QueryLocator.QUERY_USER );
1471            locator2.setUser( JetspeedSecurity.getUser("turbine") );
1472            Iterator JavaDoc x2 = query( locator2 );
1473            dump( x2 );
1474
1475
1476            QueryLocator locator4 = new QueryLocator( QueryLocator.QUERY_GROUP );
1477// locator4.setGroup( JetspeedSecurity.getGroup("apache") );
1478
Iterator JavaDoc x4 = query( locator4 );
1479            dump( x4 );
1480          }
1481        catch (Exception JavaDoc e)
1482        {
1483            System.out.println( "Exception in Debug:" + e);
1484        }
1485    }
1486
1487    protected void dump( Iterator JavaDoc it )
1488    {
1489        System.out.println("===============================================");
1490        while (it.hasNext() )
1491        {
1492            Profile profile = (Profile)it.next();
1493            dumpProfile(profile);
1494        }
1495        System.out.println("===============================================");
1496    }
1497
1498    protected void dumpProfile(Profile profile)
1499    {
1500        JetspeedUser user = profile.getUser();
1501        Group group = profile.getGroup();
1502        Role role = profile.getRole();
1503        if (profile.getAnonymous() == true)
1504            System.out.println("ANON USER");
1505        System.out.println("RESOURCE = " + profile.getName());
1506        if (null != user)
1507            System.out.println("USER = " + user.getUserName() );
1508        if (null != group)
1509            System.out.println("GROUP = " + group.getName() );
1510        if (null != role)
1511            System.out.println("ROLE = " + role.getName() );
1512        System.out.println("MEDIA TYPE = " + profile.getMediaType());
1513        System.out.println("LANGUAGE = " + profile.getLanguage());
1514        System.out.println("COUNTRY = " + profile.getCountry());
1515        PSMLDocument doc = profile.getDocument();
1516        if (null == doc)
1517            System.out.println("Document is null");
1518        else
1519        {
1520            if (null == profile.getName())
1521                System.out.println("profile name is null");
1522            else
1523                System.out.println("Doc.name=" + profile.getName());
1524        }
1525
1526        System.out.println("----------------------");
1527    }
1528
1529    /**
1530     * Refresh event, called when the entry is being refreshed from file system.
1531     *
1532     * @param entry the entry being refreshed.
1533     */

1534    public void refresh(FileCacheEntry entry)
1535    {
1536        if (logger.isInfoEnabled())
1537        {
1538            logger.info("CastorPsmlManager: Entry is refreshing: " + entry.getFile().getPath());
1539        }
1540
1541        Profile profile = (Profile) entry.getDocument();
1542        String JavaDoc path = null;
1543
1544        if (profile != null)
1545        {
1546            try
1547            {
1548                path = entry.getFile().getCanonicalPath();
1549                profile.setDocument(loadDocument(path));
1550            }
1551            catch(java.io.IOException JavaDoc e)
1552            {
1553                logger.error("CastorPsmlManager: Failed to refresh document "+path);
1554            }
1555        }
1556    }
1557
1558    /**
1559     * Evict event, called when the entry is being evicted out of the cache
1560     *
1561     * @param entry the entry being refreshed.
1562     */

1563    public void evict(FileCacheEntry entry)
1564    {
1565        System.out.println("entry is evicting: " + entry.getFile().getName());
1566    }
1567
1568}
1569
1570
Popular Tags