Эх сурвалжийг харах

Code cleanup / add basic exception handling

David Luhmer 7 жил өмнө
parent
commit
0547a0974d

+ 0 - 226
src/main/java/com/owncloud/android/services/AccountManagerService.java

@@ -40,235 +40,9 @@ import de.luhmer.owncloud.accountimporter.helper.NextcloudRequest;
 
 public class AccountManagerService extends Service {
 
-    private static final String TAG = AccountManagerService.class.getCanonicalName();
-
-    /** Command to the service to display a message */
-    private static final int MSG_CREATE_NEW_ACCOUNT = 3;
-
-    private static final int MSG_REQUEST_NETWORK_REQUEST = 4;
-    private static final int MSG_RESPONSE_NETWORK_REQUEST = 5;
-
     @Override
     public IBinder onBind(Intent intent) {
         return (new InputStreamBinder(this));
     }
 
-    /**
-     * Handler of incoming messages from clients.
-     */
-    class IncomingHandler extends Handler {
-        @Override
-        public void handleMessage(final Message msg) {
-            switch (msg.what) {
-                case MSG_CREATE_NEW_ACCOUNT:
-                    addNewAccount();
-                    break;
-                case MSG_REQUEST_NETWORK_REQUEST:
-                    // TODO token check here!
-                    // Validate a Token here! - Make sure, that the other app has the permission to use this functionality
-                    String expectedToken = "test"; // Use the android account manager to get/verify token
-                    final String accountName = msg.getData().getString("account");  // e.g. david@nextcloud.test.de
-                    String token             = msg.getData().getString("token");    // token that the other app received by calling the AccountManager
-                    final boolean stream     = msg.getData().getBoolean("stream");  // Do you want to stream the result?
-                    final Integer port       = msg.getData().getInt("port");
-                    final NextcloudRequest request = (NextcloudRequest) msg.getData().getSerializable("request");
-
-                    if(token.equals(expectedToken)) {
-
-                        Object result = null;
-                        Exception exception = null;
-                        try {
-                            result = AsyncTaskHelper.executeBlockingRequest(() -> {
-                                Account account = AccountUtils.getOwnCloudAccountByName(AccountManagerService.this, accountName); // TODO handle case that account is not found!
-                                OwnCloudAccount ocAccount = new OwnCloudAccount(account, AccountManagerService.this);
-                                OwnCloudClient client = OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(ocAccount, AccountManagerService.this);
-
-                                //OwnCloudVersion version = AccountUtils.getServerVersion(account);
-                                //client.setOwnCloudVersion(version);
-
-                                // TODO do some checks if url is correct!! (prevent ../ in url etc..
-                                request.url = client.getBaseUri() + request.url;
-
-                                INetworkInterface network = (stream) ? new StreamingRequest(port) : new PlainRequest();
-
-                                switch(request.method) {
-                                    case "GET":
-                                        GetMethod get = new GetMethod(request.url);
-                                        get.setQueryString(convertMapToNVP(request.parameter));
-                                        get.addRequestHeader("OCS-APIREQUEST", "true");
-                                        int status = client.executeMethod(get);
-                                        if(status == 200) {
-                                            return network.handleGetRequest(get);
-                                        } else {
-                                            throw new Exception("Network error!!");
-                                        }
-                                    case "POST":
-                                        PostMethod post = new PostMethod(request.url);
-                                        post.setQueryString(convertMapToNVP(request.parameter));
-                                        post.addRequestHeader("OCS-APIREQUEST", "true");
-
-                                        if(request.requestBody != null) {
-                                            StringRequestEntity requestEntity = new StringRequestEntity(
-                                                    request.requestBody,
-                                                    "application/json",
-                                                    "UTF-8");
-                                            post.setRequestEntity(requestEntity);
-                                        }
-                                        int status2 = client.executeMethod(post);
-                                        if(status2 == 200) {
-                                            return network.handlePostRequest(post);
-                                        } else {
-                                            throw new Exception("Network error!!");
-                                        }
-                                    case "PUT":
-                                        PutMethod put = new PutMethod(request.url);
-                                        put.setQueryString(convertMapToNVP(request.parameter));
-                                        put.addRequestHeader("OCS-APIREQUEST", "true");
-
-                                        if(request.requestBody != null) {
-                                            StringRequestEntity requestEntity = new StringRequestEntity(
-                                                    request.requestBody,
-                                                    "application/json",
-                                                    "UTF-8");
-                                            put.setRequestEntity(requestEntity);
-                                        }
-                                        int status4 = client.executeMethod(put);
-                                        if(status4 == 200) {
-                                            return network.handlePutRequest(put);
-                                        } else {
-                                            throw new Exception("Network error!!");
-                                        }
-
-                                    case "DELETE":
-                                        DeleteMethod delete = new DeleteMethod(request.url);
-                                        delete.setQueryString(convertMapToNVP(request.parameter));
-                                        delete.addRequestHeader("OCS-APIREQUEST", "true");
-                                        int status3 = client.executeMethod(delete);
-                                        if(status3 == 200) {
-                                            return true;
-                                        } else {
-                                            throw new Exception("Network error!!");
-                                        }
-                                    default:
-                                        throw new Exception("Unexpected type!!");
-                                }
-                            });
-                        } catch (Exception e) {
-                            e.printStackTrace();
-                            exception = e;
-                        }
-
-                        try {
-                            Message resp = Message.obtain(null, MSG_RESPONSE_NETWORK_REQUEST);
-                            Bundle bResp = new Bundle();
-                            if(!stream) {
-                                bResp.putByteArray("result", (byte[]) result);
-                            } else {
-                                // TODO return streaming server port
-                                Log_OC.d(TAG, "Stream found, but currently not used");
-                            }
-                            bResp.putSerializable("exception", exception);
-                            resp.setData(bResp);
-                            msg.replyTo.send(resp);
-                        } catch (RemoteException e) {
-                            Toast.makeText(AccountManagerService.this, e.getMessage(), Toast.LENGTH_SHORT).show();
-                            e.printStackTrace();
-                        }
-                    }
-
-                    break;
-                default:
-                    super.handleMessage(msg);
-            }
-        }
-    }
-
-    interface INetworkInterface {
-
-        Object handleGetRequest(GetMethod get) throws IOException;
-        Object handlePostRequest(PostMethod post) throws IOException;
-        Object handlePutRequest(PutMethod put) throws IOException;
-    }
-
-    private NameValuePair[] convertMapToNVP(Map<String, String> map) {
-        NameValuePair[] nvp = new NameValuePair[map.size()];
-        int i = 0;
-        for (String key : map.keySet()) {
-            nvp[i] = new NameValuePair(key, map.get(key));
-            i++;
-        }
-        return nvp;
-    }
-
-    public class PlainRequest implements INetworkInterface {
-
-        @Override
-        public Object handleGetRequest(GetMethod get) throws IOException {
-            return get.getResponseBody();
-        }
-
-        @Override
-        public Object handlePostRequest(PostMethod post) throws IOException {
-            return true;
-        }
-
-        @Override
-        public Object handlePutRequest(PutMethod put) throws IOException {
-            return true;
-        }
-
-    }
-
-    public class StreamingRequest implements INetworkInterface {
-
-        private int port;
-
-        public StreamingRequest(int port) {
-            this.port = port;
-        }
-
-        @Override
-        public Object handleGetRequest(GetMethod get) throws IOException {
-            Log.d(TAG, "handleGetRequest() called with: get = [" + get + "]");
-
-
-            Socket m_activity_socket = new Socket();
-            SocketAddress sockaddr = new InetSocketAddress("127.0.0.1", port);
-            m_activity_socket.connect(sockaddr, 5000);
-
-
-            if (m_activity_socket.isConnected()) {
-                InputStream in = get.getResponseBodyAsStream();
-                OutputStream out = m_activity_socket.getOutputStream();
-                // the header describes the frame data (type, width, height, length)
-                // frame width and height have been previously decoded
-                //byte[] header = new byte[16];
-                //build_header( 1, width, height, frameData.length, header, 1 );
-                //m_nos.write( header );  // message header
-
-                IOUtils.copy(in, out);
-                in.close();
-                out.close();
-            }
-            return null;
-        }
-
-        @Override
-        public Object handlePostRequest(PostMethod post) throws IOException {
-            return true;
-        }
-
-        @Override
-        public Object handlePutRequest(PutMethod put) throws IOException {
-            return true;
-        }
-    }
-
-
-    private void addNewAccount() {
-        Intent dialogIntent = new Intent(AccountManagerService.this, FileDisplayActivity.class);
-        dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        // TODO make the activity start the "add new account" dialog automatically...
-        startActivity(dialogIntent);
-    }
 }

