KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > source > impl > SlideSource


1 /*
2  * Copyright 1999-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.cocoon.components.source.impl;
18
19 import java.io.ByteArrayOutputStream JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.io.InputStream JavaDoc;
22 import java.io.OutputStream JavaDoc;
23 import java.io.StringReader JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Collection JavaDoc;
26 import java.util.Collections JavaDoc;
27 import java.util.Date JavaDoc;
28 import java.util.Enumeration JavaDoc;
29 import java.util.List JavaDoc;
30
31 import org.apache.avalon.framework.activity.Initializable;
32 import org.apache.avalon.framework.context.Context;
33 import org.apache.avalon.framework.context.ContextException;
34 import org.apache.avalon.framework.context.Contextualizable;
35 import org.apache.avalon.framework.logger.AbstractLogEnabled;
36 import org.apache.avalon.framework.logger.LogEnabled;
37 import org.apache.avalon.framework.logger.Logger;
38 import org.apache.avalon.framework.service.ServiceManager;
39 import org.apache.avalon.framework.service.Serviceable;
40 import org.apache.cocoon.CascadingIOException;
41 import org.apache.cocoon.Constants;
42 import org.apache.cocoon.components.source.InspectableSource;
43 import org.apache.cocoon.components.source.LockableSource;
44 import org.apache.cocoon.components.source.VersionableSource;
45 import org.apache.cocoon.components.source.helpers.SourceLock;
46 import org.apache.cocoon.components.source.helpers.SourceProperty;
47 import org.apache.excalibur.source.ModifiableTraversableSource;
48 import org.apache.excalibur.source.MoveableSource;
49 import org.apache.excalibur.source.Source;
50 import org.apache.excalibur.source.SourceException;
51 import org.apache.excalibur.source.SourceUtil;
52 import org.apache.excalibur.source.SourceValidity;
53 import org.apache.excalibur.source.impl.validity.TimeStampValidity;
54 import org.apache.excalibur.xml.dom.DOMParser;
55 import org.apache.slide.authenticate.CredentialsToken;
56 import org.apache.slide.common.NamespaceAccessToken;
57 import org.apache.slide.common.SlideException;
58 import org.apache.slide.common.SlideToken;
59 import org.apache.slide.common.SlideTokenImpl;
60 import org.apache.slide.content.Content;
61 import org.apache.slide.content.NodeProperty;
62 import org.apache.slide.content.NodeRevisionContent;
63 import org.apache.slide.content.NodeRevisionDescriptor;
64 import org.apache.slide.content.NodeRevisionDescriptors;
65 import org.apache.slide.content.NodeRevisionNumber;
66 import org.apache.slide.content.RevisionDescriptorNotFoundException;
67 import org.apache.slide.lock.Lock;
68 import org.apache.slide.lock.NodeLock;
69 import org.apache.slide.macro.Macro;
70 import org.apache.slide.security.AccessDeniedException;
71 import org.apache.slide.structure.ObjectNode;
72 import org.apache.slide.structure.ObjectNotFoundException;
73 import org.apache.slide.structure.Structure;
74 import org.apache.slide.structure.SubjectNode;
75 import org.w3c.dom.Document JavaDoc;
76 import org.xml.sax.InputSource JavaDoc;
77
78 /**
79  * A sources from jakarta slide repositories.
80  *
81  * @version CVS $Id: SlideSource.java 30932 2004-07-29 17:35:38Z vgritsenko $
82  */

