001: /*
002: * Adapted from FCKEditor Java file by Nabh Information Systems, Inc.
003: * Modifications (c) 2006 Nabh Information Systems, Inc.
004: *
005: * FCKeditor - The text editor for internet
006: * Copyright (C) 2003-2005 Frederico Caldeira Knabben
007: *
008: * Licensed under the terms of the GNU Lesser General Public License:
009: * http://www.opensource.org/licenses/lgpl-license.php
010: *
011: * For further information visit:
012: * http://www.fckeditor.net/
013: *
014: * File Name: ConnectorServlet.java
015: * Java Connector for Resource Manager class.
016: *
017: * Version: 2.3
018: * Modified: 2005-08-11 16:29:00
019: *
020: * File Authors:
021: * Simone Chiaretta (simo@users.sourceforge.net)
022: */
023:
024: package com.nabhinc.portal.core;
025:
026: import java.io.*;
027: import javax.servlet.*;
028: import javax.servlet.http.*;
029:
030: import java.rmi.RemoteException;
031: import java.util.*;
032:
033: import org.apache.commons.fileupload.*;
034: import org.apache.commons.fileupload.disk.DiskFileItemFactory;
035: import org.apache.commons.fileupload.servlet.ServletFileUpload;
036:
037: import javax.xml.parsers.*;
038: import org.w3c.dom.*;
039:
040: import com.nabhinc.util.StringUtil;
041:
042: import javax.xml.transform.*;
043: import javax.xml.transform.dom.DOMSource;
044: import javax.xml.transform.stream.StreamResult;
045:
046: /**
047: * Servlet to upload and browse files.<br>
048: *
049: * This servlet accepts 4 commands used to retrieve and create files and folders from a server directory.
050: * The allowed commands are:
051: * <ul>
052: * <li>GetFolders: Retrive the list of directory under the current folder
053: * <li>GetFoldersAndFiles: Retrive the list of files and directory under the current folder
054: * <li>CreateFolder: Create a new directory under the current folder
055: * <li>FileUpload: Send a new file to the server (must be sent with a POST)
056: * </ul>
057: *
058: * @author Simone Chiaretta (simo@users.sourceforge.net)
059: * @author Padmanabh Dabke (padmanabh.dabke@nabhinc.com)
060: */
061: public class ResourceServlet extends HttpServlet {
062:
063: /**
064: *
065: */
066: private static final long serialVersionUID = 3441951616734030859L;
067: private static String baseDir;
068: private static boolean debug = false;
069: private static String servletPath = "/resource";
070: private static Hashtable allowedExtensions;
071: private static Hashtable deniedExtensions;
072:
073: /**
074: * Initialize the servlet.<br>
075: * Retrieve from the servlet configuration the "baseDir" which is the root of the file repository:<br>
076: * If not specified the value of "/psite_resources/" will be used.
077: *
078: */
079: @SuppressWarnings("unchecked")
080: public void init() throws ServletException {
081: baseDir = getInitParameter("baseDir");
082: debug = (new Boolean(getInitParameter("debug"))).booleanValue();
083: if (baseDir == null)
084: baseDir = PortalConstants.BASE_CONTENT_DIR;
085: else if (baseDir.endsWith("/"))
086: baseDir = baseDir.substring(0, baseDir.length() - 1);
087: String realBaseDir = getServletContext().getRealPath(baseDir);
088: File baseFile = new File(realBaseDir);
089: if (!baseFile.exists()) {
090: baseFile.mkdir();
091: }
092:
093: if (StringUtil
094: .isNotNullOrEmpty(getInitParameter("servletPath"))) {
095: servletPath = getInitParameter("servletPath");
096: }
097:
098: // Stuff related to file upload
099: allowedExtensions = new Hashtable(3);
100: deniedExtensions = new Hashtable(3);
101:
102: allowedExtensions
103: .put(
104: "File",
105: stringToArrayList(getInitParameter("AllowedExtensionsFile")));
106: deniedExtensions
107: .put(
108: "File",
109: stringToArrayList(getInitParameter("DeniedExtensionsFile")));
110:
111: allowedExtensions
112: .put(
113: "Image",
114: stringToArrayList(getInitParameter("AllowedExtensionsImage")));
115: deniedExtensions
116: .put(
117: "Image",
118: stringToArrayList(getInitParameter("DeniedExtensionsImage")));
119:
120: allowedExtensions
121: .put(
122: "Flash",
123: stringToArrayList(getInitParameter("AllowedExtensionsFlash")));
124: deniedExtensions
125: .put(
126: "Flash",
127: stringToArrayList(getInitParameter("DeniedExtensionsFlash")));
128:
129: }
130:
131: /**
132: * Manage the Get requests (GetFolders, GetFoldersAndFiles, CreateFolder).<br>
133: *
134: * The servlet accepts commands sent in the following format:<br>
135: * connector?Command=CommandName&Type=ResourceType&CurrentFolder=FolderPath<br><br>
136: * It execute the command and then return the results to the client in XML format.
137: *
138: */
139: public void doGet(HttpServletRequest request,
140: HttpServletResponse response) throws ServletException,
141: IOException {
142:
143: if (debug)
144: System.out.println("--- BEGIN DOGET ---");
145:
146: response.setContentType("text/xml; charset=UTF-8");
147: response.setHeader("Cache-Control", "no-cache");
148: PrintWriter out = response.getWriter();
149:
150: String commandStr = request.getParameter("Command");
151: String typeStr = request.getParameter("Type");
152: String currentFolderStr = request.getParameter("CurrentFolder");
153: String prefix = request.getContextPath() + servletPath;
154: String appPath = request.getRequestURI().substring(
155: prefix.length());
156: String baseAppDir = baseDir + appPath;
157: if (!baseAppDir.endsWith("/"))
158: baseAppDir += "/";
159: String currentPath = baseAppDir + typeStr + currentFolderStr;
160:
161: File currentDir = getCurrentDirectory(request);
162: Document document = null;
163: try {
164: DocumentBuilderFactory factory = DocumentBuilderFactory
165: .newInstance();
166: DocumentBuilder builder = factory.newDocumentBuilder();
167: document = builder.newDocument();
168: } catch (ParserConfigurationException pce) {
169: pce.printStackTrace();
170: }
171:
172: Node root = CreateCommonXml(document, commandStr, typeStr,
173: currentFolderStr, request.getContextPath()
174: + currentPath);
175:
176: if (debug)
177: System.out.println("Command = " + commandStr);
178:
179: if (request.getRemoteUser() == null) {
180: setErrorResponse(root, document,
181: "You must be logged in to manage resources.");
182: } else if (!checkAccess(request, appPath)) {
183: setErrorResponse(root, document, "Access not permitted.");
184: } else {
185:
186: if (commandStr.equals("GetFolders")) {
187: getFolders(currentDir, root, document);
188: } else if (commandStr.equals("GetFoldersAndFiles")) {
189: getFolders(currentDir, root, document);
190: getFiles(currentDir, root, document);
191: } else if (commandStr.equals("CreateFolder")) {
192: String newFolderStr = request
193: .getParameter("NewFolderName");
194: File newFolder = new File(currentDir, newFolderStr);
195: String retValue = "110";
196:
197: if (newFolder.exists()) {
198: retValue = "101";
199: } else {
200: try {
201: boolean dirCreated = newFolder.mkdir();
202: if (dirCreated)
203: retValue = "0";
204: else
205: retValue = "102";
206: } catch (SecurityException sex) {
207: retValue = "103";
208: }
209:
210: }
211: setCreateFolderResponse(retValue, root, document);
212: } else if (commandStr.equals("DeleteFile")) {
213: String retValue = "0";
214: String fileName = request.getParameter("FileName");
215: boolean success = new File(currentDir, fileName)
216: .delete();
217: if (!success)
218: retValue = "101";
219: if (StringUtil.isNotNullOrEmpty(fileName)) {
220:
221: }
222: setCreateFolderResponse(retValue, root, document);
223: }
224: }
225:
226: document.getDocumentElement().normalize();
227: try {
228: TransformerFactory tFactory = TransformerFactory
229: .newInstance();
230: Transformer transformer = tFactory.newTransformer();
231:
232: DOMSource source = new DOMSource(document);
233:
234: StreamResult result = new StreamResult(out);
235: transformer.transform(source, result);
236:
237: if (debug) {
238: StreamResult dbgResult = new StreamResult(System.out);
239: transformer.transform(source, dbgResult);
240: System.out.println("");
241: System.out.println("--- END DOGET ---");
242: }
243:
244: } catch (Exception ex) {
245: ex.printStackTrace();
246: }
247:
248: out.flush();
249: out.close();
250: }
251:
252: /**
253: * Manage the Post requests (FileUpload).<br>
254: *
255: * The servlet accepts commands sent in the following format:<br>
256: * connector?Command=FileUpload&Type=ResourceType&CurrentFolder=FolderPath<br><br>
257: * It store the file (renaming it in case a file with the same name exists) and then return an HTML file
258: * with a javascript command in it.
259: *
260: */
261: @SuppressWarnings("unchecked")
262: public void doPost(HttpServletRequest request,
263: HttpServletResponse response) throws ServletException,
264: IOException {
265:
266: if (debug)
267: System.out.println("--- BEGIN DOPOST ---");
268:
269: response.setContentType("text/html; charset=UTF-8");
270: response.setHeader("Cache-Control", "no-cache");
271: PrintWriter out = response.getWriter();
272:
273: String commandStr = request.getParameter("Command");
274: String typeStr = request.getParameter("Type");
275: String currentFolderStr = request.getParameter("CurrentFolder");
276:
277: String currentPath = baseDir + typeStr + currentFolderStr;
278: String currentDirPath = getServletContext().getRealPath(
279: currentPath);
280:
281: if (debug)
282: System.out.println(currentDirPath);
283:
284: String retVal = "0";
285: String newName = "";
286:
287: if (!commandStr.equals("FileUpload"))
288: retVal = "203";
289: else {
290: //DiskFileUpload upload = new DiskFileUpload();
291: DiskFileItemFactory factory = new DiskFileItemFactory();
292: ServletFileUpload upload = new ServletFileUpload(factory);
293: try {
294: List items = upload.parseRequest(request);
295:
296: Map fields = new HashMap();
297:
298: Iterator iter = items.iterator();
299: while (iter.hasNext()) {
300: FileItem item = (FileItem) iter.next();
301: if (item.isFormField())
302: fields.put(item.getFieldName(), item
303: .getString());
304: else
305: fields.put(item.getFieldName(), item);
306: }
307: FileItem uplFile = (FileItem) fields.get("NewFile");
308: String fileNameLong = uplFile.getName();
309: fileNameLong = fileNameLong.replace('\\', '/');
310: String[] pathParts = fileNameLong.split("/");
311: String fileName = pathParts[pathParts.length - 1];
312:
313: String nameWithoutExt = getNameWithoutExtension(fileName);
314: String ext = getExtension(fileName);
315:
316: if (extIsAllowed(typeStr, ext)) {
317: File pathToSave = new File(
318: getCurrentDirectory(request), fileName);
319: int counter = 1;
320: while (pathToSave.exists()) {
321: newName = nameWithoutExt + "(" + counter + ")"
322: + "." + ext;
323: retVal = "201";
324: pathToSave = new File(currentDirPath, newName);
325: counter++;
326: }
327: uplFile.write(pathToSave);
328: } else {
329: retVal = "202";
330: if (debug)
331: System.out.println("Invalid file type: " + ext);
332:
333: }
334: } catch (Exception ex) {
335: retVal = "203";
336: }
337:
338: }
339:
340: out.println("<script type=\"text/javascript\">");
341: out
342: .println("window.parent.frames['frmUpload'].OnUploadCompleted("
343: + retVal + ",'" + newName + "');");
344: out.println("</script>");
345: out.flush();
346: out.close();
347:
348: if (debug)
349: System.out.println("--- END DOPOST ---");
350:
351: }
352:
353: /*
354: * This method was fixed after Kris Barnhoorn (kurioskronic) submitted SF bug #991489
355: */
356: private static String getNameWithoutExtension(String fileName) {
357: return fileName.substring(0, fileName.lastIndexOf("."));
358: }
359:
360: /*
361: * This method was fixed after Kris Barnhoorn (kurioskronic) submitted SF bug #991489
362: */
363: private String getExtension(String fileName) {
364: return fileName.substring(fileName.lastIndexOf(".") + 1);
365: }
366:
367: private void setErrorResponse(Node root, Document doc, String msg) {
368: Element myEl = doc.createElement("Error");
369: myEl.setAttribute("number", "1");
370: myEl.setAttribute("text", msg);
371: root.appendChild(myEl);
372:
373: }
374:
375: private void setCreateFolderResponse(String retValue, Node root,
376: Document doc) {
377: Element myEl = doc.createElement("Error");
378: myEl.setAttribute("number", retValue);
379: root.appendChild(myEl);
380: }
381:
382: private void getFolders(File dir, Node root, Document doc) {
383: Element folders = doc.createElement("Folders");
384: root.appendChild(folders);
385: File[] fileList = dir.listFiles();
386: for (int i = 0; i < fileList.length; ++i) {
387: if (fileList[i].isDirectory()) {
388: Element myEl = doc.createElement("Folder");
389: myEl.setAttribute("name", fileList[i].getName());
390: folders.appendChild(myEl);
391: }
392: }
393: }
394:
395: private void getFiles(File dir, Node root, Document doc) {
396: Element files = doc.createElement("Files");
397: root.appendChild(files);
398: File[] fileList = dir.listFiles();
399: for (int i = 0; i < fileList.length; ++i) {
400: if (fileList[i].isFile()) {
401: Element myEl = doc.createElement("File");
402: myEl.setAttribute("name", fileList[i].getName());
403: myEl.setAttribute("size", "" + fileList[i].length()
404: / 1024);
405: files.appendChild(myEl);
406: }
407: }
408: }
409:
410: private Node CreateCommonXml(Document doc, String commandStr,
411: String typeStr, String currentPath, String currentUrl) {
412:
413: Element root = doc.createElement("Connector");
414: doc.appendChild(root);
415: root.setAttribute("command", commandStr);
416: root.setAttribute("resourceType", typeStr);
417:
418: Element myEl = doc.createElement("CurrentFolder");
419: myEl.setAttribute("path", currentPath);
420: myEl.setAttribute("url", currentUrl);
421: root.appendChild(myEl);
422:
423: return root;
424:
425: }
426:
427: /**
428: * Helper function to convert the configuration string to an ArrayList.
429: */
430:
431: @SuppressWarnings("unchecked")
432: private ArrayList stringToArrayList(String str) {
433:
434: if (debug)
435: System.out.println(str);
436: String[] strArr = str.split("\\|");
437:
438: ArrayList tmp = new ArrayList();
439: if (str.length() > 0) {
440: for (int i = 0; i < strArr.length; ++i) {
441: if (debug)
442: System.out.println(i + " - " + strArr[i]);
443: tmp.add(strArr[i].toLowerCase());
444: }
445: }
446: return tmp;
447: }
448:
449: /**
450: * Helper function to verify if a file extension is allowed or not allowed.
451: */
452:
453: private boolean extIsAllowed(String fileType, String ext) {
454:
455: ext = ext.toLowerCase();
456:
457: ArrayList allowList = (ArrayList) allowedExtensions
458: .get(fileType);
459: ArrayList denyList = (ArrayList) deniedExtensions.get(fileType);
460:
461: if (allowList.size() == 0)
462: if (denyList.contains(ext))
463: return false;
464: else
465: return true;
466:
467: if (denyList.size() == 0)
468: if (allowList.contains(ext))
469: return true;
470: else
471: return false;
472:
473: return false;
474: }
475:
476: private File getCurrentDirectory(HttpServletRequest request) {
477: String typeStr = request.getParameter("Type");
478: String currentFolderStr = request.getParameter("CurrentFolder");
479: String prefix = request.getContextPath() + servletPath;
480: String baseAppDir = baseDir
481: + request.getRequestURI().substring(prefix.length());
482: if (!baseAppDir.endsWith("/"))
483: baseAppDir += "/";
484: String currentPath = baseAppDir + typeStr + currentFolderStr;
485: String currentDirPath = getServletContext().getRealPath(
486: currentPath);
487:
488: File currentDir = new File(currentDirPath);
489: if (!currentDir.exists()) {
490: currentDir.mkdirs();
491: }
492: return currentDir;
493: }
494:
495: private boolean checkAccess(HttpServletRequest request,
496: String appPath) throws ServletException, RemoteException {
497: SessionCache sCache = (SessionCache) request.getSession()
498: .getAttribute(PortalConstants.SESSION_CACHE_ATTRIBUTE);
499: return sCache.getCachedPortalApplicationView(appPath).isAdminable;
500:
501: }
502:
503: }
|