View Javadoc
1   /*
2    * Copyright (C) 2003-2015 eXo Platform SAS.
3    *
4    * This is free software; you can redistribute it and/or modify it
5    * under the terms of the GNU Lesser General Public License as
6    * published by the Free Software Foundation; either version 3 of
7    * the License, or (at your option) any later version.
8    *
9    * This software is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this software; if not, write to the Free
16   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18   */
19  package org.exoplatform.shareextension.service;
20  
21  import java.io.IOException;
22  import java.io.OutputStream;
23  import java.io.OutputStreamWriter;
24  import java.io.PrintWriter;
25  import java.io.UnsupportedEncodingException;
26  import java.net.HttpURLConnection;
27  import java.net.URL;
28  
29  import org.apache.http.HttpResponse;
30  import org.apache.http.HttpStatus;
31  import org.apache.http.client.ClientProtocolException;
32  import org.apache.http.client.CookieStore;
33  import org.apache.http.client.methods.HttpGet;
34  import org.apache.http.cookie.Cookie;
35  import org.exoplatform.model.SocialPostInfo;
36  import org.exoplatform.shareextension.service.ShareService.UploadInfo;
37  import org.exoplatform.singleton.DocumentHelper;
38  import org.exoplatform.utils.ExoConnectionUtils;
39  import org.exoplatform.utils.ExoConstants;
40  import org.exoplatform.utils.Log;
41  
42  import android.net.Uri;
43  
44  /**
45   * Created by The eXo Platform SAS<br/>
46   * An Action for uploading a file to Platform. Uses the upload service of ECMS.
47   * 
48   * @author Philippe Aristote paristote@exoplatform.com
49   * @since Jun 17, 2015
50   */
51  public class UploadAction extends Action {
52  
53    private UploadInfo uploadInfo;
54  
55    @Override
56    protected void check() {
57      if (uploadInfo == null)
58        throw new IllegalArgumentException("Cannot pass null as the UploadInfo argument");
59      super.check();
60    }
61  
62    /**
63     * create and execute upload action, wait for result
64     * 
65     * @param post
66     * @param upload
67     * @param listener
68     * @return
69     */
70    public static boolean execute(SocialPostInfo post, UploadInfo upload, ActionListener listener) {
71      UploadAction action = new UploadAction();
72      action.postInfo = post;
73      action.uploadInfo = upload;
74      action.listener = listener;
75      return action.execute();
76    }
77  
78    @Override
79    protected boolean doExecute() {
80      String id = uploadInfo.uploadId;
81      String boundary = "----------------------------" + id;
82      String CRLF = "\r\n";
83      int status = -1;
84      OutputStream output = null;
85      PrintWriter writer = null;
86      try {
87        if (postInfo == null || postInfo.ownerAccount == null)
88          throw new IOException(new StringBuilder("Input parameter null info=").append(postInfo).toString());
89        // Open a connection to the upload web service
90        StringBuffer stringUrl = new StringBuffer(postInfo.ownerAccount.serverUrl).append("/portal")
91                                                                                  .append(ExoConstants.DOCUMENT_UPLOAD_PATH_REST)
92                                                                                  .append("?uploadId=")
93                                                                                  .append(id);
94        URL uploadUrl = new URL(stringUrl.toString());
95        // TODO need check case https connection ?
96        HttpURLConnection uploadReq = (HttpURLConnection) uploadUrl.openConnection();
97        uploadReq.setDoOutput(true);
98        uploadReq.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
99        // Pass the session cookies for authentication
100       CookieStore store = ExoConnectionUtils.cookiesStore;
101       if (store != null) {
102         StringBuffer cookieString = new StringBuffer();
103         for (Cookie cookie : store.getCookies()) {
104           cookieString.append(cookie.getName()).append("=").append(cookie.getValue()).append("; ");
105         }
106         uploadReq.addRequestProperty("Cookie", cookieString.toString());
107       }
108       ExoConnectionUtils.setUserAgent(uploadReq);
109       // Write the form data
110       output = uploadReq.getOutputStream();
111       writer = new PrintWriter(new OutputStreamWriter(output, "UTF-8"), true);
112       writer.append("--").append(boundary).append(CRLF);
113       writer.append("Content-Disposition: form-data; name=\"file\"; filename=\"")
114             .append(uploadInfo.fileToUpload.documentName)
115             .append("\"")
116             .append(CRLF);
117       writer.append("Content-Type: ").append(uploadInfo.fileToUpload.documentMimeType).append(CRLF);
118       writer.append(CRLF).flush();
119       byte[] buf = new byte[1024];
120       while (uploadInfo.fileToUpload.documentData.read(buf) != -1) {
121         output.write(buf);
122       }
123       output.flush();
124       writer.append(CRLF).flush();
125       writer.append("--").append(boundary).append("--").append(CRLF).flush();
126       // Execute the connection and retrieve the status code
127       status = uploadReq.getResponseCode();
128     } catch (UnsupportedEncodingException e) {
129       Log.e(LOG_TAG, "Error while uploading ", uploadInfo.fileToUpload, Log.getStackTraceString(e));
130     } catch (IOException e) {
131       Log.e(LOG_TAG, "Error while uploading ", uploadInfo.fileToUpload, Log.getStackTraceString(e));
132     } finally {
133       if (uploadInfo != null && uploadInfo.fileToUpload != null && uploadInfo.fileToUpload.documentData != null)
134         try {
135           uploadInfo.fileToUpload.documentData.close();
136         } catch (IOException e1) {
137           Log.e(LOG_TAG, "Error while closing the upload stream", e1);
138         }
139       if (output != null)
140         try {
141           output.close();
142         } catch (IOException e) {
143           Log.e(LOG_TAG, "Error while closing the connection", e);
144         }
145       if (writer != null)
146         writer.close();
147     }
148     if (status < HttpURLConnection.HTTP_OK || status >= HttpURLConnection.HTTP_MULT_CHOICE) {
149       // Exit if the upload went wrong
150       return listener.onError(String.format("Could not upload the file %s", uploadInfo.fileToUpload.documentName));
151     }
152     status = -1;
153     try
154 
155     {
156       if (postInfo == null || postInfo.ownerAccount == null)
157         throw new IOException(new StringBuilder("Input parameter null info=").append(postInfo).toString());
158       // Prepare the request to save the file in JCR
159       String stringUrl = new StringBuilder(postInfo.ownerAccount.serverUrl).append("/portal")
160                                                                            .append(ExoConstants.DOCUMENT_CONTROL_PATH_REST)
161                                                                            .toString();
162       Uri moveUri = Uri.parse(stringUrl);
163       moveUri = moveUri.buildUpon()
164                        .appendQueryParameter("uploadId", id)
165                        .appendQueryParameter("action", "save")
166                        .appendQueryParameter("workspaceName", DocumentHelper.getInstance().workspace)
167                        .appendQueryParameter("driveName", uploadInfo.drive)
168                        .appendQueryParameter("currentFolder", uploadInfo.folder)
169                        .appendQueryParameter("fileName", uploadInfo.fileToUpload.documentName)
170                        .build();
171       HttpGet moveReq = new HttpGet(moveUri.toString());
172       // Execute the request and retrieve the status code
173       HttpResponse move = ExoConnectionUtils.httpClient.execute(moveReq);
174       status = move.getStatusLine().getStatusCode();
175     } catch (
176 
177     ClientProtocolException e)
178 
179     {
180       Log.e(LOG_TAG, "Error while saving ", uploadInfo.fileToUpload, " in JCR", Log.getStackTraceString(e));
181     } catch (
182 
183     IOException e)
184 
185     {
186       Log.e(LOG_TAG, "Error while saving ", uploadInfo.fileToUpload, " in JCR", Log.getStackTraceString(e));
187     } catch (
188 
189     Exception e)
190 
191     {
192       // XXX can not remove because Uri.parse can throw runtime exception.
193       Log.e(LOG_TAG, "Error while saving ", uploadInfo.fileToUpload, " in JCR", Log.getStackTraceString(e));
194     }
195 
196     boolean ret = false;
197     if (status >= HttpStatus.SC_OK && status < HttpStatus.SC_MULTIPLE_CHOICES)
198 
199     {
200       ret = listener.onSuccess(String.format("File %s uploaded successfully", uploadInfo.fileToUpload.documentName));
201     } else
202 
203     {
204       ret = listener.onError(String.format("Could not save the file %s", uploadInfo.fileToUpload.documentName));
205     }
206     return ret;
207   }
208 
209 }