001: /*
002: $Id: GroovySocketServer.java 2273 2005-06-10 14:05:02Z cstein $
003:
004: Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
005:
006: Redistribution and use of this software and associated documentation
007: ("Software"), with or without modification, are permitted provided
008: that the following conditions are met:
009:
010: 1. Redistributions of source code must retain copyright
011: statements and notices. Redistributions must also contain a
012: copy of this document.
013:
014: 2. Redistributions in binary form must reproduce the
015: above copyright notice, this list of conditions and the
016: following disclaimer in the documentation and/or other
017: materials provided with the distribution.
018:
019: 3. The name "groovy" must not be used to endorse or promote
020: products derived from this Software without prior written
021: permission of The Codehaus. For written permission,
022: please contact info@codehaus.org.
023:
024: 4. Products derived from this Software may not be called "groovy"
025: nor may "groovy" appear in their names without prior written
026: permission of The Codehaus. "groovy" is a registered
027: trademark of The Codehaus.
028:
029: 5. Due credit should be given to The Codehaus -
030: http://groovy.codehaus.org/
031:
032: THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
033: ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
034: NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
035: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
036: THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
037: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
038: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
039: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
040: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
041: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
042: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
043: OF THE POSSIBILITY OF SUCH DAMAGE.
044:
045: */
046: package groovy.ui;
047:
048: import groovy.lang.GroovyShell;
049: import groovy.lang.Script;
050:
051: import java.io.BufferedReader;
052: import java.io.FileInputStream;
053: import java.io.IOException;
054: import java.io.InputStreamReader;
055: import java.io.PrintWriter;
056: import java.net.InetAddress;
057: import java.net.ServerSocket;
058: import java.net.Socket;
059: import java.net.URL;
060:
061: /**
062: * Simple server that executes supplied script against a socket
063: * @author Jeremy Rayner
064: */
065:
066: public class GroovySocketServer implements Runnable {
067: private URL url;
068: private GroovyShell groovy;
069: private boolean isScriptFile;
070: private String scriptFilenameOrText;
071: private boolean autoOutput;
072:
073: public GroovySocketServer(GroovyShell groovy, boolean isScriptFile,
074: String scriptFilenameOrText, boolean autoOutput, int port) {
075: this .groovy = groovy;
076: this .isScriptFile = isScriptFile;
077: this .scriptFilenameOrText = scriptFilenameOrText;
078: this .autoOutput = autoOutput;
079: try {
080: url = new URL("http", InetAddress.getLocalHost()
081: .getHostAddress(), port, "/");
082: System.out.println("groovy is listening on port " + port);
083: } catch (IOException e) {
084: e.printStackTrace();
085: }
086: new Thread(this ).start();
087: }
088:
089: public void run() {
090: try {
091: ServerSocket serverSocket = new ServerSocket(url.getPort());
092: while (true) {
093: // Create one script per socket connection.
094: // This is purposefully not caching the Script
095: // so that the script source file can be changed on the fly,
096: // as each connection is made to the server.
097: Script script;
098: if (isScriptFile) {
099: GroovyMain gm = new GroovyMain();
100: script = groovy
101: .parse(new FileInputStream(
102: gm
103: .huntForTheScriptFile(scriptFilenameOrText)));
104: } else {
105: script = groovy.parse(scriptFilenameOrText);
106: }
107: new GroovyClientConnection(script, autoOutput,
108: serverSocket.accept());
109: }
110: } catch (Exception e) {
111: e.printStackTrace();
112: }
113: }
114:
115: class GroovyClientConnection implements Runnable {
116: private Script script;
117: private Socket socket;
118: private BufferedReader reader;
119: private PrintWriter writer;
120: private boolean autoOutputFlag;
121:
122: GroovyClientConnection(Script script, boolean autoOutput,
123: Socket socket) throws IOException {
124: this .script = script;
125: this .autoOutputFlag = autoOutput;
126: this .socket = socket;
127: reader = new BufferedReader(new InputStreamReader(socket
128: .getInputStream()));
129: writer = new PrintWriter(socket.getOutputStream());
130: new Thread(this , "Groovy client connection - "
131: + socket.getInetAddress().getHostAddress()).start();
132: }
133:
134: public void run() {
135: try {
136: String line = null;
137: script.setProperty("out", writer);
138: script.setProperty("socket", socket);
139: script.setProperty("init", Boolean.TRUE);
140: while ((line = reader.readLine()) != null) {
141: // System.out.println(line);
142: script.setProperty("line", line);
143: Object o = script.run();
144: script.setProperty("init", Boolean.FALSE);
145: if (o != null) {
146: if ("success".equals(o)) {
147: break; // to close sockets gracefully etc...
148: } else {
149: if (autoOutputFlag) {
150: writer.println(o);
151: }
152: }
153: }
154: writer.flush();
155: }
156: } catch (IOException e) {
157: e.printStackTrace();
158: } finally {
159: try {
160: writer.flush();
161: writer.close();
162: } finally {
163: try {
164: socket.close();
165: } catch (IOException e3) {
166: e3.printStackTrace();
167: }
168: }
169: }
170: }
171: }
172: }
|