<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Inside Java2Script &#187; Browser</title>
	<atom:link href="http://inside.java2script.com/category/browser/feed" rel="self" type="application/rss+xml" />
	<link>http://inside.java2script.com</link>
	<description>A Book about Java to JavaScript Details</description>
	<lastBuildDate>Mon, 22 Sep 2008 23:21:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Introducing Java2Script&#8217;s Simple Pipe</title>
		<link>http://inside.java2script.com/2007/08/01/introducing-java2scripts-simple-pipe.html</link>
		<comments>http://inside.java2script.com/2007/08/01/introducing-java2scripts-simple-pipe.html#comments</comments>
		<pubDate>Wed, 01 Aug 2007 11:56:32 +0000</pubDate>
		<dc:creator>Zhou Renjian</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Browser]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://inside.java2script.com/2007/08/01/introducing-java2scripts-simple-pipe.html</guid>
		<description><![CDATA[Communications between server and browser are essential things in AJAX world. Basic Knowledge Each HTTP connection is forked by browser. And one HTTP connection may serve multiple sessions in HTTP 1.1 but server only one session in HTTP 1.0. There &#8230; <a href="http://inside.java2script.com/2007/08/01/introducing-java2scripts-simple-pipe.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Communications between server and browser are essential things in AJAX world. </p>
<p>Basic Knowledge</p>
<p>Each HTTP connection is forked by browser. And one HTTP connection may serve multiple sessions in HTTP 1.1 but server only one session in HTTP 1.0. There is no time limit or data transfer limit on each HTTP connection. This is basic knowledge of HTTP connections.</p>
<p>An HTML web page, may contains lots of resources, images, style sheets or JavaScript files, and each resources requires an HTTP session. And according technologies called AJAX, browser can load resources at any specific time.</p>
<p>What is Simple Pipe?</p>
<p>Simple Pipe is a kind of data transformation from server to browser. Once browser open up an HTTP connection to the server, the server keep the connection open. And whenever the server get data, it will flush data through the HTTP connection to browser. The data transfered through the connection is serialized and deserialized in SimpleSerializable format. </p>
<p>How to Setup a Simple Pipe?</p>
<p>Simple Pipe is currently designed for Java language. There is a class named &#8220;com.java2script.ajax.pipe.SimplePipeRequest&#8221; with a static method named &#8220;pipeRequest&#8221; which accept a parameter in type of &#8220;com.java2script.ajax.pipe.SimplePipeRunnable&#8221;. The SimplePipeRunnable is will accept parameters from browser side, and then be passed to server side (Tomcat or other Servlet containers), and its action will be executed. In most cases, an other-type connection is created, and listeners are added to the connections for up-coming events. And the connection will be registered with a generated pipe key. And the pipe key will be sent back to browser side. Browser side will create another connection to the server with the given pipe key. Server will check the pipe key, and hold the HTTP connection, and flush any data from previous registered connection to browser side in format of SimpleSerializable. Browser will use IFRAME to accept the data, and return back to object instances. In keeping the HTTP connection, browser will send a notifying signal (HTTP connection) to server to make sure that browser is keeping the connection live. If browser likes to close the pipe, it will send another Simple RPC call the server to notify server that pipe should be closed. If it happens that browser exit without notifying closing pipe, server will close the pipe in a minute or so, as there is no such signals for the pipe to be kept alive.</p>
<p>As Simple Pipe is a subset of Java2Script library API, Simple Pipe may only be used in Java language. But after being converted to JavaScript by Java2Script compiler, Simple Pipe technology can be used in JavaScript language. And <a href="http://demo.java2script.org/gtalk/">JavaScript demo of Google Talk</a> is an example of Simple Pipe.</p>
<p>Code Snippets</p>
<p>SimplePipeSWTRequest#swtPipe usage:</p>
<blockquote class="code"><p><code>        SimplePipeSWTRequest.swtPipe(<span class="keyword">new</span> LoginRunnable() <span class="scope">{</span></p>
<p>            @Override<br />
            <span class="keyword">public</span> <span class="keyword">void</span> ajaxIn() <span class="scope">{</span><br />
                username = userNameText.getText().trim();<br />
                password = passwordText.getText();<br />
            <span class="scope">}</span></p>
<p>            @Override<br />
            <span class="keyword">public</span> <span class="keyword">void</span> ajaxOut() <span class="scope">{</span><br />
                <span class="keyword">if</span> (failed) <span class="scope">{</span><br />
                    MessageBox messageBox = <span class="keyword">new</span> MessageBox(MainWindow.<span class="keyword">this</span>, SWT.ICON_ERROR);<br />
                    <span class="comment">// notify error</span><br />
                    <span class="keyword">return</span>;<br />
                <span class="scope">}</span><br />
                setData(<span class="string">&quot;ConnectionKey&quot;</span>, key);<br />
                setData(<span class="string">&quot;PipeKey&quot;</span>, pipeKey);<br />
                <span class="comment">// continue to login</span><br />
            <span class="scope">}</span></p>
<p>            @Override<br />
            <span class="keyword">public</span> <span class="keyword">void</span> ajaxFail() <span class="scope">{</span><br />
                MessageBox messageBox = <span class="keyword">new</span> MessageBox(MainWindow.<span class="keyword">this</span>, SWT.ICON_ERROR);<br />
                <span class="comment">// .. notify errors</span><br />
            <span class="scope">}</span></p>
<p>            <span class="keyword">public</span> <span class="keyword">void</span> deal(PresenceSerializable ps) <span class="scope">{</span><br />
                <span class="comment">// Data received from pipe! To update presence status</span><br />
            <span class="scope">}</span></p>
<p>            @Override<br />
            <span class="keyword">public</span> <span class="keyword">void</span> deal(<span class="keyword">final</span> MessageSerializable ms) <span class="scope">{</span><br />
                <span class="comment">// Data received from pipe! To popup chatting dialog...</span><br />
            <span class="scope">}</span></p>
<p>            @Override<br />
            <span class="keyword">public</span> <span class="keyword">void</span> deal(RosterSerializable rs) <span class="scope">{</span><br />
                <span class="comment">// Data received from pipe! To update roster entries...</span><br />
            <span class="scope">}</span></p>
<p>        <span class="scope">}</span>);<br />
</code></p></blockquote>
<p>LoginRunnable</p>
<blockquote class="code"><p><code><span class="keyword">public</span> <span class="keyword">class</span> LoginRunnable <span class="keyword">extends</span> SimplePipeRunnable <span class="scope">{</span></p>
<p>    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">class</span> PresenceSerializable <span class="keyword">extends</span> SimpleSerializable <span class="scope">{</span><br />
        <span class="keyword">public</span> String name;<br />
        <span class="keyword">public</span> String email;<br />
        <span class="keyword">public</span> String status;<br />
        <span class="keyword">public</span> String type;<br />
        <span class="keyword">public</span> String mode;<br />
    <span class="scope">}</span></p>
<p>    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">class</span> MessageSerializable <span class="keyword">extends</span> SimpleSerializable <span class="scope">{</span><br />
        <span class="keyword">public</span> String from;<br />
        <span class="keyword">public</span> String body;<br />
        <span class="keyword">public</span> String to;<br />
    <span class="scope">}</span></p>
<p>    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">class</span> RosterSerializable <span class="keyword">extends</span> SimpleSerializable <span class="scope">{</span><br />
        <span class="keyword">public</span> String from;<br />
    <span class="scope">}</span></p>
