Skip to content

Commit

Permalink
Beginning refactor to clean up basic structure / readability
Browse files Browse the repository at this point in the history
  • Loading branch information
daleharvey committed Jan 25, 2011
1 parent 0bf34a2 commit 73b2ca6
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 142 deletions.
2 changes: 2 additions & 0 deletions res/values/strings.xml
Expand Up @@ -3,4 +3,6 @@
<string name="app_name">CouchDB</string>
<string name="stop">Stop CouchDB</string>
<string name="delete">Delete Databases</string>
<string name="loading_dialog">CouchDB is Loading...</string>
<string name="confirm_delete">Are you sure you want to delete, this will delete all of your existing data?</string>
</resources>
8 changes: 4 additions & 4 deletions src/org/couchdb/android/CouchCtrlListener.java
Expand Up @@ -28,7 +28,7 @@ public CouchCtrlListener(String couchUrl, String db, String user,

public void start() {

Log.v(CouchFutonActivity.TAG, "Starting Listener for " + ctrl);
Log.v(CouchProcess.TAG, "Starting Listener for " + ctrl);

if (!running) {
try {
Expand Down Expand Up @@ -82,7 +82,7 @@ private void changes(int seq) throws JSONException {
+ "/_changes?include_docs=true&feed=longpoll&since="
+ Integer.toString(seq);
JSONObject json = HTTPRequest.get(url, headers()).json;
Log.v(CouchFutonActivity.TAG, "Received Changes for " + ctrl);
Log.v(CouchProcess.TAG, "Received Changes for " + ctrl);

seq = json.getInt("last_seq");
JSONArray results = json.getJSONArray("results");
Expand All @@ -91,13 +91,13 @@ private void changes(int seq) throws JSONException {
handleChange(results.getJSONObject(i).getJSONObject("doc"));
}
}
Log.v(CouchFutonActivity.TAG, "Changes listener on " + ctrl + " has stopped");
Log.v(CouchProcess.TAG, "Changes listener on " + ctrl + " has stopped");
running = false;
cancelled = false;
}

public void cancel() {
Log.v(CouchFutonActivity.TAG, "Cancelling changes listener for " + ctrl);
Log.v(CouchProcess.TAG, "Cancelling changes listener for " + ctrl);
cancelled = true;
}

Expand Down
265 changes: 141 additions & 124 deletions src/org/couchdb/android/CouchFutonActivity.java
Expand Up @@ -16,7 +16,6 @@
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
Expand All @@ -28,20 +27,57 @@

public class CouchFutonActivity extends Activity {

public final static String TAG = "CouchDB";
public final static String FUTON = "http://127.0.0.1:5984/_utils/";
private CouchProcess couch = CouchProcess.getInstance();

private ProgressDialog loading;

private ICouchService couchService;
public Boolean serviceStarted = false;

private WebView webView;
private static final int COUCH_STARTED = 1;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
attemptLaunch();
}

@Override
public void onRestart() {
super.onRestart();
attemptLaunch();
}

@Override
protected void onDestroy() {
super.onDestroy();
if (webView != null) {
webView.destroy();
}
if (couchService != null) {
unbindService(mConnection);
}
}

/*
* Checks to see if Couch is fully installed, if not prompt to complete
* installation otherwise start the couchdb service
*/
private void attemptLaunch() {
if (!CouchInstaller.checkInstalled()) {
startActivity(new Intent(this, CouchInstallActivity.class));
} else if (!CouchProcess.getInstance().couchStarted) {
String msg = this.getString(R.string.loading_dialog);
loading = ProgressDialog.show(this, "", msg, true);
bindService(new Intent(ICouchService.class.getName()), mConnection, Context.BIND_AUTO_CREATE);
}
}

/*
* This holds the connection to the CouchDB Service
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
try {
serviceStarted = true;
couchService = ICouchService.Stub.asInterface(service);
couchService.initCouchDB(mCallback);
} catch (RemoteException e) {
Expand All @@ -53,93 +89,53 @@ public void onServiceDisconnected(ComponentName className) {
couchService = null;
}
};

private void setFutonView() {

String user = CouchProcess.getInstance().adminUser;
String pass = CouchProcess.getInstance().adminPass;

WebView webView = new WebView(CouchFutonActivity.this);
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new CustomWebViewClient());
webView.setHttpAuthUsernamePassword("127.0.0.1", "administrator", user, pass);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
setContentView(webView);
webView.loadUrl(FUTON);
};

private class CustomWebViewClient extends WebViewClient {

/*
* Implement the callbacks that allow CouchDB to talk to this app
*/
private ICouchClient mCallback = new ICouchClient.Stub() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
public void couchStarted(String host, int port) throws RemoteException {
mHandler.sendMessage(mHandler.obtainMessage(COUCH_STARTED));
}

@Override
public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm) {
String[] up = view.getHttpAuthUsernamePassword(host, realm);
handler.proceed(up[0], up[1]);
public void databaseCreated(String name, String user, String pass,
String tag) throws RemoteException {
}
}

private void showLoading() {
loading = ProgressDialog.show(this, "", "CouchDB is Loading...", true);
}
};

private Boolean deleteDirectory(File dir) {
if (dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDirectory(new File(dir, children[i]));
if (!success) {
return false;
}
/*
* Because the service communication happens in a seperate thread, we need
* a message handler to control the ui in this thread
*/
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case COUCH_STARTED:
loading.dismiss();
launchFuton();
break;
default:
super.handleMessage(msg);
}
}
return dir.delete();
}

