Revision f58bf9f4

b/.classpath
1 1
<?xml version="1.0" encoding="UTF-8"?>
2 2
<classpath>
3
	<classpathentry kind="src" path="src"/>
4 3
	<classpathentry kind="src" path="gen"/>
5 4
	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
5
	<classpathentry kind="src" path="src"/>
6 6
	<classpathentry kind="output" path="bin"/>
7 7
</classpath>
b/AndroidManifest.xml
78 78
        </activity>
79 79
        
80 80
		<activity android:name=".Preferences" android:label="@string/preference_name"/>
81
		<activity android:name="BackupServerActivity"></activity>
82
		<activity android:name="PasswordServerActivity"></activity>
83
		<activity android:name="PingServerActivity"></activity>
81 84

  
82 85
    </application>
83 86
    <uses-sdk android:minSdkVersion="4" />
b/res/layout/viewbackup.xml
1
<?xml version="1.0" encoding="utf-8"?>
2
<LinearLayout
3
  xmlns:android="http://schemas.android.com/apk/res/android"
4
  android:layout_width="fill_parent"
5
  android:layout_height="fill_parent" 
6
  android:orientation="vertical">
7
    <TextView 
8
    	android:layout_height="wrap_content" 
9
        android:layout_width="wrap_content" 
10
    	android:text="Daily Backup Window (GMT)" 
11
    	android:layout_marginLeft="22dip">
12
    </TextView>
13
    <Spinner 
14
    	android:layout_height="wrap_content" 
15
        android:layout_marginLeft="22dip" 
16
    	android:layout_width="wrap_content" 
17
    	android:id="@+id/daily_backup_spinner">
18
    </Spinner>
19
    <TextView 
20
    	android:layout_height="wrap_content" 
21
    	android:layout_width="wrap_content" 
22
    	android:layout_marginLeft="22dip" 
23
    	android:layout_marginTop="10dip"
24
    	android:text="Weekly Backup Window">
25
    </TextView>
26
    <Spinner 
27
    	android:layout_height="wrap_content" 
28
    	android:layout_marginLeft="22dip" 
29
    	android:layout_width="wrap_content" 
30
    	android:prompt="@string/weekly_backup_prompt" 
31
    	android:id="@+id/weekly_backup_spinner">
32
    </Spinner>
33
    <CheckBox 
34
    	android:layout_width="wrap_content" 
35
    	android:layout_height="wrap_content" 
36
    	android:layout_marginLeft="22dip" 
37
    	android:text="Enable Backups" 
38
    	android:layout_marginTop="10dip" 
39
    	android:id="@+id/enable_backup_checkbox">
40
    </CheckBox>
41
    <RelativeLayout 
42
    	android:layout_width="fill_parent" 
43
    	android:layout_height="wrap_content">
44
        <Button 
45
        	android:id="@+id/backup_update_button" 
46
        	android:text="Update" 
47
        	android:layout_height="wrap_content" 
48
        	android:layout_width="130dip" 
49
        	android:layout_centerInParent="true" 
50
        	android:layout_marginTop="20dip">
51
        </Button>
52
    </RelativeLayout>
53
</LinearLayout>
b/res/layout/viewchangepassword.xml
1
<?xml version="1.0" encoding="utf-8"?>
2
<LinearLayout
3
  xmlns:android="http://schemas.android.com/apk/res/android"
4
  android:layout_width="fill_parent"
5
  android:layout_height="fill_parent">
6
    <LinearLayout 
7
    	android:layout_width="wrap_content" 
8
    	android:layout_height="wrap_content" 
9
    	android:orientation="vertical">
10
        <TextView 
11
        	android:layout_width="wrap_content" 
12
        	android:layout_height="wrap_content" 
13
        	android:layout_marginLeft="22dip" 
14
        	android:id="@+id/new_password_label" 
15
        	android:text="New Password">
16
        </TextView>
17
        <EditText 
18
        	android:layout_height="wrap_content" 
19
        	android:id="@+id/password_edittext" 
20
        	android:layout_marginLeft="22dip" 
21
        	android:inputType="textPassword" 
22
        	android:layout_marginRight="30dip" 
23
        	android:layout_width="fill_parent">
24
        </EditText>
25
        <TextView 
26
        	android:layout_width="wrap_content" 
27
        	android:layout_height="wrap_content" 
28
        	android:text="Confirm Password" 
29
        	android:layout_marginLeft="22dip" 
30
        	android:layout_marginTop="15dip">
31
        </TextView>
32
        <EditText 
33
        	android:layout_height="wrap_content" 
34
        	android:id="@+id/password_confirm_edittext" 
35
        	android:layout_marginLeft="22dip" 
36
        	android:password="true" 
37
        	android:inputType="textPassword" 
38
        	android:layout_width="fill_parent" 
39
        	android:layout_marginRight="30dip">
40
        </EditText>
41
        <TextView 
42
        	android:layout_width="wrap_content" 
43
        	android:layout_height="wrap_content" 
44
        	android:text="@string/change_password_warning" 
45
        	android:gravity="center" 
46
        	android:layout_marginTop="10dip" 
47
        	android:layout_marginBottom="10dip">
48
        </TextView>
49
        <RelativeLayout android:layout_width="fill_parent" android:id="@+id/relativeLayout1" android:layout_height="wrap_content">
50
            <Button android:layout_alignParentTop="true" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_width="130dip" android:id="@+id/password_change_button" android:text="Submit"></Button>
51
        </RelativeLayout>
52
    </LinearLayout>
53
</LinearLayout>
b/res/layout/viewpingserver.xml
1
<?xml version="1.0" encoding="utf-8"?>
2
<LinearLayout
3
  xmlns:android="http://schemas.android.com/apk/res/android"
