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
25
26
27
28
29
30
31
32
33
34
35 public class FileCopy {
36 private static final String JSAGA_FACTORY = Base.getSagaFactory();
37
38
39 private Session m_session;
40 private AbstractSyncFileImpl m_sourceFile;
41 private DataAdaptor m_adaptor;
42
43
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
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
111
112
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
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) {
130 throw new IncorrectStateException("Source file does not exist: "+m_sourceFile.getURL(), e);
131 }
132
133
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
150 if (progressMonitor != null) {
151 progressMonitor.increment(writelen);
152 }
153 }
154 readlen = in.read(data,0, data.length);
155 }
156
157 try{
158 out.close();
159 }catch (Exception e) {
160
161 }
162 } catch (IOException e) {
163 throw new TimeoutException(e);
164 } finally {
165 try {
166
167 targetFile.close();
168 } catch (Exception e) {
169
170
171 }
172 }
173 } finally {
174 try {
175 in.close();
176 } catch (IOException e) {
177
178
179 }
180 }
181
182
183
184 }
185
186 private AbstractSyncFileImpl createTargetFile(URL target, int flags) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, BadParameterException, IncorrectStateException, AlreadyExistsException, TimeoutException, NoSuccessException, IncorrectURLException {
187
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 }