001: /*
002: * $Id: AnyURL.java,v 1.24 2002/09/16 08:05:03 jkl Exp $
003: *
004: * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
005: *
006: * Use is subject to license terms, as defined in
007: * Anvil Sofware License, Version 1.1. See LICENSE
008: * file, or http://njet.org/license-1.1.txt
009: */
010: package anvil.core.net;
011:
012: import anvil.core.Any;
013: import anvil.core.AnyMap;
014: import anvil.core.AnyAbstractClass;
015: import anvil.core.Array;
016: import anvil.core.io.AnyInputStream;
017: import anvil.core.Serialization;
018: import anvil.core.Serializer;
019: import anvil.core.Unserializer;
020: import anvil.core.UnserializationException;
021: import anvil.script.Context;
022: import anvil.java.util.BindingEnumeration;
023: import anvil.util.Conversions;
024: import java.io.BufferedOutputStream;
025: import java.io.IOException;
026: import java.io.OutputStream;
027: import java.io.PrintWriter;
028: import java.io.Writer;
029: import java.net.HttpURLConnection;
030: import java.net.InetAddress;
031: import java.net.MalformedURLException;
032: import java.net.UnknownHostException;
033: import java.net.URL;
034:
035: ///
036: /// @class URL
037: /// Uniform Resource Locator.
038: /// Class URL represents a URL address,
039: /// a pointer to a "resource" on the World Wide Web.
040: ///
041:
042: /**
043: * class AnyURL
044: *
045: * @author: Jani Lehtimäki
046: */
047: public class AnyURL extends AnyAbstractClass {
048:
049: ///
050: /// @constructor URL
051: /// Creates and returns a new URL, or null if it was invalid.
052: /// @synopsis URL(string context)
053: /// @synopsis URL(string context, string ref)
054: /// @synopsis URL(url context, string ref)
055: ///
056: public static final Object[] newInstance = { null, "context",
057: "*child", null };
058:
059: public static final Any newInstance(Context context, Any p1,
060: String p2) {
061: try {
062: URL ctx = null;
063: if (p1 instanceof AnyURL) {
064: ctx = (URL) p1.toObject();
065: } else {
066: ctx = new URL(p1.toString());
067: }
068: if (p2 != null) {
069: return new AnyURL(new URL(ctx, p2));
070: } else {
071: return new AnyURL(ctx);
072: }
073: } catch (MalformedURLException e) {
074: throw context.exception(e);
075: }
076: }
077:
078: private URL _url;
079:
080: public static final Any create(String url) {
081: try {
082: return new AnyURL(new URL(url));
083: } catch (MalformedURLException e) {
084: return UNDEFINED;
085: }
086: }
087:
088: public AnyURL(URL url) {
089: _url = url;
090: }
091:
092: public final anvil.script.ClassType classOf() {
093: return __class__;
094: }
095:
096: public Object toObject() {
097: return _url;
098: }
099:
100: public String toString() {
101: return _url.toExternalForm();
102: }
103:
104: public Writer toAnvil(Writer writer) throws IOException {
105: writer.write("new anvil.net.URL(\"");
106: writer.write(anvil.util.Conversions.escape(_url
107: .toExternalForm(), true));
108: writer.write(')');
109: writer.write('"');
110: return writer;
111: }
112:
113: public Writer toJava(Writer writer) throws IOException {
114: writer.write("anvil.core.net.AnyURL.create(\"");
115: writer.write(anvil.util.Conversions.escape(_url
116: .toExternalForm(), true));
117: writer.write('"');
118: writer.write(')');
119: return writer;
120: }
121:
122: public anvil.codec.Code toCode(anvil.codec.Code code) {
123: anvil.codec.ConstantPool pool = code.getPool();
124: code.astring(_url.toExternalForm());
125: code.invokestatic(code.getPool().addMethodRef(
126: "anvil/core/io/AnyURL", "create",
127: "(Ljava/lang/String;)Lanvil/core/Any;"));
128: return code;
129: }
130:
131: public boolean equals(Object o) {
132: if (o == this ) {
133: return true;
134: }
135: if (o instanceof AnyURL) {
136: return _url.equals(((AnyURL) o)._url);
137: }
138: return false;
139: }
140:
141: public void serialize(Serializer serializer) throws IOException {
142: if (serializer.register(this )) {
143: return;
144: }
145: String s = _url.toExternalForm();
146: serializer.write('U');
147: serializer.write(s.length());
148: serializer.write(':');
149: serializer.writeUTF16(s);
150: }
151:
152: public static final Any unserialize(Unserializer unserializer)
153: throws UnserializationException {
154: try {
155: AnyURL url = new AnyURL(new URL(unserializer
156: .getUTF16String()));
157: unserializer.register(url);
158: return url;
159: } catch (MalformedURLException e) {
160: throw new UnserializationException(e.toString());
161: }
162: }
163:
164: /// @method getFile
165: /// Returns the file name of this URL.
166: /// @synopsis string getFile()
167: /// @return file name
168: public Any m_getFile() {
169: return Any.create(_url.getFile());
170: }
171:
172: /// @method getHost
173: /// Returns the host name name of this URL, if applicable.
174: /// @synopsis string getHost()
175: /// @return host name
176: public Any m_getHost() {
177: return Any.create(_url.getHost());
178: }
179:
180: /// @method getAddress
181: /// Returns the internet address refererred by this URL.
182: /// @synopsis InetAddress getAddress()
183: /// @return internet address
184: /// @throws UnknownHost If specified host is invalid
185: public Any m_getAddress(Context context) {
186: String host = _url.getHost();
187: if (host != null && host.length() > 0) {
188: try {
189: return new AnyInetAddress(InetAddress.getByName(host));
190: } catch (UnknownHostException e) {
191: throw context.exception(e);
192: }
193: }
194: return NULL;
195: }
196:
197: /// @method getPort
198: /// Returns the port number of this URL.
199: /// @synopsis int getPort()
200: /// @return the port number
201: public Any m_getPort() {
202: return Any.create(_url.getPort());
203: }
204:
205: /// @method getProtocol
206: /// Returns the protocol name this URL.
207: /// @synopsis string getProtocol()
208: /// @return the protocol name
209: public Any m_getProtocol() {
210: return Any.create(_url.getProtocol());
211: }
212:
213: /// @method getRef
214: /// Returns the reference (anchor) of this URL.
215: /// @synopsis string getRef()
216: /// @return the reference (anchor) of this URL.
217: public Any m_getRef() {
218: return Any.create(_url.getRef());
219: }
220:
221: /// @method sameFile
222: /// Checks if this url is equal to given parameter (excluding the "ref" field).
223: /// @synopsis boolean sameFile(string url)
224: /// @synopsis boolean sameFile(URL url)
225: /// @param url the url to compare against.
226: /// @return true if they reference the same remote object; false otherwise.
227: public static final Object[] p_sameFile = { "url" };
228:
229: public Any m_sameFile(Any url_) {
230: URL url;
231: if (url_ instanceof AnyURL) {
232: url = (URL) url_.toObject();
233: } else {
234: try {
235: url = new URL(url_.toString());
236: } catch (MalformedURLException e) {
237: return FALSE;
238: }
239: }
240: return _url.sameFile(url) ? TRUE : FALSE;
241: }
242:
243: /// @method open
244: /// Opens and returns a connection to this URL.
245: /// @synopsis URLConnection open()
246: /// @return url connection
247: /// @throws IOError If an IO error occured
248: public Any m_open(Context context) {
249: if (_url.getProtocol().equals("file")) {
250: context.checkRead(_url.getFile());
251: }
252: try {
253: return new AnyURLConnection(_url.openConnection());
254: } catch (IOException e) {
255: throw context.exception(e);
256: }
257: }
258:
259: /// @method openStream
260: /// Opens and returns a connection to this URL.
261: /// @synopsis InputStream openStream()
262: /// @synopsis InputStream openStream(postParameters...)
263: /// @return input stream
264: /// @throws IOError If an IO error occured
265: public static final Object[] p_openStream = { null,
266: "postParameters" };
267:
268: public Any m_openStream(Context context, Any[] parameters)
269: {
270: try {
271: String protocol = _url.getProtocol();
272: int n = parameters.length;
273: if (n == 0) {
274: if (protocol.equals("file")) {
275: context.checkRead(_url.getFile());
276: }
277: return new AnyInputStream(_url.openStream());
278: } else {
279: if (protocol.equals("http")) {
280: HttpURLConnection uc = (HttpURLConnection)_url.openConnection();
281: uc.setDoInput(true);
282: uc.setDoOutput(true);
283: uc.setRequestMethod("POST");
284: uc.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
285: PrintWriter writer = new PrintWriter(new BufferedOutputStream(uc.getOutputStream()));
286: for(int i=0; i<n; i++) {
287: Any param = parameters[i];
288: if (i>0) {
289: writer.write('&');
290: }
291: if (param.isArray()) {
292: BindingEnumeration enum = param.toArray().keysAndElements();
293: while(enum.hasMoreElements()) {
294: writer.write(Conversions.URLEncode(enum.nextKey().toString()));
295: writer.write('=');
296: writer.write(Conversions.URLEncode(enum.nextElement().toString()));
297: }
298: } else if (param.isMap()) {
299: AnyMap map = param.toMap();
300: writer.write(Conversions.URLEncode(map.getLeft().toString()));
301: writer.write('=');
302: writer.write(Conversions.URLEncode(map.getRight().toString()));
303: } else {
304: writer.write(Conversions.URLEncode(param.toString()));
305: writer.write('=');
306: }
307: }
308: writer.close();
309: uc.connect();
310: return new AnyInputStream(uc.getInputStream());
311: } else {
312: throw context.TypeError("POST method unsupported: "+_url);
313: }
314: }
315: } catch (IOException e) {
316: throw context.exception(e);
317: }
318: }
319:
320: public static final anvil.script.compiler.NativeClass __class__ = new anvil.script.compiler.NativeClass(
321: "URL",
322: AnyURL.class,
323: //DOC{{
324: ""
325: + "\n"
326: + " @class URL\n"
327: + " Uniform Resource Locator.\n"
328: + " Class URL represents a URL address, \n"
329: + " a pointer to a \"resource\" on the World Wide Web.\n"
330: + "\n"
331: + "\n"
332: + " @constructor URL\n"
333: + " Creates and returns a new URL, or null if it was invalid.\n"
334: + " @synopsis URL(string context)\n"
335: + " @synopsis URL(string context, string ref)\n"
336: + " @synopsis URL(url context, string ref)\n"
337: + "\n"
338: + " @method getFile\n"
339: + " Returns the file name of this URL.\n"
340: + " @synopsis string getFile()\n"
341: + " @return file name\n"
342: + " @method getHost\n"
343: + " Returns the host name name of this URL, if applicable.\n"
344: + " @synopsis string getHost()\n"
345: + " @return host name\n"
346: + " @method getAddress\n"
347: + " Returns the internet address refererred by this URL.\n"
348: + " @synopsis InetAddress getAddress()\n"
349: + " @return internet address\n"
350: + " @throws UnknownHost If specified host is invalid\n"
351: + " @method getPort\n"
352: + " Returns the port number of this URL.\n"
353: + " @synopsis int getPort()\n"
354: + " @return the port number\n"
355: + " @method getProtocol\n"
356: + " Returns the protocol name this URL.\n"
357: + " @synopsis string getProtocol()\n"
358: + " @return the protocol name\n"
359: + " @method getRef\n"
360: + " Returns the reference (anchor) of this URL.\n"
361: + " @synopsis string getRef()\n"
362: + " @return the reference (anchor) of this URL.\n"
363: + " @method sameFile\n"
364: + " Checks if this url is equal to given parameter (excluding the \"ref\" field).\n"
365: + " @synopsis boolean sameFile(string url)\n"
366: + " @synopsis boolean sameFile(URL url)\n"
367: + " @param url the url to compare against.\n"
368: + " @return true if they reference the same remote object; false otherwise.\n"
369: + " @method open\n"
370: + " Opens and returns a connection to this URL.\n"
371: + " @synopsis URLConnection open()\n"
372: + " @return url connection\n"
373: + " @throws IOError If an IO error occured\n"
374: + " @method openStream\n"
375: + " Opens and returns a connection to this URL.\n"
376: + " @synopsis InputStream openStream()\n"
377: + " @synopsis InputStream openStream(postParameters...)\n"
378: + " @return input stream\n"
379: + " @throws IOError If an IO error occured\n"
380: //}}DOC
381: );
382: static {
383: NetModule.class.getName();
384: }
385:
386: }
|