<p>    <span class="keyword">public</span> String username;</p>
<p>    <span class="keyword">public</span> String password;</p>
<p>    <span class="keyword">public</span> String host;</p>
<p>    <span class="keyword">public</span> <span class="keyword">int </span>port;</p>
<p>    <span class="keyword">public</span> String service;</p>
<p>    <span class="keyword">public</span> String key;</p>
<p>    <span class="keyword">public</span> <span class="keyword">boolean</span> failed;</p>
<p>    @Override<br />
    <span class="keyword">public</span> String getHttpURL() <span class="scope">{</span><br />
        <span class="keyword">return</span> TalkRunnble.TALK_URL_BASE + <span class="string">&quot;simplerpc&quot;</span>;<br />
    <span class="scope">}</span></p>
<p>    @Override<br />
    <span class="keyword">public</span> String getPipeURL() <span class="scope">{</span><br />
        <span class="keyword">return</span> TalkRunnble.TALK_URL_BASE + <span class="string">&quot;simplepipe&quot;</span>;<br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * TODO: {@link #pipeSetup()} should be ignored by Java2Script compiler<br />
	 * by default.<br />
	 * @j2sIgnore<br />
	 */</span><br />
    @Override<br />
    <span class="keyword">public</span> <span class="keyword">void</span> pipeSetup() <span class="scope">{</span><br />
        failed = <span class="keyword">false</span>;<br />
        JabberHelper instance = JabberHelper.getInstance();<br />
        key = instance.login(username, password, host, port, service);<br />
        <span class="keyword">if</span> (key == <span class="keyword">null</span>) <span class="scope">{</span><br />
            failed = <span class="keyword">true</span>;<br />
            <span class="keyword">return</span>;<br />
        <span class="scope">}</span><br />
        <span class="keyword">new</span> Thread(<span class="keyword">new</span> Runnable() <span class="scope">{</span></p>
<p>            <span class="keyword">public</span> <span class="keyword">void</span> run() <span class="scope">{</span><br />
                <span class="keyword">while</span> (<span class="keyword">true</span>) <span class="scope">{</span><br />
                    try <span class="scope">{</span><br />
                        Thread.sleep(30000);<br />
                    <span class="scope">}</span> catch (InterruptedException e) <span class="scope">{</span><br />
                        <span class="comment">//e.printStackTrace();</span><br />
                    <span class="scope">}</span><br />
                    <span class="keyword">if</span> (!isPipeLive()) <span class="scope">{</span><br />
                        pipeDestroy();<br />
                        break;<br />
                    <span class="scope">}</span><br />
                <span class="scope">}</span><br />
            <span class="scope">}</span></p>
<p>        <span class="scope">}</span>, <span class="string">&quot;Jabber Connection Monitor&quot;</span>).start();</p>
<p>        XMPPConnection conn = instance.getConnectionByKey(key);</p>
<p>        Presence presence = <span class="keyword">new</span> Presence(Presence.Type.available);<br />
        conn.sendPacket(presence);</p>
<p>        <span class="comment">//XMPPConnection conn = JabberHelper.getInstance().getConnectionByKey(key);</span><br />
        conn.addPacketListener(<span class="keyword">new</span> PacketListener() <span class="scope">{</span></p>
<p>            <span class="keyword">public</span> <span class="keyword">void</span> processPacket(Packet packet) <span class="scope">{</span><br />
                pipeThrough(packet);<br />
            <span class="scope">}</span></p>
<p>        <span class="scope">}</span>, <span class="keyword">null</span>);<br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * @j2sIgnore<br />
	 */</span><br />
    @Override<br />
    <span class="keyword">public</span> <span class="keyword">boolean</span> isPipeLive() <span class="scope">{</span><br />
        JabberHelper instance = JabberHelper.getInstance();<br />
        XMPPConnection conn = instance.getConnectionByKey(key);<br />
        <span class="keyword">return</span> <span class="keyword">super</span>.isPipeLive() &amp;&amp; conn != <span class="keyword">null</span> &amp;&amp; conn.isConnected()<br />
                &amp;&amp; !instance.isConnectionLost(key);<br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * @j2sIgnore<br />
	 */</span><br />
    @Override<br />
    <span class="keyword">public</span> <span class="keyword">void</span> pipeDestroy() <span class="scope">{</span><br />
        JabberHelper instance = JabberHelper.getInstance();<br />
        instance.logout(key); <span class="comment">// try to logout</span><br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * @j2sIgnore<br />
	 */</span><br />
    @Override<br />
    <span class="keyword">public</span> <span class="keyword">void</span> keepPipeLive() <span class="scope">{</span><br />
        JabberHelper instance = JabberHelper.getInstance();<br />
        instance.update(key);<br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * TODO: {@link #through(Object...)} should be ignored by Java2Script<br />
	 * compiler by default.<br />
	 * @j2sIgnore<br />
	 */</span><br />
    <span class="keyword">public</span> SimpleSerializable[] through(Object... args) <span class="scope">{</span><br />
        <span class="keyword">if</span> (args != <span class="keyword">null</span> &amp;&amp; args.length <span class="tag">&gt;</span> 0) <span class="scope">{</span><br />
            Packet packet = (Packet) args[0];<br />
            SimpleSerializable[] ss = <span class="keyword">new</span> SimpleSerializable[1];<br />
            <span class="keyword">if</span> (packet instanceof Presence) <span class="scope">{</span><br />
                Presence presence = (Presence) packet;<br />
                PresenceSerializable ps = <span class="keyword">new</span> PresenceSerializable();<br />
                ps.email = presence.getFrom();<br />
                Mode mode = presence.getMode();<br />
                ps.mode = mode == <span class="keyword">null</span> ? <span class="keyword">null</span> : mode.name();<br />
                Type type = presence.getType();<br />
                ps.type = type == <span class="keyword">null</span> ? <span class="keyword">null</span> : type.name();<br />
                ps.status = presence.getStatus();<br />
                ss[0] = ps;<br />
                <span class="keyword">return</span> ss;<br />
            <span class="scope">}</span> <span class="keyword">else</span> <span class="keyword">if</span> (packet instanceof Message) <span class="scope">{</span><br />
                Message message = (Message) packet;<br />
                MessageSerializable ms = <span class="keyword">new</span> MessageSerializable();<br />
                ms.from = message.getFrom();<br />
                ms.body = message.getBody();<br />
                ms.to = message.getTo();<br />
                ss[0] = ms;<br />
                <span class="keyword">return</span> ss;<br />
            <span class="scope">}</span> <span class="keyword">else</span> <span class="keyword">if</span> (packet instanceof RosterPacket) <span class="scope">{</span><br />
                RosterPacket roster = (RosterPacket) packet;<br />
                RosterSerializable rs = <span class="keyword">new</span> RosterSerializable();<br />
                rs.from = roster.getFrom();<br />
                roster.getType();<br />
                ss[0] = rs;<br />
                <span class="keyword">return</span> ss;<br />
            <span class="scope">}</span><br />
        <span class="scope">}</span><br />
        <span class="keyword">return</span> <span class="keyword">null</span>;<br />
    <span class="scope">}</span></p>
<p>    <span class="keyword">public</span> <span class="keyword">void</span> deal(PresenceSerializable ps) <span class="scope">{</span><br />
        <span class="comment">// To be override</span><br />
    <span class="scope">}</span></p>
<p>    <span class="keyword">public</span> <span class="keyword">void</span> deal(MessageSerializable ms) <span class="scope">{</span><br />
        <span class="comment">// To be override</span><br />
    <span class="scope">}</span></p>
<p>    <span class="keyword">public</span> <span class="keyword">void</span> deal(RosterSerializable rs) <span class="scope">{</span><br />
        <span class="comment">// To be override</span><br />
    <span class="scope">}</span></p>
<p><span class="scope">}</span><br />
</code></p></blockquote>
<p>SimplePipeRunnable</p>
<blockquote class="code"><p><code><span class="keyword">public</span> abstract <span class="keyword">class</span> SimplePipeRunnable <span class="keyword">extends</span> SimpleRPCRunnable <span class="scope">{</span></p>
<p>    <span class="comment">/**<br />
	 * Pipe's id<br />
	 */</span><br />
    <span class="keyword">public</span> String pipeKey;</p>
<p>    <span class="keyword">private</span> <span class="keyword">boolean</span> pipeAlive;</p>
<p>    <span class="keyword">private</span> SimplePipeHelper.IPipeThrough helper;</p>
<p>    <span class="comment">/**<br />
	 *<br />
	 * @param helper<br />
	 * @j2sIgnore<br />
	 */</span><br />
    <span class="keyword">void</span> setPipeHelper(SimplePipeHelper.IPipeThrough helper) <span class="scope">{</span><br />
        <span class="keyword">this</span>.helper = helper;<br />
    <span class="scope">}</span></p>
<p>    <span class="keyword">public</span> String getPipeURL() <span class="scope">{</span><br />
        <span class="keyword">return</span> <span class="string">&quot;simplepipe&quot;</span>; <span class="comment">// url is relative to the servlet!</span><br />
    <span class="scope">}</span></p>
<p>    <span class="keyword">public</span> String getPipeMethod() <span class="scope">{</span><br />
        <span class="keyword">return</span> <span class="string">&quot;GET&quot;</span>;<br />
    <span class="scope">}</span></p>
<p>    @Override<br />
    <span class="keyword">public</span> <span class="keyword">void</span> ajaxRun() <span class="scope">{</span><br />
        pipeKey = SimplePipeHelper.registerPipe(<span class="keyword">this</span>);<br />
        <span class="keyword">if</span> (pipeKey != <span class="keyword">null</span>) <span class="scope">{</span><br />
            pipeSetup();<br />
            pipeAlive = <span class="keyword">true</span>;<br />
        <span class="scope">}</span> <span class="keyword">else</span> <span class="scope">{</span> <span class="comment">// failed!</span><br />
            pipeAlive = <span class="keyword">false</span>;<br />
        <span class="scope">}</span><br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * Listening on given events and pipe events from Simple RPC to client.<br />
	 */</span><br />
    <span class="keyword">public</span> abstract <span class="keyword">void</span> pipeSetup();</p>
<p>    <span class="comment">/**<br />
	 * Destroy the pipe and remove listeners.<br />
	 * After pipe is destroyed, {@link #isPipeLive()} must be false<br />
	 */</span><br />
    <span class="keyword">public</span> abstract <span class="keyword">void</span> pipeDestroy();</p>
<p>    <span class="comment">/**<br />
	 * Return whether the pipe is still live or not.<br />
	 * @return pipe is live or not.<br />
	 */</span><br />
    <span class="keyword">public</span> <span class="keyword">boolean</span> isPipeLive() <span class="scope">{</span><br />
        <span class="keyword">return</span> pipeAlive;<br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * Notify that the pipe is still alive.<br />
	 */</span><br />
    <span class="keyword">public</span> <span class="keyword">void</span> keepPipeLive() <span class="scope">{</span><br />
        <span class="comment">// to be override</span><br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * Update pipe's live status.<br />
	 *<br />
	 * @param live if live is true, just notify the pipe is still alive. if live is false<br />
	 * and {@link #isPipeLive()} is true, {@link #pipeDestroy()} will be called.<br />
	 */</span><br />
    <span class="keyword">protected</span> <span class="keyword">void</span> updateStatus(<span class="keyword">boolean</span> live) <span class="scope">{</span><br />
        <span class="keyword">if</span> (live) <span class="scope">{</span><br />
            keepPipeLive();<br />
            pipeAlive = <span class="keyword">true</span>;<br />
        <span class="scope">}</span> <span class="keyword">else</span> <span class="keyword">if</span> (isPipeLive()) <span class="scope">{</span><br />
            pipeDestroy();<br />
            pipeAlive = <span class="keyword">false</span>;<br />
        <span class="scope">}</span><br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * Convert input objects into SimpleSerializable objects.<br />
	 *<br />
	 * @param args<br />
	 * @return SimpleSerializable objects to be sent through the pipe.<br />
	 */</span><br />
    <span class="keyword">public</span> abstract SimpleSerializable[] through(Object ... args);</p>
<p>    <span class="keyword">public</span> <span class="keyword">void</span> deal(SimpleSerializable ss) <span class="scope">{</span><br />
        try <span class="scope">{</span><br />
            Class<span class="tag">&lt;</span>? <span class="keyword">extends</span> SimpleSerializable<span class="tag">&gt;</span> clazz = ss.getClass();<br />
            <span class="keyword">if</span> (<span class="string">&quot;net.sf.j2s.ajax.SimpleSerializable&quot;</span>.equals(clazz.getName())) <span class="scope">{</span><br />
                System.out.println(<span class="string">&quot;Default!&quot;</span>);<br />
            <span class="scope">}</span><br />
            Method method = <span class="keyword">null</span>;</p>
<p>            Class<span class="tag">&lt;</span>?<span class="tag">&gt;</span> clzz = getClass();<br />
            String clazzName = clzz.getName();<br />
            <span class="keyword">int </span>idx = -1;<br />
            <span class="keyword">while</span> ((idx = clazzName.lastIndexOf(<span class="string">&apos;$&apos;</span>)) != -1) <span class="scope">{</span><br />
                <span class="keyword">if</span> (clazzName.length() <span class="tag">&gt;</span> idx + 1) <span class="scope">{</span><br />
                    char ch = clazzName.charAt(idx + 1);<br />
                    <span class="keyword">if</span> (ch <span class="tag">&lt;</span> <span class="string">&apos;0&apos;</span> &amp;&amp; ch <span class="tag">&gt;</span> <span class="string">&apos;9&apos;</span>) <span class="scope">{</span> <span class="comment">// not a number</span><br />
                        break; <span class="comment">// inner class</span><br />
                    <span class="scope">}</span><br />
                <span class="scope">}</span><br />
                clzz = clzz.getSuper<span class="keyword">class</span>();<br />
                <span class="keyword">if</span> (clzz == <span class="keyword">null</span>) <span class="scope">{</span><br />
                    break; <span class="comment">// should never happen!</span><br />
                <span class="scope">}</span><br />
                clazzName = clzz.getName();<br />
            <span class="scope">}</span><br />
            <span class="keyword">if</span> (clzz != <span class="keyword">null</span>) <span class="scope">{</span><br />
                method = clzz.getMethod(<span class="string">&quot;deal&quot;</span>, clazz);<br />
                <span class="keyword">if</span> (method != <span class="keyword">null</span>) <span class="scope">{</span><br />
                    method.invoke(<span class="keyword">this</span>, ss);<br />
                    <span class="keyword">return</span>;<br />
                <span class="scope">}</span><br />
            <span class="scope">}</span><br />
        <span class="scope">}</span> catch (Exception e) <span class="scope">{</span><br />
            e.printStackTrace();<br />
        <span class="scope">}</span><br />
        <span class="comment">// default</span><br />
        System.out.println(<span class="string">&quot;Default!&quot;</span>);<br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * A method used to pipe a bundle of instances through.<br />
	 *<br />
	 * Attention: Only visible inside {@link #pipeSetup()}.<br />
	 * @param args<br />
	 * @j2sIgnore<br />
	 */</span><br />
    <span class="keyword">protected</span> <span class="keyword">void</span> pipeThrough(Object ... args) <span class="scope">{</span><br />
        SimplePipeRunnable pipe = SimplePipeHelper.getPipe(pipeKey);<br />
        <span class="keyword">if</span> (pipe == <span class="keyword">null</span>) <span class="keyword">return</span>;<br />
        SimpleSerializable[] objs = pipe.through(args);</p>
<p>        <span class="keyword">if</span> (objs == <span class="keyword">null</span> || objs.length == 0) <span class="keyword">return</span>;</p>
<p>        <span class="keyword">if</span> (pipe instanceof SimplePipeRunnable) <span class="scope">{</span><br />
            SimplePipeRunnable pipeRunnable = (SimplePipeRunnable) pipe;<br />
            <span class="keyword">if</span> (pipeRunnable.helper != <span class="keyword">null</span>) <span class="scope">{</span><br />
                pipeRunnable.helper.helpThrough(pipe, objs);<br />
                <span class="keyword">return</span>;<br />
            <span class="scope">}</span><br />
        <span class="scope">}</span><br />
        <span class="keyword">for</span> (<span class="keyword">int </span>i = 0; i <span class="tag">&lt;</span> objs.length; i++) <span class="scope">{</span><br />
            pipe.deal(objs[i]);<br />
        <span class="scope">}</span><br />
    <span class="scope">}</span></p>
<p><span class="scope">}</span><br />
</code></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://inside.java2script.com/2007/08/01/introducing-java2scripts-simple-pipe.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Browser Statistics Among Web Developers</title>
		<link>http://inside.java2script.com/2007/06/16/browser-statistics-among-web-developers.html</link>
		<comments>http://inside.java2script.com/2007/06/16/browser-statistics-among-web-developers.html#comments</comments>
		<pubDate>Sat, 16 Jun 2007 02:49:03 +0000</pubDate>
		<dc:creator>Zhou Renjian</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Browser]]></category>

		<guid isPermaLink="false">http://inside.java2script.com/2007/06/16/browser-issue.html</guid>
		<description><![CDATA[Here are some numbers about browsers used among web developers: 1. Firefox 54.63% 2. Internet Explorer 38.10% 3. Opera 3.84% 4. Safari 1.56% 5. Mozilla 1.34% Firefox versions: 1. 2.0.0.3 50.74% 2. 2.0.0.4 30.25% 3. 1.5.0.11 6.05% 4. 1.5.0.12 3.65% &#8230; <a href="http://inside.java2script.com/2007/06/16/browser-statistics-among-web-developers.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Here are some numbers about browsers used among <strong>web developers</strong>:</p>
<p>1. <strong>Firefox</strong> 54.63%<br />
2. <strong>Internet Explorer</strong> 38.10%<br />
3. <strong>Opera</strong> 3.84%<br />
4. <strong>Safari</strong> 1.56%<br />
5. <strong>Mozilla</strong> 1.34%</p>
<p>Firefox versions:<br />
1. <strong>2.0.0.3</strong> 50.74%<br />
2. <strong>2.0.0.4</strong> 30.25%<br />
3. <strong>1.5.0.11</strong> 6.05%<br />
4. <strong>1.5.0.12</strong> 3.65%<br />
5. <strong>2.0.0.2</strong> 1.88%<br />
6. <strong>2.0.0.1</strong> 1.26%<br />
7. <strong>2.0</strong> 1.26%<br />
8. <strong>1.0.7</strong> 1.26%</p>
<p>Internet Explorer versions:<br />
1. <strong>6.0</strong> 67.27%<br />
2. <strong>7.0</strong> 32.65%</p>
<p>BTW: From the latest 15 days, more and more people update their Firefox to 2.0.0.4/1.5.0.12:<br />
1. <strong>2.0.0.4</strong> 71.76% (<strong>up</strong>)<br />
2. <strong>2.0.0.3</strong> 11.11%<br />
3. <strong>1.5.0.12</strong> 8.10% (<strong>up</strong>)<br />
4. <strong>2.0.0.2</strong> 1.44%</p>
]]></content:encoded>
			<wfw:commentRss>http://inside.java2script.com/2007/06/16/browser-statistics-among-web-developers.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