4
  android:layout_width="fill_parent"
5
  android:layout_height="fill_parent">
6
    <android.webkit.WebView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/ping_server_webview"></android.webkit.WebView>
7
</LinearLayout>
b/res/layout/viewserver.xml
240 240
            android:layout_marginTop="10dip"
241 241
            />
242 242
    </LinearLayout>
243
    
244
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
245
    	android:id="@+id/linearLayout1" 
246
    	android:layout_width="fill_parent" 
247
    	android:layout_marginTop="10dip" 
248
    	android:orientation="horizontal" 
249
    	android:layout_height="fill_parent">
250
        <Button xmlns:android="http://schemas.android.com/apk/res/android"
251
        	android:text="Rename Server" 
252
        	android:layout_width="130dip" 
253
        	android:layout_marginTop="10dip" 
254
        	android:layout_gravity="left" 
255
        	android:id="@+id/view_server_rename_button" 
256
        	android:layout_marginLeft="20dip" 
257
        	android:layout_height="wrap_content">
258
        </Button>
259
        <Button xmlns:android="http://schemas.android.com/apk/res/android"
260
        	android:text="Rebuild Server" 
261
        	android:layout_width="130dip" 
262
        	android:layout_marginTop="10dip" 
263
        	android:layout_gravity="left" 
264
        	android:id="@+id/view_server_rebuild_button" 
265
        	android:layout_marginLeft="10dip" 
266
        	android:layout_height="wrap_content">
267
        </Button>
268
    </LinearLayout>
269
  
270
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
271
    	android:layout_width="fill_parent" 
272
    	android:orientation="horizontal" 	
273
    	android:layout_height="fill_parent" 
274
    	android:layout_marginTop="10dip">
275
    	
276
    	<Button xmlns:android="http://schemas.android.com/apk/res/android"
277
            android:text="Backup Schedule"
278
            android:layout_width="130dip"
279
            android:layout_height="wrap_content"
280
            android:layout_gravity="left"
281
            android:layout_marginLeft="20dip"
282
            android:layout_marginTop="10dip"
283
            android:id="@+id/view_server_backup_button"/>
284
    	<Button xmlns:android="http://schemas.android.com/apk/res/android"
285
    		android:id="@+id/view_server_password_button" 
286
    		android:text="Change Root Password" 
287
    		android:layout_width="130dip" 
288
    		android:layout_marginTop="10dip" 
289
    		android:layout_marginLeft="10dip" 
290
    		android:layout_gravity="left" 
291
    		android:layout_height="fill_parent" 
292
    		android:gravity="center">
293
    	</Button>
294
    	 
295
    </LinearLayout>
296
    <LinearLayout android:layout_width="fill_parent" android:id="@+id/linearLayout1" android:orientation="horizontal" android:layout_marginTop="10dip" android:layout_height="fill_parent">
297
        <Button android:layout_width="130dip" android:layout_marginLeft="20dip" android:layout_gravity="left" android:text="Ping Server" android:layout_marginTop="10dip" android:id="@+id/view_server_ping_button" android:layout_height="wrap_content"></Button>
298
    </LinearLayout>
243 299

  
244
</LinearLayout>
245 300

  
246
<!--
247
    android:layout_height="wrap_content"
248
 -->
301
	</LinearLayout>
249 302
 </ScrollView>
b/res/values/arrays.xml
21 21
<item> true</item>
22 22
<item> false</item>
23 23
</string-array>
24

  
24 25
</resources>
b/res/values/strings.xml
20 20
</string-array>
21 21
<string name="country_default_value">0</string>
22 22
<string name="preference_name">Preferences</string>
23
<string name="weekly_backup_prompt">Select a weekly backup window</string>
24
<string-array name="weeklyBackupValues">
25
	<item> Disabled</item>
26
	<item> Sunday</item>
27
	<item> Monday</item>
28
	<item> Tuesday</item>
29
	<item> Wednesday</item>
30
	<item> Thursday</item>
31
	<item> Friday</item>
32
	<item> Saturday</item>
33
</string-array>
34
<string name="daily_backup_prompt">Select a daily backup window</string>
35
<string-array name="dailyBackupValues">
36
	<item> Disabled</item>
37
	<item> 0000-0200</item>
38
	<item> 0200-0400</item>
39
	<item> 0400-0600</item>
40
	<item> 0600-0800</item>
41
	<item> 0800-1000</item>
42
	<item> 1000-1200</item>
43
	<item> 1200-1400</item>
44
	<item> 1400-1600</item>
45
	<item> 1600-1800</item>
46
	<item> 1800-2000</item>
47
	<item> 2000-2200</item>
48
	<item> 2200-0000</item>
49
</string-array>
50
<string name="change_password_warning">The root password will be updated and the server will be restarted.  This process will only work
51
	if you have a user line for \"root\" in your passwd or shadow file.</string>
52

  
23 53
</resources>
b/src/com/rackspace/cloud/servers/api/client/Backup.java
1
package com.rackspace.cloud.servers.api.client;
2

  
3
public class Backup {
4
	
5
	private static final String[] weeklyBackupValues = {"DISABLED", "SUNDAY", "MONDAY", 
6
			"TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"};
7
	
8
	private static final String[] dailyBackupValues = {"DISABLED", "H_0000_0200", "H_0200_0400", "H_0400_0600", "H_0600_0800",
9
					"H_0800_1000", "H_1000_1200", "H_1200_1400", "H_1400_1600", "H_1600_1800", "H_1800_2000",
10
					"H_2000_2200", "H_2200_0000"};
11
	
12
	public static String getWeeklyValue(int i){
13
		return weeklyBackupValues[i];
14
	}
15
	
16
	public static String getDailyValue(int i){
17
		return dailyBackupValues[i];
18
	}
19

  
20
}
b/src/com/rackspace/cloud/servers/api/client/ServerManager.java
18 18
import org.apache.http.client.methods.HttpDelete;
19 19
import org.apache.http.client.methods.HttpGet;
20 20
import org.apache.http.client.methods.HttpPost;
21
import org.apache.http.client.methods.HttpPut;
21 22
import org.apache.http.entity.StringEntity;
22 23
import org.apache.http.impl.client.BasicResponseHandler;
23 24
import org.apache.http.impl.client.DefaultHttpClient;
......
312 313
		}	
