KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > repo > webdav > WebDAVHelper


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.repo.webdav;
18
19 import java.io.UnsupportedEncodingException JavaDoc;
20 import java.net.URLEncoder JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.Collections JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.StringTokenizer JavaDoc;
25
26 import org.alfresco.model.ContentModel;
27 import org.alfresco.service.ServiceRegistry;
28 import org.alfresco.service.cmr.dictionary.DictionaryService;
29 import org.alfresco.service.cmr.lock.LockService;
30 import org.alfresco.service.cmr.model.FileFolderService;
31 import org.alfresco.service.cmr.model.FileInfo;
32 import org.alfresco.service.cmr.model.FileNotFoundException;
33 import org.alfresco.service.cmr.repository.CopyService;
34 import org.alfresco.service.cmr.repository.MimetypeService;
35 import org.alfresco.service.cmr.repository.NodeRef;
36 import org.alfresco.service.cmr.repository.NodeService;
37 import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
38 import org.alfresco.service.cmr.search.SearchService;
39 import org.alfresco.service.cmr.security.AuthenticationService;
40 import org.alfresco.service.namespace.NamespaceService;
41 import org.alfresco.util.EqualsHelper;
42 import org.apache.commons.logging.Log;
43 import org.apache.commons.logging.LogFactory;
44 import org.xml.sax.helpers.AttributesImpl JavaDoc;
45
46 /**
47  * WebDAV Protocol Helper Class
48  *
49  * <p>Provides helper methods for repository access using the WebDAV protocol.
50  *
51  * @author GKSpencer
52  */

