/*
* Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.sockets.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.sockets.client.impl.FlashBinarySocketImpl;
import com.google.gwt.sockets.client.impl.FlashTextSocketImpl;
import com.google.gwt.sockets.client.impl.JavaBinarySocketImpl;
import com.google.gwt.sockets.client.impl.JavaTextSocketImpl;
/**
* <p>Creation of sockets should be done using this factory class. It determines what implementation of
* sockets can be supported by client's browser and creates it. There are Java and Flash implementations of text
* and binary sockets so far. For special needs it is possible to create sockets directly from implementation
* classes.</p>
*
* <p>Macromedia Flash has security restriction - it allows to connect to a server only after downloading
* a specific file from it with security policies. This means that we cannot connect to any server, only to
* those which have this file. But if you still want to connect to such servers you can use Java implementation
* of sockets. See Java {@link com.google.gwt.sockets.client.impl.JavaTextSocketImpl TextSocket} and
* {@link com.google.gwt.sockets.client.impl.JavaBinarySocketImpl BinarySocket} implementations</p>
*
* <p>To provide Macromedia Flash with policy file you should specify URL to that file on a server you want to
* connect to. There are two protocols available for downloading a policy file:
* <li>HTTP on 80 port. In this case only ports 1024 and later will be available for connecting. URL to the
* policy file should looks like <code>http://127.0.0.1/crossdomain.xml</code>
* <li>XMLSocket protocol. The policy file obtained by XMLSocket protocol allows to connect to any port. After
* establishing a connection with the specified port, Flash Player transmits
* <code><policy-file-request /></code>, terminated by a <i>null</i> byte, then server should return
* contents of the policy file terminated by a <i>null</i> byte. URL to policy file looks like
* <code>xmlsocket://127.0.0.1:1234</code>
* </p>
*
* More information about Macromedia Flash security you can read at
* http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00005403.html
*
* @see com.google.gwt.sockets.client.AbstractSocket
* @see com.google.gwt.sockets.client.TextSocket
* @see com.google.gwt.sockets.client.BinarySocket
* @author Aleksey Lagoshin
*/
public class SocketsFactory {
/**
* Returns a text socket implementation which is supported by client's browser. Also the default crossdomain
* policy file for Flash will be downloaded from the server where this GWT application is located. The
* default policy file allows Flash to connect to the server where this GWT application is located on
* ports 1024 and later.
*
* @param listener a listener for the socket
* @return a text socket implementation which is supported by client's browser, or null if client's browser
* doesn't support any of existed implementations
* @see com.google.gwt.sockets.client.AbstractSocket
* @see com.google.gwt.sockets.client.TextSocket
*/
public static TextSocket createTextSocket(SocketListener listener) {
return createTextSocket(listener, getDefaultPolicyFile());
}
/**
* Returns a text socket implementation which is supported by client's browser.
*
* @param listener a listener for the socket
* @param policyFileURL URL to Flash security policy file location, if it is null Flash will download a
* default crossdomain policy file from the server where this GWT application is located; the
* default policy file allows Flash to connect to the server where this GWT application is located on
* ports 1024 and later
* @return a text socket implementation which is supported by client's browser, or null if client's browser
* doesn't support any of existed implementations
* @see com.google.gwt.sockets.client.AbstractSocket
* @see com.google.gwt.sockets.client.TextSocket
*/
public static TextSocket createTextSocket(SocketListener listener, String policyFileURL) {
if (isFlashXSupported(6))
return new FlashTextSocketImpl(listener, policyFileURL);
if (isJavaSupported() && GWT.isScript())
return new JavaTextSocketImpl(listener);
return null;
}
/**
* Returns a binary socket implementation which is supported by client's browser. Also the default crossdomain
* policy file for Flash will be downloaded from the server where this GWT application is located. The
* default policy file allows Flash to connect to the server where this GWT application is located on
* ports 1024 and later.
*
* @param listener a listener for the socket
* @return a binary socket implementation which is supported by client's browser, or null if client's browser
* doesn't support any of existed implementations.
* @see com.google.gwt.sockets.client.AbstractSocket
* @see com.google.gwt.sockets.client.BinarySocket
*/
public static BinarySocket createBinarySocket(SocketListener listener) {
return createBinarySocket(listener, getDefaultPolicyFile());
}
/**
* Returns a binary socket implementation which is supported by client's browser.
*
* @param listener a listener for the socket
* @param policyFileURL URL to Flash security policy file location, if it is null Flash will download a
* default crossdomain policy file from the server where this GWT application is located; the
* default policy file allows Flash to connect to the server where this GWT application is located on
* ports 1024 and later
* @return a binary socket implementation which is supported by client's browser, or null if client's browser
* doesn't support any of existed implementations
* @see com.google.gwt.sockets.client.AbstractSocket
* @see com.google.gwt.sockets.client.BinarySocket
*/
public static BinarySocket createBinarySocket(SocketListener listener, String policyFileURL) {
if (isFlashXSupported(9))
return new FlashBinarySocketImpl(listener, policyFileURL);
if (isJavaSupported() && GWT.isScript())
return new JavaBinarySocketImpl(listener);
return null;
}
/**
* Determines if client's browser supports Java Plugin. Java Plugin is needed for Java implementaions of Text
* and Binary Sockets.
*
* @return true if Java Plugin is supported by client's browser
*/
public static native boolean isJavaSupported()/*-{
return (typeof $wnd.navigator.javaEnabled != undefined && $wnd.navigator.javaEnabled());
}-*/;
/**
* Determines if client's browser supports Macromedia Flash. Flash 6+ is needed for Flash implementation of Text
* sockets and Binary Sockets requires Flash 9+.
*
* @param version the verison of Flash
* @return true if Flash 9 is supported by client's browser
*/
public static native boolean isFlashXSupported(int version) /*-{
// If browser is Internet Explorer
if ($wnd.navigator.userAgent.indexOf("MSIE") != -1)
try {
return (typeof new ActiveXObject("ShockwaveFlash.ShockwaveFlash." + version) == "object");
}
catch (e) {
return false;
}
// Other browsers
else {
var flashPlugin = $wnd.navigator.plugins["Shockwave Flash"];
if (flashPlugin == undefined)
return false;
var flashDescription = flashPlugin.description;
if (flashDescription == undefined)
return false;
return flashDescription.charAt(flashDescription.indexOf(".") - 1) >= version;
}
}-*/;
/**
* Returns URL to the default crossdomain policy file for Flash (see crossdomain.xml in public folder).
* This policy file allows Flash to connect to server where this GWT application is located on ports
* 1024 and later.
*
* @return URL to crossdomain policy file.
*/
public static native String getDefaultPolicyFile() /*-{
var result;
var href = $wnd.location.href;
var index = href.indexOf("?");
result = index != -1 ? href.substr(0, index) : href;
return result.substr(0, result.lastIndexOf("/") + 1) + "crossdomain.xml";
}-*/;
}