001: package org.syrup.services;
002:
003: import java.io.ByteArrayOutputStream;
004: import java.io.IOException;
005: import java.io.InputStream;
006: import java.io.OutputStream;
007: import java.io.Serializable;
008: import java.net.Socket;
009: import java.net.URL;
010: import java.util.Hashtable;
011:
012: import javax.naming.NamingException;
013: import javax.naming.Reference;
014: import javax.naming.Referenceable;
015: import javax.naming.StringRefAddr;
016:
017: /**
018: * Provides BLOB storage functionality by sending requests to the BlobServer.
019: *
020: * @author Robbert van Dalen
021: */
022: public class BlobClient implements Serializable, Referenceable {
023: static final String COPYRIGHT = "Copyright 2005 Robbert van Dalen."
024: + "At your option, you may copy, distribute, or make derivative works under "
025: + "the terms of The Artistic License. This License may be found at "
026: + "http://www.opensource.org/licenses/artistic-license.php. "
027: + "THERE IS NO WARRANTY; USE THIS PRODUCT AT YOUR OWN RISK.";
028:
029: // [TODO: Socket handling - cleanup - exception etc];
030:
031: public final String host;
032:
033: public final int port;
034:
035: public static final long serialVersionUID = 1;
036:
037: /**
038: */
039:
040: public BlobClient(String host_, int port_) {
041: host = host_;
042: port = port_;
043: }
044:
045: public BlobClient(String location) throws Exception {
046: this (getHost(location), getPort(location));
047: }
048:
049: private static String getHost(String location) {
050: return location.split(":")[0];
051: }
052:
053: private static int getPort(String location) {
054: return Integer.parseInt(location.split(":")[1]);
055: }
056:
057: public String getLocation() {
058: return host + ":" + port;
059: }
060:
061: public static void main(String[] args) throws Throwable {
062: String location = "localhost:6666";
063:
064: if (args.length >= 1) {
065: if (args.length >= 2) {
066: location = args[1];
067: }
068:
069: BlobClient client = new BlobClient(location);
070:
071: if (args[0].equals("read")) {
072: client.read(System.in, System.out);
073: return;
074: } else if (args[0].equals("get")) {
075: client.get(System.in, System.out);
076: return;
077: } else if (args[0].equals("write")) {
078: client.write(System.in, System.out);
079: return;
080: } else if (args[0].equals("post")) {
081: client.post(System.in, System.out);
082: return;
083: }
084: throw new Exception(
085: "Specify command: read,get or write,post");
086: }
087:
088: }
089:
090: /**
091: */
092: public void read(InputStream id, OutputStream result)
093: throws Exception {
094: Socket s = new Socket(host, port);
095: try {
096: read(id, result, s);
097: } finally {
098: result.flush();
099: s.close();
100: }
101: }
102:
103: /**
104: */
105: public void write(InputStream content, OutputStream id)
106: throws Exception {
107: Socket s = new Socket(host, port);
108: try {
109: write(content, id, s);
110: } finally {
111: id.flush();
112: s.close();
113: }
114: }
115:
116: /**
117: */
118: public void post(InputStream content, OutputStream id)
119: throws Exception {
120: Socket s = new Socket(host, port);
121: try {
122: ByteArrayOutputStream ido = new ByteArrayOutputStream();
123: write(content, ido, s);
124: if (ido.size() > 0) {
125: String url = "http://" + host + ":" + port + "/";
126: id.write(url.getBytes());
127: id.write(ido.toByteArray());
128: }
129: } finally {
130: id.flush();
131: s.close();
132: }
133: }
134:
135: /**
136: */
137: public void get(InputStream i, OutputStream o) throws Exception {
138: byte b[] = new byte[8192];
139: int l = read(i, b, 0, 256);
140: if (l > 0) {
141:
142: String ss = new String(b, 0, l).trim();
143:
144: URL url = new URL(ss);
145: InputStream ii = null;
146:
147: try {
148: ii = url.openStream();
149: while ((l = ii.read(b)) >= 0) {
150: o.write(b, 0, l);
151: }
152: } finally {
153: if (ii != null) {
154: ii.close();
155: }
156: }
157: }
158: }
159:
160: /**
161: */
162: private static void read(InputStream i, OutputStream o, Socket s)
163: throws Exception {
164: byte b[] = new byte[80];
165: int il = read(i, b, 0, 80);
166:
167: if (il >= 80 || il <= 0) {
168: throw new Exception(
169: "Input has invalid identifier length (must range between 80 characters)");
170: }
171: OutputStream os = s.getOutputStream();
172: InputStream is = s.getInputStream();
173:
174: os.write('R');
175:
176: os.write(b, 0, il);
177: s.shutdownOutput();
178:
179: while ((il = is.read(b)) >= 0) {
180: o.write(b, 0, il);
181: }
182: }
183:
184: /**
185: */
186: private static void write(InputStream i, OutputStream o, Socket s)
187: throws Exception {
188: byte b[] = new byte[8192];
189: int li = 0;
190:
191: OutputStream os = s.getOutputStream();
192: InputStream is = s.getInputStream();
193:
194: os.write('W');
195: while ((li = i.read(b)) >= 0) {
196: os.write(b, 0, li);
197: }
198: s.shutdownOutput();
199:
200: li = read(is, b, 0, 80);
201: if (li <= 80) {
202: if (li >= 0) {
203: o.write(b, 0, li);
204: }
205: is.close();
206: os.close();
207: } else {
208: throw new Exception(
209: "Server returned invalid identifier length: " + li);
210: }
211: }
212:
213: /**
214: */
215: private static int read(InputStream i, byte[] b, int s, int l)
216: throws IOException {
217: int k = 0;
218: int t = 0;
219:
220: while ((k = i.read(b, s, l)) >= 0 && s < l) {
221: s += k;
222: t += k;
223: l -= k;
224: }
225: return t;
226: }
227:
228: /**
229: */
230: public Reference getReference() throws NamingException {
231: Hashtable env = new Hashtable();
232: return new Reference(BlobClient.class.getName(),
233: new StringRefAddr("blobclient", getLocation()),
234: BlobClientFactory.class.getName(), null);
235: }
236: }
|