83 public class SlideSource extends AbstractLogEnabled
84 implements Contextualizable, Serviceable, Initializable, Source, ModifiableTraversableSource,
85            MoveableSource, LockableSource, InspectableSource,
86            VersionableSource {
87
88     /* framework objects */
89     private Context m_context;
90     private ServiceManager m_manager;
91     
92     /* Slide access */
93     private NamespaceAccessToken m_nat;
94     private SlideToken m_slideToken;
95     
96     /* Slide helpers */
97     private Structure m_structure;
98     private Content m_content;
99     private Lock m_lock;
100     private Macro m_macro;
101
102     /* Source specifics */
103     private String JavaDoc m_scheme;
104     private String JavaDoc m_path;
105     private String JavaDoc m_scope;
106     private String JavaDoc m_uri;
107     
108     private ObjectNode m_node;
109     private NodeRevisionNumber m_version;
110     private NodeRevisionDescriptors m_descriptors;
111     private NodeRevisionDescriptor m_descriptor;
112     
113     private String JavaDoc m_principal;
114     private SourceValidity m_validity;
115
116     private SlideSourceOutputStream m_outputStream;
117
118     /**
119      * Create a slide source.
120      *
121      * @param nat Namespace access token
122      * @param scheme Scheme of the source
123      * @param path Path of the source.
124      */

125     public SlideSource(NamespaceAccessToken nat,
126                        String JavaDoc scheme,
127                        String JavaDoc scope,
128                        String JavaDoc path,
129                        String JavaDoc principal,
130                        String JavaDoc version) {
131
132         m_nat = nat;
133         m_scheme = scheme;
134         m_scope = scope;
135         m_path = path;
136         if (path.equals("/")) {
137             m_uri = scope;
138         }
139         else if (scope.equals("/")){
140             m_uri = path;
141         }
142         else {
143             m_uri = scope + path;
144         }
145         m_principal = principal;
146         if (version != null) {
147             m_version = new NodeRevisionNumber(version);
148         }
149     }
150     
151     /**
152      * Pass the Context to the component.
153      * This method is called after the LogEnabled.enableLogging() (if present)
154      * method and before any other method.
155      *
156      * @param context The context.
157      */

158     public void contextualize(Context context) {
159         this.m_context = context;
160     }
161
162     /**
163      * Pass the ServiceManager to the composer. The Serviceable implementation
164      * should use the specified ServiceManager to acquire the services it needs for execution
165      *
166      * @param manager The ServiceManager which this Serviceable uses
167      */

168     public void service(ServiceManager manager) {
169         m_manager = manager;
170     }
171
172     public void initialize() throws SourceException {
173         
174         CredentialsToken credentials = new CredentialsToken(m_principal);
175         m_slideToken = new SlideTokenImpl(credentials);
176         
177         m_structure = m_nat.getStructureHelper();
178         m_content = m_nat.getContentHelper();
179         m_lock = m_nat.getLockHelper();
180         m_macro = m_nat.getMacroHelper();
181         
182         try {
183             if (m_node == null) {
184                 m_node = m_structure.retrieve(m_slideToken,m_uri);
185             }
186                 
187             m_descriptors = m_content.retrieve(m_slideToken,m_uri);
188             if (m_version != null) {
189                 // get a specific version
190
m_descriptor = m_content.retrieve(m_slideToken,m_descriptors,m_version);
191             }
192             else {
193                 // get the latest one
194
m_descriptor = m_content.retrieve(m_slideToken,m_descriptors);
195                 m_version = m_descriptor.getRevisionNumber();
196             }
197         }
198         catch (ObjectNotFoundException e) {
199             if (getLogger().isDebugEnabled()) {
200                 getLogger().debug("Not found.",e);
201             }
202             // assert m_node == null;
203
}
204         catch (RevisionDescriptorNotFoundException e) {
205             if (getLogger().isDebugEnabled()) {
206                 getLogger().debug("Could not retrieve descriptor.",e);
207             }
208             // assert m_descriptor == null;
209
}
210         catch (AccessDeniedException e) {
211             throw new SourceException("Access denied.",e);
212         }
213         catch (SlideException e) {
214             throw new SourceException("Failure during source initialization.",e);
215         }
216     }
217
218     /**
219      * Return an <code>InputStream</code> object to read from the source.
220      * This is the data at the point of invocation of this method,
221      * so if this is Modifiable, you might get different content
222      * from two different invocations.
223      *
224      * @return Input stream for the source.
225      *
226      * @throws IOException If an IO excepetion occurs.
227      * @throws SourceException If an exception occurs.
228      */

229     public InputStream JavaDoc getInputStream() throws IOException JavaDoc, SourceException {
230         try {
231             return m_content.retrieve(m_slideToken,m_descriptors,m_descriptor).streamContent();
232         } catch (SlideException se) {
233             throw new SourceException("Could not get source", se);
234         }
235     }
236
237     /**
238      * Return the unique identifer for this source
239      *
240      * @return System identifier for the source.
241      */

242     public String JavaDoc getURI() {
243         return m_scheme + "://" + m_principal + "@" + m_nat.getName() + m_path;
244     }
245
246     /**
247      * @see org.apache.excalibur.source.Source#getScheme()
248      *
249      * @return Scheme of the source.
250      */

251     public String JavaDoc getScheme() {
252         return m_scheme;
253     }
254
255     /**
256      * Get the Validity object. This can either wrap the last modification
257      * date or the expires information or...
258      * If it is currently not possible to calculate such an information
259      * <code>null</code> is returned.
260      *
261      * @return Validity for the source.
262      */

263     public SourceValidity getValidity() {
264         if (m_validity == null && m_descriptor != null) {
265             final long lastModified = getLastModified();
266             if (lastModified > 0) {
267                 m_validity = new TimeStampValidity(lastModified);
268             }
269         }
270         return m_validity;
271     }
272
273     /**
274      * Refresh the content of this object after the underlying data
275      * content has changed.
276      */

277     public void refresh() {
278         m_validity = null;
279     }
280
281     /**
282      * The mime-type of the content described by this object.
283      * If the source is not able to determine the mime-type by itself
284      * this can be null.
285      *
286      * @return Mime type of the source.
287      */

288     public String JavaDoc getMimeType() {
289         if (m_descriptor != null) {
290             return m_descriptor.getContentType();
291         }
292         return null;
293     }
294
295     /**
296      * Does this source actually exist ?
297      *
298      * @return true if the resource exists.
299      */

300     public boolean exists() {
301         return m_node != null;
302     }
303
304     /**
305      * Return the content length of the content or -1 if the length is
306      * unknown.
307      *
308      * @return Content length of the source.
309      */

310     public long getContentLength() {
311         if (m_descriptor != null) {
312             return m_descriptor.getContentLength();
313         }
314         return -1;
315     }
316
317     /**
318      * Get the last modification date of the source or 0 if it
319      * is not possible to determine the date.
320      *
321      * @return Last modified date of the source.
322      */

323     public long getLastModified() {
324         if (m_descriptor != null) {
325             return m_descriptor.getLastModifiedAsDate().getTime();
326         }
327         return 0;
328     }
329     
330     // ---------------------------------------------------- ModifiableTraversableSource
331

332     /**
333      * Get an <code>OutputStream</code> where raw bytes can be written to.
334      * The signification of these bytes is implementation-dependent and
335      * is not restricted to a serialized XML document.
336      *
337      * @return a stream to write to
338      *
339      * @throws IOException
340      * @throws SourceException
341      */

342     public OutputStream JavaDoc getOutputStream()
343       throws IOException JavaDoc, SourceException {
344         if (m_outputStream == null) {
345             m_outputStream = new SlideSourceOutputStream();
346             m_outputStream.enableLogging(getLogger());
347         }
348         return m_outputStream;
349     }
350
351     /**
352      * Can the data sent to an <code>OutputStream</code> returned by
353      * {@link #getOutputStream()} be cancelled ?
354      *
355      * @param stream The ouput stream, which should be cancelled.
356      * @return true if the stream can be cancelled
357      */

358     public boolean canCancel(OutputStream JavaDoc stream) {
359         return m_outputStream.canCancel();
360     }
361
362     /**
363      * Cancel the data sent to an <code>OutputStream</code> returned by
364      * {@link #getOutputStream()}.
365      * <p>
366      * After cancel, the stream should no more be used.
367      *
368      * @param stream The ouput stream, which should be cancelled.
369      *
370      * @throws SourceException If the ouput stream can't be cancelled.
371      */

372     public void cancel(OutputStream JavaDoc stream) throws SourceException {
373         if (m_outputStream == stream) {
374             try {
375                 m_outputStream.cancel();
376             } catch (Exception JavaDoc e) {
377                 throw new SourceException("Could not cancel output stream",e);
378             }
379         }
380     }
381     
382     /**
383      * Delete the source.
384      */

385     public void delete() {
386         try {
387             m_nat.begin();
388             m_macro.delete(m_slideToken,m_uri);
389             m_nat.commit();
390         } catch (Exception JavaDoc se) {
391             getLogger().error("Could not delete source.",se);
392             try {
393                 m_nat.rollback();
394             } catch (Exception JavaDoc rbe) {
395                 getLogger().error("Rollback failed for moving source",rbe);
396             }
397         }
398     }
399     
400     public void makeCollection() throws SourceException {
401         SubjectNode collection = new SubjectNode();
402         NodeRevisionDescriptor descriptor = new NodeRevisionDescriptor(0);
403
404         descriptor.setResourceType("<collection/>");
405         descriptor.setCreationDate(new Date JavaDoc());
406         descriptor.setLastModified(new Date JavaDoc());
407         descriptor.setContentLength(0);
408         descriptor.setSource("");
409         descriptor.setOwner(m_slideToken.getCredentialsToken().getPublicCredentials());
410
411         try {
412             m_nat.begin();
413             m_structure.create(m_slideToken,collection,m_uri);
414             m_content.create(m_slideToken,m_uri,descriptor,null);
415             m_nat.commit();
416         } catch (Exception JavaDoc se) {
417             try {
418                 m_nat.rollback();
419             } catch (Exception JavaDoc rbe) {
420                 getLogger().error("Rollback failed for creating collection", rbe);
421             }
422             throw new SourceException("Could not create collection.", se);
423         }
424     }
425     
426     public Source getChild(String JavaDoc name) throws SourceException {
427         return getChildByPath(m_path+"/"+name);
428     }
429     
430     private Source getChildByPath(String JavaDoc path) throws SourceException {
431         SlideSource child = new SlideSource(m_nat,m_scheme,m_scope,path,m_principal,null);
432         child.enableLogging(getLogger());
433         child.contextualize(m_context);
434         child.service(m_manager);
435         child.initialize();
436         return child;
437     }
438
439     public Collection JavaDoc getChildren() throws SourceException {
440         if (m_node == null || !m_node.hasChildren()) {
441             return Collections.EMPTY_LIST;
442         }
443         List JavaDoc result = new ArrayList JavaDoc();
444         final Enumeration JavaDoc children = m_node.enumerateChildren();
445         while (children.hasMoreElements()) {
446             String JavaDoc child = (String JavaDoc) children.nextElement();
447             child = child.substring(m_scope.length());
448             result.add(getChildByPath(child));
449         }
450         return result;
451     }
452     
453     public String JavaDoc getName() {
454         int index = m_path.lastIndexOf('/');
455         if (index != -1) {
456             return m_path.substring(index+1);
457         }
458         return m_path;
459     }
460     
461     public Source getParent() throws SourceException {
462         if (m_path.length() == 1) {
463             // assert m_path.equals("/")
464
return null;
465         }
466         int index = m_path.lastIndexOf('/');
467         if (index == -1) {
468             return null;
469         }
470         String JavaDoc parentPath;
471         if (index == 0) {
472             parentPath = "/";
473         }
474         else if (index == m_path.length()-1) {
475             // assert m_path.endsWith("/")
476
parentPath = m_path.substring(0,m_path.substring(0, m_path.length()-1).lastIndexOf('/'));
477         }
478         else {
479             parentPath = m_path.substring(0,index);
480         }
481         SlideSource parent = new SlideSource(m_nat,m_scheme,m_scope,parentPath,m_principal,null);
482         parent.enableLogging(getLogger());
483         parent.contextualize(m_context);
484         parent.service(m_manager);
485         parent.initialize();
486         return parent;
487
488     }
489     
490     public boolean isCollection() {
491         if (m_node == null) {
492             return false;
493         }
494         if (m_descriptor == null) {
495             // FIXME: is this correct?
496
return true;
497         }
498         NodeProperty property = m_descriptor.getProperty("resourcetype");
499         if (property != null && ((String JavaDoc) property.getValue()).startsWith("<collection/>")) {
500             return true;
501         }
502         return false;
503     }
504     
505     /**
506      * A helper for the getOutputStream() method
507      */

508     class SlideSourceOutputStream extends ByteArrayOutputStream JavaDoc implements LogEnabled {
509         private boolean isClosed = false;
510         private Logger logger = null;
511
512         /**
513          * Provide component with a logger.
514          *
515          * @param logger the logger
516          */

517         public void enableLogging(Logger logger) {
518             this.logger = logger;
519         }
520
521         /**
522          *
523          *
524          * @throws IOException
525          */

526         public void close() throws IOException JavaDoc {
527             super.close();
528
529             byte[] bytes = new byte[0]; // must be initialized
530

531             try {
532                 NodeRevisionContent content = new NodeRevisionContent();
533                 bytes = toByteArray();
534                 content.setContent(bytes);
535
536                 if (m_descriptor == null) {
537                     m_descriptor = new NodeRevisionDescriptor(0);
538                     m_descriptor.setName(getName());
539                 }
540
541                 m_descriptor.setContentLength(bytes.length);
542                 m_descriptor.setLastModified(new Date JavaDoc());
543
544                 m_nat.begin();
545                 if (m_version == null) {
546                     m_content.create(m_slideToken,m_uri,m_descriptor,null);
547                 }
548                 m_content.store(m_slideToken,m_uri,m_descriptor,content);
549                 try {
550                     m_nat.commit();
551                 } catch (Exception JavaDoc cme) {
552                     throw new CascadingIOException("Could not commit the transaction",cme);
553                 }
554
555             } catch (ObjectNotFoundException e) {
556                 
557                 // Todo : Check to see if parent exists
558
SubjectNode subject = new SubjectNode();
559
560                 try {
561                     // Creating an object
562
m_structure.create(m_slideToken,subject,m_uri);
563                 } catch (SlideException se) {
564                     throw new CascadingIOException(se);
565                 }
566
567                 NodeRevisionDescriptor descriptor = new NodeRevisionDescriptor(bytes.length);
568                 descriptor.setResourceType("");
569                 descriptor.setSource("");
570                 descriptor.setContentLanguage("en");
571                 descriptor.setContentLength(bytes.length);
572                 String JavaDoc contentType = null;
573
574                 try {
575                     contentType = ((org.apache.cocoon.environment.Context)
576                         m_context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT)).getMimeType(m_path);
577                 } catch (ContextException ce) {
578                     this.logger.warn("Could not get context to determine the mime type.");
579                 }
580                 if (contentType == null) {
581                     contentType = "application/octet-stream";
582                 }
583                 descriptor.setContentType(contentType);
584                 descriptor.setLastModified(new Date JavaDoc());
585                 descriptor.setOwner(m_slideToken.getCredentialsToken().getPublicCredentials());
586                 NodeRevisionContent content = new NodeRevisionContent();
587                 
588                 content.setContent(bytes);
589                 try {
590                     m_content.create(m_slideToken,m_uri,descriptor,content);
591                     try {
592                         m_nat.commit();
593                     } catch (Exception JavaDoc cme) {
594                         throw new CascadingIOException("Could not commit the transaction",cme);
595
596                     }
597                 } catch (SlideException se) {
598                     try {
599                         m_nat.rollback();
600                     } catch (Exception JavaDoc rbe) {
601                         this.logger.warn("Could not rollback the transaction.",rbe);
602                     }
603                     throw new CascadingIOException("Could not create source",se);
604                 }
605
606             } catch (Exception JavaDoc e) {
607                 if (e instanceof IOException JavaDoc) {
608                     throw (IOException JavaDoc) e;
609                 }
610                 throw new CascadingIOException("Could not create source", e);
611             } finally {
612                 this.isClosed = true;
613             }
614         }
615
616         /**
617          * Can the data sent to an <code>OutputStream</code> returned by
618          * {@link SlideSource#getOutputStream()} be cancelled ?
619          *
620          * @return true if the stream can be cancelled
621          */

622         boolean canCancel() {
623             return !this.isClosed;
624         }
625
626         /**
627          * Cancel the data sent to an <code>OutputStream</code> returned by
628          * {@link SlideSource#getOutputStream()}.
629          * <p>
630          * After cancel, the stream should no more be used.
631          *
632          */

633         void cancel() throws Exception JavaDoc {
634             if (this.isClosed) {
635                 throw new IllegalStateException JavaDoc("Cannot cancel : outputstrem is already closed");
636             }
637             this.isClosed = true;
638             super.close();
639         }
640     }
641
642     // ---------------------------------------------------- MoveableSource
643

