Revision 76:b4fce4e13ec9

b/java/jgsscli/src/jgsscli/cli/GSSClient.java
1 1
package jgsscli.cli;
2 2

  
3 3
import java.io.PrintWriter;
4
import java.text.DecimalFormat;
5
import java.util.Formatter;
4 6
import java.util.List;
5
import java.util.logging.ConsoleHandler;
6
import java.util.logging.Logger;
7 7

  
8
import jgsscli.commands.Event;
8 9
import jgsscli.commands.GSSCmd;
10
import jgsscli.commands.Observable;
11
import jgsscli.commands.Observer;
9 12

  
10 13

  
11
public class GSSClient {
14
public class GSSClient implements Observer {
12 15

  
16
    private static final DecimalFormat FORMAT_TWO_DEC = 
17
	new DecimalFormat("#.##");
18
    private static final DecimalFormat FORMAT_ONE_DEC = 
19
	new DecimalFormat("#.#");
20
    private static final int TWO_TEN = 1024;
21
    private static final int MBYTE = TWO_TEN * TWO_TEN;
22

  
23
    private OverwritePrinter progressPrinter = new OverwritePrinter();
24

  
25
    private long transferred = 0;
26
    
13 27
    public GSSClient() { }
14 28
    
15 29
    private void processCmd(String args[]) {
......
30 44
	}
31 45
	for (GSSCmd command : commands) {
32 46
	    if (command != null) {
47
		command.addObserver(this);
33 48
		command.execute();
34 49
		PrintWriter out = new PrintWriter(System.out);
35 50
		command.printOutput(out);
......
38 53
	}
39 54
    }
40 55
    
56
    public void update(Observable o, Event arg) {
57
	Event.Type type = arg.getType();
58
	switch (type) {
59
	case TRANSFER:
60
	    StringBuilder sb = new StringBuilder();
61
	    Formatter formatter = new Formatter(sb);
62
	    Event.TuplePayload payLoad = (Event.TuplePayload) arg.getPayLoad();
63
	    transferred += (Integer) payLoad.getFirst();
64
	    long size = (Long) payLoad.getSecond();
65
	    float percent = (transferred / (float) size) * 100;
66
	    formatter.format("%1$s (%2$.2f%%)", 
67
		    produceByteCount(transferred), percent);
68
	    progressPrinter.print(sb.toString());
69
	    break;
70
	}
71
    }
72
    
73
    private String produceByteCount(long bytes) {
74
	String byteCount;
75
	if (bytes > TWO_TEN) {
76
	    if (bytes > MBYTE) {
77
		byteCount = 
78
		    FORMAT_ONE_DEC.format(bytes / (MBYTE)) + " Mb";
79
	    }
80
	    else byteCount = FORMAT_TWO_DEC.format(bytes / TWO_TEN) + " Kb";
81
	} else {
82
	    byteCount = Long.toString(bytes);
83
	}
84
	return byteCount;
85
    }
41 86
    
42 87
    public static void main(String args[]) {
43

  
44
	Logger logger = Logger.getLogger("org.xsocket");
45
	//logger.setLevel(Level.FINE);
46
	ConsoleHandler ch = new ConsoleHandler();
47

  
48
	//ch.setLevel(Level.FINE);
49

  
50
	logger.addHandler(ch);
51 88
	GSSClient gssclient = new GSSClient();
52 89
	gssclient.processCmd(args);
53
    }
54
    
90
    }    
55 91
}
b/java/jgsscli/src/jgsscli/cli/OverwritePrinter.java
1
package jgsscli.cli;
2

  
3
import java.util.Arrays;
4

  
5
/**
6
 * Class for printing output at a single line; each new output overwrites 
7
 * the contents of the line. Can be used for progress lines etc.
8
 */