313 314
		return resp;
314 315
	}
316
	
317
	public HttpResponse rename(Server server, String name) throws CloudServersException{
318
		HttpResponse resp = null;
319
		DefaultHttpClient httpclient = new DefaultHttpClient();
320
		HttpPut put = new HttpPut(Account.getServerUrl() + "/servers/" + server.getId() + ".xml");
321
	
322
		put.addHeader("X-Auth-Token", Account.getAuthToken());
323
		put.addHeader("Content-Type", "application/xml");
324
		httpclient.removeRequestInterceptorByClass(RequestExpectContinue.class);  //*******FIND OUT WITH THIS DOES?
325
	
326
		StringEntity tmp = null;
327
		try {
328
			tmp = new StringEntity("<server xmlns=\"http://docs.rackspacecloud.com/servers/api/v1.0\" name=\"" + name + "\"/>");
329
		} catch (UnsupportedEncodingException e) {
330
			CloudServersException cse = new CloudServersException();
331
			cse.setMessage(e.getLocalizedMessage());
332
			throw cse;
333
		}
334
		put.setEntity(tmp);
335
		
336
		try {			
337
			resp = httpclient.execute(put);
338
		} catch (ClientProtocolException e) {
339
			CloudServersException cse = new CloudServersException();
340
			cse.setMessage(e.getLocalizedMessage());
341
			throw cse;
342
		} catch (IOException e) {
343
			CloudServersException cse = new CloudServersException();
344
			cse.setMessage(e.getLocalizedMessage());
345
			throw cse;
346
		} catch (FactoryConfigurationError e) {
347
			CloudServersException cse = new CloudServersException();
348
			cse.setMessage(e.getLocalizedMessage());
349
			throw cse;
350
		}	
351
		return resp;
352
	}
353
	
354
	public HttpResponse rebuild(Server server, int imageId) throws CloudServersException {
355
		HttpResponse resp = null;
356
		DefaultHttpClient httpclient = new DefaultHttpClient();
357
		HttpPost post = new HttpPost(Account.getServerUrl() + "/servers/" + server.getId() + "/action.xml");
358
				
359
		post.addHeader("X-Auth-Token", Account.getAuthToken());
360
		post.addHeader("Content-Type", "application/xml");
361
		httpclient.removeRequestInterceptorByClass(RequestExpectContinue.class);
362

  
363
		StringEntity tmp = null;
364
		try {
365
			tmp = new StringEntity("<rebuild xmlns=\"http://docs.rackspacecloud.com/servers/api/v1.0\" imageId=\"" + imageId + "\"/>");
366
		} catch (UnsupportedEncodingException e) {
367
			CloudServersException cse = new CloudServersException();
368
			cse.setMessage(e.getLocalizedMessage());
369
			throw cse;
370
		}
371
		post.setEntity(tmp);
372

  
373
		try {			
374
			resp = httpclient.execute(post);
375
		} catch (ClientProtocolException e) {
376
			CloudServersException cse = new CloudServersException();
377
			cse.setMessage(e.getLocalizedMessage());
378
			throw cse;
379
		} catch (IOException e) {
380
			CloudServersException cse = new CloudServersException();
381
			cse.setMessage(e.getLocalizedMessage());
382
			throw cse;
383
		} catch (FactoryConfigurationError e) {
384
			CloudServersException cse = new CloudServersException();
385
			cse.setMessage(e.getLocalizedMessage());
386
			throw cse;
387
		}	
388
		return resp;
389
	}
315 390

  
391
	public HttpResponse backup(Server server, String weeklyValue, String dailyValue, boolean enabled) throws CloudServersException {
392
		HttpResponse resp = null;
393
		DefaultHttpClient httpclient = new DefaultHttpClient();
394
		HttpPost post = new HttpPost(Account.getServerUrl() + "/servers/" + server.getId() + "/backup_schedule.xml");
395
				
396
		post.addHeader("X-Auth-Token", Account.getAuthToken());
397
		post.addHeader("Content-Type", "application/xml");
398
		httpclient.removeRequestInterceptorByClass(RequestExpectContinue.class);
399

  
400
		StringEntity tmp = null;
401
		try {
402
			tmp = new StringEntity("<backupSchedule xmlns=\"http://docs.rackspacecloud.com/servers/api/v1.0\" enabled=\"" + enabled + "\" " +
403
					"weekly=\"" + weeklyValue + "\" daily=\"" + dailyValue + "\"/>");
404
			
405
		} catch (UnsupportedEncodingException e) {
406
			CloudServersException cse = new CloudServersException();
407
			cse.setMessage(e.getLocalizedMessage());
408
			throw cse;
409
		}
410
		post.setEntity(tmp);
411

  
412
		try {			
413
			resp = httpclient.execute(post);
414
		} catch (ClientProtocolException e) {
415
			CloudServersException cse = new CloudServersException();
416
			cse.setMessage(e.getLocalizedMessage());
417
			throw cse;
418
		} catch (IOException e) {
419
			CloudServersException cse = new CloudServersException();
420
			cse.setMessage(e.getLocalizedMessage());
421
			throw cse;
422
		} catch (FactoryConfigurationError e) {
423
			CloudServersException cse = new CloudServersException();
424
			cse.setMessage(e.getLocalizedMessage());
425
			throw cse;
426
		}	
427
		return resp;
428
	}