644     /**
645      * Move the current source to a specified destination.
646      *
647      * @param source
648      *
649      * @throws SourceException If an exception occurs during the move.
650      */

651     public void moveTo(Source source) throws SourceException {
652         if (source instanceof SlideSource) {
653             try {
654                 m_nat.begin();
655                 String JavaDoc destination = m_scope+((SlideSource) source).m_path;
656                 m_macro.move(m_slideToken,m_uri,destination);
657                 m_nat.commit();
658             } catch (Exception JavaDoc se) {
659                 try {
660                     m_nat.rollback();
661                 } catch (Exception JavaDoc rbe) {
662                     getLogger().error("Rollback failed for moving source", rbe);
663                 }
664                 throw new SourceException("Could not move source.", se);
665             }
666         } else {
667             SourceUtil.move(this,source);
668         }
669     }
670
671     /**
672      * Copy the current source to a specified destination.
673      *
674      * @param source
675      *
676      * @throws SourceException If an exception occurs during the copy.
677      */

678     public void copyTo(Source source) throws SourceException {
679         if (source instanceof SlideSource) {
680             try {
681                 m_nat.begin();
682                 String JavaDoc destination = m_scope+((SlideSource) source).m_path;
683                 m_macro.copy(m_slideToken,m_uri,destination);
684                 m_nat.commit();
685             } catch (Exception JavaDoc se) {
686                 try {
687                     m_nat.rollback();
688                 } catch (Exception JavaDoc rbe) {
689                     
690                     getLogger().error("Rollback failed for moving source",rbe);
691                 }
692                 throw new SourceException("Could not move source.",se);
693             }
694         } else {
695             SourceUtil.copy(this,source);
696         }
697     }
698
699     // ---------------------------------------------------- InspectableSource
700