private void deleteDatabases() {
unbindService(mConnection);
CouchProcess.getInstance().stopCouchDB();
Log.v(TAG, "DELETING EVERYTHING");
File couchDir = new File(Environment.getExternalStorageDirectory(),
"couch");
// ARG THIS IS TOTALLY SCARY AND WRONG
deleteDirectory(couchDir);
finish();
}

private void confirmDelete() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(
"Are you sure you want to delete, this will delete all of your existing data?")
.setCancelable(false)
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
CouchFutonActivity.this.deleteDatabases();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
};

/*
* Creates the menu items
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
};

/*
* Handles the menu item callbacks
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
Expand All @@ -154,61 +150,82 @@ public boolean onOptionsItemSelected(MenuItem item) {
}
}

@Override
protected void onDestroy() {
super.onDestroy();
if (couchService != null) {
unbindService(mConnection);
}
/*
* Confirm that the user wants to delete their databases
*/
private void confirmDelete() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(this.getString(R.string.confirm_delete))
.setCancelable(false)
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
CouchFutonActivity.this.deleteDatabases();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boot();
/*
* Because we store the database files on the sdcard, uninstalling the application
* will persist the databases on reinstall, this will delete the entire
* couch directory on the sdcard and quit the application, the next time the
* user starts up again they will be prompted to reinstall couch
*
* However this is dangerous and messy and the functionality should probably
* be removed entirely
*/
private void deleteDatabases() {
unbindService(mConnection);
CouchProcess.getInstance().stopCouchDB();
File couchDir = new File(Environment.getExternalStorageDirectory(), "couch");
deleteDirectory(couchDir);
finish();
}

@Override
public void onRestart() {
super.onRestart();
boot();
};

private void boot() {
boolean installed = CouchInstaller.checkInstalled();
if (!installed && !serviceStarted) {
startActivity(new Intent(this, CouchInstallActivity.class));
} else if (!serviceStarted) {
showLoading();
bindService(new Intent(ICouchService.class.getName()), mConnection,
Context.BIND_AUTO_CREATE);
}

private void launchFuton() {
webView = new WebView(CouchFutonActivity.this);
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new CustomWebViewClient());
webView.setHttpAuthUsernamePassword(couch.host, "administrator", couch.adminUser, couch.adminPass);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
setContentView(webView);
webView.loadUrl(couch.couchUrl() + "_utils/");
};

private ICouchClient mCallback = new ICouchClient.Stub() {
@Override
public void couchStarted(String host, int port) throws RemoteException {
mHandler.sendMessage(mHandler.obtainMessage(COUCH_STARTED));
private Boolean deleteDirectory(File dir) {
if (dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDirectory(new File(dir, children[i]));
if (!success) {
return false;
}
}
}

return dir.delete();
}

private class CustomWebViewClient extends WebViewClient {
@Override
public void databaseCreated(String name, String user, String pass,
String tag) throws RemoteException {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
};

private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case COUCH_STARTED:
loading.dismiss();
setFutonView();
break;
default:
super.handleMessage(msg);
}
public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm) {
String[] up = view.getHttpAuthUsernamePassword(host, realm);
handler.proceed(up[0], up[1]);
}
};

}
}
3 changes: 1 addition & 2 deletions src/org/couchdb/android/CouchInstallActivity.java
Expand Up @@ -53,7 +53,7 @@ public void onClick(DialogInterface dialog,

case CouchInstallActivity.COMPLETE:
installProgress.dismiss();
Log.v(CouchFutonActivity.TAG, "Launching Couchdb activity");
Log.v(CouchProcess.TAG, "Launching Couchdb activity");
startActivity(new Intent(getApplicationContext(), CouchFutonActivity.class));
break;
}
Expand Down Expand Up @@ -101,7 +101,6 @@ public void run() {

class InstallError {
public String description;

public InstallError(String description) {
this.description = description;
}
Expand Down

0 comments on commit 73b2ca6

Please sign in to comment.