429
	
430
	public HttpResponse changePassword(Server server, String password) throws CloudServersException{
431
		HttpResponse resp = null;
432
		DefaultHttpClient httpclient = new DefaultHttpClient();
433
		HttpPut put = new HttpPut(Account.getServerUrl() + "/servers/" + server.getId() + ".xml");
434
	
435
		put.addHeader("X-Auth-Token", Account.getAuthToken());
436
		put.addHeader("Content-Type", "application/xml");
437
		httpclient.removeRequestInterceptorByClass(RequestExpectContinue.class); 
438
	
439
		StringEntity tmp = null;
440
		try {
441
			tmp = new StringEntity("<server xmlns=\"http://docs.rackspacecloud.com/servers/api/v1.0\" adminPass=\"" + password + "\"/>");
442
		} catch (UnsupportedEncodingException e) {
443
			CloudServersException cse = new CloudServersException();
444
			cse.setMessage(e.getLocalizedMessage());
445
			throw cse;
446
		}
447
		put.setEntity(tmp);
448
		
449
		try {			
450
			resp = httpclient.execute(put);
451
		} catch (ClientProtocolException e) {
452
			CloudServersException cse = new CloudServersException();
453
			cse.setMessage(e.getLocalizedMessage());
454
			throw cse;
455
		} catch (IOException e) {
456
			CloudServersException cse = new CloudServersException();
457
			cse.setMessage(e.getLocalizedMessage());
458
			throw cse;
459
		} catch (FactoryConfigurationError e) {
460
			CloudServersException cse = new CloudServersException();
461
			cse.setMessage(e.getLocalizedMessage());
462
			throw cse;
463
		}	
464
		return resp;
465
	}
466
	
316 467
}
b/src/com/rackspace/cloud/servers/api/client/http/Authentication.java
10 10
import org.apache.http.client.methods.HttpGet;
11 11
import org.apache.http.impl.client.DefaultHttpClient;
12 12

  
13
import android.util.Log;
14

  
13 15
import com.rackspace.cloud.servers.api.client.Account;
14 16

  
15 17
/**
......
19 21
public class Authentication {
20 22

  
21 23
	public static boolean authenticate() {
24
		
22 25
		DefaultHttpClient httpclient = new DefaultHttpClient();
23 26
		HttpGet get = new HttpGet(Account.getAuthServer());
24
		
27

  
25 28
		get.addHeader("X-Auth-User", Account.getUsername());
26 29
		get.addHeader("X-Auth-Key", Account.getApiKey());
27 30
		
28 31
		try {			
29 32
			HttpResponse resp = httpclient.execute(get);
30
		    
33
		    			
31 34
		    if (resp.getStatusLine().getStatusCode() == 204) {
32 35
		    	Account.setAuthToken(resp.getFirstHeader("X-Auth-Token").getValue());
33 36
		    	Account.setServerUrl(resp.getFirstHeader("X-Server-Management-Url").getValue());
......
36 39
		    	Account.setCdnManagementUrl(resp.getFirstHeader("X-Cdn-Management-Url").getValue());
37 40
		    	return true;
38 41
		    } else {
42
		    	Log.d("status code", Integer.toString(resp.getStatusLine().getStatusCode()));
39 43
		    	return false;
40 44
		    }
41 45
		} catch (ClientProtocolException cpe) {
42 46
			return false;
43 47
		} catch (IOException e) {
48
			Log.v("info", e.toString());
44 49
			return false;
45 50
		}
46 51
	}
b/src/com/rackspacecloud/android/BackupServerActivity.java
1
package com.rackspacecloud.android;
2

  
3
import java.io.IOException;
4
import java.io.StringReader;
5

  
6
import javax.xml.parsers.FactoryConfigurationError;
7
import javax.xml.parsers.ParserConfigurationException;
8
import javax.xml.parsers.SAXParser;
9
import javax.xml.parsers.SAXParserFactory;
10

  
11
import org.apache.http.HttpResponse;
12
import org.apache.http.client.ClientProtocolException;
13
import org.apache.http.impl.client.BasicResponseHandler;
14
import org.xml.sax.InputSource;
15
import org.xml.sax.SAXException;
16
import org.xml.sax.XMLReader;
17

  
18
import com.rackspace.cloud.servers.api.client.Backup;
19
import com.rackspace.cloud.servers.api.client.CloudServersException;
20
import com.rackspace.cloud.servers.api.client.Server;
21
import com.rackspace.cloud.servers.api.client.ServerManager;
22
import com.rackspace.cloud.servers.api.client.parsers.CloudServersFaultXMLParser;
23

  
24
import android.app.Activity;
25
import android.app.AlertDialog;
26
import android.content.DialogInterface;
27

  
28
import android.os.AsyncTask;
29
import android.os.Bundle;
30
import android.util.Log;
31
import android.view.View;
32
import android.view.View.OnClickListener;
33
import android.widget.AdapterView;
34
import android.widget.AdapterView.OnItemSelectedListener;
35
import android.widget.ArrayAdapter;
36
import android.widget.Button;
37
import android.widget.CheckBox;
38
import android.widget.Spinner;
39

  
40
public class BackupServerActivity extends Activity implements OnItemSelectedListener, OnClickListener {
41
		
42
	private Server server;
43
	private Spinner weeklyBackupSpinner;
44
	private Spinner dailyBackupSpinner;
45
	private CheckBox enableCheckBox;
46
	private String selectedWeeklyBackup;
47
	private String selectedDailyBackup;
48

  
49
	
50
	/** Called when the activity is first created. */
