All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src-main.org.awakefw.file.api.client.AwakeFileSession Maven / Gradle / Ivy

Go to download

Awake FILE is a secure Open Source framework that allows to program very easily file uploads/downloads and RPC through http. File transfers include powerful features like file chunking and automatic recovery mechanism. Security has been taken into account from the design: server side allows to specify strong security rules in order to protect the files and to secure the RPC calls.

There is a newer version: 3.0
Show newest version
/*
 * This file is part of Awake FILE. 
 * Awake FILE: Easy file upload & download over HTTP with Java.                                    
 * Copyright (C) 2014,  KawanSoft SAS
 * (http://www.kawansoft.com). All rights reserved.                                
 *                                                                               
 * Awake FILE is free software; you can redistribute it and/or                 
 * modify it under the terms of the GNU Lesser General Public                    
 * License as published by the Free Software Foundation; either                  
 * version 2.1 of the License, or (at your option) any later version.            
 *                                                                               
 * Awake FILE is distributed in the hope that it will be useful,               
 * but WITHOUT ANY WARRANTY; without even the implied warranty of                
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU             
 * Lesser General Public License for more details.                               
 *                                                                               
 * You should have received a copy of the GNU Lesser General Public              
 * License along with this library; if not, write to the Free Software           
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
 * 02110-1301  USA
 *
 * Any modifications to this file must keep this entire header
 * intact.
 */
package org.awakefw.file.api.client;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Vector;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.message.BasicNameValuePair;
import org.awakefw.commons.api.client.AwakeProgressManager;
import org.awakefw.commons.api.client.HttpProtocolParameters;
import org.awakefw.commons.api.client.HttpProxy;
import org.awakefw.commons.api.client.InvalidLoginException;
import org.awakefw.commons.api.client.RemoteException;
import org.awakefw.file.api.util.AwakeDebug;
import org.awakefw.file.api.util.DefaultParms;
import org.awakefw.file.api.util.FilenameSplitter;
import org.awakefw.file.api.util.HtmlConverter;
import org.awakefw.file.http.HttpTransfer;
import org.awakefw.file.http.HttpTransferOne;
import org.awakefw.file.http.exception.HttpTransferInterruptedException;
import org.awakefw.file.json.ListOfStringTransport;
import org.awakefw.file.util.AwakeClientLogger;
import org.awakefw.file.util.AwakeFileUtil;
import org.awakefw.file.util.KeepTempFilePolicyParms;
import org.awakefw.file.util.StringUtil;
import org.awakefw.file.util.Tag;
import org.awakefw.file.util.parms.Action;
import org.awakefw.file.util.parms.Parameter;
import org.awakefw.file.util.parms.ReturnCode;
import org.awakefw.file.version.AwakeFileVersion;

