hammant 02/02/27 06:47:36 Modified: altrmi build.xml tests2.xml Added: altrmi/lib beepcore.jar altrmi/src/java/org/apache/commons/altrmi/client/impl/beep BEEPHostContext.java BEEPInvocationHandler.java altrmi/src/java/org/apache/commons/altrmi/server/impl/beep AltrmiBEEPServerProfile.java BEEPServerConnection.java CompleteBEEPServer.java ServerBEEPReadWriter.java altrmi/src/java/org/apache/commons/altrmi/test BeepClientTest.java BeepServerTest.java Log: prototype BEEP usage Revision Changes Path 1.8 +4 -1 jakarta-commons-sandbox/altrmi/build.xml Index: build.xml =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/altrmi/build.xml,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- build.xml 1 Feb 2002 00:17:00 -0000 1.7 +++ build.xml 27 Feb 2002 14:47:36 -0000 1.8 @@ -3,7 +3,7 @@ <!-- "Alternative (to) RMI" component of the Jakarta Commons Subproject - $Id: build.xml,v 1.7 2002/02/01 00:17:00 hammant Exp $ + $Id: build.xml,v 1.8 2002/02/27 14:47:36 hammant Exp $ --> @@ -81,6 +81,9 @@ <path id="compile.classpath"> <pathelement location="${build.home}/classes"/> <pathelement location="${commons-collections.jar}"/> + <fileset dir="lib"> + <include name="*.jar" /> + </fileset> </path> <!-- ========== Test Execution Defaults =================================== --> 1.2 +40 -5 jakarta-commons-sandbox/altrmi/tests2.xml Index: tests2.xml =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/altrmi/tests2.xml,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- tests2.xml 18 Feb 2002 21:40:28 -0000 1.1 +++ tests2.xml 27 Feb 2002 14:47:36 -0000 1.2 @@ -3,7 +3,7 @@ <!-- "Alt (to) RMI" component of the Jakarta Commons Subproject - $Id: tests2.xml,v 1.1 2002/02/18 21:40:28 hammant Exp $ + $Id: tests2.xml,v 1.2 2002/02/27 14:47:36 hammant Exp $ --> @@ -48,7 +48,7 @@ <path id="testB1.classpath"> <pathelement location="${build.home}/classes"/> - <pathelement location="${build.home}/classes3"/> + <pathelement location="${build.home}/classes2"/> </path> <path id="testB2.classpath"> @@ -57,9 +57,22 @@ <path id="testC1.classpath"> <pathelement location="${build.home}/classes"/> - <pathelement location="D:/jdk1.4/lib/tools.jar"/> + <pathelement location="${build.home}/classes2"/> + <!-- beep libraries --> + <fileset dir="lib"> + <include name="*.jar" /> + </fileset> + </path> - + <path id="testC2.classpath"> + <pathelement location="${build.home}/classes"/> + <!-- beep libraries --> + <fileset dir="lib"> + <include name="*.jar" /> + </fileset> + + </path> + @@ -110,7 +123,14 @@ <pathelement location="${build.home}/classes"/> </classpath> </altrmiinterfaces> - + <altrmiinterfaces genname="Hello" srcgendir="${build.home}/genjava" + classgendir="${build.home}/classes2" + classesorinterfaces="org.apache.commons.altrmi.test.TestInterface" + additionalfacades="org.apache.commons.altrmi.test.TestInterface2"> + <classpath> + <pathelement location="${build.home}/classes"/> + </classpath> + </altrmiinterfaces> </target> <target name="procon-serve"> @@ -128,5 +148,20 @@ <arg value="ObjectStream"/> </java> </target> + + <target name="beep-serve" > + <java classname="org.apache.commons.altrmi.test.BeepServerTest" fork="true"> + <classpath refid="testC1.classpath"/> + <arg value="S"/> + </java> + </target> + + <target name="beep-client" depends="generate"> + <java classname="org.apache.commons.altrmi.test.BeepClientTest" fork="true"> + <classpath refid="testC2.classpath"/> + <arg value="S"/> + </java> + </target> + </project> 1.1 jakarta-commons-sandbox/altrmi/lib/beepcore.jar <<Binary file>> 1.1 jakarta-commons-sandbox/altrmi/src/java/org/apache/commons/altrmi/client/impl/beep/BEEPHostContext.java Index: BEEPHostContext.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE.txt file. */ package org.apache.commons.altrmi.client.impl.beep; import org.apache.commons.altrmi.client.impl.AbstractHostContext; import org.apache.commons.altrmi.common.AltrmiConnectionException; import java.net.Socket; /** * Class BEEPHostContext * * * @author Vinay Chandrasekharan<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a> * @version $Revision: 1.1 $ */ public class BEEPHostContext extends AbstractHostContext { /** * Constructor BEEPHostContext * * * @param host * @param port * * @throws AltrmiConnectionException * */ public BEEPHostContext(String host, int port) throws AltrmiConnectionException { super(new BEEPInvocationHandler(host, port)); } } 1.1 jakarta-commons-sandbox/altrmi/src/java/org/apache/commons/altrmi/client/impl/beep/BEEPInvocationHandler.java Index: BEEPInvocationHandler.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE.txt file. */ package org.apache.commons.altrmi.client.impl.beep; import java.io.*; import org.apache.commons.altrmi.common.AltrmiConnectionException; import org.apache.commons.altrmi.common.AltrmiRequest; import org.apache.commons.altrmi.common.AltrmiReply; import org.apache.commons.altrmi.common.SerializationHelper; import org.apache.commons.altrmi.client.impl.stream.StreamInvocationHandler; import org.apache.commons.altrmi.client.impl.stream.ClientStreamReadWriter; import org.beepcore.beep.core.BEEPError; import org.beepcore.beep.core.BEEPException; import org.beepcore.beep.core.BEEPInterruptedException; import org.beepcore.beep.core.ByteDataStream; import org.beepcore.beep.core.Channel; import org.beepcore.beep.core.MessageListener; import org.beepcore.beep.core.Message; import org.beepcore.beep.core.DataStream; import org.beepcore.beep.core.ProfileRegistry; import org.beepcore.beep.core.Session; import org.beepcore.beep.core.StringDataStream; import org.beepcore.beep.core.ReplyListener; import org.beepcore.beep.lib.NullReplyListener; import org.beepcore.beep.lib.MessageQueue; import org.beepcore.beep.profile.ProfileConfiguration; import org.beepcore.beep.transport.tcp.AutomatedTCPSessionCreator; /** * Class BEEPInvocationHandler * * * @author Vinay Chandrasekharan<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a> * @version $Revision: 1.1 $ */ public class BEEPInvocationHandler extends StreamInvocationHandler { public static final String ALTRMI_SERVER_URI="http://jakarta.apache.org/commons/profiles/AltrmiServer"; private String mHost; private int mPort; private Session session; private Channel channel; /** * Constructor BEEPInvocationHandler * * * @param host * @param port * * @throws AltrmiConnectionException * */ public BEEPInvocationHandler(String host, int port) throws AltrmiConnectionException { mHost = host; mPort = port; try { //TODO: // Change here if the client needs to enable callbacks // Client will have a profiles too advertise session = AutomatedTCPSessionCreator.initiate(mHost, mPort,new ProfileRegistry()); } catch (BEEPException e) { e.printStackTrace(); throw new AltrmiConnectionException("BEEPInvocationHandler construction failed"+e.getMessage()); } try { channel = session.startChannel(ALTRMI_SERVER_URI); } catch (BEEPError e) { String errMsg=""; if (e.getCode() == 550) errMsg="BEEPInvocationHandler: Error the listener peer does not support ALTRMIServerProfile"; else errMsg="BEEPInvocationHandler: Error while communicating with the peer code["+ e.getCode() + "] msg[ " + e.getMessage() + "]"; System.err.println(errMsg); throw new AltrmiConnectionException(errMsg); } catch (BEEPException e) { String errMsg="BEEPInvocationHandler: Error starting channel (" + e.getMessage() + ")"; System.err.println(errMsg); throw new AltrmiConnectionException(errMsg); } ClientBEEPReadWriter beepReadWriter =(ClientBEEPReadWriter )createClientStreamReadWriter(); channel.setDataListener(beepReadWriter.mQueue); setObjectReadWriter(beepReadWriter); } public BEEPInvocationHandler(String host, int port,String profileClassName,String profileURI) throws AltrmiConnectionException { //TODO: Client can decide the profiles and thus the decide on the way // callbacks must be handled ...Is this flexibility needed ?? this(host,port); //change } /** * Method tryReconnect * * * @return connected or not. */ protected boolean tryReconnect() { return false; } protected ClientStreamReadWriter createClientStreamReadWriter() { return new ClientBEEPReadWriter (channel); } /** * Class ClientBEEPReadWriter : * Write REQUESTs and reads the RESPONSE back from the server. */ private class ClientBEEPReadWriter extends ClientStreamReadWriter //implements MessageListener { private Channel channel; private ReplyListener replyListener; Object lock = new Object(); private boolean m_isLocked=true; byte[] byteArray; MessageQueue mQueue; ClientBEEPReadWriter (Channel channel) { this.channel=channel; replyListener= NullReplyListener.getListener(); mQueue=new MessageQueue(); } protected synchronized AltrmiReply postRequest(AltrmiRequest altrmiRequest) throws IOException, ClassNotFoundException { writeRequest(altrmiRequest); return readReply(); } private void writeRequest(AltrmiRequest altrmiRequest) throws IOException { byte[] aBytes = SerializationHelper.getBytesFromInstance(altrmiRequest); try { channel.sendMSG(new ByteDataStream(aBytes),replyListener); } catch(BEEPException be) { throw new IOException(be.getMessage()); } } private AltrmiReply readReply() throws IOException, ClassNotFoundException { try { receive(); return (AltrmiReply) SerializationHelper.getInstanceFromBytes(byteArray); } catch(Exception e) { e.printStackTrace(); throw new IOException(e.getMessage()); } } public void receive() throws BEEPError { try { Message message=mQueue.getNextMessage(); message.sendRPY(new StringDataStream("OK")); DataStream ds = message.getDataStream(); InputStream is = ds.getInputStream(); byte[] buf = new byte[4096]; ByteArrayOutputStream data = new ByteArrayOutputStream(); while (true) { try { int n = is.read(buf); if (n == -1) break; data.write(buf, 0, n); } catch (IOException e) { e.printStackTrace(); message.getChannel().getSession().terminate(e.getMessage()); return; } } byteArray=data.toByteArray(); } catch(Exception e) { e.printStackTrace(); throw new BEEPError(BEEPError.CODE_GENERAL_SYNTAX_ERROR,e.getMessage()); } } } //end of inner class } 1.1 jakarta-commons-sandbox/altrmi/src/java/org/apache/commons/altrmi/server/impl/beep/AltrmiBEEPServerProfile.java Index: AltrmiBEEPServerProfile.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE.txt file. */ package org.apache.commons.altrmi.server.impl.beep; import org.apache.commons.altrmi.server.impl.AbstractServer; import org.beepcore.beep.core.BEEPError; import org.beepcore.beep.core.BEEPException; import org.beepcore.beep.core.Channel; import org.beepcore.beep.core.CloseChannelException; import org.beepcore.beep.core.StartChannelListener; import org.beepcore.beep.core.Message; import org.beepcore.beep.core.MessageListener; import org.beepcore.beep.core.Session; import org.beepcore.beep.core.StartChannelException; import org.beepcore.beep.core.StartChannelListener; import org.beepcore.beep.lib.MessageQueue; import org.beepcore.beep.profile.Profile; import org.beepcore.beep.profile.ProfileConfiguration; import java.util.Vector; /** * Class AltrmiBEEPProfile * * * @author Vinay Chandrasekharan * @version $Revision: 1.1 $ */ public class AltrmiBEEPServerProfile implements Profile, StartChannelListener { private AbstractServer abstractServer; public static final String ALTRMI_SERVER_URI="http://jakarta.apache.org/commons/profiles/AltrmiServer"; public void setAbstractServer(AbstractServer abstractServer) { this.abstractServer=abstractServer; } public StartChannelListener init(String uri, ProfileConfiguration config) throws BEEPException { return this; } public void startChannel(Channel channel, String encoding, String data) throws StartChannelException { ServerBEEPReadWriter beepReadWriter = new ServerBEEPReadWriter(channel); BEEPServerConnection beepServerConnectoin = new BEEPServerConnection(abstractServer,beepReadWriter); channel.setDataListener(beepReadWriter.mQueue); //spawning BEEP channel Thread beepConnectionThread= new Thread(beepServerConnectoin); beepConnectionThread.start(); } public void closeChannel(Channel channel) throws CloseChannelException { channel.setDataListener(null); channel.setAppData(null); } public boolean advertiseProfile(Session session) { return true; } } 1.1 jakarta-commons-sandbox/altrmi/src/java/org/apache/commons/altrmi/server/impl/beep/BEEPServerConnection.java Index: BEEPServerConnection.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE.txt file. */ package org.apache.commons.altrmi.server.impl.beep; import org.apache.commons.altrmi.common.AltrmiRequest; import org.apache.commons.altrmi.common.AltrmiReply; import org.apache.commons.altrmi.common.EndConnectionReply; import org.apache.commons.altrmi.server.AltrmiServerConnection; import org.apache.commons.altrmi.server.impl.AbstractServer; import org.apache.commons.altrmi.server.impl.StreamServerConnection; import org.apache.commons.altrmi.server.impl.ServerStreamReadWriter; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.InputStream; import java.net.Socket; import java.net.SocketException; /** * Class BEEPServerConnection * * * @author Vinay Chandrasekharan * @version $Revision: 1.1 $ */ public class BEEPServerConnection extends StreamServerConnection{ /** * Constructor StreamServerConnection * * * @param abstractServer * @param readWriter * */ public BEEPServerConnection (AbstractServer abstractServer, ServerStreamReadWriter readWriter) { super(abstractServer,readWriter); } /** * Method killConnection * * */ public void killConnection() { } } 1.1 jakarta-commons-sandbox/altrmi/src/java/org/apache/commons/altrmi/server/impl/beep/CompleteBEEPServer.java Index: CompleteBEEPServer.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE.txt file. */ package org.apache.commons.altrmi.server.impl.beep; import java.net.InetAddress; import org.apache.commons.altrmi.server.impl.AbstractServer; import org.beepcore.beep.core.BEEPException; import org.beepcore.beep.core.ProfileRegistry; import org.beepcore.beep.core.Session; import org.beepcore.beep.profile.ProfileConfiguration; import org.beepcore.beep.transport.tcp.AutomatedTCPSessionCreator; /** * Class CompleteBEEPServer * * * @author Vinay Chandrasekharan * @version $Revision: 1.1 $ */ public class CompleteBEEPServer extends AbstractServer { private static final String profileClassName="org.apache.commons.altrmi.server.impl.beep.AltrmiBEEPServerProfile"; private ProfileRegistry mProfileRegistry; private ProfileConfiguration profileConfig; private Thread mThread; private int mPort; /** * Constructor */ public CompleteBEEPServer(int port) throws Exception { mPort=port; AltrmiBEEPServerProfile abp; try { abp = (AltrmiBEEPServerProfile) Class.forName(profileClassName).newInstance(); abp.setAbstractServer(this); } catch (InstantiationException e) { throw new Exception("Class " + profileClassName + " returned an error"); } catch (IllegalAccessException e) { throw new Exception("Class " + profileClassName + " cannot be constructed."); } catch (ClassNotFoundException e) { throw new Exception("Class " + profileClassName + " not found"); } catch (ClassCastException e) { throw new Exception("class " + profileClassName + " does not " + "implement the org.beepcore.beep.profile.Profile interface"); } profileConfig = new ProfileConfiguration(); mProfileRegistry = new ProfileRegistry(); mProfileRegistry.addStartChannelListener( AltrmiBEEPServerProfile.ALTRMI_SERVER_URI, abp.init( AltrmiBEEPServerProfile.ALTRMI_SERVER_URI, profileConfig), null ); } /** * Method start * */ public void start() { mState = STARTED; getThread().start(); } /** * Method stop * */ public void stop() { mState = SHUTTINGDOWN; getThread().interrupt(); mState = STOPPED; } private Thread getThread() { if (mThread == null) { mThread = new BeepSeesionDeamon(this); } return mThread; } /** * Incoming Beep session deamon thread */ private class BeepSeesionDeamon extends Thread { private CompleteBEEPServer beepServer; BeepSeesionDeamon( CompleteBEEPServer beepServer) { super( "CompleteBEEPServer.BeepSessionDaemon Thread"); this.beepServer= beepServer; } public void run() { while (true) { try { System.out.println("Listening at port["+beepServer.mPort+"]"); // Loop listening for new Sessions Session session = AutomatedTCPSessionCreator.listen(beepServer.mPort,beepServer.mProfileRegistry); } catch (BEEPException e) { e.printStackTrace(); } catch (Throwable e) { System.out.println("BeepSessionDaemon Thread killed"); e.printStackTrace(); break; } } } } } 1.1 jakarta-commons-sandbox/altrmi/src/java/org/apache/commons/altrmi/server/impl/beep/ServerBEEPReadWriter.java Index: ServerBEEPReadWriter.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE.txt file. */ package org.apache.commons.altrmi.server.impl.beep; import org.apache.commons.altrmi.common.AltrmiRequest; import org.apache.commons.altrmi.common.AltrmiReply; import org.apache.commons.altrmi.common.SerializationHelper; import org.apache.commons.altrmi.server.impl.ServerStreamReadWriter ; import org.beepcore.beep.core.BEEPException; import org.beepcore.beep.core.BEEPError; import org.beepcore.beep.core.Channel; import org.beepcore.beep.core.Message; import org.beepcore.beep.lib.MessageQueue; import org.beepcore.beep.core.MessageListener; import org.beepcore.beep.core.StringDataStream; import org.beepcore.beep.core.DataStream; import org.beepcore.beep.core.ByteDataStream; import org.beepcore.beep.core.ReplyListener; import org.beepcore.beep.lib.NullReplyListener; import java.util.*; import java.io.*; import java.io.DataOutputStream; import java.io.IOException; import java.io.BufferedOutputStream; /** * Class ServerBEEPReadWriter * * * @author Vinay Chandrasekharan * @version $Revision: 1.1 $ */ public class ServerBEEPReadWriter extends ServerStreamReadWriter //implements MessageListener { Channel channel; int byteArraySize=0; byte[] byteArray ; Object lock = new Object(); private boolean m_isLocked=true; private ReplyListener replyListener; public MessageQueue mQueue; protected ServerBEEPReadWriter (Channel channel) { this.channel=channel; replyListener= NullReplyListener.getListener(); mQueue=new MessageQueue(); } protected void initialize() { } protected synchronized AltrmiRequest writeReplyAndGetRequest(AltrmiReply altrmiReply) throws IOException, ClassNotFoundException { if (altrmiReply != null) { writeReply(altrmiReply); } return readRequest(); } private void writeReply(AltrmiReply altrmiReply) throws IOException { byte[] aBytes = SerializationHelper.getBytesFromInstance(altrmiReply); try { channel.sendMSG(new ByteDataStream(aBytes),replyListener); } catch(BEEPException be) { throw new IOException(be.getMessage()); } } private AltrmiRequest readRequest() throws IOException, ClassNotFoundException { try { receive(); return (AltrmiRequest) SerializationHelper.getInstanceFromBytes(byteArray); } catch(Exception e) { e.printStackTrace(); throw new IOException(e.getMessage()); } } public void receive() throws BEEPError { try { Message message=mQueue.getNextMessage(); message.sendRPY(new StringDataStream("OK")); DataStream ds = message.getDataStream(); InputStream is = ds.getInputStream(); byte[] buf = new byte[4096]; ByteArrayOutputStream data = new ByteArrayOutputStream(); while (true) { try { int n = is.read(buf); if (n == -1) break; data.write(buf, 0, n); } catch (IOException e) { message.getChannel().getSession().terminate(e.getMessage()); return; } } byteArray=data.toByteArray(); } catch(Exception e) { e.printStackTrace(); throw new BEEPError(BEEPError.CODE_GENERAL_SYNTAX_ERROR,e.getMessage()); } } } 1.1 jakarta-commons-sandbox/altrmi/src/java/org/apache/commons/altrmi/test/BeepClientTest.java Index: BeepClientTest.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE.txt file. */ package org.apache.commons.altrmi.test; import org.apache.commons.altrmi.client.AltrmiHostContext; import org.apache.commons.altrmi.client.AltrmiFactory; import org.apache.commons.altrmi.common.AltrmiConnectionException; import org.apache.commons.altrmi.client.impl.beep.BEEPHostContext; import org.apache.commons.altrmi.client.impl.ServerClassAltrmiFactory; import org.apache.commons.altrmi.client.impl.ClientClassAltrmiFactory; import java.io.IOException; /** * Class BeepClient * * * @author Vinay Chandrasekharan */ public class BeepClientTest { /** * Method main * * * @param args * * @throws Exception * */ public static void main(String[] args) throws Exception { System.out.println("BEEP Profile Based Altrmi Client"); AltrmiHostContext arhc; arhc = new BEEPHostContext("127.0.0.1", 1236); AltrmiFactory af = null; if (args[0].equals("S")) { af = new ServerClassAltrmiFactory(false); } else { af = new ClientClassAltrmiFactory(false); } af.setHostContext(arhc); //list System.out.println("Listing Published Objects At Server..."); String[] listOfPublishedObjectsOnServer = af.list(); for (int i = 0; i < listOfPublishedObjectsOnServer.length; i++) { System.out.println("..[" + i + "]:" + listOfPublishedObjectsOnServer[i]); } TestInterface ti = (TestInterface) af.lookup("Hello"); new TestClient(ti); af.close(); } } 1.1 jakarta-commons-sandbox/altrmi/src/java/org/apache/commons/altrmi/test/BeepServerTest.java Index: BeepServerTest.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE.txt file. */ package org.apache.commons.altrmi.test; import org.apache.commons.altrmi.server.impl.beep.CompleteBEEPServer; import org.apache.commons.altrmi.server.impl.classretrievers.JarFileClassRetriever; import org.apache.commons.altrmi.server.impl.AbstractServer; import org.apache.commons.altrmi.server.PublicationDescription; import java.io.IOException; /** * Class BeepServerTest * * * @author Vinay Chandrasekharan */ public class BeepServerTest { /** * Method main * * * @param args * * @throws Exception * */ public static void main(String[] args) throws Exception { System.out.println("BEEP Profile Based Server"); AbstractServer as; as = new CompleteBEEPServer(1236); if (args[0].equals("S")) { as.setClassRetriever(new JarFileClassRetriever("build/classes2")); } TestInterfaceImpl ti = new TestInterfaceImpl(); PublicationDescription pd = new PublicationDescription(TestInterface.class, TestInterface2.class); as.publish(ti, "Hello", pd); as.start(); } }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>