51
    @Override
52
    public void onCreate(Bundle savedInstanceState) {
53
        super.onCreate(savedInstanceState);
54
        server = (Server) this.getIntent().getExtras().get("server");
55
        setContentView(R.layout.viewbackup); 
56
        setupSpinners();
57
    	setupButtons();
58
    	setupCheckBox();        
59
    }
60

  
61
    private void setupSpinners(){
62
    	weeklyBackupSpinner = (Spinner) findViewById(R.id.weekly_backup_spinner);
63
    	ArrayAdapter<CharSequence> weeklyAdapter = ArrayAdapter.createFromResource(this, R.array.weeklyBackupValues, android.R.layout.simple_spinner_item);
64
    	weeklyAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
65
    	weeklyBackupSpinner.setAdapter(weeklyAdapter);
66
    	weeklyBackupSpinner.setOnItemSelectedListener(this);
67
    	
68
    	
69
    	dailyBackupSpinner = (Spinner) findViewById(R.id.daily_backup_spinner);
70
    	ArrayAdapter<CharSequence> dailyAdapter = ArrayAdapter.createFromResource(this, R.array.dailyBackupValues, android.R.layout.simple_spinner_item);
71
    	dailyAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
72
    	dailyBackupSpinner.setAdapter(dailyAdapter);
73
    	dailyBackupSpinner.setOnItemSelectedListener(this);
74
    }
75
    
76
	private void setupButtons() {
77
		Button update = (Button) findViewById(R.id.backup_update_button);
78
		update.setOnClickListener(this);
79
	}
80
	
81
	private void setupCheckBox(){
82
		enableCheckBox = (CheckBox) findViewById(R.id.enable_backup_checkbox);
83
	}
84

  
85
	public void onClick(View v) {
86
		new BackupServerTask().execute((Void[]) null);
87
	}
88

  
89
	public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
90
		if(parent == weeklyBackupSpinner){
91
			selectedWeeklyBackup = Backup.getWeeklyValue(pos);
92
		}
93
		if(parent == dailyBackupSpinner){
94
			selectedDailyBackup = Backup.getDailyValue(pos);
95
		}
96
		
97
	}
98

  
99
	public void onNothingSelected(AdapterView<?> parent) {
100
		//do nothing
101
	}
102
	
103
	
104
	private void showAlert(String title, String message) {
105
		AlertDialog alert = new AlertDialog.Builder(this).create();
106
		alert.setTitle(title);
107
		alert.setMessage(message);
108
		alert.setButton("OK", new DialogInterface.OnClickListener() {
109
	      public void onClick(DialogInterface dialog, int which) {
110
	        return;
111
	    } }); 
112
		alert.show();
113
	}
114
	
115
	private CloudServersException parseCloudServersException(HttpResponse response) {
116
		CloudServersException cse = new CloudServersException();
117
		try {
118
		    BasicResponseHandler responseHandler = new BasicResponseHandler();
119
		    String body = responseHandler.handleResponse(response);
120
	    	CloudServersFaultXMLParser parser = new CloudServersFaultXMLParser();
121
	    	SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
122
	    	XMLReader xmlReader = saxParser.getXMLReader();
123
	    	xmlReader.setContentHandler(parser);
124
	    	xmlReader.parse(new InputSource(new StringReader(body)));		    	
125
	    	cse = parser.getException();		    	
126
		} catch (ClientProtocolException e) {
127
			cse = new CloudServersException();
128
			cse.setMessage(e.getLocalizedMessage());
129
		} catch (IOException e) {
130
			cse = new CloudServersException();
131
			cse.setMessage(e.getLocalizedMessage());
132
		} catch (ParserConfigurationException e) {
133
			cse = new CloudServersException();
134
			cse.setMessage(e.getLocalizedMessage());
135
		} catch (SAXException e) {
136
			cse = new CloudServersException();
137
			cse.setMessage(e.getLocalizedMessage());
138
		} catch (FactoryConfigurationError e) {
139
			cse = new CloudServersException();
140
			cse.setMessage(e.getLocalizedMessage());
141
		}
142
		return cse;
143
    }
144
	
145
	private class BackupServerTask extends AsyncTask<Void, Void, HttpResponse> {
146
    	
147
		private CloudServersException exception;
148
		
149
		@Override
150
		protected HttpResponse doInBackground(Void... arg0) {
151
			HttpResponse resp = null;
152
			try {
153
				resp = (new ServerManager()).backup(server, selectedWeeklyBackup, selectedDailyBackup, enableCheckBox.isChecked());
154
			} catch (CloudServersException e) {
155
				exception = e;
156
			}
157
			return resp;
158
		}
159
    	
160
		@Override
161
		protected void onPostExecute(HttpResponse response) {
162

  
163
			if (response != null) {
164
				int statusCode = response.getStatusLine().getStatusCode();	
165
				Log.d("statuscode", Integer.toString(statusCode));
166
				if (statusCode != 204) {
167
					CloudServersException cse = parseCloudServersException(response);
168
					if ("".equals(cse.getMessage())) {
169
						showAlert("Error", "There was a problem rebooting your server.");
170
					} else {
171
						showAlert("Error", "There was a problem rebooting your server: " + cse.getMessage() + " " + statusCode);
172
					}
173
				}
174
			} else if (exception != null) {
175
				showAlert("Error", "There was a problem rebooting your server: " + exception.getMessage());
176
				
177
			}
178
		}
179
    }
180
}
b/src/com/rackspacecloud/android/ContainerObjectDetails.java
151 151
    }
152 152
    