/**
 * Main class for executing from a Client (typically a PC) all sorts of
 * operations on remote files or remote classes through a Http or Https session.
 * 

* Class includes methods to: *

    *
  • Get remote files size.
  • *
  • Delete remote files or directories.
  • *
  • Test if a remote file or directory exists.
  • *
  • Create a remote directory.
  • *
  • Get the list of files of a remote directory.
  • *
  • Get the list of sub-directories of a remote directory.
  • *
  • Upload files.
  • *
  • Download files.
  • *
  • Call remote Java methods.
  • *
*

* Example:

* *
 * // Create an AwakeFile instance and username on the remote server
 * // using the URL of the path to the AwakeFileManager Servlet
 * String url = "https://www.acme.org/AwakeFileManager";
 * 
 * // The login info for strong authentication on server side:
 * String username = "myUsername";
 * char[] password = { 'm', 'y', 'P', 'a', 's', 's', 'w', 'o', 'r', 'd' };
 * 
 * AwakeFileSession awakeFileSession = new AwakeFileSession(url, username,
 * 	password);
 * 
 * // OK: upload a file
 * awakeFileSession.upload(new File("c:\\myFile.txt"), "myFile.txt");
 * 
* *
*

* Communication via an (authenticating) proxy server is done using a * {@link org.awakefw.commons.api.client.HttpProxy} instance:

* *
 * HttpProxy httpProxy = new HttpProxy("myproxyhost", 8080);
 * String url = "https://www.acme.org/AwakeFileManager";
 * 
 * // The login info for strong authentication on server side:
 * String username = "myUsername";
 * char[] password = { 'm', 'y', 'P', 'a', 's', 's', 'w', 'o', 'r', 'd' };
 * 
 * AwakeFileSession awakeFileSession = new AwakeFileSession(url, username,
 * 	password, httpProxy);
 * 
 * // Etc.
 * 
 
* *
*

* All long operations that need to be run on a separated thread may be followed * in Swing using a Java Progress Bar or Progress Monitor: just implement the * {@link org.awakefw.commons.api.client.AwakeProgressManager} interface. *

* * @see org.awakefw.commons.api.client.HttpProxy * @see org.awakefw.commons.api.client.AwakeProgressManager * * @author Nicolas de Pomereu * @since 1.0 */ public class AwakeFileSession implements Cloneable { private static final String AWAKE_SESSION_IS_CLOSED = "Awake Session is closed."; /** For debug info */ private static boolean DEBUG = AwakeDebug.isSet(AwakeFileSession.class); /** Defines 1 kilobyte */ public static final int KB = 1024; /** Defines 1 megabyte */ public static final int MB = 1024 * KB; /** Defines if we must use base64 or html encode when using call() */ private static boolean USE_HTML_ENCODING = true; /** The url to use to connectet to the Awake FILE Server */ private String url = null; /** * The username is stored in static memory to be passed to upload file * servlet */ private String username = null; /** * Token is stored in static to be available during all session and contains * SHA-1(userId + ServerClientLogin.SECRET_FOR_LOGIN) computed by server. * Token is re-send and checked at each send or recv command to be sure user * is authenticated. */ private String authenticationToken = null; /** The Http Proxy instance */ private HttpProxy httpProxy = null; /** The Http Parameters instance */ private HttpProtocolParameters httpProtocolParameters = null; /** The Awake Progress Manager for upload */ private AwakeProgressManager awakeProgressManager = null; /** The http transfer instance */ private HttpTransfer httpTransfer = null; /** * Says if we wan to use base64 encoding for parameters passed to call() - * This is a method for legacy applications prior to v1.0. */ public static void setUseBase64EncodingForCall() { USE_HTML_ENCODING = false; } /** * Private constructor for clone(). * * @param url * the URL of the path to the AwakeFileManager Servlet * @param username * the username for authentication on the Awake Server (may be * null for call() or downloadUrl()) * @param authenticationToken * the actual token of the Awake FILE session to clone * @param httpProxy * the http proxy to use * @param httpProtocolParameters * the http parameters to use */ private AwakeFileSession(String url, String username, String authenticationToken, HttpProxy httpProxy, HttpProtocolParameters httpProtocolParameters) { this.url = url; this.username = username; this.authenticationToken = authenticationToken; this.httpProxy = httpProxy; this.httpProtocolParameters = httpProtocolParameters; httpTransfer = new HttpTransferOne(url, httpProxy, httpProtocolParameters, null); } /** * Creates an AwakeFile session with a proxy and protocol parameters. *

* * @param url * the URL of the path to the AwakeFileManager Servlet * @param username * the username for authentication on the Awake Server (may be * null for call() * @param password * the user password for authentication on the Awake Server (may * be null) * @param httpProxy * the http proxy to use (null if none) * @param httpProtocolParameters * the http parameters to use (may be null) * * @throws MalformedURLException * if the url is malformed * @throws UnknownHostException * if Host url (http://www.acme.org) does not exists or no * Internet Connection.. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws InvalidLoginException * the username or password is invalid * @throws SecurityException * Scheme is required to be https (SSL/TLS) * @throws RemoteException * an exception has been thrown on the server side. This traps * an Awake product failure and should not happen. * @throws IOException * For all other IO / Network / System Error */ public AwakeFileSession(String url, String username, char[] password, HttpProxy httpProxy, HttpProtocolParameters httpProtocolParameters) throws MalformedURLException, UnknownHostException, ConnectException, InvalidLoginException, RemoteException, SecurityException, IOException { if (url == null) { throw new MalformedURLException("url can not be null!"); } @SuppressWarnings("unused") URL asUrl = new URL(url); // Try to raise a MalformedURLException; this.username = username; this.url = url; this.httpProxy = httpProxy; this.httpProtocolParameters = httpProtocolParameters; // username & password may be null: for call() if (username == null) { return; } // if (password == null) { // throw new IllegalArgumentException("password can not be null!"); // } // Launch the Servlet httpTransfer = new HttpTransferOne(url, httpProxy, httpProtocolParameters, null); // Test if SSL required by host if (this.url.toLowerCase().startsWith("http://") && isForceHttps()) { throw new SecurityException( Tag.AWAKE_SECURITY + "Remote Host requires a SSL url that starts with \"https\" scheme"); } String passwordStr = new String(password); // Prepare the request parameters List requestParams = new Vector(); requestParams.add(new BasicNameValuePair(Parameter.TEST_CRYPTO, Parameter.TEST_CRYPTO)); requestParams.add(new BasicNameValuePair(Parameter.ACTION, Action.LOGIN_ACTION)); requestParams.add(new BasicNameValuePair(Parameter.USERNAME, username)); requestParams.add(new BasicNameValuePair(Parameter.PASSWORD, passwordStr)); httpTransfer.send(requestParams); // If everything is OK, we have in our protocol a response that // 1) starts with "OK". 2) Is followed by the Authentication Token // else: response starts with "INVALID_LOGIN_OR_PASSWORD". String receive = httpTransfer.recv(); debug("receive: " + receive); if (receive.startsWith(ReturnCode.INVALID_LOGIN_OR_PASSWORD)) { throw new InvalidLoginException("Invalid username or password."); } else if (receive.startsWith(ReturnCode.OK)) { // OK! We are logged in & and correctly authenticated // Keep in static memory the Authentication Token for next api // commands (First 20 chars) String theToken = receive.substring(ReturnCode.OK.length() + 1); authenticationToken = StringUtils.left(theToken, Parameter.TOKEN_LEFT_SIZE); } else { this.username = null; // Should never happen throw new InvalidLoginException(Tag.AWAKE_PRODUCT_FAIL + " Please contact support."); } } /** * * Tests if remote host requires our URL to be SSL * * @return true if the host requires SSL * * @throws UnknownHostException * @throws ConnectException * @throws RemoteException * @throws SecurityException * @throws IOException */ private boolean isForceHttps() throws UnknownHostException, ConnectException, RemoteException, SecurityException, IOException { // Launch the Servlet // httpTransfer = new HttpTransferOne(url, httpProxy, // httpProtocolParameters, null); // Prepare the request parameters List requestParams = new Vector(); requestParams.add(new BasicNameValuePair(Parameter.ACTION, Action.BEFORE_LOGIN_ACTION)); httpTransfer.send(requestParams); // If everything is OK, we have in our protocol a response that // 1) starts with "OK". 2) Is followed by the Authentication Token // else: response starts with "INVALID_LOGIN_OR_PASSWORD". String receive = httpTransfer.recv(); Boolean isForceHttps = new Boolean(receive); return isForceHttps.booleanValue(); } /** * Creates an AwakeFile session with a proxy. *

* * @param url * the URL of the path to the AwakeFileManager Servlet * @param username * the username for authentication on the Awake Server (may be * null for call() * @param password * the user password for authentication on the Awake Server (may * be null) * @param httpProxy * the http proxy to use (null if none) * * @throws MalformedURLException * if the url is malformed * @throws UnknownHostException * if Host url (http://www.acme.org) does not exists or no * Internet Connection.. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws InvalidLoginException * the username or password is invalid * @throws SecurityException * Scheme is required to be https (SSL/TLS) * @throws RemoteException * an exception has been thrown on the server side * @throws IOException * For all other IO / Network / System Error */ public AwakeFileSession(String url, String username, char[] password, HttpProxy httpProxy) throws MalformedURLException, UnknownHostException, ConnectException, InvalidLoginException, RemoteException, SecurityException, IOException { this(url, username, password, httpProxy, null); } /** * Creates an AwakeFile session. *

* * @param url * the URL of the path to the AwakeFileManager Servlet * @param username * the username for authentication on the Awake Server (may be * null for call() * @param password * the user password for authentication on the Awake Server (may * be null) * * @throws MalformedURLException * if the url is malformed * @throws UnknownHostException * if Host url (http://www.acme.org) does not exists or no * Internet Connection.. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws InvalidLoginException * the username or password is invalid * @throws SecurityException * Scheme is required to be https (SSL/TLS) * @throws RemoteException * an exception has been thrown on the server side * @throws IOException * For all other IO / Network / System Error */ public AwakeFileSession(String url, String username, char[] password) throws MalformedURLException, UnknownHostException, ConnectException, InvalidLoginException, RemoteException, IOException, SecurityException { this(url, username, password, null, null); } /** * Allows to set an Awake Progress Manager instance. * * @param awakeProgressManager * the Awake Progress Manager instance */ public void setAwakeProgressManager( AwakeProgressManager awakeProgressManager) { this.awakeProgressManager = awakeProgressManager; httpTransfer.setAwakeProgressManager(awakeProgressManager); } /** * Returns the username of this Awake FILE session * * @return the username of this Awake FILE session */ public String getUsername() { return this.username; } /** * Returns the AwakeProgresManager in use. * * @return the AwakeProgresManager in use */ public AwakeProgressManager getAwakeProgressManager() { return this.awakeProgressManager; } /** * Returns the HttpProtocolParameters instance in use for the Awake FILE * session. * * @return the HttpProtocolParameters instance in use for the Awake FILE * session */ public HttpProtocolParameters getHttpProtocolParameters() { return this.httpProtocolParameters; } /** * Returns the URL of the path to the AwakeFileManager Servlet * (or AwakeSqlManager Servlet if session has been initiated by * an AwakeConnection). * * @return the URL of the path to the AwakeFileManager Servlet */ public String getUrl() { return url; } /** * Returns the HttpProxy instance in use for this Awake session. * * @return the HttpProxy instance in use for this Awake session */ public HttpProxy getHttpProxy() { return this.httpProxy; } /** * Returns the http status code of the last executed verb * * @return the http status code of the last executed verb */ public int getHttpStatusCode() { if (httpTransfer != null) { return httpTransfer.getHttpStatusCode(); } else { return 0; } } /** * Returns the Authentication Token. This method is used by other Awake * products (Awake SQL, ...) * * @return the Authentication Token */ public String getAuthenticationToken() { return this.authenticationToken; } /** * Downloads a file from the remote server. *

* The path of the remote file name is relative depending on the Awake FILE * configuration on the server. The path may be expressed *

* * @param remoteFile * the file name on the host * @param file * the file to create on the Client side * * @throws IllegalArgumentException * if remoteFile or file is null * @throws InvalidLoginException * the session has been closed by a logoff() * @throws FileNotFoundException * if the remote file is not found on server * * @throws UnknownHostException * if Host url (http://www.acme.org) does not exists or no * Internet Connection. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws InvalidLoginException * the session has been closed by a logoff() * @throws RemoteException * an exception has been thrown on the server side * @throws IOException * For all other IO / Network / System Error */ public void download(String remoteFile, File file) throws IllegalArgumentException, InvalidLoginException, FileNotFoundException, UnknownHostException, ConnectException, RemoteException, IOException { if (remoteFile == null) { throw new IllegalArgumentException("remoteFile can not be null!"); } if (file == null) { throw new IllegalArgumentException("file can not be null!"); } if (username == null || authenticationToken == null) { throw new InvalidLoginException(AWAKE_SESSION_IS_CLOSED); } // debug("downloadFile Begin"); try { // httpTransfer = new HttpTransferOne(url, this.httpProxy, // httpProtocolParameters, awakeProgressManager); // Prepare the request parameters List requestParams = new Vector(); requestParams.add(new BasicNameValuePair(Parameter.ACTION, Action.DOWNLOAD_FILE_ACTION)); requestParams.add(new BasicNameValuePair(Parameter.USERNAME, username)); requestParams.add(new BasicNameValuePair(Parameter.TOKEN, authenticationToken)); requestParams.add(new BasicNameValuePair(Parameter.FILENAME, remoteFile)); httpTransfer.download(requestParams, file); } catch (HttpTransferInterruptedException e) { throw new IOException(new InterruptedException( e.getLocalizedMessage())); } // If everything is OK, we have in our protocol a response that // 1) starts with "OK". 2) Is followed by the authentication token // else: response starts with "INVALID_LOGIN_OR_PASSWORD". // Analyze the answer, case of invalid login or FileNotFound Tag String receive = httpTransfer.recv(); if (receive.length() > 1) { if (receive.startsWith(ReturnCode.INVALID_LOGIN_OR_PASSWORD)) { throw new InvalidLoginException(AWAKE_SESSION_IS_CLOSED); } if (receive.startsWith(Tag.FileNotFoundException)) { throw new FileNotFoundException("Remote file does not exists: " + remoteFile); } // Should never happen throw new IOException(Tag.AWAKE_PRODUCT_FAIL + "Invalid received buffer: " + receive); } } /** * Uploads a file in one chunk on the server. *

* The path of the remote file name is relative depending on the Awake FILE * configuration on the server. *

* * @param in * the input stream for upload * @param remoteFile * the file name on the host * * @throws IllegalArgumentException * if file or remoteFile is null * @throws InvalidLoginException * the session has been closed by a logoff() * @throws FileNotFoundException * if the file to upload is not found * * @throws UnknownHostException * if Host url (http://www.acme.org) does not exists or no * Internet Connection. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws RemoteException * an exception has been thrown on the server side * @throws IOException * For all other IO / Network / System Error * */ private void uploadOneChunk(InputStream in, String remoteFile) throws IllegalArgumentException, InvalidLoginException, FileNotFoundException, UnknownHostException, ConnectException, RemoteException, IOException { if (remoteFile == null) { throw new IllegalArgumentException("remoteFile can not be null!"); } if (in == null) { throw new IllegalArgumentException("in can not be null!"); } if (username == null || authenticationToken == null) { throw new InvalidLoginException(AWAKE_SESSION_IS_CLOSED); } // HttpTransferOne instance is now built outside if we want to reuse the // info (tempLen) // httpTransfer = new HttpTransferOne(url, this.httpProxy, // httpProtocolParameters, awakeProgressManager); // Prepare the request parameters List requestParams = new Vector(); requestParams.add(new BasicNameValuePair(Parameter.ACTION, Action.UPLOAD_FILE_ACTION)); requestParams.add(new BasicNameValuePair(Parameter.USERNAME, username)); requestParams.add(new BasicNameValuePair(Parameter.TOKEN, authenticationToken)); requestParams .add(new BasicNameValuePair(Parameter.FILENAME, remoteFile)); httpTransfer.send(requestParams, in); if (awakeProgressManager != null && awakeProgressManager.isCancelled()) { throw new IOException(new InterruptedException(Tag.AWAKE + "File upload interrupted by user.")); } // If everything is OK, we have in our protocol a response that // 1) starts with "OK". 2) Is followed by the authenticaiton token // else: response starts with "INVALID_LOGIN_OR_PASSWORD". // Return the answer String receive = httpTransfer.recv(); debug("receive: " + receive); if (receive.startsWith(ReturnCode.INVALID_LOGIN_OR_PASSWORD)) { throw new InvalidLoginException(AWAKE_SESSION_IS_CLOSED); } } /** * Uploads a file on the server. *

* The path of the remote file name is relative depending on the Awake FILE * configuration on the server. *

* Large files are split in chunks that are uploaded in sequence. The * default chunk length is 100 Mb. You can change the default value with * {@link HttpProtocolParameters#setUploadChunkLength(long)} before passing * {@code HttpProtocolParameters} to this class constructor. *

* Note that file chunking requires that all chunks be sent to the same web * server that will aggregate the chunks after the last send. Thus, file * chunking does not support true stateless architecture with multiple * identical web servers. If you want to set a full stateless architecture * with multiple identical web servers, you must disable file chunking. This * is done by setting a 0 upload chunk length value using * {@link HttpProtocolParameters#setUploadChunkLength(long)}. * * @param file * the file to upload * @param remoteFile * the file name on the host * * @throws IllegalArgumentException * if file or remoteFile is null * @throws InvalidLoginException * the session has been closed by a logoff() * @throws FileNotFoundException * if the file to upload is not found * * @throws UnknownHostException * if Host url (http://www.acme.org) does not exists or no * Internet Connection. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws RemoteException * an exception has been thrown on the server side * @throws IOException * For all other IO / Network / System Error * */ public void upload(File file, String remoteFile) throws IllegalArgumentException, InvalidLoginException, FileNotFoundException, UnknownHostException, ConnectException, RemoteException, IOException { if (remoteFile == null) { throw new IllegalArgumentException("remoteFile can not be null!"); } if (file == null) { throw new IllegalArgumentException("file can not be null!"); } if (!file.exists()) { throw new FileNotFoundException("File does not exists: " + file); } long chunkLength = DefaultParms.DEFAULT_UPLOAD_CHUNK_LENGTH; if (httpProtocolParameters != null) { chunkLength = httpProtocolParameters.getUploadChunkLength(); } // No chunks for small files or chunkLength = 0 if (file.length() < chunkLength || chunkLength == 0) { InputStream in = null; try { in = new BufferedInputStream(new FileInputStream(file)); // httpTransfer = new HttpTransferOne(url, this.httpProxy, // httpProtocolParameters, awakeProgressManager); uploadOneChunk(in, remoteFile); } finally { IOUtils.closeQuietly(in); } return; } // Ok, split remote filename into chunk names FilenameSplitter fileSplitter = new FilenameSplitter(); fileSplitter.split(file, remoteFile, chunkLength); List fileParts = fileSplitter.getFileParts(); InputStream in = null; try { in = new BufferedInputStream(new FileInputStream(file)); // httpTransfer = new HttpTransferOne(url, this.httpProxy, // httpProtocolParameters, awakeProgressManager); // Upload each file part/chunk using same InputStream from begin to // end for (int i = 0; i < fileParts.size(); i++) { String remoteFilePart = fileParts.get(i); debug("remoteFilePart: " + remoteFilePart); uploadOneChunk(in, remoteFilePart); } } finally { IOUtils.closeQuietly(in); } } /** * Returns the length of a a list of files located on the remote host. * * @param remoteFiles * the list of the files located on the remote host. * * @return the total length of the files located on the remote host. * * @throws IllegalArgumentException * remoteFilesPath is null * @throws InvalidLoginException * the session has been closed by a logoff() * * @throws UnknownHostException * if the host url (http://www.acme.org) does not exists or no * Internet Connection. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws RemoteException * an exception has been thrown on the server side * @throws IOException * For all other IO / Network / System Error */ public long length(List remoteFiles) throws IllegalArgumentException, InvalidLoginException, UnknownHostException, ConnectException, RemoteException, IOException { if (remoteFiles == null) { throw new IllegalArgumentException( "remotesFilePath can not be null!"); } if (username == null || authenticationToken == null) { throw new InvalidLoginException(AWAKE_SESSION_IS_CLOSED); } remoteFiles = HtmlConverter.toHtml(remoteFiles); // httpTransfer = new HttpTransferOne(url, httpProxy, // httpProtocolParameters, awakeProgressManager); // ListHolder listHolderRemoteFilesPath = new ListHolder(); // listHolderRemoteFilesPath.setList(remoteFiles); String jsonString = ListOfStringTransport.toJson(remoteFiles); // Prepare the request parameters List requestParams = new Vector(); requestParams.add(new BasicNameValuePair(Parameter.ACTION, Action.GET_FILE_LENGTH_ACTION)); requestParams.add(new BasicNameValuePair(Parameter.USERNAME, username)); requestParams.add(new BasicNameValuePair(Parameter.TOKEN, authenticationToken)); requestParams .add(new BasicNameValuePair(Parameter.FILENAME, jsonString)); httpTransfer.send(requestParams); // If everything is OK, we have in our protocol a response that // 1) starts with "OK". 2) Is followed by the Authentication Token // else: response starts with "INVALID_LOGIN_OR_PASSWORD". String response = httpTransfer.recv(); if (response.startsWith(ReturnCode.INVALID_LOGIN_OR_PASSWORD)) { throw new InvalidLoginException(AWAKE_SESSION_IS_CLOSED); } else { try { long fileLength = Long.parseLong(response); return fileLength; } catch (NumberFormatException nfe) { // Build an Awake Exception with the content of the recv stream throw new IOException( Tag.AWAKE_PRODUCT_FAIL + nfe.getMessage(), nfe); } } } /** * Returns the length of a file located on the remote host. * * @param remoteFile * the file name on the host * * @return the length of the file located on the remote host. * * @throws IllegalArgumentException * if remoteFilesPath is null * @throws InvalidLoginException * the session has been closed by a logoff() * * @throws UnknownHostException * if the Host url (http://www.acme.org) does not exists or no * Internet Connection. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws RemoteException * an exception has been thrown on the server side * @throws IOException * For all other IO / Network / System Error */ public long length(String remoteFile) throws IllegalArgumentException, InvalidLoginException, UnknownHostException, ConnectException, RemoteException, IOException { if (remoteFile == null) { throw new IllegalArgumentException( "remotesFilePath can not be null!"); } if (username == null || authenticationToken == null) { throw new InvalidLoginException(AWAKE_SESSION_IS_CLOSED); } List list = new Vector(); list.add(remoteFile); return length(list); } /** * Deletes a remote file or remote directory on the host. (Directory must be * empty to be deleted). * * @param remoteFile * the file name on the host * * @return true if the file has been deleted * * @throws IllegalArgumentException * if remoteFile is null * @throws InvalidLoginException * the session has been closed by a logoff() * * @throws UnknownHostException * if Host url (http://www.acme.org) does not exists or no * Internet Connection. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws RemoteException * an exception has been thrown on the server side * @throws SecurityException * the url is not secured with https (SSL) * @throws IOException * For all other IO / Network / System Error */ public boolean delete(String remoteFile) throws IllegalArgumentException, InvalidLoginException, UnknownHostException, ConnectException, RemoteException, IOException { return actionOnUniqueFile(remoteFile, Action.DELETE_FILE_ACTION); } /** * Says if a remote file or directory exists. * * @param remoteFile * the file name on the host * * @return true if the file or directory exists * * @throws IllegalArgumentException * if remoteFile is null * @throws InvalidLoginException * the session has been closed by a logoff() * * @throws UnknownHostException * if Host url (http://www.acme.org) does not exists or no * Internet Connection. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws RemoteException * an exception has been thrown on the server side * @throws SecurityException * the url is not secured with https (SSL) * @throws IOException * For all other IO / Network / System Error */ public boolean exists(String remoteFile) throws IllegalArgumentException, InvalidLoginException, UnknownHostException, ConnectException, RemoteException, IOException { return actionOnUniqueFile(remoteFile, Action.EXISTS_ACTION); } /** * Executes a Java File.mkdir() on the Host. * * @param remoteFile * the file name on the host * * @return true if the mkdir() is successful * * @throws IllegalArgumentException * if remoteFile is null * @throws InvalidLoginException * the session has been closed by a logoff() * * @throws UnknownHostException * if host url (http://www.acme.org) does not exists or no * Internet Connection. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws IOException * For all other IO / Network / System Error */ public boolean mkdir(String remoteFile) throws IllegalArgumentException, InvalidLoginException, UnknownHostException, ConnectException, RemoteException, IOException { return actionOnUniqueFile(remoteFile, Action.MKDIR_ACTION); } /** * Executes a Java File.mkdirs() on the Host. * * @param remoteFile * the file name on the host * * @return true if the mkdirs() is successful * * @throws IllegalArgumentException * if remoteFile is null * @throws InvalidLoginException * the session has been closed by a logoff() * * @throws UnknownHostException * if host url (http://www.acme.org) does not exists or no * Internet Connection. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws IOException * For all other IO / Network / System Error */ public boolean mkdirs(String remoteFile) throws IllegalArgumentException, InvalidLoginException, UnknownHostException, ConnectException, RemoteException, IOException { return actionOnUniqueFile(remoteFile, Action.MKDIRS_ACTION); } /** * * Do a boolean action on a unique file or directory * * @param remoteFile * the file name on the host * * @return true if the file has been deleted * * @throws IllegalArgumentException * if remoteFile or action is null * @throws InvalidLoginException * the session has been closed by a logoff() * * @throws UnknownHostException * if Host url (http://www.acme.org) does not exists or no * Internet Connection. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws RemoteException * an exception has been thrown on the server side * @throws IOException * For all other IO / Network / System Error */ private boolean actionOnUniqueFile(String remoteFile, String action) throws IllegalArgumentException, InvalidLoginException, UnknownHostException, ConnectException, RemoteException, IOException { if (remoteFile == null) { throw new IllegalArgumentException("remoteFile can not be null!"); } if (action == null) { throw new IllegalArgumentException("action can not be null!"); } if (username == null || authenticationToken == null) { throw new InvalidLoginException(AWAKE_SESSION_IS_CLOSED); } // Launch the Servlet // httpTransfer = new HttpTransferOne(url, httpProxy, // httpProtocolParameters, awakeProgressManager); // Prepare the request parameters List requestParams = new Vector(); requestParams.add(new BasicNameValuePair(Parameter.ACTION, action)); requestParams.add(new BasicNameValuePair(Parameter.USERNAME, username)); requestParams.add(new BasicNameValuePair(Parameter.TOKEN, authenticationToken)); requestParams .add(new BasicNameValuePair(Parameter.FILENAME, remoteFile)); httpTransfer.send(requestParams); // If everything is OK, we have in our protocol a response that // 1) starts with "OK". 2) Is followed by the authenticaiton token // else: response starts with "INVALID_LOGIN_OR_PASSWORD". String response = httpTransfer.recv(); if (response.startsWith(ReturnCode.INVALID_LOGIN_OR_PASSWORD)) { throw new InvalidLoginException(AWAKE_SESSION_IS_CLOSED); } try { boolean actionDone = Boolean.parseBoolean(response); return actionDone; } catch (NumberFormatException nfe) { // Build an Awake Exception with the content of the recv stream throw new IOException(Tag.AWAKE_PRODUCT_FAIL + nfe.getMessage(), nfe); } } /** * Lists the files contained in a remote directory. * * @param remoteFile * the file name of the directory on the host * * @return the list of files in the remote directory. Will be * null if the remote directory does not exists. Will * be empty if the remote directory exists but has no files. * * @throws IllegalArgumentException * if remoteFile is null * @throws InvalidLoginException * the session has been closed by a logoff() * * @throws UnknownHostException * if Host url (http://www.acme.org) does not exists or no * Internet Connection. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws RemoteException * an exception has been thrown on the server side * @throws IOException * For all other IO / Network / System Error */ public List listFiles(String remoteFile) throws IllegalArgumentException, InvalidLoginException, UnknownHostException, ConnectException, RemoteException, IOException { return listFilesOrDirectory(remoteFile, Action.LIST_FILES_IN_DIR_ACTION); } /** * Lists the sub-directories contained in a remote directory * * @param remoteFile * the file name of the directory on the host * * @return the list of directories in the remote directory. Will be * null if the remote directory does not exists. Will * be empty if the remote directory exists but has no * sub-directories. * * @throws IllegalArgumentException * if remoteFile is null * @throws InvalidLoginException * the session has been closed by a logoff() * * @throws UnknownHostException * if Host url (http://www.acme.org) does not exists or no * Internet Connection. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws RemoteException * an exception has been thrown on the server side * @throws IOException * For all other IO / Network / System Error */ public List listDirectories(String remoteFile) throws IllegalArgumentException, InvalidLoginException, UnknownHostException, ConnectException, RemoteException, IOException { return listFilesOrDirectory(remoteFile, Action.LIST_DIRS_IN_DIR_ACTION); } /** * * Returns the list of files or directory in the remote directory. * * @param remoteFile * the file name of the directory on the host * * @return the list of files or directories in the remote directory. Will be * null if the remote directory does not exists. Will * be empty if the remote directory exists but is empty. * * @throws IllegalArgumentException * if remoteFile is null * @throws InvalidLoginException * if the username is refused by the remote host * * @throws UnknownHostException * if Host url (http://www.acme.org) does not exists or no * Internet Connection. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws RemoteException * an exception has been thrown on the server side * @throws SecurityException * the url is not secured with https (SSL) * @throws IOException * For all other IO / Network / System Error */ private List listFilesOrDirectory(String remoteFile, String action) throws IllegalArgumentException, InvalidLoginException, UnknownHostException, ConnectException, RemoteException, IOException { if (remoteFile == null) { throw new IllegalArgumentException("remoteFile can not be null!"); } if (action == null) { throw new IllegalArgumentException("action can not be null!"); } if (username == null || authenticationToken == null) { throw new InvalidLoginException(AWAKE_SESSION_IS_CLOSED); } // Launch the Servlet // httpTransfer = new HttpTransferOne(url, httpProxy, // httpProtocolParameters, awakeProgressManager); // Prepare the request parameters List requestParams = new Vector(); requestParams.add(new BasicNameValuePair(Parameter.ACTION, action)); requestParams.add(new BasicNameValuePair(Parameter.USERNAME, username)); requestParams.add(new BasicNameValuePair(Parameter.TOKEN, authenticationToken)); requestParams .add(new BasicNameValuePair(Parameter.FILENAME, remoteFile)); httpTransfer.setReceiveInFile(true); // To say we get the result into a // file httpTransfer.send(requestParams); // If everything is OK, we have in our protocol a response that // 1) starts with "OK". 2) Is followed by the authenticaiton token // else: response starts with "INVALID_LOGIN_OR_PASSWORD". File receiveFile = httpTransfer.getReceiveFile(); String receive = AwakeFileUtil.getFirstLineOfFile(receiveFile); // Content is OK if (receive.startsWith(ReturnCode.INVALID_LOGIN_OR_PASSWORD)) { if (!DEBUG && !KeepTempFilePolicyParms.KEEP_TEMP_FILE) { receiveFile.delete(); } throw new InvalidLoginException(AWAKE_SESSION_IS_CLOSED); } try { if (receive.equals("null")) { return null; } else if (receive.equals("[]")) { return new Vector(); } else { List list = getFilesListFromFile(receiveFile); return list; } } catch (Exception e) { throw new IOException(e.getMessage(), e); } finally { if (!DEBUG && !KeepTempFilePolicyParms.KEEP_TEMP_FILE) { receiveFile.delete(); } } } /** * Transforms the content of the file in Base64 lines into a list. * * @param file * the file containing the file names * * @return the content of the file lines into a list * @throws IOException * if any IO / Network / System Error occurs */ private List getFilesListFromFile(File file) throws IOException { List listBase = FileUtils.readLines(file); List files = new Vector(); for (String theFileStr : listBase) { theFileStr = HtmlConverter.fromHtml(theFileStr); files.add(theFileStr); } return files; } /** * Logs off from the remote host.  This will purge the authentication * values necessary for method calls. *

* Method should be called at the closure of the Client application. */ public void logoff() { username = null; authenticationToken = null; httpProxy = null; httpProtocolParameters = null; awakeProgressManager = null; if (httpTransfer != null) { httpTransfer.close(); httpTransfer = null; } } /** * Calls a remote Java {@code class.method} and (eventually) pass some * parameters to it. This method transforms the values in Base64. It's a * legacy method not to be used anymore: use {@code call} instead. * * @param methodName * the full method name to call in the format * org.acme.config.package.MyClass.myMethod * @param params * the array of parameters passed to the method * @return the result of the Java call as string * * @throws IllegalArgumentException * if methodName is null * @throws InvalidLoginException * the session has been closed by a logoff() * * @throws UnknownHostException * if Host url (http://www.acme.org) does not exists or no * Internet Connection. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws RemoteException * an exception has been thrown on the server side * @throws IOException * For all other IO / Network / System Error * */ private String callBase64Encoded(String methodName, Object... params) throws IllegalArgumentException, InvalidLoginException, UnknownHostException, ConnectException, RemoteException, IOException { // Class and method name can not be null if (methodName == null) { throw new IllegalArgumentException("methodName can not be null!"); } // username & Authentication Token may be null // because some methods can be called freely if (username == null) { username = "null"; } if (authenticationToken == null) { authenticationToken = "null"; } // Build the params types List paramsTypes = new Vector(); // Build the params values List paramsValues = new Vector(); debug(""); for (int i = 0; i < params.length; i++) { if (params[i] == null) { throw new IllegalArgumentException( Tag.AWAKE + "null values are not supported. Please provide a value for all parameters."); } else { String classType = params[i].getClass().getName(); // NO! can alter class name if value is obsfucated // classType = StringUtils.substringAfterLast(classType, "."); paramsTypes.add(classType); String value = params[i].toString(); debug(""); debug("classType: " + classType); debug("value : " + value); paramsValues.add(value); } } // ListHolder listHolderTypes = new ListHolder(); // listHolderTypes.setList(paramsTypes); String jsonParamTypes = ListOfStringTransport.toJson(paramsTypes); // ListHolder listHolderValues = new ListHolder(); // listHolderValues.setList(paramsValues); String jsonParamValues = ListOfStringTransport.toJson(paramsValues); debug("methodName : " + methodName); debug("jsonParamTypes : " + jsonParamTypes); debug("jsonParamValues: " + jsonParamValues); // httpTransfer = new HttpTransferOne(url, httpProxy, // httpProtocolParameters, awakeProgressManager); // Prepare the request parameters List requestParams = new Vector(); requestParams.add(new BasicNameValuePair(Parameter.ACTION, Action.CALL_ACTION)); // requestParams.add(new BasicNameValuePair(Parameter.LOGIN, // StringUtil.toBase64(username))); requestParams.add(new BasicNameValuePair(Parameter.USERNAME, username)); requestParams.add(new BasicNameValuePair(Parameter.TOKEN, authenticationToken)); requestParams.add(new BasicNameValuePair(Parameter.METHOD_NAME, methodName)); requestParams.add(new BasicNameValuePair(Parameter.PARAMS_TYPES, StringUtil.toBase64(jsonParamTypes))); requestParams.add(new BasicNameValuePair(Parameter.PARAMS_VALUES, StringUtil.toBase64(jsonParamValues))); httpTransfer.send(requestParams); // Return the answer String response = httpTransfer.recv(); debug("response: " + response); // Content is OK if (response.startsWith(ReturnCode.INVALID_LOGIN_OR_PASSWORD)) { throw new InvalidLoginException(AWAKE_SESSION_IS_CLOSED); } // The response is in Base 64 try { if (!response.isEmpty()) { response = StringUtil.fromBase64(response); } } catch (Exception e) { debug(response); // May happen till new Awake FILE is not deployed on Server throw new IOException(Tag.AWAKE_PRODUCT_FAIL + "Response must be and is not base64!", e); } return response; } /** * Calls a remote Java class.method and (eventually) pass some parameters to * it. * * @param methodName * the full method name to call in the format * org.acme.config.package.MyClass.myMethod * @param params * the array of parameters passed to the method * @return the result of the Java call as string * * @throws IllegalArgumentException * if methodName is null * @throws InvalidLoginException * the session has been closed by a logoff() * * @throws UnknownHostException * if Host url (http://www.acme.org) does not exists or no * Internet Connection. * @throws ConnectException * if the Host is correct but the AwakeFileManager Servlet is * not reachable (http://www.acme.org/AwakeFileManager) and * access failed with a status != OK (200). (If the host is * incorrect, or is impossible to connect to - Tomcat down - the * ConnectException will be the sub exception * HttpHostConnectException.) * @throws RemoteException * an exception has been thrown on the server side * @throws IOException * For all other IO / Network / System Error * */ public String call(String methodName, Object... params) throws IllegalArgumentException, InvalidLoginException, UnknownHostException, ConnectException, RemoteException, IOException { // For legacy methods if (!USE_HTML_ENCODING) { return callBase64Encoded(methodName, params); } // Class and method name can not be null if (methodName == null) { throw new IllegalArgumentException("methodName can not be null!"); } // username & Authentication Token may be null // because some methods can be called freely if (username == null) { username = "null"; } if (authenticationToken == null) { authenticationToken = "null"; } // Build the params types List paramsTypes = new Vector(); // Build the params values List paramsValues = new Vector(); debug(""); for (int i = 0; i < params.length; i++) { if (params[i] == null) { throw new IllegalArgumentException( Tag.AWAKE + "null values are not supported. Please provide a value for all parameters."); } else { String classType = params[i].getClass().getName(); // NO! can alter class name if value is obsfucated // classType = StringUtils.substringAfterLast(classType, "."); paramsTypes.add(classType); String value = params[i].toString(); debug(""); debug("classType: " + classType); debug("value : " + value); paramsValues.add(value); } } // ListHolder listHolderTypes = new ListHolder(); // listHolderTypes.setList(paramsTypes); String jsonParamTypes = ListOfStringTransport.toJson(paramsTypes); // ListHolder listHolderValues = new ListHolder(); // listHolderValues.setList(paramsValues); String jsonParamValues = ListOfStringTransport.toJson(paramsValues); debug("methodName : " + methodName); debug("jsonParamTypes : " + jsonParamTypes); debug("jsonParamValues: " + jsonParamValues); // httpTransfer = new HttpTransferOne(url, httpProxy, // httpProtocolParameters, awakeProgressManager); // Prepare the request parameters List requestParams = new Vector(); requestParams.add(new BasicNameValuePair(Parameter.ACTION, Action.CALL_ACTION_HTML_ENCODED)); requestParams.add(new BasicNameValuePair(Parameter.USERNAME, username)); requestParams.add(new BasicNameValuePair(Parameter.TOKEN, authenticationToken)); requestParams.add(new BasicNameValuePair(Parameter.METHOD_NAME, methodName)); requestParams.add(new BasicNameValuePair(Parameter.PARAMS_TYPES, jsonParamTypes)); requestParams.add(new BasicNameValuePair(Parameter.PARAMS_VALUES, jsonParamValues)); httpTransfer.send(requestParams); // Return the answer String response = httpTransfer.recv(); debug("response: " + response); // Content is OK if (response.startsWith(ReturnCode.INVALID_LOGIN_OR_PASSWORD)) { throw new InvalidLoginException(AWAKE_SESSION_IS_CLOSED); } // The response is in Html encode: if (!response.isEmpty()) { response = HtmlConverter.fromHtml(response); } return response; } /** * Allows to get a copy of the current AwakeFileSession: use it * to do some simultaneous operations in a different thread (in order to * avoid conflicts). */ @Override public AwakeFileSession clone() { AwakeFileSession awakeFileSession = new AwakeFileSession(this.url, this.username, this.authenticationToken, this.httpProxy, this.httpProtocolParameters); awakeFileSession.setAwakeProgressManager(awakeProgressManager); return awakeFileSession; } /** * Returns the Awake FILE Version. * * @return the Awake FILE Version */ public String getVersion() { return AwakeFileVersion.getVersion(); } /** * debug tool */ private void debug(String s) { if (DEBUG) { AwakeClientLogger.log(s); } } } // End





© 2015 - 2024 Weber Informatics LLC | Privacy Policy