701     /**
702      * Returns a property from a source.
703      *
704      * @param namespace Namespace of the property
705      * @param name Name of the property
706      *
707      * @return Property of the source.
708      *
709      * @throws SourceException If an exception occurs.
710      */

711     public SourceProperty getSourceProperty(String JavaDoc namespace, String JavaDoc name)
712         throws SourceException {
713
714         if (m_descriptor == null) {
715             return null;
716         }
717
718         final String JavaDoc quote = "\"";
719         NodeProperty property = m_descriptor.getProperty(name, namespace);
720
721         if (property == null) {
722             return null;
723         }
724
725         String JavaDoc pre = "<"+name+" xmlns="+quote+namespace+quote+" >";
726         String JavaDoc post = "</"+name+" >";
727
728         StringReader JavaDoc reader = new StringReader JavaDoc(pre+property.getValue().toString()+post);
729         InputSource JavaDoc src = new InputSource JavaDoc(reader);
730
731         DOMParser parser = null;
732         Document JavaDoc doc = null;
733
734         try {
735             parser = (DOMParser) this.m_manager.lookup(DOMParser.ROLE);
736             doc = parser.parseDocument(src);
737         } catch (Exception JavaDoc e) {
738             throw new SourceException("Could not parse property", e);
739         } finally {
740             this.m_manager.release(parser);
741         }
742
743         return new SourceProperty(doc.getDocumentElement());
744     }
745     
746     /**
747      * Sets a property for a source.
748      *
749      * @param property Property of the source
750      *
751      * @throws SourceException If an exception occurs during this operation
752      */

