/*
* Copyright (c) 2001-2004 Ant-Contrib project. All rights reserved.
*
* 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 net.sf.antcontrib.antserver.server;
import java.io.*;
import java.net.Socket;
import org.apache.tools.ant.Project;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import net.sf.antcontrib.antserver.Command;
import net.sf.antcontrib.antserver.Response;
import net.sf.antcontrib.antserver.Util;
import net.sf.antcontrib.antserver.commands.DisconnectCommand;
import net.sf.antcontrib.antserver.commands.ShutdownCommand;
/****************************************************************************
* Place class description here.
*
* @author Matthew Inger
* @author
*
* @since
*
****************************************************************************/
public class ConnectionHandler
implements Runnable
{
private static long nextGroupId = 0;
private ServerTask task;
private Socket socket;
private Thread thread;
private Throwable thrown;
public ConnectionHandler(ServerTask task, Socket socket)
{
super();
this.socket = socket;
this.task = task;
}
public void start()
{
long gid = nextGroupId;
if (nextGroupId == Long.MAX_VALUE)
nextGroupId = 0;
else
nextGroupId++;
ThreadGroup group = new ThreadGroup("server-tg-" + gid);
thread = new Thread(group, this);
thread.start();
}
public Throwable getThrown()
{
return thrown;
}
public void run()
{
InputStream is = null;
OutputStream os = null;
try
{
ConnectionBuildListener cbl = null;
is = socket.getInputStream();
os = socket.getOutputStream();
ObjectInputStream ois = new ObjectInputStream(is);
ObjectOutputStream oos = new ObjectOutputStream(os);
// Write the initial response object so that the
// object stream is initialized
oos.writeObject(new Response());
boolean disconnect = false;
Command inputCommand = null;
Response response = null;
while (! disconnect)
{
task.getProject().log("Reading command object.",
Project.MSG_DEBUG);
inputCommand = (Command) ois.readObject();
task.getProject().log("Executing command object: " + inputCommand,
Project.MSG_DEBUG);
response = new Response();
try
{
cbl = new ConnectionBuildListener();
task.getProject().addBuildListener(cbl);
inputCommand.execute(task.getProject(),
inputCommand.getContentLength(),
is);
response.setSucceeded(true);
}
catch (Throwable t)
{
response.setSucceeded(false);
response.setThrowable(t);
}
finally
{
if (cbl != null)
task.getProject().removeBuildListener(cbl);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
XMLSerializer serial = new XMLSerializer();
OutputFormat fmt = new OutputFormat();
fmt.setOmitDocumentType(true);
fmt.setOmitXMLDeclaration(false);
serial.setOutputFormat(fmt);
serial.setOutputByteStream(baos);
serial.serialize(cbl.getDocument());
response.setResultsXml(baos.toString());
task.getProject().log("Executed command object: " + inputCommand,
Project.MSG_DEBUG);
task.getProject().log("Sending response: " + response,
Project.MSG_DEBUG);
response.setContentLength(inputCommand.getContentLength());
oos.writeObject(response);
if (inputCommand.getResponseContentLength() != 0)
{
Util.transferBytes(inputCommand.getReponseContentStream(),
inputCommand.getResponseContentLength(),
os,
true);
}
if (inputCommand instanceof DisconnectCommand)
{
disconnect = true;
task.getProject().log("Got disconnect command",
Project.MSG_DEBUG);
}
else if (inputCommand instanceof ShutdownCommand)
{
disconnect = true;
task.getProject().log("Got shutdown command",
Project.MSG_DEBUG);
task.shutdown();
}
}
}
catch (ClassNotFoundException e)
{
thrown = e;
}
catch (IOException e)
{
thrown = e;
}
catch (Throwable t)
{
thrown = t;
}
finally
{
if (is != null)
{
try
{
is.close();
}
catch (IOException e)
{
}
}
if (os != null)
{
try
{
os.close();
}
catch (IOException e)
{
}
}
if (socket != null)
{
try
{
socket.close();
}
catch (IOException e)
{
}
}
}
}
}