001 
002 /*
003  *  Descripter 1.0 - Java Script Engines
004  *  Copyright (C) 2010-2015  Jianjun Liu (J.J.Liu)
005  *  
006  *  This program is free software: you can redistribute it and/or modify
007  *  it under the terms of the GNU Affero General Public License as published by
008  *  the Free Software Foundation, either version 3 of the License, or
009  *  (at your option) any later version.
010  *  
011  *  This program is distributed in the hope that it will be useful,
012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014  *  GNU Affero General Public License for more details.
015  *  
016  *  You should have received a copy of the GNU Affero General Public License
017  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
018  */
019 
020 package org.descripter.js.ss;
021 
022 import java.io.IOException;
023 import java.net.InetSocketAddress;
024 
025 import com.sun.net.httpserver.HttpExchange;
026 import com.sun.net.httpserver.HttpHandler;
027 
028 import org.descripter.js.api.Core;
029 import org.descripter.js.api.Global;
030 import org.descripter.js.api.Key;
031 import org.descripter.js.api.Script;
032 import org.descripter.js.api.core.CArray;
033 import org.descripter.js.api.core.CObject;
034 
035 import com.sun.net.httpserver.HttpServer;
036 
037 /**
038  * <p>A simple HTTP server for servlets and server-pages in JavaScript.</p>
039  * 
040  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.descripter.org" target="_blank">http://www.descripter.org</a>
041  * @since Descripter 1.0
042  */
043 public class Daemon extends Core
044 {
045     /**
046      * <p>The command-line starter for a daemon of the containing type.</p>
047      * @param args A string array of the command-line arguments.
048      * @since Descripter 1.0
049      */
050     public static void main(String[] args) {
051         if (args == null || args.length < 1) {
052             new Daemon(8000, "/echo").run();
053             return;
054         }
055         int alen = args.length;
056         if (args == null || alen > 2) {
057             usage();
058             return;
059         }
060         int port = 8000;
061         String root = ".";
062         if (alen > 0) {
063             root = args[0];
064         }
065         if (alen > 1) {
066             port = Integer.parseInt(args[1]);
067         }
068         new Daemon(port, root).run();
069     }
070 
071     private final static void usage() {
072         System.out.println("Descripter 1.0 Core Daemon,  All right reserved.");
073         System.out.println("Copyright (C) 2010-2012  J.J.Liu<jianjunliu@126.com> www.descripter.org");
074         System.out.println("java -jar descripter.jar <root> <port>");
075         System.out.println("java -cp descripter.jar daemon <root> <port>");
076         System.out.println("java -cp descripter.jar org.descripter.js.ss.Daemon <root> <port>");
077     }
078 
079     /**
080      * <p>Executes the script context of this type.</p>
081      * @since Descripter 1.0
082      */
083     @Override
084     public void run() {
085         try {
086             HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
087             server.createContext(cntx, new HttpHandler(){
088                 @Override
089                 public void handle(HttpExchange xchg) throws IOException {
090                     new Thread(
091                             new Scriptlet<Daemon>(Daemon.this, xchg)
092                     ).run();
093                 }});
094             server.start();
095         } catch (IOException e) {
096             e.printStackTrace();
097         }
098     }
099 
100     /**
101      * <p>The runtime {@link Key} for the <tt>Request</tt> identifier or property.</p>
102      * @since Descripter 1.0
103      */
104     public final Key _Request   = key("Request");
105     /**
106      * <p>The runtime {@link Key} for the <tt>Response</tt> identifier or property.</p>
107      * @since Descripter 1.0
108      */
109     public final Key _Response  = key("Response");
110 
111     /**
112      * <p>Gets the runtime <tt>Request</tt> identifier or property.</p>
113      * @param script A {@link Script} context
114      * @return The runtime <tt>Request</tt> identifier or property of the 
115      * specified {@link Script} context
116      * @since Descripter 1.0
117      */
118     protected CObject getRequest(Script<?> script) {
119         return (CObject)script.get(_Request);
120     }
121 
122     /**
123      * <p>Gets the runtime <tt>Response</tt> identifier or property.</p>
124      * @param script A {@link Script} context
125      * @return The runtime <tt>Response</tt> identifier or property of the 
126      * specified {@link Script} context
127      * @since Descripter 1.0
128      */
129     protected CArray getResponse(Script<?> script) {
130         return (CArray)script.get(_Response);
131     }
132 
133     /**
134      * <p>A native global service for <tt>HTTP Response</tt> output.</p>
135      * <p>This method prints the elements of <tt>args</tt> to <tt>HTTP Response</tt> in HTML lines.</p>
136      * @param script The script context that invoked this function
137      * @param args An array of the arguments passed by the invocation
138      * @see Core#_print
139      * @see Global#globalize(String)
140      * @since Descripter 1.0
141      */
142     @Override
143     public void print(Script<?> script, Object ...args) {
144         CArray r = getResponse(script);
145         r.push(array(args));
146         r.put(r.length(), "\r\n");
147     }
148 
149     /**
150      * <p>Constructs a writable {@link Core} context with the current path as the root.</p>
151      * @param port The port number for the HTTP server
152      * @param cntx The context path for the HTTP server
153      * @since Descripter 1.0
154      */
155     public Daemon(int port, String cntx) {
156         this(port, cntx, false);
157     }
158 
159     /**
160      * <p>Constructs a {@link Core} context with the current path as the root.</p>
161      * @param port The port number for the HTTP server
162      * @param cntx The context path for the HTTP server
163      * @param readOnly <tt>true</tt> for a read-only core context; <tt>false</tt>, otherwise.
164      * @since Descripter 1.0
165      */
166     public Daemon(int port, String cntx, boolean readOnly) {
167         this(".", port, cntx, readOnly);
168     }
169 
170     /**
171      * <p>Constructs a writable {@link Core} context.</p>
172      * @param root The root path for the HTTP server
173      * @param port The port number for the HTTP server
174      * @param cntx The context path for the HTTP server
175      * @since Descripter 1.0
176      */
177     public Daemon(String root, int port, String cntx) {
178         this(root, port, cntx, false);
179     }
180 
181     /**
182      * <p>The root path for the HTTP server.</p>
183      * @since Descripter 1.0
184      */
185     public final String root;
186     /**
187      * <p>The context path for the HTTP server.</p>
188      * @since Descripter 1.0
189      */
190     public final String cntx;
191     /**
192      * <p>The port number for the HTTP server.</p>
193      * @since Descripter 1.0
194      */
195     public final int port;
196     /**
197      * <p>The object of MIME types.</p>
198      * @since Descripter 1.0
199      */
200     public final CObject mime;
201 
202     /**
203      * <p>Constructs the specific {@link Core} context.</p>
204      * @param root The root path for the HTTP server
205      * @param port The port number for the HTTP server
206      * @param cntx The context path for the HTTP server
207      * @param readOnly <tt>true</tt> for a read-only core context; <tt>false</tt>, otherwise.
208      * @since Descripter 1.0
209      */
210     public Daemon(String root, int port, String cntx, boolean readOnly) {
211         super(false);
212 
213         System.out.println("Descripter 1.0 Daemon,  All right reserved.");
214         System.out.println("Copyright (C) 2010-2012  J.J.Liu<jianjunliu@126.com> www.descripter.org");
215 
216         put(_this, this);
217         this.port = port;
218         this.cntx = cntx;
219         this.root = root;
220         this.mime = object();
221         set(mime, "js"   , "application/javascript");
222         set(mime, "class", "application/octet-stream");
223         set(mime, "exe"  , "application/octet-stream");
224         set(mime, "jar"  , "application/octet-stream");
225         set(mime, "zip"  , "application/octet-stream");
226         set(mime, "doc"  , "application/msword");
227         set(mime, "pdf"  , "application/pdf");
228         set(mime, "ogg"  , "application/x-ogg");
229         set(mime, "swf"  , "application/x-shockwave-flash");
230         set(mime, "mp3"  , "audio/mpeg");
231         set(mime, "m3u"  , "audio/mpeg-url");
232         set(mime, "gif"  , "image/gif");
233         set(mime, "jpeg" , "image/jpeg");
234         set(mime, "jpg"  , "image/jpeg");
235         set(mime, "png"  , "image/png");
236         set(mime, "css"  , "text/css");
237         set(mime, "htm"  , "text/html");
238         set(mime, "html" , "text/html");
239         set(mime, "asc"  , "text/plain");
240         set(mime, "txt"  , "text/plain");
241         set(mime, "xml"  , "text/xml");
242         set(mime, "mp4"  , "video/mp4");
243         set(mime, "ogv"  , "video/ogg");
244         set(mime, "mov"  , "video/quicktime");
245         set(mime, "flv"  , "video/x-flv");
246         readOnly(readOnly);
247         System.out.println("Descripter 1.0 Daemon initialized.");
248     }
249 }