753     public void setSourceProperty(SourceProperty property)
754       throws SourceException {
755         try {
756             m_descriptor.setProperty(property.getName(),
757                                      property.getNamespace(),
758                                      property.getValueAsString());
759             m_descriptor.setLastModified(new Date JavaDoc());
760
761             m_nat.begin();
762             m_content.store(m_slideToken,m_uri,m_descriptor,null);
763             m_nat.commit();
764         } catch (Exception JavaDoc se) {
765             try {
766                 m_nat.rollback();
767             } catch (Exception JavaDoc rbe) {
768                 getLogger().error("Rollback failed for setting a source property", rbe);
769             }
770             throw new SourceException("Could not set source property", se);
771         }
772     }
773
774     /**
775      * Returns a enumeration of the properties
776      *
777      * @return Enumeration of SourceProperty
778      *
779      * @throws SourceException If an exception occurs.
780      */

781     public SourceProperty[] getSourceProperties() throws SourceException {
782
783         if (m_descriptor == null) {
784             return new SourceProperty[0];
785         }
786
787         List JavaDoc properties = new ArrayList JavaDoc();
788         DOMParser parser = null;
789         String JavaDoc xml = "";
790
791         try {
792             parser = (DOMParser) m_manager.lookup(DOMParser.ROLE);
793             final String JavaDoc quote = "\"";
794             Enumeration JavaDoc e = m_descriptor.enumerateProperties();
795             while (e.hasMoreElements()) {
796                 NodeProperty property = (NodeProperty) e.nextElement();
797                 String JavaDoc name = property.getName();
798                 String JavaDoc namespace = property.getNamespace();
799                 String JavaDoc pre = "<"+name+" xmlns="+quote+namespace+quote+" >";
800                 String JavaDoc post = "</"+name+" >";
801                 xml = pre+property.getValue().toString()+post;
802                 
803                 StringReader JavaDoc reader = new StringReader JavaDoc(xml);
804                 Document JavaDoc doc = parser.parseDocument(new InputSource JavaDoc(reader));
805                 properties.add(new SourceProperty(doc.getDocumentElement()));
806             }
807         } catch (Exception JavaDoc e) {
808             throw new SourceException("Could not parse property "+xml, e);
809         } finally {
810             m_manager.release(parser);
811         }
812
813         return (SourceProperty[]) properties.toArray(new SourceProperty[properties.size()]);
814     }
815
816     /**
817      * Remove a specified source property.
818      *
819      * @param namespace Namespace of the property.
820      * @param name Name of the property.
821      *
822      * @throws SourceException If an exception occurs.
823      */

