View Javadoc

1   package fr.in2p3.jsaga.impl.namespace;
2   
3   import fr.in2p3.jsaga.adaptor.data.DataAdaptor;
4   import fr.in2p3.jsaga.adaptor.data.optimise.DataRename;
5   import fr.in2p3.jsaga.adaptor.data.read.DataReaderAdaptor;
6   import fr.in2p3.jsaga.adaptor.data.read.FileAttributes;
7   import fr.in2p3.jsaga.adaptor.data.write.DataWriterAdaptor;
8   import fr.in2p3.jsaga.impl.file.FileImpl;
9   import fr.in2p3.jsaga.impl.file.copy.AbstractCopyTask;
10  import fr.in2p3.jsaga.impl.url.AbstractURLImpl;
11  import fr.in2p3.jsaga.impl.url.URLHelper;
12  import fr.in2p3.jsaga.sync.namespace.SyncNSDirectory;
13  import fr.in2p3.jsaga.sync.namespace.SyncNSEntry;
14  import org.ogf.saga.error.*;
15  import org.ogf.saga.namespace.*;
16  import org.ogf.saga.session.Session;
17  import org.ogf.saga.url.URL;
18  import org.ogf.saga.url.URLFactory;
19  
20  /* ***************************************************
21   * *** Centre de Calcul de l'IN2P3 - Lyon (France) ***
22   * ***             http://cc.in2p3.fr/             ***
23   * ***************************************************
24   * File:   AbstractNSEntryDirImpl
25   * Author: Sylvain Reynaud (sreynaud@in2p3.fr)
26   * Date:   17 sept. 2007
27   * ***************************************************
28   * Description:                                      */
29  /**
30   * This class override some methods of AbstractNSEntryImpl for directories
31   */
32  public abstract class AbstractNSEntryDirImpl extends AbstractNSEntryImpl implements SyncNSDirectory {
33  
34      /** constructor for factory */
35      protected AbstractNSEntryDirImpl(Session session, URL url, DataAdaptor adaptor, int flags) throws NotImplementedException, IncorrectURLException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, DoesNotExistException, TimeoutException, NoSuccessException {
36          super(session, url, adaptor, flags);
37      }
38  
39      /** constructor for NSDirectory.open() */
40      protected AbstractNSEntryDirImpl(AbstractNSDirectoryImpl dir, URL relativeUrl, int flags) throws NotImplementedException, IncorrectURLException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, DoesNotExistException, TimeoutException, NoSuccessException {
41          super(dir, relativeUrl, flags);
42      }
43  
44      /** constructor for NSEntry.openAbsolute() */
45      protected AbstractNSEntryDirImpl(AbstractNSEntryImpl entry, String absolutePath, int flags) throws NotImplementedException, IncorrectURLException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, DoesNotExistException, TimeoutException, NoSuccessException {
46          super(entry, absolutePath, flags);
47      }
48  
49      ////////////////////////////////////// override methods of SyncNSEntry //////////////////////////////////////
50      /** override super.getCWDSync() */
51      public URL getCWDSync() throws NotImplementedException, IncorrectStateException, TimeoutException, NoSuccessException {
52          return m_url.normalize();
53      }
54  
55      /** override super.permissionsAllowSync() */
56      public void permissionsAllowSync(String id, int permissions, int flags) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, IncorrectStateException, BadParameterException, TimeoutException, NoSuccessException {
57          new FlagsHelper(flags).allowed(Flags.DEREFERENCE, Flags.RECURSIVE);
58          new FlagsHelper(flags).required(Flags.RECURSIVE);
59          try {
60              if (Flags.DEREFERENCE.isSet(flags)) {
61                  AbstractSyncNSEntryImpl dir = this._dereferenceDir();
62                  try {
63                      dir.permissionsAllowSync(id, permissions, flags - Flags.DEREFERENCE.getValue());
64                  } finally {
65                      dir.close();
66                  }
67                  return; //==========> EXIT
68              }
69              // allow permission on current directory
70              super.permissionsAllowSync(id, permissions, flags - Flags.RECURSIVE.getValue());
71              // allow permission on child entries
72              for (FileAttributes child : this._listAttributes(m_url.getPath())) {
73                  SyncNSEntry childEntry = this._openNS(child);
74                  try {
75                      int childFlags = (childEntry instanceof AbstractSyncNSDirectoryImpl
76                              ? flags
77                              : flags - Flags.RECURSIVE.getValue());
78                      childEntry.permissionsAllowSync(id, permissions, childFlags);
79                  } finally {
80                      ((NSEntry) childEntry).close();
81                  }
82              }
83          } catch (IncorrectURLException e) {
84              throw new NoSuccessException(e);
85          }
86      }
87  
88      /** override super.permissionsDenySync() */
89      public void permissionsDenySync(String id, int permissions, int flags) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, IncorrectStateException, BadParameterException, TimeoutException, NoSuccessException {
90          new FlagsHelper(flags).allowed(Flags.DEREFERENCE, Flags.RECURSIVE);
91          new FlagsHelper(flags).required(Flags.RECURSIVE);
92          try {
93              if (Flags.DEREFERENCE.isSet(flags)) {
94                  AbstractSyncNSEntryImpl dir = this._dereferenceDir();
95                  try {
96                      dir.permissionsDenySync(id, permissions, flags - Flags.DEREFERENCE.getValue());
97                  } finally {
98                      dir.close();
99                  }
100                 return; //==========> EXIT
101             }
102             // deny permission on current directory
103             super.permissionsDenySync(id, permissions, flags - Flags.RECURSIVE.getValue());
104             // deny permission on child entries
105             for (FileAttributes child : this._listAttributes(m_url.getPath())) {
106                 SyncNSEntry childEntry = this._openNS(child);
107                 try {
108                     int childFlags = (childEntry instanceof AbstractSyncNSDirectoryImpl
109                             ? flags
110                             : flags - Flags.RECURSIVE.getValue());
111                     childEntry.permissionsDenySync(id, permissions, childFlags);
112                 } finally {
113                     ((NSEntry) childEntry).close();
114                 }
115             }
116         } catch (IncorrectURLException e) {
117             throw new NoSuccessException(e);
118         }
119     }
120 
121     /** override super.copySync() */
122     public void copySync(URL target, int flags) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, DoesNotExistException, AlreadyExistsException, TimeoutException, NoSuccessException, IncorrectURLException {
123         this._copyAndMonitor(target, flags, null);
124     }
125 
126     public void _copyAndMonitor(URL target, int flags, AbstractCopyTask progressMonitor) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, DoesNotExistException, AlreadyExistsException, TimeoutException, NoSuccessException, IncorrectURLException {
127         new FlagsHelper(flags).allowed(JSAGAFlags.PRESERVETIMES, Flags.DEREFERENCE, Flags.RECURSIVE, Flags.OVERWRITE, Flags.CREATEPARENTS);
128         new FlagsHelper(flags).required(Flags.RECURSIVE);
129         if (Flags.DEREFERENCE.isSet(flags)) {
130             AbstractSyncNSEntryImpl dir = this._dereferenceDir();
131             try {
132                 dir.copySync(target, flags - Flags.DEREFERENCE.getValue());
133             } finally {
134                 dir.close();
135             }
136             return; //==========> EXIT
137         }
138         URL effectiveTarget = this._getEffectiveURL(target);
139         if (m_adaptor instanceof DataReaderAdaptor) {
140             // make target directory
141             this._makeDir(effectiveTarget, flags);
142             // copy source childs
143             FileAttributes[] sourceChilds = this._listAttributes(m_url.getPath());
144             for (int i = 0; i < sourceChilds.length; i++) {
145                 SyncNSEntry sourceChildEntry = this._openNS(sourceChilds[i]);
146                 try {
147                     if (sourceChildEntry instanceof AbstractSyncNSDirectoryImpl) {
148                         ((AbstractSyncNSDirectoryImpl) sourceChildEntry)._copyAndMonitor(effectiveTarget, flags, progressMonitor);
149                     } else {
150                         // remove RECURSIVE flag (which is always set for NSDirectory.copy())
151                         int childFlags = flags - Flags.RECURSIVE.getValue();
152                         if (sourceChildEntry instanceof FileImpl) {
153                             ((FileImpl) sourceChildEntry)._copyAndMonitor(effectiveTarget, childFlags, progressMonitor);
154                         } else {
155                             sourceChildEntry.copySync(effectiveTarget, childFlags);
156                         }
157                     }
158                 } finally {
159                     ((NSEntry) sourceChildEntry).close();
160                 }
161             }
162         } else {
163             throw new NotImplementedException("Not supported for this protocol: " + m_url.getScheme(), this);
164         }
165     }
166 
167     /** override super.copyFromSync() */
168     public void copyFromSync(URL source, int flags) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, DoesNotExistException, TimeoutException, NoSuccessException, IncorrectURLException {
169         new FlagsHelper(flags).allowed(JSAGAFlags.PRESERVETIMES, Flags.DEREFERENCE, Flags.RECURSIVE, Flags.OVERWRITE);
170         new FlagsHelper(flags).required(Flags.RECURSIVE);
171         if (Flags.DEREFERENCE.isSet(flags)) {
172             AbstractSyncNSEntryImpl dir = this._dereferenceDir();
173             try {
174                 dir.copyFromSync(source, flags - Flags.DEREFERENCE.getValue());
175             } finally {
176                 dir.close();
177             }
178             return; //==========> EXIT
179         }
180         if (m_adaptor instanceof DataWriterAdaptor) {
181             try {
182                 NSDirectory sourceDir = NSFactory.createNSDirectory(JSAGA_FACTORY, m_session, source);
183                 try {
184                     sourceDir.copy(m_url, flags);
185                 } finally {
186                     sourceDir.close();
187                 }
188             } catch (AlreadyExistsException e) {
189                 throw new IncorrectStateException("Unexpected exception", e);
190             }
191         } else {
192             throw new NotImplementedException("Not supported for this protocol: " + m_url.getScheme(), this);
193         }
194     }
195 
196     /** override super.moveSync() */
197     public void moveSync(URL target, int flags) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, DoesNotExistException, AlreadyExistsException, TimeoutException, NoSuccessException, IncorrectURLException {
198         new FlagsHelper(flags).allowed(Flags.DEREFERENCE, Flags.RECURSIVE, Flags.OVERWRITE, Flags.CREATEPARENTS);
199         new FlagsHelper(flags).required(Flags.RECURSIVE);
200         if (Flags.DEREFERENCE.isSet(flags)) {
201             AbstractSyncNSEntryImpl dir = this._dereferenceDir();
202             try {
203                 dir.moveSync(target, flags - Flags.DEREFERENCE.getValue());
204             } finally {
205                 dir.close();
206             }
207             return; //==========> EXIT
208         }
209         URL effectiveTarget;
210         try {
211             NSFactory.createNSDirectory(JSAGA_FACTORY, m_session, target, Flags.NONE.getValue()).close();
212             // Target Directory already exists, operation is MOVE
213             effectiveTarget = this._getEffectiveURL(target);
214         } catch (DoesNotExistException dnee) {
215             // Target directory does not exist: operation is RENAME
216             effectiveTarget = target;
217         }
218         if (m_adaptor instanceof DataRename
219                 && m_url.getScheme().equals(effectiveTarget.getScheme())
220                 && (m_url.getUserInfo() == null || m_url.getUserInfo().equals(effectiveTarget.getUserInfo()))
221                 && (m_url.getHost() == null || m_url.getHost().equals(effectiveTarget.getHost()))
222                 && (m_url.getPort() == effectiveTarget.getPort())) {
223             boolean overwrite = Flags.OVERWRITE.isSet(flags);
224             try {
225                 ((DataRename) m_adaptor).rename(
226                         m_url.getPath(),
227                         effectiveTarget.getPath(),
228                         overwrite,
229                         m_url.getQuery());
230             } catch (DoesNotExistException doesNotExist) {
231                 throw new IncorrectStateException("Directory does not exist: " + m_url, doesNotExist);
232             } catch (AlreadyExistsException alreadyExists) {
233                 throw new AlreadyExistsException("Target entry already exists: " + effectiveTarget, alreadyExists.getCause());
234             }
235             if (m_url instanceof AbstractURLImpl) {
236                 ((AbstractURLImpl) m_url).setCache(null);
237             }
238         } else if (m_adaptor instanceof DataReaderAdaptor) {
239             // make target directory
240             this._makeDir(effectiveTarget, flags);
241             // move source childs to target directory
242             FileAttributes[] sourceChilds = this._listAttributes(m_url.getPath());
243             for (int i = 0; i < sourceChilds.length; i++) {
244                 URL remoteChild = URLHelper.createURL(effectiveTarget, sourceChilds[i].getRelativePath());
245                 SyncNSEntry entry = this._openNS(sourceChilds[i]);
246                 try {
247                     if (entry instanceof SyncNSDirectory) {
248                         entry.moveSync(remoteChild, flags);
249                     } else {
250                         // remove RECURSIVE flag (always set for NSDirectory.move())
251                         entry.moveSync(remoteChild, flags - Flags.RECURSIVE.getValue());
252                     }
253                 } finally {
254                     ((NSEntry) entry).close();
255                 }
256             }
257             // remove source directory
258             if (Flags.OVERWRITE.isSet(flags))
259             	flags = flags - Flags.OVERWRITE.getValue();
260             this.removeSync(flags);
261             if (m_url instanceof AbstractURLImpl) {
262                 ((AbstractURLImpl) m_url).setCache(null);
263             }
264         } else {
265             throw new NotImplementedException("Not supported for this protocol: " + m_url.getScheme(), this);
266         }
267     }
268 
269     /**
270      * override super.removeSync()
271      * <br>Note: does not throw a BadParamater exception when RECURSIVE flag is not set, unless directory has some descendants.
272      */
273     public void removeSync(int flags) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, TimeoutException, NoSuccessException {
274         new FlagsHelper(flags).allowed(Flags.DEREFERENCE, Flags.RECURSIVE);
275         if (Flags.DEREFERENCE.isSet(flags)) {
276             try {
277                 AbstractSyncNSEntryImpl dir = this._dereferenceDir();
278                 try {
279                     dir.removeSync(flags - Flags.DEREFERENCE.getValue());
280                 } finally {
281                     dir.close();
282                 }
283             } catch (IncorrectURLException e) {
284                 throw new NoSuccessException(e);
285             }
286             return; //==========> EXIT
287         }
288         if (m_adaptor instanceof DataReaderAdaptor && m_adaptor instanceof DataWriterAdaptor) {
289             if (Flags.RECURSIVE.isSet(flags)) {
290                 // remove childs
291                 FileAttributes[] sourceChilds = this._listAttributes(m_url.getPath());
292                 for (int i = 0; i < sourceChilds.length; i++) {
293                     SyncNSEntry entry;
294                     try {
295                         entry = this._openNS(sourceChilds[i]);
296                         try {
297                             if (entry instanceof SyncNSDirectory) {
298                                 entry.removeSync(flags);
299                             } else {
300                                 // remove RECURSIVE flag (always set here)
301                                 entry.removeSync(flags - Flags.RECURSIVE.getValue());
302                             }
303                         } finally {
304                             ((NSEntry) entry).close();
305                         }
306                     } catch (IncorrectURLException e) {
307                         throw new NoSuccessException(e);
308                     }
309                 }
310             } else {
311                 // check that there is no child
312                 FileAttributes[] sourceChilds = this._listAttributes(m_url.getPath());
313                 if (sourceChilds.length > 0) {
314                     throw new BadParameterException("Flag 'Recursive' is required for non-empty directory: " + m_url);
315                 }
316             }
317 
318             // remove this directory
319             URL parent = super._getParentDirURL();
320             String directoryName = super._getEntryName();
321             try {
322                 ((DataWriterAdaptor) m_adaptor).removeDir(
323                         parent.getPath(),
324                         directoryName,
325                         m_url.getQuery());
326             } catch (DoesNotExistException doesNotExist) {
327                 throw new IncorrectStateException("Directory does not exist: " + m_url, doesNotExist);
328             }
329         } else {
330             throw new NotImplementedException("Not supported for this protocol: " + m_url.getScheme(), this);
331         }
332     }
333 
334     ////////////////////////////////////// interface NSDirectory //////////////////////////////////////
335     public abstract NSDirectory openDir(URL name, int flags) throws NotImplementedException, IncorrectURLException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, AlreadyExistsException, DoesNotExistException, TimeoutException, NoSuccessException;
336 
337     public abstract NSDirectory openDir(URL name) throws NotImplementedException, IncorrectURLException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, AlreadyExistsException, DoesNotExistException, TimeoutException, NoSuccessException;
338 
339     public abstract NSEntry open(URL name, int flags) throws NotImplementedException, IncorrectURLException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, AlreadyExistsException, DoesNotExistException, TimeoutException, NoSuccessException;
340 
341     public abstract NSEntry open(URL name) throws NotImplementedException, IncorrectURLException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, AlreadyExistsException, DoesNotExistException, TimeoutException, NoSuccessException;
342 
343     ///////////////////////////////////////// protected methods /////////////////////////////////////////
344     /** override super._getEffectiveURL() */
345     protected URL _getEffectiveURL(URL target) throws NotImplementedException, IncorrectStateException, BadParameterException, TimeoutException, NoSuccessException {
346         if (target.getPath().endsWith("/")) {
347             return URLHelper.createURL(target, super._getEntryName() + "/");
348         } else {
349             return target;
350         }
351     }
352 
353     protected FileAttributes[] _listAttributes(String absolutePath) throws NotImplementedException, PermissionDeniedException, IncorrectStateException, TimeoutException, NoSuccessException {
354         if (m_adaptor instanceof DataReaderAdaptor) {
355             try {
356                 return ((DataReaderAdaptor) m_adaptor).listAttributes(absolutePath, m_url.getQuery());
357             } catch (BadParameterException badParameter) {
358                 throw new IncorrectStateException("Entry is not a directory: " + absolutePath, badParameter);
359             } catch (DoesNotExistException doesNotExist) {
360                 throw new IncorrectStateException("Directory does not exist: " + absolutePath, doesNotExist);
361             }
362         } else {
363             throw new NotImplementedException("Not supported for this protocol: " + m_url.getScheme(), this);
364         }
365     }
366 
367     //does not throw DoesNotExistException because it would mean "parent directory does not exist"
368     protected SyncNSEntry _openNS(FileAttributes attr) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, TimeoutException, NoSuccessException, IncorrectURLException {
369         switch (attr.getType()) {
370             case FileAttributes.TYPE_DIRECTORY:
371                 return this._openNSDir(URLFactory.createURL(JSAGA_FACTORY, attr.getRelativePath()));
372             case FileAttributes.TYPE_FILE:
373             case FileAttributes.TYPE_LINK:
374                 return this._openNSEntry(URLFactory.createURL(JSAGA_FACTORY, attr.getRelativePath()));
375             case FileAttributes.TYPE_UNKNOWN:
376             default:
377                 SyncNSEntry entry = this._openNSEntry(URLFactory.createURL(JSAGA_FACTORY, attr.getRelativePath()));
378                 if (entry.isDirSync()) {
379                     return this._openNSDir(URLFactory.createURL(JSAGA_FACTORY, attr.getRelativePath()));
380                 } else {
381                     return entry;
382                 }
383         }
384     }
385 
386     //does not throw DoesNotExistException because it would mean "parent directory does not exist"
387     protected SyncNSDirectory _openNSDir(URL name) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, TimeoutException, NoSuccessException, IncorrectURLException {
388         try {
389             return (SyncNSDirectory) this.openDir(name, Flags.NONE.getValue());
390         } catch (DoesNotExistException e) {
391             throw new IncorrectStateException(e);
392         } catch (AlreadyExistsException e) {
393             throw new IncorrectStateException(e);
394         }
395     }
396 
397     //does not throw DoesNotExistException because it would mean "parent directory does not exist"
398     protected SyncNSEntry _openNSEntry(URL name) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, TimeoutException, NoSuccessException, IncorrectURLException {
399         try {
400             return (SyncNSEntry) this.open(name, Flags.NONE.getValue());
401         } catch (DoesNotExistException e) {
402             throw new IncorrectStateException(e);
403         } catch (AlreadyExistsException e) {
404             throw new IncorrectStateException(e);
405         }
406     }
407 
408     protected void _makeDir(URL target, int flags) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, DoesNotExistException, AlreadyExistsException, TimeoutException, NoSuccessException, IncorrectURLException {
409         // set makeDirFlags
410         int makeDirFlags = Flags.CREATE.getValue();
411         if (!Flags.OVERWRITE.isSet(flags)) {
412             makeDirFlags = Flags.EXCL.or(makeDirFlags);
413         }
414         if (Flags.CREATEPARENTS.isSet(flags)) {
415             makeDirFlags = Flags.CREATEPARENTS.or(makeDirFlags);
416         }
417 
418         // makeDir
419         NSFactory.createNSDirectory(JSAGA_FACTORY, m_session, target, makeDirFlags).close();
420     }
421 }