9
public class OverwritePrinter {
10

  
11
    private String previousString = "";
12
    
13
    public OverwritePrinter() {
14
    }
15
    
16
    public void print(String currentString) {
17
	int prevLength = previousString.length();
18
	char[] overwrite = new char[prevLength];
19
	Arrays.fill(overwrite, '\b'); 
20
	String outputString = new String(overwrite) + currentString;
21
	System.out.print(outputString);
22
	previousString = outputString;
23
    }
24
}
b/java/jgsscli/src/jgsscli/commands/Event.java
1
package jgsscli.commands;
2

  
3
public class Event {
4
    public static enum Type { TRANSFER, FINISH };
5
 
6
    private Type type;
7
    private Object payLoad;
8

  
9
    public Event(Type type, Object payLoad) {
10
	this.type = type;
11
	this.payLoad = payLoad;
12
    }
13
    
14
    public Type getType() {
15
	return this.type;
16
    }
17
    
18
    public void setPayLoad(Object payLoad) {
19
	this.payLoad = payLoad;
20
    }
21

  
22
    public Object getPayLoad() {
23
	return payLoad;
24
    }
25

  
26
    public static class TuplePayload {
27
	private Object first;
28
	private Object second;
29
	
30
	public TuplePayload(Object first, Object second) {
31
	    this.setFirst(first);
32
	    this.setSecond(second);
33
	}
34

  
35
	public Object getFirst() {
36
	    return first;
37
	}
38

  
39
	public void setFirst(Object first) {
40
	    this.first = first;
41
	}
42

  
43
	public Object getSecond() {
44
	    return second;
45
	}
46

  
47
	public void setSecond(Object second) {
48
	    this.second = second;
49
	}
50
    }
51
    
52
}
b/java/jgsscli/src/jgsscli/commands/GSSCmd.java
16 16
 * Interface for GSS commands. A command is something that can be executed,
17 17
 * and returns a value depending on the execution outcome. 
18 18
 */
