001: /**
002: * $Id: NetFileOpenFileServlet.java,v 1.28 2005/11/30 11:26:34 ss150821 Exp $
003: * Copyright 2002 Sun Microsystems, Inc. All
004: * rights reserved. Use of this product is subject
005: * to license terms. Federal Acquisitions:
006: * Commercial Software -- Government Users
007: * Subject to Standard License Terms and
008: * Conditions.
009: *
010: * Sun, Sun Microsystems, the Sun logo, and Sun ONE
011: * are trademarks or registered trademarks of Sun Microsystems,
012: * Inc. in the United States and other countries.
013: */package com.sun.portal.netfile.servlet.java1;
014:
015: import java.io.*;
016: import com.sun.portal.log.common.PortalLogger;
017: import java.util.*;
018: import java.util.logging.*;
019: import javax.servlet.*;
020: import javax.servlet.http.*;
021: import com.iplanet.sso.SSOToken;
022: import com.iplanet.sso.SSOTokenManager;
023: import com.iplanet.sso.SSOException;
024: import com.iplanet.am.util.SystemProperties;
025:
026: /*
027: * Handles opening & downloading of files/folders. 2 requests are made to the server.
028: * In the first request, store the meta data in the ssotoken based on nfid and in the second
029: * request based on the nfid, get the stored data and write out file contents to
030: * the clients.
031: * First request reads the object stream whereas second request uses plain streams.
032: *
033: */
034:
035: public class NetFileOpenFileServlet extends HttpServlet {
036:
037: private static Logger logger = PortalLogger
038: .getLogger(NetFileOpenFileServlet.class);
039: private static final String CONTENT_TYPE_TEXT_PLAIN = "text/plain; charset=UTF-8";
040: private int bufSize = 8 * 1024;
041: String nfid = "";
042:
043: public void init(ServletConfig config) throws ServletException {
044: super .init(config);
045: }
046:
047: public void doGet(HttpServletRequest req, HttpServletResponse res)
048: throws ServletException, IOException {
049: doGetPost(req, res);
050: }
051:
052: public void doPost(HttpServletRequest req, HttpServletResponse res)
053: throws ServletException, IOException {
054: doGetPost(req, res);
055: }
056:
057: public void doGetPost(HttpServletRequest req,
058: HttpServletResponse res) throws ServletException,
059: IOException {
060:
061: String fileName = null;
062: FileOption file_option = null;
063: NetFileLogManager logManager = null;
064:
065: SSOTokenManager manager = null;
066: SSOToken ssoToken = null;
067:
068: String processingType = null;
069:
070: try {
071: manager = SSOTokenManager.getInstance();
072: ssoToken = manager.createSSOToken(extractSession(req));
073:
074: processingType = getProcessMethod(req);
075:
076: NetFileContext nfContext = new NetFileContextImpl(ssoToken);
077: nfContext.determineHTMLCharset(req);
078: String htmlCharset = nfContext.getHTMLCharset(); // required to set Charset when opening files.
079:
080: if (logManager == null) {
081: logManager = createLogManager(ssoToken);
082: }
083:
084: if (processingType == null || processingType.equals("")) {
085: HashMap parameters = parseHttpRequestForParameters(req);
086:
087: String requestId = getValue(parameters, "nfid");
088: String function = getValue(parameters, "function");
089: String locale = getValue(parameters, "locale");
090:
091: List dataValues = getFromSession(ssoToken, requestId);
092:
093: String encoding = (String) dataValues.get(4);
094:
095: file_option = new FileOption(logManager, encoding);
096:
097: NetFileResource resourceBundle = getUserLocaleBundle(
098: file_option, locale, encoding);
099:
100: fileName = (String) dataValues.get(6);
101: String returnType = getReturnType(fileName,
102: resourceBundle, logManager, ssoToken, encoding);
103:
104: if (function.equals("viewFile")) {
105: setContentTypeForOpen(res, fileName, returnType,
106: htmlCharset);
107: } else if (function.equals("downloadFile")) {
108: setContentTypeForDownload(res, fileName,
109: htmlCharset);
110: }
111:
112: openFile(dataValues, encoding, ssoToken, req, res,
113: resourceBundle, logManager, htmlCharset,
114: function);
115: return;
116:
117: } else if (processingType
118: .equalsIgnoreCase("ObjectProcessor")) {
119: if (!validateSession(res, ssoToken, nfContext)) {
120: processInitialRequest(req, res, null);
121: return;
122: }
123: processInitialRequest(req, res, ssoToken);
124: return;
125: }
126: } catch (NetFileException e) {
127: writeErrorDebug("Exception while fetching files", e);
128: file_option.doError(e.getMessage(file_option
129: .getPlatformLocalisedBundle()));
130: } catch (Exception e) {
131: writeErrorDebug("Exception opening file " + fileName, e);
132: } finally {
133: file_option = null;
134: }
135: }
136:
137: private void processInitialRequest(HttpServletRequest req,
138: HttpServletResponse res, SSOToken ssoToken)
139: throws Exception {
140: PrintWriter pw = null;
141:
142: try {
143: res.setContentType("application/octet-stream");
144: pw = new PrintWriter(new BufferedWriter(
145: new OutputStreamWriter(res.getOutputStream(),
146: "UTF8")));
147:
148: // Assume session invalid, if token is null
149: if (ssoToken == null) {
150: pw.println("ERROR: Unable to Open File.");
151: pw.close();
152: pw = null;
153: return;
154: }
155:
156: Hashtable requestData = unmarshallRequestData(req);
157: // add to the session
158: addToSession(ssoToken, requestData);
159:
160: pw.println("Success");
161: pw.close();
162: pw = null;
163:
164: } catch (NetFileException nfe) {
165: writeErrorDebug("Failed processing initial request - "
166: + nfe.toString(), null);
167: }
168: }
169:
170: private Hashtable unmarshallRequestData(HttpServletRequest request)
171: throws Exception {
172: Hashtable returnData = new Hashtable();
173:
174: ObjectInputStream objectInputStream = new ObjectInputStream(request
175: .getInputStream());
176: Hashtable requestData = (Hashtable) objectInputStream.readObject();
177: Enumeration enum = requestData.keys();
178:
179: String key = "";
180: Object value = null;
181: while (enum.hasMoreElements()) {
182: key = (String) (enum.nextElement());
183: value = requestData.get(key);
184: if (value != null) {
185: returnData.put(key, value);
186: }
187: }
188:
189: return returnData;
190: }
191:
192: private String getValue(HashMap reqParams, String key)
193: throws Exception {
194: Object o = reqParams.get(key);
195: if (o == null) {
196: return null;
197: } else {
198: String sa_value = (String) o;
199: return sa_value;
200: }
201: }
202:
203: private String getProcessMethod(HttpServletRequest request) {
204: return request.getHeader("NetFileOpenFileProcessMethod");
205: }
206:
207: private NetFileResource getUserLocaleBundle(FileOption file_option,
208: String s_locale, String s_machine_encoding)
209: throws Exception {
210: NetFileResource nfr_user_locale_i18n_bucket = null;
211: if (s_locale == null) {
212: nfr_user_locale_i18n_bucket = file_option
213: .getPlatformLocalisedBundle();
214: } else {
215: nfr_user_locale_i18n_bucket = NetFileResource.getInstance(
216: FileOption.APPLET_PROPERTIES, s_locale);
217: }
218: return nfr_user_locale_i18n_bucket;
219: }
220:
221: private String getReturnType(String fileName,
222: NetFileResource nfr_user_locale_i18n_bucket,
223: NetFileLogManager logManager, SSOToken token,
224: String s_machine_encoding) throws Exception {
225: int i_index_of_dot = fileName.lastIndexOf('.');
226: String suffix = fileName.substring(i_index_of_dot + 1, fileName
227: .length());
228: FileOption file_option = new FileOption(logManager,
229: s_machine_encoding);
230: file_option.setSSOToken(token);
231: return file_option.getFileContentType(suffix,
232: nfr_user_locale_i18n_bucket);
233: }
234:
235: private void setContentTypeForOpen(HttpServletResponse res,
236: String filename, String returntype, String HTMLcharsetname)
237: throws Exception {
238: /*
239: * Set the Charset of the content based on client's locale.
240: * It should not be hardcoded to "UTF8" encoding , in which case
241: * multibyte characters will be garbled when they are opened( bug - 4735316)
242: */
243: if ((returntype == null) || (returntype.trim().length() == 0))
244: res.setContentType("application/octet-stream; charset="
245: + HTMLcharsetname);
246: else
247: res.setContentType(returntype.trim() + "; charset="
248: + HTMLcharsetname);
249:
250: res.setHeader("Content-Disposition", "filename=" + filename);
251: }
252:
253: private void setContentTypeForDownload(HttpServletResponse res,
254: String filename, String HTMLcharsetname) {
255: res.setHeader("Content-Type",
256: "application/octet-stream; charset=" + HTMLcharsetname);
257: res.setHeader("Content-Disposition", "attachment; filename="
258: + filename);
259: res.setHeader("Content-Transfer-Encoding", HTMLcharsetname);
260: }
261:
262: private void addToSession(SSOToken ssoToken, Hashtable data)
263: throws NetFileException {
264: StringBuffer sb = new StringBuffer();
265:
266: String username = (String) data.get("username");
267: String passwrd = (String) data.get("pass");
268: String machnam = (String) data.get("machine");
269: String machtyp = (String) data.get("type");
270: String encoding = (String) data.get("machine_encoding");
271: String VMSnam = (String) data.get("VMS");
272: String mainfilename = (String) data.get("filename");
273: String dir = (String) data.get("dir");
274: String domainname = (String) data.get("domain");
275:
276: nfid = (String) data.get("nfid");
277:
278: sb.append(username).append('\n');
279: if ((passwrd == null) || (passwrd.equals("")))
280: sb.append("").append('\n');
281: else
282: sb.append(passwrd).append('\n');
283: sb.append(machnam).append('\n');
284: sb.append(machtyp).append('\n');
285: sb.append(encoding).append('\n');
286: sb.append(VMSnam).append('\n');
287: sb.append(mainfilename).append('\n');
288:
289: if ((dir == null) || (dir.equals("")))
290: sb.append("").append('\n');
291: else
292: sb.append(dir).append('\n');
293:
294: if ((domainname == null) || (domainname.equals("")))
295: sb.append("").append('\n');
296: else
297: sb.append(domainname).append('\n');
298:
299: try {
300: ssoToken.setProperty(nfid, sb.toString());
301: } catch (SSOException ssoe) {
302: throw new NetFileException(
303: "Data could not be added to the session. Cannot proceed further with open/download");
304: }
305: }
306:
307: private List getFromSession(SSOToken ssoToken, String szRequestID)
308: throws NetFileException {
309:
310: String value = null;
311:
312: try {
313: value = ssoToken.getProperty(szRequestID);
314: } catch (SSOException ssoe) {
315: writeErrorDebug(
316: "SSOException in getting the stored property", ssoe);
317: throw new NetFileException(
318: "Exception occured in retrieving data from the session. Cannot proceed further with open/download");
319: }
320:
321: if (value == null)
322: throw new NetFileException(
323: "Data could not be retrieved from the session. Cannot proceed further with open/download");
324:
325: List dataVals = new ArrayList();
326:
327: if (value.equals("")) {
328: throw new NetFileException(
329: "Data could not be retrieved from the session. Cannot proceed further with open/download");
330: //TBD: Get the string from the resource Bundle.
331: } else {
332: int beginIndex = 0, curIndex = 0;
333: while (true) {
334: curIndex = value.indexOf('\n', beginIndex);
335: if (curIndex == -1) {
336: break;
337: }
338: String dataElement = value.substring(beginIndex,
339: curIndex);
340: dataVals.add(dataElement);
341: beginIndex = curIndex + 1;
342: }
343: }
344: return dataVals;
345: }
346:
347: void openFile(List dataValues, String encoding, SSOToken ssoToken,
348: HttpServletRequest req, HttpServletResponse res,
349: NetFileResource nfRes, NetFileLogManager logManager,
350: String htmlCharset, String szFunction)
351: throws NetFileException {
352:
353: NetWareFile nwfile = null;
354: FtpFile gff = null;
355: NfsFile gfs = null;
356: XFileInterface gpc = null;
357: InputStream instream;
358: OutputStream outstream;
359:
360: String username = (String) dataValues.get(0);
361: String password = (String) dataValues.get(1);
362: String machine = (String) dataValues.get(2);
363: String machineType = (String) dataValues.get(3);
364: String share = (String) dataValues.get(5);
365: String mainFileName = (String) dataValues.get(6);
366: String directory = (String) dataValues.get(7);
367: String domain = (String) dataValues.get(8);
368: String functionName = "";
369:
370: if (szFunction.equals("viewFile")) {
371: functionName = nfRes.getString("openFileLog");
372: } else if (szFunction.equals("downloadFile")
373: || szFunction.equals("downloadFolder")) {
374: functionName = nfRes.getString("downloadFileLog");
375: }
376:
377: try {
378:
379: if (machineType.indexOf("NETWARE", 0) >= 0) {
380: nwfile = new NetWareFile(logManager, encoding);
381: instream = nwfile.getInputFTPStream(username, password,
382: machine, share, mainFileName, directory);
383: outstream = res.getOutputStream();
384: readWriteBytes(instream, outstream);
385:
386: } else if ((machineType.indexOf("WIN", 0) >= 0)
387: || (machineType.indexOf("NT", 0) >= 0)) {
388: gpc = XFileFactory.getInstance().newXFileInstance(
389: logManager, encoding, ssoToken);
390:
391: instream = gpc.getInputStream(username, password,
392: domain, machine, share, directory,
393: mainFileName, nfRes);
394: outstream = res.getOutputStream();
395: readWriteBytes(instream, outstream);
396:
397: } else if (machineType.indexOf("FTP", 0) >= 0) {
398: gff = new FtpFile(logManager, encoding);
399: instream = gff.getInputFTPStream(username, password,
400: machine, share, mainFileName, directory);
401: outstream = res.getOutputStream();
402: readWriteBytes(instream, outstream);
403: gff.closeFtpFile();
404:
405: } else if (machineType.indexOf("NFS", 0) >= 0) {
406: gfs = new NfsFile(logManager, encoding);
407: instream = gfs.getNFSInputStream(username, password,
408: share, machine, mainFileName, directory);
409: outstream = res.getOutputStream();
410: readWriteBytes(instream, outstream);
411: }
412:
413: doLog(logManager, nfRes.getString("successLog.1",
414: new Object[] { functionName, mainFileName,
415: username, machine, share, directory }));
416: return;
417:
418: } catch (NetFileException nfe) {
419: writeErrorDebug("Problem getting file - ", nfe);
420: doLog(logManager, nfRes.getString("failureLog.1",
421: new Object[] { functionName, mainFileName,
422: username, machine, share, directory }));
423:
424: try {
425: if (szFunction.equals("downloadFolder")) {
426: /*
427: * send error message as bytes when downloading folders.
428: */
429: writeErrorBytes("NetFileOpenFileError:"
430: + nfe.getMessage(), res);
431: }
432: writeErrorHTML(res, htmlCharset, nfRes, nfe
433: .getMessage(), mainFileName, szFunction);
434: } catch (IOException ioe) {
435: return;
436: }
437: } catch (Exception e) {
438: writeErrorDebug("Problem getting file -- ", e);
439: doLog(logManager, nfRes.getString("failureLog.1",
440: new Object[] { functionName, mainFileName,
441: username, machine, share, directory }));
442:
443: try {
444: if (szFunction.equals("downloadFolder")) {
445: writeErrorBytes("NetFileOpenFileError:"
446: + e.getMessage(), res);
447: }
448: writeErrorHTML(res, htmlCharset, nfRes, nfRes
449: .getString("nofs.1"), mainFileName, szFunction);
450: //nofs.1 - Exception occured in obtaining the file. Unable to open/download file.
451: } catch (IOException ioe) {
452: return;
453: }
454: }
455: }
456:
457: private void readWriteBytes(InputStream instream,
458: OutputStream outstream) throws IOException {
459: int len;
460: byte[] buf = new byte[bufSize];
461: try {
462: while ((len = instream.read(buf)) > -1) {
463: outstream.write(buf, 0, len);
464: }
465: } catch (IOException ioe) {
466: ioe.printStackTrace();
467: throw ioe;
468: } finally {
469: try {
470: if (outstream != null)
471: outstream.close();
472: if (instream != null)
473: instream.close();
474: } catch (IOException ioe) {
475: }
476: }
477: }
478:
479: private java.util.HashMap parseHttpRequestForParameters(
480: HttpServletRequest req) throws Exception {
481: String szQueryString = req.getQueryString();
482: StringTokenizer stTokens = new StringTokenizer(szQueryString,
483: "&");
484: HashMap paramMap = new HashMap();
485: NetFileURLDecoder decoder = new NetFileURLDecoder();
486:
487: while (stTokens.hasMoreTokens()) {
488: String token = stTokens.nextToken();
489: int index = token.indexOf('=');
490:
491: if (index > 0) {
492: String key = token.substring(0, index);
493: index++;
494: String value = "";
495: if (index < token.length()) {
496: value = token.substring(index, token.length());
497: }
498: if (value != null)
499: value = decoder.decode(value, "UTF8");
500:
501: paramMap.put(key, value);
502: }
503: }
504: return paramMap;
505: }
506:
507: private boolean validateSession(HttpServletResponse res,
508: SSOToken ssoToken, NetFileContext nfContext) {
509: PrintWriter out = null;
510: try {
511: if (nfContext.isSessionValid(ssoToken)
512: && nfContext.isExecutable(ssoToken)) {
513: return true;
514: } else {
515: if (out == null) {
516: res
517: .setContentType(NetFileOpenFileServlet.CONTENT_TYPE_TEXT_PLAIN);
518: out = new PrintWriter(new BufferedWriter(
519: new OutputStreamWriter(res
520: .getOutputStream(), "UTF8")));
521: }
522: out
523: .println("ERROR: Session is Invalid or no policy to execute ");
524: out.close();
525: return false;
526: }
527: } catch (Exception e) {
528: if (out == null) {
529: try {
530: res
531: .setContentType(NetFileOpenFileServlet.CONTENT_TYPE_TEXT_PLAIN);
532: out = new PrintWriter(new BufferedWriter(
533: new OutputStreamWriter(res
534: .getOutputStream(), "UTF8")));
535: } catch (Exception e1) {
536: return false;
537: }
538: }
539: out.println("ERROR:" + e.getMessage());
540: writeErrorDebug(
541: "General Exception in NetFileOpenFileServlet", e);
542: return false;
543: }
544: }
545:
546: private String extractSession(HttpServletRequest req) {
547: String session = null;
548: session = req.getHeader("nfid");
549: Cookie[] cookie = req.getCookies();
550:
551: if (cookie != null) {
552: for (int i = 0; i < cookie.length; i++) {
553: if (cookie[i].getName().equalsIgnoreCase(
554: SystemProperties.get(
555: "com.iplanet.am.cookie.name",
556: "iPlanetDirectoryPro"))) {
557: session = cookie[i].getValue();
558: if (NetFileServlet.isEncoded)
559: session = java.net.URLDecoder.decode(session);
560: }
561: }
562: }
563: return session;
564: }
565:
566: private PrintWriter getWriter(HttpServletResponse res,
567: String charset) throws IOException {
568: if (charset == null) {
569: res.setContentType("text/html");
570: return res.getWriter();
571: } else {
572: res.setContentType("text/html; charset=" + charset);
573: return new PrintWriter(new BufferedWriter(
574: new OutputStreamWriter(res.getOutputStream(),
575: charset)));
576: }
577: }
578:
579: private void writeErrorHTML(HttpServletResponse res,
580: String htmlCharset, NetFileResource nfRes, String msg,
581: String mainfilename, String szFunction) throws IOException {
582: PrintWriter out = getWriter(res, htmlCharset);
583: res.setHeader("Cache-Control", "max-age=0");
584:
585: String bgcolors = nfRes.getString("bgcolorS");
586: String textcolors = nfRes.getString("textcolorS");
587:
588: out.println("<html><head><title>" + nfRes.getString("nftitle")
589: + "</title></head>");
590: out.print("<body text='");
591: out.print(textcolors);
592: out.print("'");
593: out.print(" bgcolor='");
594: out.print(bgcolors);
595: out.print("'>");
596: out.println("<h2>" + nfRes.getString("nftitle") + "</h2>");
597: out.print("<p><b>" + nfRes.getString("nfmsg.1"));
598: if (szFunction.equals("downloadFile"))
599: out.print(' ' + nfRes.getString("nofs.3") + ' '
600: + mainfilename);
601: else if (szFunction.equals("viewFile"))
602: out.print(' ' + nfRes.getString("nofs.2") + ' '
603: + mainfilename);
604: else if (szFunction.equals("ERROR:"))
605: out.print(' ' + nfRes.getString("nfs.1") + ' ');
606: out.println("</FONT> <br><br>");
607: out.println(msg + " </b></p>");
608: out.println("</html>");
609: out.close();
610: }
611:
612: private void writeErrorBytes(String msg, HttpServletResponse res) {
613: OutputStream os = null;
614: try {
615: res.setHeader("Content-Type", "text/html");
616: os = res.getOutputStream();
617: byte[] byteMsg = msg.getBytes("ISO-8859-1");
618: os.write(byteMsg);
619: } catch (IOException ioe) {
620: writeErrorDebug("Exception while getting output stream-",
621: ioe);
622: } finally {
623: try {
624: if (os != null)
625: os.close();
626: } catch (IOException ioe) {
627: writeErrorDebug(
628: "Exception while closing output stream-", ioe);
629: }
630: }
631: }
632:
633: private void writeErrorDebug(String szError, Throwable e) {
634: if (e != null)
635: // logger.log(Level.SEVERE, szError, e);
636: logger.log(Level.SEVERE, "PSSRNF_CSPNSJ1135");
637: else
638: // logger.severe(szError);
639: logger.severe("PSSRNF_CSPNSJ1136");
640: }
641:
642: private NetFileLogManager createLogManager(SSOToken ssoToken) {
643: String tokenId = ssoToken.getTokenID().toString();
644: try {
645: Object obj = NetFileServlet.logManagerCache.get(tokenId);
646: if (obj == null) {
647: NetFileLogManager logMgr = new NetFileLogManager(
648: ssoToken);
649: NetFileServlet.logManagerCache.put(tokenId, logMgr);
650: return logMgr;
651: } else {
652: return (NetFileLogManager) obj;
653: }
654: } catch (Exception e) {
655: writeErrorDebug(
656: "Unable to create LogManager for ssoToken - "
657: + tokenId, e);
658: return null;
659: }
660: }
661:
662: private void doLog(NetFileLogManager logManager, String msg) {
663: if (logManager == null) {
664: writeErrorDebug("LogManager is null", null);
665: return;
666: }
667: logManager.doLog(msg);
668: }
669:
670: }
|