153 153
    private class MyOnClickListener implements View.OnClickListener {
154
        @Override
154
        //@Override********************************************************************remove comment
155 155
        public void onClick(View v) {
156 156
        	Intent viewIntent = new Intent("android.intent.action.VIEW", Uri.parse(cdnURL + "/" + objects.getCName()));
157 157
        	startActivity(viewIntent);  
b/src/com/rackspacecloud/android/PasswordServerActivity.java
1
package com.rackspacecloud.android;
2

  
3
import java.io.IOException;
4
import java.io.StringReader;
5

  
6
import javax.xml.parsers.FactoryConfigurationError;
7
import javax.xml.parsers.ParserConfigurationException;
8
import javax.xml.parsers.SAXParser;
9
import javax.xml.parsers.SAXParserFactory;
10

  
11
import org.apache.http.HttpResponse;
12
import org.apache.http.client.ClientProtocolException;
13
import org.apache.http.impl.client.BasicResponseHandler;
14
import org.xml.sax.InputSource;
15
import org.xml.sax.SAXException;
16
import org.xml.sax.XMLReader;
17

  
18
import android.app.Activity;
19
import android.app.AlertDialog;
20
import android.content.DialogInterface;
21
import android.os.AsyncTask;
22
import android.os.Bundle;
23
import android.view.View;
24
import android.view.View.OnClickListener;
25
import android.widget.Button;
26
import android.widget.EditText;
27
import android.widget.Toast;
28

  
29
import com.rackspace.cloud.servers.api.client.CloudServersException;
30
import com.rackspace.cloud.servers.api.client.Server;
31
import com.rackspace.cloud.servers.api.client.ServerManager;
32
import com.rackspace.cloud.servers.api.client.parsers.CloudServersFaultXMLParser;
33

  
34
public class PasswordServerActivity extends Activity implements OnClickListener{
35
	
36
	private Server server;
37
	private String modifiedPassword;
38
	
39
	public void onCreate(Bundle savedInstanceState) {
40
        super.onCreate(savedInstanceState);
41
        setContentView(R.layout.viewchangepassword); 
42
        server = (Server) this.getIntent().getExtras().get("server");
43
    	setupButtons();       
44
    }
45

  
46
	private void setupButtons() {
47
		Button update = (Button) findViewById(R.id.password_change_button);
48
		update.setOnClickListener(this);
49
	}
50
	
51
	@Override
52
	public void onClick(View v) {
53
		String password = ((EditText)findViewById(R.id.password_edittext)).getText().toString();
54
		String confirm = ((EditText)findViewById(R.id.password_confirm_edittext)).getText().toString();
55
		if(password.equals(confirm)){
56
			new PasswordServerTask().execute((Void[]) null);	
57
		}
58
		else{
59
			String mustMatch = "The password and confirmation do not match.";
60
			Toast passwordError = Toast.makeText(getApplicationContext(), mustMatch, Toast.LENGTH_SHORT);
61
			passwordError.show();
62
		}
63
	}
64
	
65
	private void showAlert(String title, String message) {
66
		AlertDialog alert = new AlertDialog.Builder(this).create();
67
		alert.setTitle(title);
68
		alert.setMessage(message);
69
		alert.setButton("OK", new DialogInterface.OnClickListener() {
70
			public void onClick(DialogInterface dialog, int which) {
71
				return;
72
			} }); 
73
		alert.show();
74
	}
75

  
76
	private CloudServersException parseCloudServersException(HttpResponse response) {
77
		CloudServersException cse = new CloudServersException();
78
		try {
79
		    BasicResponseHandler responseHandler = new BasicResponseHandler();
80
		    String body = responseHandler.handleResponse(response);
81
	    	CloudServersFaultXMLParser parser = new CloudServersFaultXMLParser();
82
	    	SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
83
	    	XMLReader xmlReader = saxParser.getXMLReader();
84
	    	xmlReader.setContentHandler(parser);
85
	    	xmlReader.parse(new InputSource(new StringReader(body)));		    	
86
	    	cse = parser.getException();		    	
87
		} catch (ClientProtocolException e) {
88
			cse = new CloudServersException();
89
			cse.setMessage(e.getLocalizedMessage());
90
		} catch (IOException e) {
91
			cse = new CloudServersException();
92
			cse.setMessage(e.getLocalizedMessage());
93
		} catch (ParserConfigurationException e) {
94
			cse = new CloudServersException();
95
			cse.setMessage(e.getLocalizedMessage());
96
		} catch (SAXException e) {
97
			cse = new CloudServersException();
98
			cse.setMessage(e.getLocalizedMessage());
99
		} catch (FactoryConfigurationError e) {
100
			cse = new CloudServersException();
101
			cse.setMessage(e.getLocalizedMessage());
102
		}
103
		return cse;
104
	}
105

  
106
	private class PasswordServerTask extends AsyncTask<Void, Void, HttpResponse> {
107

  
108
		private CloudServersException exception;
109

  
110
		@Override
111
		protected HttpResponse doInBackground(Void... arg0) {
112
			HttpResponse resp = null;
113
			try {
114
				resp = (new ServerManager()).changePassword(server, modifiedPassword);
115
			} catch (CloudServersException e) {
116
				exception = e;
117
			}
118
			return resp;
119
		}
120

  
121
		@Override
122
		protected void onPostExecute(HttpResponse response) {
123
			if (response != null) {
124
				int statusCode = response.getStatusLine().getStatusCode();	
125
				if(statusCode == 204){
126
					String mustMatch = "The server's root password has successfully been changed.";
127
					Toast passwordError = Toast.makeText(getApplicationContext(), mustMatch, Toast.LENGTH_SHORT);
128
					passwordError.show();
129
					finish();
130
				}
131
				if (statusCode != 204) {
132
					CloudServersException cse = parseCloudServersException(response);
133
					if ("".equals(cse.getMessage())) {
134
						showAlert("Error", "There was a problem changing your password.");
135
					} else {
136
						showAlert("Error", "There was a problem changing your password: " + cse.getMessage() + " " + statusCode);
137
					}
138
				}
139
			} else if (exception != null) {
140
				showAlert("Error", "There was a problem changing your password: " + exception.getMessage());
141
				
142
			}
143
		}
144

  
145

  
146
	}
147
}
b/src/com/rackspacecloud/android/PingServerActivity.java
1
package com.rackspacecloud.android;
2

  
3
import android.app.Activity;
4
import android.os.Bundle;
5
import android.webkit.WebView;
6

  
7
public class PingServerActivity extends Activity{
8
	
9
	private WebView pingSiteView;
10
	private String ipAddress;
11
	private final String url = "http://just-ping.com/index.php?vh=&c=&s=ping!";
12
	
13
	public void onCreate(Bundle savedInstanceState){
14
		super.onCreate(savedInstanceState);
15
		setContentView(R.layout.viewpingserver);
16
		ipAddress = (String) this.getIntent().getExtras().get("ipAddress");
17
		String urlWIp = getUrl(ipAddress);
18
		pingSiteView = (WebView) findViewById(R.id.ping_server_webview);
19
		//just-ping.com uses javascript to make requests
20
		pingSiteView.getSettings().setJavaScriptEnabled(true);
21
		pingSiteView.loadUrl(urlWIp);
22
		
23
	}
24
	
25
	private String getUrl(String ip){
26
		//put the ip address into the appropriate location in the url
27
		return url.substring(0, url.indexOf("=")+1) + ip + url.substring(url.indexOf("&"));
28
		
29
	}
30

  
31
}
b/src/com/rackspacecloud/android/RackspaceCloudActivity.java
57 57
        final EditText loginApiKey = (EditText) findViewById(R.id.login_apikey);
58 58

  
59 59
        show_clear.setOnClickListener(new OnClickListener() {
60
			@Override
60
        	@Override 
61 61
			public void onClick(View v) {
62 62
		        if (((CheckBox) v).isChecked()) {
63 63
		        	loginApiKey.setTransformationMethod(new SingleLineTransformationMethod());
b/src/com/rackspacecloud/android/ViewServerActivity.java
23 23
import android.app.AlertDialog;
24 24
import android.app.Dialog;
25 25
import android.content.DialogInterface;
26
import android.content.Intent;
26 27
import android.graphics.Color;
27 28
import android.os.AsyncTask;
28 29
import android.os.Bundle;
29 30
import android.view.View;
30 31
import android.view.View.OnClickListener;
31 32
import android.widget.Button;
33
import android.widget.EditText;
32 34
import android.widget.ImageView;
33 35
import android.widget.LinearLayout;
34 36
import android.widget.TextView;
35 37

  
36 38
import com.rackspace.cloud.servers.api.client.CloudServersException;
37 39
import com.rackspace.cloud.servers.api.client.Flavor;
40
import com.rackspace.cloud.servers.api.client.Image;
38 41
import com.rackspace.cloud.servers.api.client.Server;
39 42
import com.rackspace.cloud.servers.api.client.ServerManager;
40 43
import com.rackspace.cloud.servers.api.client.parsers.CloudServersFaultXMLParser;
......
51 54
	private String[] flavorNames;
52 55
	private String selectedFlavorId;
53 56
	private boolean imageLoaded;
57
    private String modifiedServerName;
58
    private Image[] images;
59
	private String[] imageNames;
60
	private String selectedImageId;
54 61
	
55 62
    /** Called when the activity is first created. */
56 63
    @Override
......
76 83
        loadServerData();
77 84
        setupButtons();
78 85
        loadFlavors();
86
        loadImages();
79 87
    }
80 88

  
81 89
    private void loadImage() {
......
160 168
		}
161 169
		selectedFlavorId = flavors[0].getId();
162 170
    }
171
    
172
    private void loadImages() {
173
		imageNames = new String[Image.getImages().size()]; 
174
		images = new Image[Image.getImages().size()];
175

  
176
		Iterator<Image> iter = Image.getImages().values().iterator();
177
		int i = 0;
178
		while (iter.hasNext()) {
179
			Image image = iter.next();
180
			images[i] = image;
181
			imageNames[i] = image.getName(); 
182
			i++;
183
		}
184
		selectedImageId = images[0].getId();
185
		
186
    }
163 187

  
164 188
    private void setupButton(int resourceId, OnClickListener onClickListener) {
165 189
		Button button = (Button) findViewById(resourceId);
......
191 215
            }
192 216
    	});
193 217
    	
218
    	setupButton(R.id.view_server_rename_button, new OnClickListener() {
219
            public void onClick(View v) {
220
                showDialog(R.id.view_server_rename_button);
221
            }
222
    	});
223
    	
224
    	setupButton(R.id.view_server_rebuild_button, new OnClickListener() {
225
            public void onClick(View v) {
226
                showDialog(R.id.view_server_rebuild_button);
227
            }
228
    	});
229
    	
230
    	
231
    	setupButton(R.id.view_server_backup_button, new OnClickListener() {
232
            public void onClick(View v) {
233
            	Intent viewIntent = new Intent(v.getContext(), BackupServerActivity.class);
234
            	viewIntent.putExtra("server", server);
235
            	startActivity(viewIntent);
236
            }
237
    	});
238
    	
239
    	setupButton(R.id.view_server_password_button, new OnClickListener() {
240
            public void onClick(View v) {
241
            	Intent viewIntent = new Intent(v.getContext(), PasswordServerActivity.class);
242
            	viewIntent.putExtra("server", server);
243
            	startActivity(viewIntent);
244
            }
245
    	});
246
    	
247
    	setupButton(R.id.view_server_ping_button, new OnClickListener() {
248
            public void onClick(View v) {
249
            	Intent viewIntent = new Intent(v.getContext(), PingServerActivity.class);
250
            	
251
            	//ping the first public ip
252
            	viewIntent.putExtra("ipAddress", server.getPublicIpAddresses()[0]);
253
            	startActivity(viewIntent);
254
            }
255
    	});
256
    	
194 257
    }
195 258
    
196 259
    private void showAlert(String title, String message) {
......
282 345
        			// User clicked Cancel so do some stuff
283 346
        		}
284 347
        	})