+ 96 - 91
src/main/java/de/luhmer/owncloud/accountimporter/helper/InputStreamBinder.java

@@ -9,7 +9,6 @@ import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.lib.common.OwnCloudAccount;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
-import com.owncloud.android.ui.asynctasks.AsyncTaskHelper;
 
 import org.apache.commons.httpclient.HttpMethodBase;
 import org.apache.commons.httpclient.NameValuePair;
@@ -19,11 +18,14 @@ import org.apache.commons.httpclient.methods.PostMethod;
 import org.apache.commons.httpclient.methods.PutMethod;
 import org.apache.commons.httpclient.methods.StringRequestEntity;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
 import java.util.Map;
-import java.util.concurrent.Callable;
 
 /**
  * Created by david on 29.06.17.
@@ -55,31 +57,48 @@ public class InputStreamBinder extends IInputStreamService.Stub {
         // read the input
         final InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(input);
 
-        try {
-            final NextcloudRequest request = deserializeObjectAndCloseStream(is);
-
-            InputStream resultStream = processRequest(request);
-            try {
-                return ParcelFileDescriptorUtil.pipeFrom(resultStream, new IThreadListener() {
-                    @Override
-                    public void onThreadFinished(Thread thread) {
-                        Log.d(TAG, "Done sending result");
-                    }
-                });
-            } catch (IOException e) {
-                e.printStackTrace();
+        Exception exception = null;
+        InputStream httpStream = new InputStream() {
+            @Override
+            public int read() throws IOException {
+                return 0;
             }
-        } catch (IOException e) {
-            Log.d(TAG, "Test #1 failed");
+        };
+        try {
+            // Start request and catch exceptions
+            NextcloudRequest request = deserializeObjectAndCloseStream(is);
+            httpStream = processRequest(request);
+        } catch (Exception e) {
             e.printStackTrace();
-        } catch (ClassNotFoundException e) {
+            exception = e;
+        }
+
+        try {
+            // Write exception to the stream followed by the actual network stream
+            InputStream exceptionStream = serializeObjectToInputStream(exception);
+            InputStream resultStream = new java.io.SequenceInputStream(exceptionStream, httpStream);
+            return ParcelFileDescriptorUtil.pipeFrom(resultStream, new IThreadListener() {
+                @Override
+                public void onThreadFinished(Thread thread) {
+                    Log.d(TAG, "Done sending result");
+                }
+            });
+        } catch (IOException e) {
             e.printStackTrace();
         }
         return null;
     }
 
+    private <T extends Serializable> ByteArrayInputStream serializeObjectToInputStream(T obj) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(obj);
+        oos.flush();
+        oos.close();
+        return new ByteArrayInputStream(baos.toByteArray());
+    }
 
-    private <T> T deserializeObjectAndCloseStream(InputStream is) throws IOException, ClassNotFoundException {
+    private <T extends Serializable> T deserializeObjectAndCloseStream(InputStream is) throws IOException, ClassNotFoundException {
         ObjectInputStream ois = new ObjectInputStream(is);
         T result = (T) ois.readObject();
         is.close();
@@ -87,80 +106,66 @@ public class InputStreamBinder extends IInputStreamService.Stub {
         return result;
     }
 
-    private InputStream processRequest(final NextcloudRequest request) {
-        try {
-            return AsyncTaskHelper.executeBlockingRequest(new Callable<InputStream>() {
-                @Override
-                public InputStream call() throws Exception {
-                    Account account = AccountUtils.getOwnCloudAccountByName(context, request.accountName); // TODO handle case that account is not found!
-                    OwnCloudAccount ocAccount = new OwnCloudAccount(account, context);
-                    OwnCloudClient client = OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(ocAccount, context);
-
-                    //OwnCloudVersion version = AccountUtils.getServerVersion(account);
-                    //client.setOwnCloudVersion(version);
-
-                    // TODO do some checks if url is correct!! (prevent ../ in url etc..
-                    request.url = client.getBaseUri() + request.url;
-
-                    //AccountManagerService.INetworkInterface network = (stream) ? new AccountManagerService.StreamingRequest(port) : new AccountManagerService.PlainRequest();
-
-                    HttpMethodBase method = null;
-
-                    switch (request.method) {
-                        case "GET":
-                            method = new GetMethod(request.url);
-                            break;
-
-                        case "POST":
-                            method = new PostMethod(request.url);
-                            if (request.requestBody != null) {
-                                StringRequestEntity requestEntity = new StringRequestEntity(
-                                        request.requestBody,
-                                        "application/json",
-                                        "UTF-8");
-                                ((PostMethod) method).setRequestEntity(requestEntity);
-                            }
-                            break;
-
-                        case "PUT":
-                            method = new PutMethod(request.url);
-                            if (request.requestBody != null) {
-                                StringRequestEntity requestEntity = new StringRequestEntity(
-                                        request.requestBody,
-                                        "application/json",
-                                        "UTF-8");
-                                ((PutMethod) method).setRequestEntity(requestEntity);
-                            }
-                            break;
-
-                        case "DELETE":
-                            method = new DeleteMethod(request.url);
-                            break;
-
-                        default:
-                            throw new Exception("Unexpected type!!");
-
-                    }
-
-                    method.setQueryString(convertMapToNVP(request.parameter));
-                    method.addRequestHeader("OCS-APIREQUEST", "true");
-
-                    //throw new Exception("Test!!!");
-
-                    int status = client.executeMethod(method);
-                    if (status == 200) {
-                        return method.getResponseBodyAsStream();
-                    } else {
-                        throw new Exception("Request returned code: " + status);
-                    }
+    private InputStream processRequest(final NextcloudRequest request) throws Exception {
+        Account account = AccountUtils.getOwnCloudAccountByName(context, request.accountName); // TODO handle case that account is not found!
+        OwnCloudAccount ocAccount = new OwnCloudAccount(account, context);
+        OwnCloudClient client = OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(ocAccount, context);
+
+        //OwnCloudVersion version = AccountUtils.getServerVersion(account);
+        //client.setOwnCloudVersion(version);
+
+        // TODO do some checks if url is correct!! (prevent ../ in url etc..
+        request.url = client.getBaseUri() + request.url;
+
+        //AccountManagerService.INetworkInterface network = (stream) ? new AccountManagerService.StreamingRequest(port) : new AccountManagerService.PlainRequest();
+
+        HttpMethodBase method = null;
+
+        switch (request.method) {
+            case "GET":
+                method = new GetMethod(request.url);
+                break;
+
+            case "POST":
+                method = new PostMethod(request.url);
+                if (request.requestBody != null) {
+                    StringRequestEntity requestEntity = new StringRequestEntity(
+                            request.requestBody,
+                            "application/json",
+                            "UTF-8");
+                    ((PostMethod) method).setRequestEntity(requestEntity);
                 }
-            });
-        } catch (Exception e) {
-            e.printStackTrace();
-            //TODO return exception to calling client app!
-            //return exceptionToInputStream(null);
+                break;
+
+            case "PUT":
+                method = new PutMethod(request.url);
+                if (request.requestBody != null) {
+                    StringRequestEntity requestEntity = new StringRequestEntity(
+                            request.requestBody,
+                            "application/json",
+                            "UTF-8");
+                    ((PutMethod) method).setRequestEntity(requestEntity);
+                }
+                break;
+
+            case "DELETE":
+                method = new DeleteMethod(request.url);
+                break;
+
+            default:
+                throw new Exception("Unexpected type!!");
+
+        }
+
+        method.setQueryString(convertMapToNVP(request.parameter));
+        method.addRequestHeader("OCS-APIREQUEST", "true");
+
+        int status = client.executeMethod(method);
+        if (status == 200) {
+            return method.getResponseBodyAsStream();
+        } else {
+            throw new Exception("Request returned code: " + status);
         }
-        return null;
     }
 
 }