KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > components > repository > SourceRepositoryImpl


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 package org.apache.cocoon.components.repository;
17
18 import java.io.IOException JavaDoc;
19 import java.util.Iterator JavaDoc;
20
21 import org.apache.avalon.framework.logger.AbstractLogEnabled;
22 import org.apache.avalon.framework.service.ServiceException;
23 import org.apache.avalon.framework.service.ServiceManager;
24 import org.apache.avalon.framework.service.Serviceable;
25 import org.apache.avalon.framework.thread.ThreadSafe;
26 import org.apache.excalibur.source.ModifiableSource;
27 import org.apache.excalibur.source.ModifiableTraversableSource;
28 import org.apache.excalibur.source.Source;
29 import org.apache.excalibur.source.SourceException;
30 import org.apache.excalibur.source.SourceResolver;
31 import org.apache.excalibur.source.SourceUtil;
32 import org.apache.excalibur.source.TraversableSource;
33
34 /**
35  * SourceRepository implementation.
36  *
37  * @version $Id: SourceRepositoryImpl.java 123799 2004-12-31 15:12:59Z antonio $
38  */

39 public class SourceRepositoryImpl extends AbstractLogEnabled
40 implements Serviceable, ThreadSafe, SourceRepository {
41     
42     private RepositoryInterceptor m_interceptor = new RepositoryInterceptorBase(){};
43     private SourceResolver m_resolver;
44     
45     
46     // ---------------------------------------------------- lifecycle
47

48     public SourceRepositoryImpl() {
49     }
50     
51     public void service(ServiceManager manager) throws ServiceException {
52         m_resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
53         if (manager.hasService(RepositoryInterceptor.ROLE)) {
54             m_interceptor = (RepositoryInterceptor) manager.lookup(RepositoryInterceptor.ROLE);
55         }
56     }
57     
58     
59     // ---------------------------------------------------- repository operations
60

61     public int save(String JavaDoc in, String JavaDoc out) throws IOException JavaDoc, SourceException {
62         
63         if (getLogger().isDebugEnabled()) {
64             getLogger().debug("save: "+in+"/"+out);
65         }
66         
67         Source source = null;
68         Source destination = null;
69         try {
70             destination = m_resolver.resolveURI(out);
71             
72             if (!(destination instanceof ModifiableSource)) {
73                 final String JavaDoc message =
74                     "Conflict during save(): protocol is not modifiable.";
75                 getLogger().warn(message);
76                 return STATUS_CONFLICT;
77             }
78             
79             final boolean exists = destination.exists();
80             if (!exists) {
81                 Source parent = ((TraversableSource) destination).getParent();
82                 if (!parent.exists()) {
83                     final String JavaDoc message =
84                         "Conflict during save(): parent does not exist.";
85                     getLogger().warn(message);
86                     return STATUS_CONFLICT;
87                 }
88             }
89             
90             if (destination instanceof TraversableSource) {
91                 if (((TraversableSource) destination).isCollection()) {
92                     final String JavaDoc message =
93                         "Conflict during save(): destination is a collection.";
94                     getLogger().warn(message);
95                     return STATUS_CONFLICT;
96                 }
97             }
98             
99             int status;
100             if (exists) {
101                 status = STATUS_OK;
102             }
103             else {
104                 status = STATUS_CREATED;
105             }
106             
107             source = m_resolver.resolveURI(in);
108             m_interceptor.preStoreSource(destination);
109             SourceUtil.copy(source,destination);
110             m_interceptor.postStoreSource(destination);
111             return status;
112         }
113         catch (IOException JavaDoc e) {
114             getLogger().error("Unexpected exception during save().",e);
115             throw e;
116         }
117         finally {
118             if (source != null) {
119                 m_resolver.release(source);
120             }
121             if (destination != null) {
122                 m_resolver.release(destination);
123             }
124         }
125         
126     }
127     
128     public int makeCollection(String JavaDoc location) throws IOException JavaDoc, SourceException {
129         
130         if (getLogger().isDebugEnabled()) {
131             getLogger().debug("makeCollection: " + location);
132         }
133         
134         Source source = null;
135         Source parent = null;
136         try {
137             source = m_resolver.resolveURI(location);
138             
139             if (source.exists()) {
140                 final String JavaDoc message =
141                     "makeCollection() is not allowed: the resource already exists.";
142                 getLogger().warn(message);
143                 return STATUS_NOT_ALLOWED;
144             }
145             
146             if (!(source instanceof ModifiableTraversableSource)) {
147                 final String JavaDoc message =
148                     "Conflict in makeCollection(): source is not modifiable traversable.";
149                 getLogger().warn(message);
150                 return STATUS_CONFLICT;
151             }
152             
153             parent = ((TraversableSource) source).getParent();
154             if (!parent.exists()) {
155                 final String JavaDoc message = "Conflict in makeCollection(): parent does not exist.";
156                 getLogger().warn(message);
157                 return STATUS_CONFLICT;
158             }
159             
160             m_interceptor.preStoreSource(source);
161             ((ModifiableTraversableSource) source).makeCollection();
162             m_interceptor.postStoreSource(source);
163             return STATUS_CREATED;
164         }
165         catch (IOException JavaDoc e) {
166             getLogger().error("Unexpected exception during makeCollection().",e);
167             throw e;
168         }
169         finally {
170             if (source != null) {
171                 m_resolver.release(source);
172             }
173             if (parent != null) {
174                 m_resolver.release(parent);
175             }
176         }
177     }
178     
179     /**
180      * Removes a Source and all of its descendants.
181      *
182      * @param location the location of the source to remove.
183      * @return a http status code describing the exit status.
184      * @throws IOException
185      */

186     public int remove(String JavaDoc location) throws IOException JavaDoc, SourceException {
187         
188         Source source = null;
189         try {
190             source = m_resolver.resolveURI(location);
191             if (!source.exists()) {
192                 final String JavaDoc message =
193                     "Trying to remove a non-existing source.";
194                 getLogger().warn(message);
195                 return STATUS_NOT_FOUND;
196             }
197             return remove(source);
198         }
199         catch (IOException JavaDoc e) {
200             getLogger().error("Unexpected exception during remove().",e);
201             throw e;
202         }
203         finally {
204             if (source != null) {
205                 m_resolver.release(source);
206             }
207         }
208         
209     }
210     
211     private int remove(Source source) throws SourceException {
212         
213         if (getLogger().isDebugEnabled()) {
214             getLogger().debug("remove: " + source.getURI());
215         }
216         
217         if (!(source instanceof ModifiableSource)) {
218             final String JavaDoc message =
219                 "Conflict in remove(): source is not modifiable";
220             getLogger().warn(message);
221             return STATUS_CONFLICT;
222         }
223         
224         if (source instanceof TraversableSource) {
225             if (((TraversableSource) source).isCollection()) {
226                 int status = STATUS_OK;
227                 final Iterator JavaDoc iter = ((TraversableSource) source).getChildren().iterator();
228                 while (iter.hasNext()) {
229                     status = remove((Source) iter.next());
230                     if (status != STATUS_OK) {
231                         return status;
232                     }
233                 }
234             }
235         }
236         m_interceptor.preRemoveSource(source);
237         ((ModifiableSource) source).delete();
238         m_interceptor.postRemoveSource(source);
239         return STATUS_OK;
240     }
241     
242     public int move(String JavaDoc from, String JavaDoc to, boolean recurse, boolean overwrite)
243     throws IOException JavaDoc, SourceException {
244         
245         int status = doCopy(from,to,recurse,overwrite);
246         if (status == STATUS_CREATED || status == STATUS_NO_CONTENT) {
247             // TODO: handle partially successful copies
248
remove(from);
249             // TODO: remove properties
250
}
251         return status;
252     }
253     
254     public int copy(String JavaDoc from, String JavaDoc to, boolean recurse, boolean overwrite)
255     throws IOException JavaDoc, SourceException {
256         
257         return doCopy(from,to,recurse,overwrite);
258         
259     }
260     
261     private int doCopy(String JavaDoc from, String JavaDoc to, boolean recurse, boolean overwrite)
262     throws IOException JavaDoc {
263         
264         if (getLogger().isDebugEnabled()) {
265             getLogger().debug("copy: " + from + " -> " + to
266                 + " (recurse=" + recurse + ", overwrite=" + overwrite + ")");
267         }
268         
269         if (from != null && from.equals(to)) {
270             final String JavaDoc message =
271                 "copy() is forbidden: " +
272                 "The source and destination URIs are the same.";
273             getLogger().warn(message);
274             return STATUS_FORBIDDEN;
275         }
276         Source source = null;
277         Source destination = null;
278         try {
279             source = m_resolver.resolveURI(from);
280             destination = m_resolver.resolveURI(to);
281             if (!source.exists()) {
282                 final String JavaDoc message =
283                     "Trying to copy a non-existing source.";
284                 getLogger().warn(message);
285                 return STATUS_NOT_FOUND;
286             }
287             int status;
288             if (destination.exists()) {
289                 if (!overwrite) {
290                     final String JavaDoc message =
291                         "Failed precondition in copy(): " +
292                         "Destination resource already exists.";
293                     getLogger().warn(message);
294                     return STATUS_PRECONDITION_FAILED;
295                 }
296                 remove(destination);
297                 status = STATUS_NO_CONTENT;
298             }
299             else {
300                 Source parent = null;
301                 try {
302                     parent = getParent(destination);
303                     if (!parent.exists()) {
304                         final String JavaDoc message =
305                             "Conflict in copy(): " +
306                             "A resource cannot be created at the destination " +
307                             "until one or more intermediate collections have been " +
308                             "created.";
309                         getLogger().warn(message);
310                         return STATUS_CONFLICT;
311                     }
312                 }
313                 finally {
314                     if (parent != null) {
315                         m_resolver.release(parent);
316                     }
317                 }
318                 status = STATUS_CREATED;
319             }
320             copy(source,destination,recurse);
321             return status;
322         }
323         catch (IOException JavaDoc e) {
324             getLogger().error("Unexpected exception during copy().",e);
325             throw e;
326         }
327         finally {
328             if (source != null) {
329                 m_resolver.release(source);
330             }
331             if (destination != null) {
332                 m_resolver.release(destination);
333             }
334         }
335     }
336     
337     private int copy(Source source, Source destination, boolean recurse)
338     throws IOException JavaDoc {
339         
340         if (getLogger().isDebugEnabled()) {
341             getLogger().debug("copy: " + source.getURI() + " -> " + destination.getURI());
342         }
343         
344         if (source instanceof TraversableSource) {
345             final TraversableSource origin = (TraversableSource) source;
346             ModifiableTraversableSource target = null;
347             if (origin.isCollection()) {
348                 if (!(destination instanceof ModifiableTraversableSource)) {
349                     final String JavaDoc message = "copy() is forbidden: " +
350                         "Cannot create a collection at the indicated destination.";
351                     getLogger().warn(message);
352                     return STATUS_FORBIDDEN;
353                 }
354                 // TODO: copy properties
355
target = ((ModifiableTraversableSource) destination);
356                 m_interceptor.preStoreSource(target);
357                 target.makeCollection();
358                 m_interceptor.postStoreSource(target);
359                 if (recurse) {
360                     Iterator JavaDoc children = origin.getChildren().iterator();
361                     while (children.hasNext()) {
362                         TraversableSource child = (TraversableSource) children.next();
363                         /*int status =*/ copy(child,target.getChild(child.getName()),recurse);
364                         // TODO: record this status
365
// according to the spec we must continue moving files even though
366
// a part of the move has not succeeded
367
}
368                 }
369                 return STATUS_CREATED;
370             }
371         }
372         if (destination instanceof ModifiableSource) {
373             // TODO: copy properties
374
m_interceptor.preStoreSource(destination);
375             SourceUtil.copy(source,destination);
376             m_interceptor.postStoreSource(destination);
377         }
378         else {
379             final String JavaDoc message = "copy() is forbidden: " +
380                 "Cannot create a resource at the indicated destination.";
381             getLogger().warn(message);
382             return STATUS_FORBIDDEN;
383         }
384         return STATUS_CREATED;
385     }
386     
387     private Source getParent(Source source) throws IOException JavaDoc {
388         if (source instanceof TraversableSource) {
389             return ((TraversableSource) source).getParent();
390         }
391         else {
392             String JavaDoc uri = source.getURI();
393             int index = uri.lastIndexOf('/');
394             if (index != -1) {
395                 return m_resolver.resolveURI(uri.substring(index+1));
396             }
397         }
398         return null;
399     }
400
401 }
402
Popular Tags