285
        	.create();
348
        	.create();          
349
         case R.id.view_server_rename_button:
350
        	final EditText input = new EditText(this);
351
        	input.setText(server.getName());
352
            return new AlertDialog.Builder(ViewServerActivity.this)
353
        	.setIcon(R.drawable.alert_dialog_icon)
354
            .setView(input)
355
        	.setTitle("Rename")
356
        	.setMessage("Enter new name for server: ")        	         
357
        	.setPositiveButton("Rename", new DialogInterface.OnClickListener() {
358
        		public void onClick(DialogInterface dialog, int whichButton) {
359
        			// User clicked OK so do some stuff
360
        			modifiedServerName = input.getText().toString();
361
        			new RenameServerTask().execute((Void[]) null);
362
        		}
363
        	})
364
        	.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
365
        		public void onClick(DialogInterface dialog, int whichButton) {
366
        			// User clicked Cancel so do some stuff
367
        		}
368
        	})
369
        	.create();     
370
         case R.id.view_server_rebuild_button:
371
            return new AlertDialog.Builder(ViewServerActivity.this)
372
            .setItems(imageNames, new RebuildClickListener())
373
         	.setIcon(R.drawable.alert_dialog_icon)
374
         	.setTitle("Rebuild Server")
375
         	.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
376
         		public void onClick(DialogInterface dialog, int whichButton) {
377
         			// User clicked Cancel so do some stuff
378
         		}
