001: /*
002: * (C) Copyright 2000 - 2003 Nabh Information Systems, Inc.
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU General Public License
006: * as published by the Free Software Foundation; either version 2
007: * of the License, or (at your option) any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: *
018: */
019:
020: package com.nabhinc.portlet.file;
021:
022: import java.io.File;
023: import java.io.IOException;
024: import java.io.Writer;
025:
026: import javax.portlet.ActionRequest;
027: import javax.portlet.ActionResponse;
028: import javax.portlet.PortletConfig;
029: import javax.portlet.PortletException;
030: import javax.portlet.PortletMode;
031: import javax.portlet.PortletSession;
032: import javax.portlet.RenderRequest;
033: import javax.portlet.RenderResponse;
034: import javax.portlet.UnavailableException;
035:
036: import com.nabhinc.core.MimeTypes;
037: import com.nabhinc.portlet.base.BasePortlet;
038: import com.nabhinc.util.IOUtil;
039:
040: /**
041: *
042: *
043: * @author Padmanabh Dabke
044: * (c) 2003 Nabh Information Systems, Inc. All Rights Reserved.
045: */
046: public class FilePortlet extends BasePortlet {
047:
048: public static final String FILE_PATH = "filePath";
049: public static final String HTML_FILE_PATH = "htmlFilePath";
050: public static final String WML_FILE_PATH = "wmlFilePath";
051: public static final String XHTML_FILE_PATH = "xhtmlFilePath";
052: public static final String FILE_CONTENT_PARAM = "content";
053: public static final String CONTENT_CACHE_ATTRIBUTE = "com.nabhinc.portlet.FilePortlet.contentCache";
054: public static final String WRITE_ACCESS_ERROR_ATTRIBUTE = "com.nabhinc.portlet.FilePortlet.writeError";
055: public static final String ADMIN_PAGE_PARAM = "adminPage";
056:
057: /**
058: * Path to the local HTML file.
059: */
060: private String fpHTMLPath = null;
061:
062: /**
063: * Cached content
064: */
065: private String fpHTMLCache = null;
066:
067: /**
068: * Path to the local WML file.
069: */
070: private String fpWMLPath = null;
071:
072: /**
073: * Cached content
074: */
075: private String fpWMLCache = null;
076:
077: /**
078: * Path to the local file.
079: */
080: private String fpXHTMLPath = null;
081:
082: /**
083: * Cached content
084: */
085: private String fpXHTMLCache = null;
086:
087: /**
088: * File modification time when last checked
089: */
090: private long fpHTMLModify = 0;
091:
092: /**
093: * File modification time when last checked
094: */
095: private long fpWMLModify = 0;
096:
097: /**
098: * File modification time when last checked
099: */
100: private long fpXHTMLModify = 0;
101:
102: /**
103: * Do nothing constructor.
104: */
105: public FilePortlet() {
106: }
107:
108: /**
109: * Gets the path of the file to be served. The file path can be configured
110: * in one of two ways. You can either specify an absolute path via <code>
111: * fileURL</code>'s <code>init</code> parameter by using: <code>file://</code>.
112: * A URL starting with <code>http://</code> can also be specified as the value
113: * of <code>fileURL</code> parameter.
114: * Alternatively, <code>filePath</code> can also be used to specify a relative
115: * path to the context path.
116: */
117: public void init(PortletConfig config) throws PortletException {
118: super .init(config);
119:
120: fpHTMLPath = config.getInitParameter(FILE_PATH);
121:
122: String temp = config.getInitParameter(HTML_FILE_PATH);
123: if (temp != null)
124: fpHTMLPath = temp;
125:
126: temp = config.getInitParameter(WML_FILE_PATH);
127: if (temp != null)
128: fpWMLPath = temp;
129:
130: temp = config.getInitParameter(XHTML_FILE_PATH);
131: if (temp != null)
132: fpXHTMLPath = temp;
133:
134: if (fpHTMLPath == null) {
135: error("init", "Path not set.");
136: throw new UnavailableException("Path not set.");
137: }
138:
139: if (fpWMLPath == null)
140: fpWMLPath = fpHTMLPath;
141: if (fpXHTMLPath == null)
142: fpXHTMLPath = fpHTMLPath;
143:
144: fpHTMLPath = validateFilePath(fpHTMLPath, config);
145: fpWMLPath = validateFilePath(fpWMLPath, config);
146: fpXHTMLPath = validateFilePath(fpXHTMLPath, config);
147:
148: }
149:
150: public void doView(RenderRequest request, RenderResponse response)
151: throws PortletException, IOException {
152:
153: String mimeType = request.getResponseContentType();
154:
155: if (mimeType == null || MimeTypes.HTML.equals(mimeType)) {
156: setHTMLContent();
157: response.getWriter().write(fpHTMLCache);
158: } else if (MimeTypes.WML.equals(mimeType)) {
159: setWMLContent();
160: response.getWriter().write(fpWMLCache);
161: } else if (MimeTypes.XHTML_MP.equals(mimeType)) {
162: setXHTMLContent();
163: response.getWriter().write(fpXHTMLCache);
164: } else {
165: throw new PortletException("Mime type " + mimeType
166: + " is not supported.");
167: }
168: // reset error
169: request.getPortletSession().removeAttribute(
170: WRITE_ACCESS_ERROR_ATTRIBUTE,
171: PortletSession.PORTLET_SCOPE);
172:
173: }
174:
175: public void doAdmin(RenderRequest request, RenderResponse response)
176: throws PortletException, IOException {
177: String contentType = request.getResponseContentType();
178: if (contentType == null || MimeTypes.HTML.equals(contentType)) {
179: if (request.getPortletSession().getAttribute(
180: WRITE_ACCESS_ERROR_ATTRIBUTE,
181: PortletSession.PORTLET_SCOPE) == null)
182: request.getPortletSession().setAttribute(
183: CONTENT_CACHE_ATTRIBUTE, fpHTMLCache,
184: PortletSession.PORTLET_SCOPE);
185: }
186:
187: Writer w = response.getWriter();
188: String textAreaId = response.getNamespace() + "_textarea";
189: w.write("<form method=\"POST\" action=\"");
190: w.write(response.createActionURL().toString());
191: // w.write("\"><center><div style=\"padding: 5px;\">");
192: w.write("\">");
193: w.write("<textarea id=\"");
194: w.write(textAreaId);
195: w.write("\" name=\"content\">");
196: w.write(fpHTMLCache);
197: w.write("</textarea>");
198: // w.write("</div></center></form>");
199: w.write("<p style=\"text-align: left;\">");
200: w
201: .write("<input class=\"button\" type=\"submit\" name=\"publish\" value=\"Save\" onclick=\"tinyMCE.triggerSave();return true;\" />");
202: w
203: .write("<input class=\"button\" type=\"submit\" name=\"cancel\" value=\"Cancel\" />");
204: w.write("</p>");
205: w.write("</center></form>");
206: // if (request.getProperty(PortalConstants.AJAX_HEADER) != null) {
207: w.write("<script type=\"text/javascript\">");
208: w
209: .write("sb_register_unload_callback(sb_remove_tiny_mce_control, '");
210: w.write(response.getNamespace());
211: w.write("');");
212: /*
213: w.write("sb_register_load_callback(sb_tiny_mce_content_saved, '");
214: w.write(response.getNamespace());
215: w.write("');");
216:
217: w.write("tinyMCE.execCommand('mceRemoveControl', true, '");
218: w.write(textAreaId);
219: w.write("');");
220: */
221: w.write("tinyMCE.execCommand('mceAddControl', true, '");
222: w.write(textAreaId);
223: w.write("');");
224:
225: /*
226: w.write("sb_add_tiny_mce_control('");
227: w.write(textAreaId);
228: w.write("');");
229: */
230: w.write("</script>");
231: }
232:
233: public void processAction(ActionRequest aReq, ActionResponse aRes)
234: throws PortletException, IOException {
235:
236: String newContent = aReq.getParameter(FILE_CONTENT_PARAM);
237: File f = new File(fpHTMLPath);
238: if (f.canWrite()) {
239: IOUtil.saveAndBackupFile(f, newContent);
240: //reset the cache
241: aReq.getPortletSession().removeAttribute(
242: CONTENT_CACHE_ATTRIBUTE,
243: PortletSession.PORTLET_SCOPE);
244: aReq.getPortletSession().removeAttribute(
245: WRITE_ACCESS_ERROR_ATTRIBUTE,
246: PortletSession.PORTLET_SCOPE);
247: aRes.setPortletMode(PortletMode.VIEW);
248: } else {
249: aReq.getPortletSession().setAttribute(
250: CONTENT_CACHE_ATTRIBUTE, newContent,
251: PortletSession.PORTLET_SCOPE);
252: aReq.getPortletSession().setAttribute(
253: WRITE_ACCESS_ERROR_ATTRIBUTE, "true",
254: PortletSession.PORTLET_SCOPE);
255: }
256: }
257:
258: /**
259: * Write the contents of this portlet to the output stream.
260: */
261: private void setHTMLContent() throws PortletException, IOException {
262:
263: File file = new File(fpHTMLPath);
264:
265: if (!file.exists()) {
266: fpHTMLCache = "File not found.";
267: error("init", "Invalid file path: " + fpHTMLPath);
268: throw new UnavailableException("Invalid file path : "
269: + fpHTMLPath);
270: }
271:
272: if (file.lastModified() != fpHTMLModify) {
273: fpHTMLModify = file.lastModified();
274: fpHTMLCache = IOUtil.getFileContentAsString(file);
275: }
276: }
277:
278: /**
279: * Write the contents of this portlet to the output stream.
280: */
281: private void setWMLContent() throws PortletException, IOException {
282:
283: File file = new File(fpWMLPath);
284:
285: if (!file.exists()) {
286: fpWMLCache = "File not found.";
287: error("init", "Invalid file path: " + fpWMLPath);
288: throw new UnavailableException("Invalid file path : "
289: + fpWMLPath);
290: }
291:
292: if (file.lastModified() != fpWMLModify) {
293: fpWMLModify = file.lastModified();
294: fpWMLCache = IOUtil.getFileContentAsString(file);
295: }
296: }
297:
298: /**
299: * Write the contents of this portlet to the output stream.
300: */
301: private void setXHTMLContent() throws PortletException, IOException {
302:
303: File file = new File(fpXHTMLPath);
304:
305: if (!file.exists()) {
306: fpXHTMLCache = "File not found.";
307: error("init", "Invalid file path: " + fpXHTMLPath);
308: throw new UnavailableException("Invalid file path : "
309: + fpXHTMLPath);
310: }
311:
312: if (file.lastModified() != fpXHTMLModify) {
313: fpXHTMLModify = file.lastModified();
314: fpXHTMLCache = IOUtil.getFileContentAsString(file);
315: }
316: }
317:
318: private String validateFilePath(String path, PortletConfig config)
319: throws UnavailableException {
320:
321: // Check if this is absolute path
322: File file = new File(path);
323: if (file.exists())
324: return path;
325:
326: // Check if the path is reletive to the Web context
327: String realPath = getRealPath(config.getPortletContext(), path);
328: if (new File(realPath).exists()) {
329: return realPath;
330: } else {
331: try {
332: IOUtil.createFile(realPath, "File is empty.", null);
333: return realPath;
334: } catch (IOException ex) {
335: throw new UnavailableException("Invalid file path: "
336: + path);
337: }
338: }
339: }
340:
341: }
|