View Javadoc

1   package fr.in2p3.jsaga.impl.file.copy;
2   
3   import fr.in2p3.jsaga.Base;
4   import fr.in2p3.jsaga.EngineProperties;
5   import fr.in2p3.jsaga.adaptor.data.DataAdaptor;
6   import fr.in2p3.jsaga.adaptor.data.ParentDoesNotExist;
7   import fr.in2p3.jsaga.adaptor.data.optimise.DataCopy;
8   import fr.in2p3.jsaga.adaptor.data.optimise.DataCopyDelegated;
9   import fr.in2p3.jsaga.adaptor.data.read.FileReader;
10  import fr.in2p3.jsaga.adaptor.data.read.FileReaderGetter;
11  import fr.in2p3.jsaga.impl.file.AbstractSyncFileImpl;
12  import fr.in2p3.jsaga.impl.namespace.FlagsHelper;
13  import fr.in2p3.jsaga.impl.namespace.JSAGAFlags;
14  import org.ogf.saga.error.*;
15  import org.ogf.saga.file.*;
16  import org.ogf.saga.namespace.Flags;
17  import org.ogf.saga.session.Session;
18  import org.ogf.saga.url.URL;
19  import org.ogf.saga.url.URLFactory;
20  
21  import java.io.IOException;
22  
23  /* ***************************************************
24  * *** Centre de Calcul de l'IN2P3 - Lyon (France) ***
25  * ***             http://cc.in2p3.fr/             ***
26  * ***************************************************
27  * File:   FileCopy
28  * Author: Sylvain Reynaud (sreynaud@in2p3.fr)
29  * Date:   9 juil. 2008
30  * ***************************************************
31  * Description:                                      */
32  /**
33   *
34   */
35  public class FileCopy {
36      private static final String JSAGA_FACTORY = Base.getSagaFactory();
37  
38      //private static final int DEFAULT_BUFFER_SIZE = 16384;
39      private Session m_session;
40      private AbstractSyncFileImpl m_sourceFile;
41      private DataAdaptor m_adaptor;
42  
43      /** constructor */
44      public FileCopy(Session session, AbstractSyncFileImpl sourceFile, DataAdaptor adaptor) throws NotImplementedException {
45          m_session = session;
46          m_sourceFile = sourceFile;
47          m_adaptor = adaptor;
48      }
49  
50      public void copy(URL effectiveTarget, int flags, AbstractCopyTask progressMonitor) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, DoesNotExistException, AlreadyExistsException, TimeoutException, NoSuccessException, IncorrectURLException {
51          boolean overwrite = Flags.OVERWRITE.isSet(flags);
52          URL source = m_sourceFile.getURL();
53          if (m_adaptor instanceof DataCopyDelegated && source.getScheme().equals(effectiveTarget.getScheme())) {
54              try {
55                  ((DataCopyDelegated)m_adaptor).requestTransfer(
56                          source,
57                          effectiveTarget,
58                          overwrite, source.getQuery());
59              } catch (DoesNotExistException doesNotExist) {
60                  throw new IncorrectStateException("Source file does not exist: "+source, doesNotExist);
61              } catch (AlreadyExistsException alreadyExists) {
62                  throw new AlreadyExistsException("Target entry already exists: "+effectiveTarget, alreadyExists.getCause());
63              }
64          } else if (m_adaptor instanceof DataCopy && source.getScheme().equals(effectiveTarget.getScheme())) {
65              try {
66                  String targetHost = effectiveTarget.getHost();
67                  int targetPort = (effectiveTarget.getPort()>-1 ? effectiveTarget.getPort() : m_adaptor.getDefaultPort());
68                  String targetPath = effectiveTarget.getPath();
69                  ((DataCopy)m_adaptor).copy(
70                          source.getPath(),
71                          targetHost, targetPort, targetPath,
72                          overwrite, source.getQuery(),
73                          progressMonitor);
74              } catch (ParentDoesNotExist parentDoesNotExist) {
75                  throw new DoesNotExistException("Target parent directory does not exist: "+effectiveTarget.resolve(URLFactory.createURL(JSAGA_FACTORY, ".")), parentDoesNotExist);
76              } catch (DoesNotExistException doesNotExist) {
77                  throw new IncorrectStateException("Source file does not exist: "+source, doesNotExist);
78              } catch (AlreadyExistsException alreadyExists) {
79                  throw new AlreadyExistsException("Target entry already exists: "+effectiveTarget, alreadyExists.getCause());
80              }
81          } else if (m_adaptor instanceof FileReaderGetter && !source.getScheme().equals(effectiveTarget.getScheme())) {
82              AbstractSyncFileImpl targetFile = this.createTargetFile(effectiveTarget, flags);
83              try {
84              	if (progressMonitor == null) {
85  	                ((FileReaderGetter)m_adaptor).getToStream(
86  	                        source.getPath(),
87  	                        source.getQuery(),
88  	                        targetFile.getFileOutputStream());
89              	} else {
90  	                ((FileReaderGetter)m_adaptor).getToStream(
91  	                        source.getPath(),
92  	                        source.getQuery(),
93  	                        new MonitoredOutputStream(targetFile.getFileOutputStream(), progressMonitor));
94              	}
95              } catch (DoesNotExistException doesNotExist) {
96                  targetFile.removeSync();
97                  throw new IncorrectStateException("Source file does not exist: "+source, doesNotExist);
98              } finally {
99                  targetFile.close();
100             }
101         } else if (m_adaptor instanceof FileReader) {
102             // todo: check that target is not a logical entry
103             this.putToPhysicalFile(effectiveTarget, flags, progressMonitor);
104         } else {
105             throw new NotImplementedException("Not supported for this protocol: "+source.getScheme());
106         }
107     }
108 
109     private void putToPhysicalFile(URL target, int flags, AbstractCopyTask progressMonitor) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, AlreadyExistsException, TimeoutException, NoSuccessException, IncorrectURLException {
110 //        IOException closingException = null;
111 
112         // open source file if it exists
113         FileInputStream in;
114         try {
115             in = m_sourceFile.newFileInputStream();
116         } catch (DoesNotExistException doesNotExist) {
117             throw new IncorrectStateException("Source file does not exist: "+m_sourceFile.getURL(), doesNotExist);
118         }
119 
120         // start to read if it exists
121         int bufferSize = EngineProperties.getInteger(EngineProperties.DATA_COPY_BUFFER_SIZE);
122         byte[] data = new byte[bufferSize];
123         int readlen;
124         try {
125             readlen = in.read(data, 0, data.length);
126         } catch (IOException e) {
127             try {
128                 in.close();
129             } catch (IOException e1) {/*ignore*/}
130             throw new IncorrectStateException("Source file does not exist: "+m_sourceFile.getURL(), e);
131         }
132 
133         // open target file and copy
134         try {
135             AbstractSyncFileImpl targetFile = this.createTargetFile(target, flags);
136             try {
137                 FileOutputStream out = targetFile.getFileOutputStream();
138                 while (readlen > 0) {
139                     int writelen;
140                     for (int total=0; total<readlen; total+=writelen) {
141                         writelen = readlen - total;
142                         if (total > 0) {
143                             byte[] dataBis = new byte[writelen];
144                             System.arraycopy(data, total, dataBis, 0, writelen);
145                             out.write(dataBis, 0, writelen);
146                         } else {
147                             out.write(data, 0, readlen);
148                         }
149                         // update progress monitor
150                         if (progressMonitor != null) {
151                             progressMonitor.increment(writelen);
152                         }
153                     }
154                     readlen = in.read(data,0, data.length);
155                 }
156                 // close stream
157                 try{
158                 	out.close();
159                 }catch (Exception e) {
160                 	// Ignore it: A problem during the close should not be a problem.
161 				}
162             } catch (IOException e) {
163                 throw new TimeoutException(e);
164             } finally {
165                 try {
166                     // close connection
167                     targetFile.close();
168                 } catch (Exception e) {
169                 	//Ignore it: A problem during the close should not be a problem.
170                    // closingException = new IOException(e.getClass().getName()+": "+e.getMessage());
171                 }
172             }
173         } finally {
174             try {
175                 in.close();
176             } catch (IOException e) {
177             	//Ignore it: A problem during the close should not be a problem.
178                 //closingException = e;
179             }
180         }
181 //        if (closingException != null) {
182 //            throw new IncorrectStateException(closingException);
183 //        }
184     }
185 
186     private AbstractSyncFileImpl createTargetFile(URL target, int flags) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, AlreadyExistsException, TimeoutException, NoSuccessException, IncorrectURLException {
187         // set corrected flags
188         int correctedFlags = flags;
189         correctedFlags = new FlagsHelper(correctedFlags).add(Flags.WRITE, Flags.CREATE);
190         correctedFlags = new FlagsHelper(correctedFlags).remove(JSAGAFlags.PRESERVETIMES);
191         if (Flags.OVERWRITE.isSet(correctedFlags)) {
192             correctedFlags = correctedFlags - Flags.OVERWRITE.getValue();
193         } else {
194             correctedFlags = correctedFlags + Flags.EXCL.getValue();
195         }
196         try {
197             return (AbstractSyncFileImpl) FileFactory.createFile(JSAGA_FACTORY, m_session, target, correctedFlags);
198         } catch (DoesNotExistException e) {
199             throw new NoSuccessException("Unexpected exception", e);
200         } catch (AlreadyExistsException alreadyExists) {
201             throw new AlreadyExistsException("Target entry already exists: "+target, alreadyExists.getCause());
202         }
203     }
204 }