19
public abstract class GSSCmd {
19
public abstract class GSSCmd implements Observer, Observable {
20 20
    
21 21
    private UserInfo userInfo;
22 22
    private Date date;
......
25 25
    private StatusCode statusCode;
26 26
    private HttpMethod request;
27 27
    private Log log;
28
    private Observable observableDelegate = new ObservableDelegate(this);
28 29
    
29 30
    public GSSCmd(UserInfo userInfo, Date date, String remotePath,
30 31
	    String localPath) {
......
118 119
    public void setLog(Log log) {
119 120
	this.log = log;
120 121
    }
121

  
122
    
123
    public void addObserver(Observer o) {
124
	observableDelegate.addObserver(o);
125
    }
126
    
127
    public int countObservers() {
128
	return observableDelegate.countObservers();
129
    }
130
    
131
    public void deleteObserver(Observer o) {
132
	observableDelegate.deleteObserver(o);
133
    }
134
    
135
    public void deleteObservers() {
136
	observableDelegate.deleteObservers();
137
    }
138
    
139
    public void notifyObservers(Event arg) {
140
	observableDelegate.notifyObservers(arg);
141
    }
142
    
143
    public void update(Observable o, Event arg) {
144
	notifyObservers(arg);
145
    }
122 146
 
123 147
}
b/java/jgsscli/src/jgsscli/commands/Observable.java
1
package jgsscli.commands;
2

  
3
public interface Observable {
4
    void addObserver(Observer o);
5
    int countObservers();
6
    void deleteObserver(Observer o);
7
    void deleteObservers();
8
    void notifyObservers(Event arg);
9
}
b/java/jgsscli/src/jgsscli/commands/ObservableDelegate.java
1
package jgsscli.commands;
2

  
3
import java.util.HashSet;
4
import java.util.Set;
5

  
6
public class ObservableDelegate implements Observable {
7
    
8
    private Observable delegator;
9
    private Set<Observer> observers = new HashSet<Observer>();
10
        
11
    public ObservableDelegate(Observable delegator) {
12
	this.delegator = delegator;
13
    }
14
    
15
    public void addObserver(Observer o) {
16
	observers.add(o);
17
    }
18
    
19
    public int countObservers() {
20
	return observers.size();
21
    }
22
    
23
    public void deleteObserver(Observer o) {
24
	observers.remove(o);
25
    }
26
    
27
    public void deleteObservers() {
28
	observers.clear();
29
    }
30
    
31
    public void notifyObservers(Event arg) {
32
	for (Observer o : observers) {
33
	    o.update(delegator, arg);
34
	}
35
    }
36
}
b/java/jgsscli/src/jgsscli/commands/Observer.java
1
package jgsscli.commands;
2

  
3
public interface Observer {
4
    public void update(Observable o, Event arg);
5
}
/dev/null
1
package jgsscli.commands;
2

  
3
import java.util.Arrays;
4

  
5
/**
6
 * Class for printing output at a single line; each new output overwrites 
7
 * the contents of the line. Can be used for progress lines etc.
8
 */
9
public class OverwritePrinter {
10

  
11
    private String previousString = "";
12
    
13
    public OverwritePrinter() {
14
    }
15
    
16
    public void print(String currentString) {
17
	int prevLength = previousString.length();
18
	char[] overwrite = new char[prevLength];
19
	Arrays.fill(overwrite, '\b'); 
20
	String outputString = new String(overwrite) + currentString;
21
	System.out.print(outputString);
22
	previousString = outputString;
23
    }
24
}
b/java/jgsscli/src/jgsscli/commands/PutFileCmd.java
4 4
import java.io.File;
5 5
import java.io.PrintWriter;
6 6
import java.io.RandomAccessFile;
7
import java.text.DecimalFormat;
8 7
import java.util.Date;
9
import java.util.Formatter;
10 8

  
11 9
import jgsscli.cli.Messages;
12 10
import jgsscli.cli.UserInfo;
......
28 26
 * as the local file. If the target is null or an empty string it is assumed
29 27
 * to be the home directory of the user at GSS.
30 28
 */
31
public class PutFileCmd extends GSSCmd implements ProgressListener {
29
public class PutFileCmd extends GSSCmd {
32 30

  
33
    private OverwritePrinter progressPrinter;
34 31
    private long fileLength;
35 32
    
36 33
    public PutFileCmd(UserInfo userInfo, Date date, String remotePath, 
......
39 36
	if (remotePath == null || remotePath.isEmpty()) {
40 37
	    setRemotePath(GSSUtils.GSS_FILEPATH_SEPARATOR);
41 38
	} 
42
	this.progressPrinter = new OverwritePrinter();
43 39
    }
44 40
    
45 41
    protected Method getMethod() {
......
71 67
		HttpMethodFactory.Scheme.HTTP,
72 68
		GSSUtils.GSS_HOME,
73 69
		getDate(), getUserInfo(), getRemotePath(), getLocalPath());
74
	
75
	method.setProgressListener(this);
70

  
71
	method.addObserver(this);
76 72
	StatusCode statusCode = method.execute();
77 73
	setStatusCode(statusCode);
78 74
	return statusCode;
79 75
    }
80 76
    
77
    public void update(Observable o, Event arg) {
78
	int bytes = (Integer) arg.getPayLoad();
79
	Event.TuplePayload payload = 
80
	    new Event.TuplePayload(bytes, this.fileLength);
81
	Event newArg = new Event(Event.Type.TRANSFER, payload);
82
	notifyObservers(newArg);
83
    }
84
    
81 85
    public void printOutput(PrintWriter out) {
82 86
	String message = getRemotePath() + " " + getStatusCode().code() + ": ";
83 87
	Messages messages = Messages.getInstance();
......
107 111
	out.println(message);
108 112
    }
109 113

  
110
    private String produceByteCount(long bytes) {
111
	String byteCount;
112
	DecimalFormat decFormatTwo = new DecimalFormat("#.##");
113
	DecimalFormat decFormatOne = new DecimalFormat("#.#");
114
	if (bytes > 1024) {
115
	    if (bytes > 1024 * 1024) {
116
		byteCount = 
117
		    decFormatOne.format(bytes / (1024.0 * 1024)) + " Mb";
118
	    }
119
	    else byteCount = decFormatTwo.format(bytes / 1024.0) + " Kb";
120
	} else {
121
	    byteCount = Long.toString(bytes);
122
	}
123
	return byteCount;
124
    }
125
    
126
    public void transferred(long bytesTransferred) {
127
	StringBuilder sb = new StringBuilder();
128
	Formatter formatter = new Formatter(sb);
129
	float percent = (bytesTransferred / (float) this.fileLength) * 100;
130
	formatter.format("%1$s (%2$.2f%%)", 
131
		produceByteCount(bytesTransferred), percent);
132
	progressPrinter.print(sb.toString());
133
    }
134
 
135 114
    public static void main(String[] args)  {
136 115

  
137 116
	Log log = LogFactory.getLog(PutFileCmd.class + "#Main");
b/java/jgsscli/src/jgsscli/httpmethods/CountingHttpEntity.java
1 1
package jgsscli.httpmethods;
2 2

  
3
import java.io.BufferedOutputStream;
4 3
import java.io.IOException;
5 4
import java.io.OutputStream;
6 5

  
7
import jgsscli.commands.ProgressListener;
6
import jgsscli.commands.Event;
7
import jgsscli.commands.Observable;
8
import jgsscli.commands.ObservableDelegate;
9
import jgsscli.commands.Observer;
8 10

  
9 11
import org.apache.http.HttpEntity;
10 12
import org.apache.http.entity.HttpEntityWrapper;
11 13

  
12
/**
13
 * 
14
 * Adapted from
15
 * http://stackoverflow.com/questions/254719/file-upload-with-java-with-progress-bar
16
 */
17
public class CountingHttpEntity extends HttpEntityWrapper {
14
public class CountingHttpEntity extends HttpEntityWrapper 
15
implements Observable, Observer {
18 16

  
19
    private ProgressListener listener;
20
    
21
    public CountingHttpEntity(HttpEntity wrapped, ProgressListener listener) {
17
    private Observable observableDelegate = new ObservableDelegate(this);
18

  
19
    public CountingHttpEntity(HttpEntity wrapped) {
22 20
	super(wrapped);
23
	this.listener = listener;
24 21
    }
25 22
    
26 23
    public void writeTo(OutputStream outstream) 
27 24
    throws IOException {
28
	wrappedEntity.writeTo(new CountingOutputStream(outstream, listener));
25
	CountingOutputStream countingOutStream = 
26
	    new CountingOutputStream(outstream);
27
	countingOutStream.addObserver(this);
28
	wrappedEntity.writeTo(countingOutStream);
29 29
    }
30

  
31
    public static class CountingOutputStream extends BufferedOutputStream {
32

  
33
        private long transferred;
34
        private ProgressListener listener;
35

  
36
        public CountingOutputStream(final OutputStream out, 
37
        	final ProgressListener listener) {
38
            super(out);
39
            this.listener = listener;
40
            this.transferred = 0;
41
        }
42
        
43
        public void write(byte[] b, int off, int len) throws IOException {
44
            super.write(b, off, len);
45
            this.transferred += len;
46
            this.listener.transferred(this.transferred);
47
        }
48
    }    
30
 
31
    public void addObserver(Observer o) {
32
	observableDelegate.addObserver(o);
33
    }
34
    
35
    public int countObservers() {
36
	return observableDelegate.countObservers();
37
    }
38
    
39
    public void deleteObserver(Observer o) {
40
	observableDelegate.deleteObserver(o);
41
    }
42
    
43
    public void deleteObservers() {
44
	observableDelegate.deleteObservers();
45
    }
46
    
47
    public void notifyObservers(Event arg) {
48
	observableDelegate.notifyObservers(arg);
49
    }
50
    
51
    public void update(Observable o, Event arg) {
52
	notifyObservers(arg);
53
    }
49 54
}
b/java/jgsscli/src/jgsscli/httpmethods/CountingOutputStream.java
1
package jgsscli.httpmethods;
2

  
3
import java.io.BufferedOutputStream;
4
import java.io.IOException;
5
import java.io.OutputStream;
6

  
7
import jgsscli.commands.Event;
8
import jgsscli.commands.Observable;
9
import jgsscli.commands.ObservableDelegate;
10
import jgsscli.commands.Observer;
11

  
12
public class CountingOutputStream extends BufferedOutputStream 
13
implements Observable {
14

  
15
    private long transferred;
16
    private Observable observableDelegate = new ObservableDelegate(this);
17
    
18
    public CountingOutputStream(final OutputStream out) {
19
	super(out);
20
	this.transferred = 0;
21
    }
22

  
23
    public void write(byte[] b, int off, int len) throws IOException {
24
	super.write(b, off, len);
25
	this.transferred += len;
26
	notifyObservers(new Event(Event.Type.TRANSFER, len));
27
    }
28

  
29
    public void addObserver(Observer o) {
30
	observableDelegate.addObserver(o);
31
    }
32
    
33
    public int countObservers() {
34
	return observableDelegate.countObservers();
35
    }
36
    
37
    public void deleteObserver(Observer o) {
38
	observableDelegate.deleteObserver(o);
39
    }
40
    
41
    public void deleteObservers() {
42
	observableDelegate.deleteObservers();
43
    }
44
    
45
    public void notifyObservers(Event arg) {
46
	observableDelegate.notifyObservers(arg);
47
    }
48
    
49
    public void update(Observable o, Event arg) {
50
	notifyObservers(arg);
51
    }
52
}
b/java/jgsscli/src/jgsscli/httpmethods/HttpMethod.java
14 14
import java.io.File;
15 15
import java.io.FileOutputStream;
16 16

  
17
import jgsscli.commands.ProgressListener;
17
import jgsscli.commands.Event;
18
import jgsscli.commands.Observable;
19
import jgsscli.commands.ObservableDelegate;
20
import jgsscli.commands.Observer;
18 21

  
19 22
import org.apache.http.HttpResponse;
20 23
import org.apache.http.client.HttpClient;
......
25 28
 * Class that encapsulates an HTTP method. 
26 29
 *
27 30
 */
28
public abstract class HttpMethod {
31
public abstract class HttpMethod implements Observable, Observer {
29 32

  
30 33
    public static enum Method {GET, HEAD, POST, PUT, DELETE};
31 34
    
......
36 39
    private HttpRequestBase request;
37 40
    private HttpResponse response;
38 41
    
39
    private ProgressListener progressListener;
42
    private Log log;
40 43
    
41
    private Log log;
44
    private Observable observableDelegate = new ObservableDelegate(this);
42 45
    
43 46
    protected HttpMethod(Method method, String uri, String localPath) {
44 47
	this.log = LogFactory.getLog(this.getClass());
......
98 101
	this.request = request;
99 102
    }
100 103
    
101
    public void setProgressListener(ProgressListener progressListener) {
102
	this.progressListener = progressListener;
103
    }
104

  
105
    public ProgressListener getProgressListener() {
106
	return progressListener;
107
    }
108
    
109 104
    public void addHeader(String name, String value) {
110 105
	this.request.addHeader(name, value);
111 106
    }
......
240 235
	return sb.toString();
241 236
    }
242 237
    
238
    public void addObserver(Observer o) {
239
	observableDelegate.addObserver(o);
240
    }
241
    
242
    public int countObservers() {
243
	return observableDelegate.countObservers();
244
    }
245
    
246
    public void deleteObserver(Observer o) {
247
	observableDelegate.deleteObserver(o);
248
    }
249
    
250
    public void deleteObservers() {
251
	observableDelegate.deleteObservers();
252
    }
253
    
254
    public void notifyObservers(Event arg) {
255
	observableDelegate.notifyObservers(arg);
256
    }
257
    
258
    public void update(Observable o, Event arg) {
259
	notifyObservers(arg);
260
    }
243 261
}
b/java/jgsscli/src/jgsscli/httpmethods/HttpPutMethod.java
3 3

  
4 4
import java.io.File;
5 5

  
6
import jgsscli.commands.ProgressListener;
7

  
8
import org.apache.http.HttpEntity;
9 6
import org.apache.http.client.methods.HttpPut;
10 7
import org.apache.http.entity.FileEntity;
11 8

  
......
16 13
	if (localPath != null) {
17 14
	    File file = new File(localPath);
18 15
	    HttpPut putRequest = new HttpPut(uri);
19
	    FileEntity entity = new FileEntity(file, "binary/octet-stream");
20
	    putRequest.setEntity(entity);
16
	    FileEntity fileEntity = 
17
		new TurboFileEntity(file, "binary/octet-stream");
18
	    CountingHttpEntity countingEntity =
19
		new CountingHttpEntity(fileEntity);
20
	    countingEntity.addObserver(this);
21
	    putRequest.setEntity(countingEntity);
21 22
	    setRequest(putRequest);
22 23
	}
23 24
    }
24
    
25
    public void setProgressListener(ProgressListener listener) {
26
	super.setProgressListener(listener);
27
	HttpPut putRequest = (HttpPut) this.getRequest();
28
	HttpEntity entity = putRequest.getEntity();
29
	CountingHttpEntity countingEntity = 
30
	    new CountingHttpEntity(entity, listener);
31
	putRequest.setEntity(countingEntity);
32
    }
33 25
}    
b/java/jgsscli/src/jgsscli/httpmethods/TurboFileEntity.java
1
package jgsscli.httpmethods;
2

  
3
import java.io.File;
4
import java.io.FileInputStream;
5
import java.io.IOException;
6
import java.io.InputStream;
7
import java.io.OutputStream;
8

  
9
import org.apache.http.entity.FileEntity;
10

  
11
public class TurboFileEntity extends FileEntity {
12
    
13
    public TurboFileEntity(final File file, final String contentType) {
14
	super(file, contentType);
15
    }
16

  
17
    public void writeTo(final OutputStream outstream)
18
    throws IOException {
19
	if (outstream == null) {
20
	    throw new IllegalArgumentException("Output stream may not be null");
21
	}
22
	InputStream instream = new FileInputStream(this .file);
23
	try {
24
	    byte[] tmp = new byte[4096 * 4096];
25
	    int l;
26
	    while ((l = instream.read(tmp)) != -1) {
27
		outstream.write(tmp, 0, l);
28
	    }
29
	    outstream.flush();
30
	} finally {
31
	    instream.close();
32
	}
33
    }
34

  
35

  
36
}

Also available in: Unified diff