53 public class WebDAVHelper
54 {
55     // Constants
56

57     // Path seperator
58
public static final String JavaDoc PathSeperator = "/";
59     public static final char PathSeperatorChar = '/';
60     
61     // Logging
62
private static Log logger = LogFactory.getLog("org.alfresco.protocol.webdav");
63     
64     // Service registry
65
private ServiceRegistry m_serviceRegistry;
66
67     // Services
68
private NodeService m_nodeService;
69     private FileFolderService m_fileFolderService;
70     private SearchService m_searchService;
71     private NamespaceService m_namespaceService;
72     private DictionaryService m_dictionaryService;
73     private MimetypeService m_mimetypeService;
74     private LockService m_lockService;
75     private AuthenticationService m_authService;
76     
77     // Empty XML attribute list
78

79     private AttributesImpl JavaDoc m_nullAttribs = new AttributesImpl JavaDoc();
80     
81     /**
82      * Class constructor
83      *
84      * @param serviceRegistry ServiceRegistry
85      * @param authService AuthenticationService
86      */

87     protected WebDAVHelper(ServiceRegistry serviceRegistry, AuthenticationService authService)
88     {
89         m_serviceRegistry = serviceRegistry;
90         
91         m_nodeService = m_serviceRegistry.getNodeService();
92         m_fileFolderService = m_serviceRegistry.getFileFolderService();
93         m_searchService = m_serviceRegistry.getSearchService();
94         m_namespaceService = m_serviceRegistry.getNamespaceService();
95         m_dictionaryService = m_serviceRegistry.getDictionaryService();
96         m_mimetypeService = m_serviceRegistry.getMimetypeService();
97         m_lockService = m_serviceRegistry.getLockService();
98         
99         m_authService = authService;
100     }
101     
102     /**
103      * Return the authentication service
104      *
105      * @return AuthenticationService
106      */

107     public final AuthenticationService getAuthenticationService()
108     {
109         return m_authService;
110     }
111     
112     /**
113      * Return the service registry
114      *
115      * @return ServiceRegistry
116      */

117     public final ServiceRegistry getServiceRegistry()
118     {
119         return m_serviceRegistry;
120     }
121     
122     /**
123      * Return the node service
124      *
125      * @return NodeService
126      */

127     public final NodeService getNodeService()
128     {
129         return m_nodeService;
130     }
131     
132     public FileFolderService getFileFolderService()
133     {
134         return m_fileFolderService;
135     }
136
137     /**
138      * Return the search service
139      *
140      * @return SearchService
141      */

142     public final SearchService getSearchService()
143     {
144         return m_searchService;
145     }
146     
147     /**
148      * Return the namespace service
149      *
150      * @return NamespaceService
151      */

152     public final NamespaceService getNamespaceService()
153     {
154         return m_namespaceService;
155     }
156     
157     /**
158      * Return the dictionary service
159      *
160      * @return DictionaryService
161      */

162     public final DictionaryService getDictionaryService()
163     {
164         return m_dictionaryService;
165     }
166
167     /**
168      * Return the mimetype service
169      *
170      * @return MimetypeService
171      */

172     public final MimetypeService getMimetypeService()
173     {
174         return m_mimetypeService;
175     }
176     
177     /**
178      * Return the lock service
179      *
180      * @return LockService
181      */

182     public final LockService getLockService()
183     {
184         return m_lockService;
185     }
186     
187     /**
188      * Return the copy service
189      *
190      * @return CopyService
191      */

192     public final CopyService getCopyService()
193     {
194         return getServiceRegistry().getCopyService();
195     }
196     
197     /**
198      * Split the path into seperate directory path and file name strings.
199      * If the path is not empty, then there will always be an entry for the filename
200      *
201      * @param path Full path string.
202      * @return Returns a String[2] with the folder path and file path.
203      */

204     public final String JavaDoc[] splitPath(String JavaDoc path)
205     {
206         if (path == null)
207             throw new IllegalArgumentException JavaDoc("path may not be null");
208         
209         // Create an array of strings to hold the path and file name strings
210
String JavaDoc[] pathStr = new String JavaDoc[] {"", ""};
211
212         // Check if the path has a trailing seperator, if so then there is no file name.
213

214         int pos = path.lastIndexOf(PathSeperatorChar);
215         if (pos == -1 || pos == (path.length() - 1))
216         {
217             // Set the path string in the returned string array
218
pathStr[1] = path;
219         }
220         else
221         {
222             pathStr[0] = path.substring(0, pos);
223             pathStr[1] = path.substring(pos + 1);
224         }
225         // Return the path strings
226
return pathStr;
227     }
228     
229     /**
230      * Split the path into all the component directories and filename
231      *
232      * @param path String
233      * @return String[]
234      */

235     public final List JavaDoc<String JavaDoc> splitAllPaths(String JavaDoc path)
236     {
237         if (path == null || path.length() == 0)
238         {
239             return Collections.emptyList();
240         }
241
242         // split the path
243
StringTokenizer JavaDoc token = new StringTokenizer JavaDoc(path, PathSeperator);
244         List JavaDoc<String JavaDoc> results = new ArrayList JavaDoc<String JavaDoc>(10);
245         while (token.hasMoreTokens())
246         {
247             results.add(token.nextToken());
248         }
249         return results;
250     }
251
252     /**
253      * Get the file info for the given paths
254      *
255      * @param rootNodeRef the acting webdav root
256      * @param path the path to search for
257      * @param servletPath the base servlet path, which may be null or empty
258      * @return Return the file info for the path
259      * @throws FileNotFoundException if the path doesn't refer to a valid node
260      */

261     public final FileInfo getNodeForPath(NodeRef rootNodeRef, String JavaDoc path, String JavaDoc servletPath) throws FileNotFoundException
262     {
263         if (rootNodeRef == null)
264         {
265             throw new IllegalArgumentException JavaDoc("Root node may not be null");
266         }
267         else if (path == null)
268         {
269             throw new IllegalArgumentException JavaDoc("Path may not be null");
270         }
271         
272         FileFolderService fileFolderService = getFileFolderService();
273         // Check for the root path
274
if ( path.length() == 0 || path.equals(PathSeperator) || EqualsHelper.nullSafeEquals(path, servletPath))
275         {
276             return fileFolderService.getFileInfo(rootNodeRef);
277         }
278         
279         // remove the servlet path from the path
280
if (servletPath != null && servletPath.length() > 0 && path.startsWith(servletPath))
281         {
282             // Strip the servlet path from the relative path
283
path = path.substring(servletPath.length());
284         }
285         
286         // split the paths up
287
List JavaDoc<String JavaDoc> splitPath = splitAllPaths(path);
288         
289         // find it
290
FileInfo fileInfo = m_fileFolderService.resolveNamePath(rootNodeRef, splitPath);
291         
292         // done
293
if (logger.isDebugEnabled())
294         {
295             logger.debug("Fetched node for path: \n" +
296                     " root: " + rootNodeRef + "\n" +
297                     " path: " + path + "\n" +
298                     " servlet path: " + servletPath + "\n" +
299                     " result: " + fileInfo);
300         }
301         return fileInfo;
302     }
303     
304     public final FileInfo getParentNodeForPath(NodeRef rootNodeRef, String JavaDoc path, String JavaDoc servletPath) throws FileNotFoundException
305     {
306         if (rootNodeRef == null)
307         {
308             throw new IllegalArgumentException JavaDoc("Root node may not be null");
309         }
310         else if (path == null)
311         {
312             throw new IllegalArgumentException JavaDoc("Path may not be null");
313         }
314         // shorten the path
315
String JavaDoc[] paths = splitPath(path);
316         return getNodeForPath(rootNodeRef, paths[0], servletPath);
317     }
318     
319     /**
320      * Return the relative path for the node walking back to the specified root node
321      *
322      * @param rootNodeRef the root below which the path will be valid
323      * @param nodeRef the node's path to get
324      * @return Returns string of form <b>/A/B/C</b> where C represents the from node and
325      */

326     public final String JavaDoc getPathFromNode(NodeRef rootNodeRef, NodeRef nodeRef) throws FileNotFoundException
327     {
328         // Check if the nodes are valid, or equal
329
if (rootNodeRef == null || nodeRef == null)
330             throw new IllegalArgumentException JavaDoc("Invalid node(s) in getPathFromNode call");
331         
332         // short cut if the path node is the root node
333
if (rootNodeRef.equals(nodeRef))
334             return "";
335         
336         FileFolderService fileFolderService = getFileFolderService();
337         
338         // get the path elements
339
List JavaDoc<FileInfo> pathInfos = fileFolderService.getNamePath(rootNodeRef, nodeRef);
340         
341         // build the path string
342
StringBuilder JavaDoc sb = new StringBuilder JavaDoc(pathInfos.size() * 20);
343         for (FileInfo fileInfo : pathInfos)
344         {
345             sb.append(WebDAVHelper.PathSeperatorChar);
346             sb.append(fileInfo.getName());
347         }
348         // done
349
if (logger.isDebugEnabled())
350         {
351             logger.debug("Build name path for node: \n" +
352                     " root: " + rootNodeRef + "\n" +
353                     " target: " + nodeRef + "\n" +
354                     " path: " + sb);
355         }
356         return sb.toString();
357     }
358     
359     /**
360      * Make an ETag value for a node using the GUID and modify date/time
361      *
362      * @param node NodeRef
363      * @return String
364      */

365     public final String JavaDoc makeETag(NodeRef node)
366     {
367         // Get the modify date/time property for the node
368

369         StringBuilder JavaDoc etag = new StringBuilder JavaDoc();
370         makeETagString(node, etag);
371         return etag.toString();
372     }
373     
374     /**
375      * Make an ETag value for a node using the GUID and modify date/time
376      *
377      * @param node NodeRef
378      * @return String
379      */

380     public final String JavaDoc makeQuotedETag(NodeRef node)
381     {
382         StringBuilder JavaDoc etag = new StringBuilder JavaDoc();
383         
384         etag.append("\"");
385         makeETagString(node, etag);
386         etag.append("\"");
387         return etag.toString();
388     }
389     
390     /**
391      * Make an ETag value for a node using the GUID and modify date/time
392      *
393      * @param node NodeRef
394      * @param str StringBuilder
395      */

396     protected final void makeETagString(NodeRef node, StringBuilder JavaDoc etag)
397     {
398         // Get the modify date/time property for the node
399

400         Object JavaDoc modVal = getNodeService().getProperty(node, ContentModel.PROP_MODIFIED);
401         
402         etag.append(node.getId());
403         
404         if ( modVal != null)
405         {
406             etag.append("_");
407             etag.append(DefaultTypeConverter.INSTANCE.longValue(modVal));
408         }
409     }
410     
411     /**
412      * Return the null XML attribute list
413      *
414      * @return AttributesImpl
415      */

416     public final AttributesImpl JavaDoc getNullAttributes()
417     {
418         return m_nullAttribs;
419     }
420     
421     /**
422      * Encodes the given string to valid URL format
423      *
424      * @param s the String to convert
425      */

426     public final static String JavaDoc encodeURL(String JavaDoc s)
427     {
428         try
429         {
430             return replace(URLEncoder.encode(s, "UTF-8"), "+", "%20");
431         }
432         catch (UnsupportedEncodingException JavaDoc err)
433         {
434             throw new RuntimeException JavaDoc(err);
435         }
436     }
437     
438     /**
439      * Replace one string instance with another within the specified string
440      *
441      * @param str
442      * @param repl
443      * @param with
444      *
445      * @return replaced string
446      */

447     public static String JavaDoc replace(String JavaDoc str, String JavaDoc repl, String JavaDoc with)
448     {
449         int lastindex = 0;
450         int pos = str.indexOf(repl);
451         
452         // If no replacement needed, return the original string
453
// and save StringBuffer allocation/char copying
454
if (pos < 0)
455         {
456             return str;
457         }
458         
459         int len = repl.length();
460         int lendiff = with.length() - repl.length();
461         StringBuilder JavaDoc out = new StringBuilder JavaDoc((lendiff <= 0) ? str.length() : (str.length() + (lendiff << 3)));
462         for (; pos >= 0; pos = str.indexOf(repl, lastindex = pos + len))
463         {
464             out.append(str.substring(lastindex, pos)).append(with);
465         }
466         
467         return out.append(str.substring(lastindex, str.length())).toString();
468     }
469     
470     /**
471      * Encodes the given string to valid HTML format
472      *
473      * @param string the String to convert
474      */

475     public final static String JavaDoc encodeHTML(String JavaDoc string)
476     {
477         if (string == null)
478         {
479             return "";
480         }
481         
482         StringBuilder JavaDoc sb = null; //create on demand
483
String JavaDoc enc;
484         char c;
485         for (int i = 0; i < string.length(); i++)
486         {
487             enc = null;
488             c = string.charAt(i);
489             switch (c)
490             {
491                 case '"': enc = "&quot;"; break; //"
492
case '&': enc = "&amp;"; break; //&
493
case '<': enc = "&lt;"; break; //<
494
case '>': enc = "&gt;"; break; //>
495

496                 //german umlauts
497
case '\u00E4' : enc = "&auml;"; break;
498                 case '\u00C4' : enc = "&Auml;"; break;
499                 case '\u00F6' : enc = "&ouml;"; break;
500                 case '\u00D6' : enc = "&Ouml;"; break;
501                 case '\u00FC' : enc = "&uuml;"; break;
502                 case '\u00DC' : enc = "&Uuml;"; break;
503                 case '\u00DF' : enc = "&szlig;"; break;
504                 
505                 //misc
506
//case 0x80: enc = "&euro;"; break; sometimes euro symbol is ascii 128, should we suport it?
507
case '\u20AC': enc = "&euro;"; break;
508                 case '\u00AB': enc = "&laquo;"; break;
509                 case '\u00BB': enc = "&raquo;"; break;
510                 case '\u00A0': enc = "&nbsp;"; break;
511                 
512                 default:
513                     if (((int)c) >= 0x80)
514                     {
515                         //encode all non basic latin characters
516
enc = "&#" + ((int)c) + ";";
517                     }
518                 break;
519             }
520             
521             if (enc != null)
522             {
523                 if (sb == null)
524                 {
525                     String JavaDoc soFar = string.substring(0, i);
526                     sb = new StringBuilder JavaDoc(i + 8);
527                     sb.append(soFar);
528                 }
529                 sb.append(enc);
530             }
531             else
532             {
533                 if (sb != null)
534                 {
535                     sb.append(c);
536                 }
537             }
538         }
539         
540         if (sb == null)
541         {
542             return string;
543         }
544         else
545         {
546             return sb.toString();
547         }
548     }
549 }
550
Popular Tags