824     public void removeSourceProperty(String JavaDoc namespace, String JavaDoc name) throws SourceException {
825         try {
826             if (m_descriptor != null && !namespace.equals("DAV:")) {
827                 m_descriptor.removeProperty(name, namespace);
828                 m_descriptor.setLastModified(new Date JavaDoc());
829                 m_nat.begin();
830                 m_content.store(m_slideToken,m_uri,m_descriptor,null);
831                 m_nat.commit();
832             }
833         } catch (Exception JavaDoc se) {
834             try {
835                 m_nat.rollback();
836             } catch (Exception JavaDoc rbe) {
837                 getLogger().error("Rollback failed for removing a source property", rbe);
838             }
839             throw new SourceException("Could not remove property", se);
840         }
841     }
842     
843     // ---------------------------------------------------- LockableSource
844

845     /**
846      * Add a lock to this source
847      *
848      * @param sourcelock Lock, which should be added
849      *
850      * @throws SourceException If an exception occurs during this operation
851      */

852     public void addSourceLocks(SourceLock sourcelock) throws SourceException {
853         throw new SourceException("Operation not yet supported");
854     }
855
856     /**
857      * Returns a enumeration of the existing locks
858      *
859      * @return Enumeration of SourceLock
860      *
861      * @throws SourceException If an exception occurs.
862      */

