001: /*
002: HttpdBase4J: An embeddable Java web server framework that supports HTTP, HTTPS,
003: templated content and serving content from inside a jar or archive.
004: Copyright (C) 2007 Donald Munro
005:
006: This library is free software; you can redistribute it and/or
007: modify it under the terms of the GNU Lesser General Public
008: License as published by the Free Software Foundation; either
009: version 2.1 of the License, or (at your option) any later version.
010:
011: This library 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 GNU
014: Lesser General Public License for more details.
015:
016: You should have received a copy of the GNU Lesser General Public
017: License along with this library; if not,see http://www.gnu.org/licenses/lgpl.txt
018: */
019:
020: package net.homeip.donaldm.httpdbase4j;
021:
022: import com.sun.net.httpserver.HttpExchange;
023: import java.io.File;
024: import java.io.FileInputStream;
025: import java.io.IOException;
026: import java.io.InputStream;
027: import java.io.UnsupportedEncodingException;
028: import java.util.ArrayList;
029: import java.util.Date;
030:
031: /**
032: * <p>
033: * Support for combining several style sheets or javascripts for file system based
034: * requests into one request.
035: * For example the client could specify:
036: * </p><br>
037: * <code>
038: * <link rel="stylesheet" type="text/css" media="all" href="styles/1.css,2.css,
039: * morestyles/3.css" />
040: * </code>
041: * <p>
042: * Different stylesheets/scripts are separated by commas; if the stylesheet name
043: * includes a / then it is assumed to be a full directory name otherwise it
044: * uses the previous entries directory. If the previoud directory did not have
045: * a directory then / is assumed eg
046: * </p><br>
047: * <code>
048: * <script type="text/javascript" src="1.js,2.js,3.js">
049: * </code><br>
050: * * 1.js, 2.js and 3.js are assumed to be in /.<br>
051: * <p>
052: * <b>This is non-standard HTML</b>, although it can be done in for example
053: * Apache using rewriting and server side scripts.
054: * (@see http://rakaz.nl/item/make_your_pages_load_faster_by_combining_and_compressing_javascript_and_css_files)
055: * </p>
056: * @author Donald Munro
057: */
058: public class FileCombinedRequest extends CombinedRequest implements
059: Cloneable
060: //=========================================================================
061: {
062:
063: /**
064: * The base directory containing the resource
065: */
066: protected File m_homeDir = null;
067:
068: /**
069: * Array of full paths of the resource.
070: */
071: protected ArrayList<File> m_requestFiles = new ArrayList<File>();
072:
073: public FileCombinedRequest(Httpd httpd, HttpExchange ex,
074: File homeDir) throws UnsupportedEncodingException,
075: IOException
076: //------------------------------------------------------------
077: {
078: super (httpd, ex);
079: m_homeDir = homeDir;
080: splitUp();
081: }
082:
083: /**
084: * @inheritDoc
085: */
086: @Override
087: protected void addFile(String file)
088: //---------------------------------
089: {
090: m_requestFiles.add(new File(m_homeDir, file.replace('/',
091: File.separatorChar)));
092: }
093:
094: /**
095: * @inheritDoc
096: */
097: @Override
098: protected int getCount() {
099: return m_requestFiles.size();
100: }
101:
102: /**
103: * @inheritDoc
104: */
105: @Override
106: protected InputStream getItemStream(int i)
107: //----------------------------------------
108: {
109: try {
110: return new FileInputStream(m_requestFiles.get(i));
111: } catch (Exception e) {
112: return null;
113: }
114: }
115:
116: /**
117: * @inheritDoc
118: */
119: @Override
120: public boolean exists()
121: //---------------------
122: {
123: for (int i = 0; i < m_requestFiles.size(); i++) {
124: if (!m_requestFiles.get(i).exists()) {
125: if (m_strict)
126: return false;
127: } else
128: return true;
129: }
130: return false;
131: }
132:
133: /**
134: * @inheritDoc
135: */
136: @Override
137: public boolean isReadable()
138: //-------------------------
139: {
140: for (int i = 0; i < m_requestFiles.size(); i++) {
141: if (!m_requestFiles.get(i).canRead()) {
142: if (m_strict)
143: return false;
144: } else
145: return true;
146: }
147: return false;
148: }
149:
150: /**
151: * @inheritDoc
152: */
153: @Override
154: public Date getDate()
155: //-------------------
156: {
157: long maxt = 0;
158: for (int i = 0; i < m_requestFiles.size(); i++) {
159: File f = m_requestFiles.get(i);
160: long t = f.lastModified();
161: if (t > maxt)
162: maxt = t;
163: }
164: return new Date(maxt);
165: }
166:
167: /**
168: * @inheritDoc
169: */
170: @Override
171: public String getName()
172: //--------------------
173: {
174: StringBuffer names = new StringBuffer();
175: for (int i = 0; i < m_requestFiles.size(); i++) {
176: String name = m_requestFiles.get(i).getName();
177: if (names.length() > 0) {
178: names.append(name);
179: names.append(m_delimiter);
180: }
181: }
182: return names.toString();
183: }
184:
185: /**
186: * @inheritDoc
187: */
188: @Override
189: public String getETag(boolean refresh)
190: //---------------------
191: {
192: if ((!refresh) && (m_eTag != null))
193: return m_eTag;
194: DirItemInterface[] items = new DirItemInterface[m_requestFiles
195: .size()];
196: for (int i = 0; i < m_requestFiles.size(); i++)
197: items[i] = new FileRequest.DirItem(m_requestFiles.get(i));
198: m_eTag = Http.eTag(items);
199: return m_eTag;
200: }
201:
202: }
|