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.File;
023 import java.io.FileInputStream;
024 import java.io.IOException;
025 import java.io.OutputStream;
026 import java.net.URI;
027 
028 import org.descripter.js.api.Script;
029 import org.descripter.js.api.core.CObject;
030 
031 import com.sun.net.httpserver.HttpExchange;
032 
033 /**
034  * <p>Handles the execution of server-side scriptlets or pages.</p>
035  * 
036  * @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>
037  * @since Descripter 1.0
038  */
039 public class Scriptlet<W extends Daemon> extends Script<W>
040 {
041     private final HttpExchange xchg;
042 
043     /**
044      * <p>Constructs this type of context.</p>
045      * 
046      * @param with The base context
047      * @param xchg The {@link HttpExchange}
048      * @since Descripter 1.0
049      */
050     public Scriptlet(W with, HttpExchange xchg) {
051         super(with);
052         this.xchg = xchg;
053     }
054 
055     /**
056      * <p>Prepares to run a scriptlet or server-page from the current script context.</p>
057      * @since Descripter 1.0
058      */
059     public void prelude() {
060         CObject request = object();
061         set(with._Request, request);
062         set(with._Response, array());
063         String method = xchg.getRequestMethod();
064         URI uri = xchg.getRequestURI();
065         if ("POST".equalsIgnoreCase(method)) {
066         } else {
067             String q = uri.getQuery();
068             if (q != null) {
069                 String[] arr = q.split("&");
070                 for (String s : arr) {
071                     String[] pair = s.split("=");
072                     request.set(key(pair[0]), pair[1]);
073                 }
074             }
075         }
076     }
077 
078     /**
079      * <p>Finishes running a scriptlet or server-page from the current script context.</p>
080      * @since Descripter 1.0
081      */
082     public void finale() throws IOException {
083         String response = with.getResponse(this).join("");
084         xchg.getResponseHeaders().add("Content-Type", "text/html");
085         xchg.sendResponseHeaders(200, response.length());
086         OutputStream os = xchg.getResponseBody();
087         os.write(response.getBytes());
088         os.close();
089     }
090 
091     /**
092      * <p>Executes the script context of this type.</p>
093      * @since Descripter 1.0
094      */
095     @Override
096     public void run() {
097         try {
098             String path = with.root + xchg.getRequestURI().getPath();
099             File file = new File(path);
100             System.out.println(file.getAbsolutePath());
101             if (!file.exists()) {
102                 xchg.sendResponseHeaders(404, -1);
103             } else if (path.endsWith(".js")) {
104                 Executable.get(this, file, false).execute(this);
105             } else if (path.endsWith(".jssp")) {
106                 Executable.get(this, file, true ).execute(this);
107             } else {
108                 FileInputStream fis = new FileInputStream(file);
109                 String type = mime(path);
110                 if (type != null) {
111                     xchg.getResponseHeaders().add("Content-Type", type);
112                 }
113                 xchg.sendResponseHeaders(200, file.length());
114                 OutputStream os = xchg.getResponseBody();
115                 byte[] buf = new byte[4096];
116                 int len;
117                 while ((len = fis.read(buf)) > 0) {
118                     os.write(buf, 0, len);
119                 }
120                 fis.close();os.close();
121             }
122         } catch (Exception e) {
123             e.printStackTrace();
124             throw new RuntimeException(e);
125         }
126     }
127 
128     /**
129      * <p>Gets the MIME type for a path.</p>
130      * 
131      * @param path The file path.
132      * @return The MIME type for the file.
133      * @since Descripter 1.0
134      */
135     public String mime(String path) {
136         CObject mime = with.mime;
137         int last = path.lastIndexOf('.');
138         return last > 0 ? var(mime, path.substring(last)).toString() : null;
139     }
140 }