863     public SourceLock[] getSourceLocks() throws SourceException {
864         try {
865             List JavaDoc result = new ArrayList JavaDoc();
866
867             NodeLock lock;
868             Enumeration JavaDoc locks = m_lock.enumerateLocks(m_slideToken,m_uri, false);
869             while (locks.hasMoreElements()) {
870                 lock = (NodeLock) locks.nextElement();
871                 result.add(new SourceLock(lock.getSubjectUri(),
872                                           lock.getTypeUri(),
873                                           lock.getExpirationDate(),
874                                           lock.isInheritable(),
875                                           lock.isExclusive()));
876             }
877
878             return (SourceLock[]) result.toArray(new SourceLock[result.size()]);
879         } catch (SlideException se) {
880             throw new SourceException("Could not retrieve locks", se);
881         }
882     }
883
884     // ---------------------------------------------------- VersionableSource
885

886     /**
887      * If this source versioned
888      *
889      * @return True if the current source is versioned.
890      *
891      * @throws SourceException If an exception occurs.
892      */

893     public boolean isVersioned() throws SourceException {
894         if (m_descriptors != null) {
895             return m_descriptors.hasRevisions();
896         }
897         return false;
898     }
899
900     /**
901      * Get the current revision of the source
902      *
903      * @return The current revision of the source
904      *
905      */