379
         	})
380
         	.create();
286 381
        }
287 382
        return null;
288 383
    }
......
296 391
    	
297 392
    }
298 393
    
394
    private class RebuildClickListener implements android.content.DialogInterface.OnClickListener {
395

  
396
		public void onClick(DialogInterface dialog, int which) {
397
			selectedImageId = images[which].getId() + "";
398
			new RebuildServerTask().execute((Void[]) null);
399
		}
400
    	
401
    }
402
    
403

  
404
    
299 405
    private CloudServersException parseCloudServersException(HttpResponse response) {
300 406
		CloudServersException cse = new CloudServersException();
301 407
		try {
......
456 562
		}
457 563
    }
458 564
	
459
	private class DeleteServerTask extends AsyncTask<Void, Void, HttpResponse> {
565
	public class DeleteServerTask extends AsyncTask<Void, Void, HttpResponse> {
460 566
    	
461 567
		private CloudServersException exception;
462 568

  
......
491 597
			}			
492 598
		}
493 599
    }
600
	
601
	private class RenameServerTask extends AsyncTask<Void, Void, HttpResponse> {
602
		
603
		private CloudServersException exception;
604
		
605
		@Override
606
		protected HttpResponse doInBackground(Void... arg0) {
607
			HttpResponse resp = null;
608
			try {
609
				resp = (new ServerManager()).rename(server, modifiedServerName);
610
			} catch (CloudServersException e) {
611
				exception = e;
612
			}
613
			return resp;
614
		}
615
		
616
		@Override
617
		protected void onPostExecute(HttpResponse response) {
618
			if (response != null) {
619
				int statusCode = response.getStatusLine().getStatusCode();			
620
				if (statusCode == 204) {	
621
					new PollServerTask().execute((Void[]) null);
622
				} else {
623
					CloudServersException cse = parseCloudServersException(response);
624
					if ("".equals(cse.getMessage())) {
625
						showAlert("Error", "There was a problem renaming your server.");
626
					} else {
627
						showAlert("Error", "There was a problem renaming your server: " + cse.getMessage());
628
					}					
629
				}
630
			}
631
		    else if (exception != null) {
632
		    	showAlert("Error", "There was a problem rebooting your server: " + exception.getMessage());	
633
		    }
634
		}
635
		
636
	}
637
	
638
	private class RebuildServerTask extends AsyncTask<Void, Void, HttpResponse> {
639
    	
640
		private CloudServersException exception;
641

  
642
		@Override
643
		protected HttpResponse doInBackground(Void... arg0) {
644
			HttpResponse resp = null;
645
			try {
646
				resp = (new ServerManager()).rebuild(server, Integer.parseInt(selectedImageId));
647
			} catch (CloudServersException e) {
648
				exception = e;
649
			}
650
			return resp;
651
		}
652
    	
653
		@Override
654
		protected void onPostExecute(HttpResponse response) {
655
			if (response != null) {
656
				int statusCode = response.getStatusLine().getStatusCode();			
657
				if (statusCode == 202) {
658
					new PollServerTask().execute((Void[]) null);
659
				} else {					
660
					CloudServersException cse = parseCloudServersException(response);
661
					if ("".equals(cse.getMessage())) {
662
						showAlert("Error", "There was a problem deleting your server.");
663
					} else {
664
						showAlert("Error", "There was a problem deleting your server: " + cse.getMessage());
665
					}					
666
				}
667
			} else if (exception != null) {
668
				showAlert("Error", "There was a problem resizing your server: " + exception.getMessage());
669
				
670
			}
671
			
672
		}
673
    }
674
	
675
	
494 676
}

Also available in: Unified diff