/*
* Copyright 2011 Chad Retz
*
* 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 org.gwtnode.examples.oophmproxy;
import org.gwtnode.core.JavaScriptUtils;
import org.gwtnode.core.node.buffer.Buffer;
import org.gwtnode.core.node.event.BooleanEventHandler;
import org.gwtnode.core.node.event.StringOrBufferEventHandler;
import org.gwtnode.core.node.fs.Fs;
import org.gwtnode.core.node.net.Net;
import org.gwtnode.core.node.net.Server;
import org.gwtnode.core.node.net.Socket;
import org.gwtnode.core.node.net.StreamEventHandler;
import org.gwtnode.core.node.stdio.Console;
import org.gwtnode.core.node.stream.WritableStream;
import org.gwtnode.dev.debug.BufferStream;
import org.gwtnode.dev.debug.BufferStream.StreamIndexOutOfBoundsException;
import org.gwtnode.dev.debug.message.Message;
import org.gwtnode.dev.debug.message.MessageType;
/**
* @author Chad Retz
*/
class OophmProxyServer {
private final Server server;
private final int proxyPort;
private Socket proxySocket;
private Socket gwtCodeSocket;
private final BufferStream proxyStream = new BufferStream();
private final BufferStream gwtCodeStream = new BufferStream();
private WritableStream logFile;
public OophmProxyServer(int proxyPort, final String gwtCodeHost, final int gwtCodePort,
final String logFilename) {
server = Net.get().createServer(new StreamEventHandler() {
@Override
protected void onEvent(Socket stream) {
if (logFilename != null) {
logFile = Fs.get().createWriteStream(logFilename);
}
proxySocket = stream;
gwtCodeSocket = Socket.create();
gwtCodeSocket.connect(gwtCodePort, gwtCodeHost);
proxySocket.onData(new StringOrBufferEventHandler() {
@Override
protected void onEvent() {
Buffer buffer = getBuffer();
proxyStream.append(buffer);
Message message;
do {
message = logMessage(proxyStream, true);
if (message != null) {
gwtCodeSocket.write(message.toBuffer());
}
} while (message != null);
//gwtCodeSocket.write(buffer);
}
});
gwtCodeSocket.onData(new StringOrBufferEventHandler() {
@Override
protected void onEvent() {
Buffer buffer = getBuffer();
gwtCodeStream.append(buffer);
Message message;
do {
message = logMessage(gwtCodeStream, false);
if (message != null) {
proxySocket.write(message.toBuffer());
}
} while (message != null);
//proxySocket.write(buffer);
}
});
proxySocket.onClose(new BooleanEventHandler() {
@Override
protected void onEvent(boolean value) {
gwtCodeSocket.end();
if (logFile != null) {
logFile.end();
logFile = null;
}
}
});
gwtCodeSocket.onClose(new BooleanEventHandler() {
@Override
protected void onEvent(boolean value) {
proxySocket.end();
if (logFile != null) {
logFile.end();
logFile = null;
}
}
});
}
});
this.proxyPort = proxyPort;
}
private Message logMessage(BufferStream stream, boolean fromClient) {
try {
stream.beginTransaction();
MessageType type = MessageType.getMessageType(stream);
Message message = type.createMessage(stream, fromClient);
if (logFile != null) {
logFile.write((fromClient ? "fromJS ** " : "toJS ** ") + message.toString() + "\n");
} else {
Console.get().info((fromClient ? "fromJS ** " : "toJS ** ") + message.toString());
}
stream.commitTransaction();
return message;
} catch (StreamIndexOutOfBoundsException e) {
stream.rollbackTransaction();
return null;
} catch (Exception e) {
logFile.write("Error: " + JavaScriptUtils.appendException(e, new StringBuilder()) + "\n");
stream.rollbackTransaction();
return null;
}
}
public void listen() {
server.listen(proxyPort);
Console.get().info("Listening on port: " + proxyPort);
}
}