906     public String JavaDoc getSourceRevision() {
907         if (m_version != null) {
908             return m_version.toString();
909         }
910         return null;
911     }
912
913     /**
914      * Not implemented.
915      *
916      * @param revision The revision, which should be used.
917      *
918      * @throws SourceException If an exception occurs.
919      */

920     public void setSourceRevision(String JavaDoc revision) throws SourceException {
921         // [UH] this method is wrong. different versions should be obtained
922
// by creating a new source
923
throw new SourceException("method not implemented");
924     }
925
926     /**
927      * Get the current branch of the revision from the source
928      *
929      * @return The branch of the revision
930      *
931      * @throws SourceException If an exception occurs.
932      */

933     public String JavaDoc getSourceRevisionBranch() throws SourceException {
934         if (m_descriptor != null) {
935             return m_descriptor.getBranchName();
936         }
937         return null;
938     }
939
940     /**
941      * Not implemented.
942      *
943      * @param branch The branch, which should be used.
944      *
945      * @throws SourceException If an exception occurs.
946      */

947     public void setSourceRevisionBranch(String JavaDoc branch) throws SourceException {
948         // [UH] this method is wrong. different versions should be obtained
949
// by creating a new source
950
throw new SourceException("method not implemented");
951     }
952
953     /**
954      * Get the latest revision
955      *
956      * @return Last revision of the source.
957      *
958      * @throws SourceException If an exception occurs.
959      */

960     public String JavaDoc getLatestSourceRevision() throws SourceException {
961         if (m_descriptors != null) {
962             return m_descriptors.getLatestRevision().toString();
963         }
964         return null;
965     }
966
967 }
968
969
Popular Tags