/*
 * $Id: DisplayAsciiServlet.java,v 1.16 2006/12/05 14:11:13 korowa Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 *
 * $Log: DisplayAsciiServlet.java,v $
 * Revision 1.16  2006/12/05 14:11:13  korowa
 * bugfixing
 *
 * Revision 1.15  2006/03/23 11:42:23  marbobo
 * + Bugfix
 *
 * Revision 1.14  2005/09/01 08:32:01  korowa
 * Es werden mehrere URL angeboten, welche direkten Zugriff auf Dateien
 *  und automatisches Anmelden als Gast erlauben.
 *
 * Revision 1.13  2005/03/31 07:02:45  lawern
 * Umstellung auf UTF-8
 *
 * Revision 1.12  2005/03/21 20:24:43  marbobo
 * + parameter "bytes" in Methode accessLog() auf long umgestellt
 *
 * Revision 1.11  2005/02/10 08:12:45  bigmac
 * Content-Disposition Header wird mit Dateinamen belegt
 *
 * Revision 1.10  2004/11/10 15:02:49  koppy
 * Projektweite Überarbeitung von Error-Logs, Stacktraces,..
 *
 * Revision 1.9  2004/10/27 12:47:39  marbobo
 * + Geöffnete ASCII-Files ebenfalls in der History merken
 *
 * Revision 1.8  2004/03/07 13:45:49  bigmac
 * Anpassungen an VKCDocumentTypeSerializer, VKCDocumentClassSerializer, VKCDocumentStatusSerializer
 *
 * Revision 1.7  2004/02/26 13:59:45  koppy
 * ANzeige von www-Kopien
 *
 * Revision 1.6  2003/12/10 14:42:59  koppy
 * Typ von archiveId geändert (Integer -->String)
 *
 * Revision 1.5  2003/12/02 17:14:21  koppy
 * auf lokalen Konverter zurückgestellt
 *
 * Revision 1.4  2003/11/30 13:07:25  koppy
 * Konvertierung entkoppelt
 *
 * Revision 1.3  2003/11/29 22:22:42  koppy
 * Als UnterKlasse vom DisplayServlet realisiert
 *
 * Revision 1.2  2003/09/11 08:28:21  lawern
 * MIME-Type und Konverter-Aufruf geändert.
 *
 * Revision 1.1  2003/09/10 15:38:19  jonyp
 * initial version
 *
  */
package vkc.servlets;

import java.io.File;
import java.util.Collection;
import java.util.Iterator;
import java.util.zip.ZipFile;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import vkc.converter.DocConverter;
import vkc.db.entities.VKCAdditionalDocumentFormat;
import vkc.db.entities.VKCDocument;
import vkc.db.entities.VKCUser;
import vkc.db.serializer.VKCDocumentSerializer;
import vkc.misc.VKCLogManager;
import vkc.util.FileUtils;
import vkc.util.ServletUtils;
import vkc.util.VKCInputStream;
import vkc.util.ZipUtils;
import vkc.view.WebShare;
import vkc.view.form.SysLinkForm;


/**
 * Servlet für die Wiedergabe eines HTML-Dokumentes 
 * aus dem Archiv als ASCII-Stream
 *
 * @author koppy
 */
public class DisplayAsciiServlet extends DisplayServlet {
	private ZipFile zipFile = null;
	 
	/**
	 * Method to process a HTTP Request
	 *
	 * @param request
	 * @param response
	 *
	 * @throws ServletException
	 */
	public void service( HttpServletRequest request, HttpServletResponse response )	throws ServletException {
		String mimeType = "text/plain; charset=utf-8";		
		zipFile = null;
		VKCInputStream tdfStream = null;
		
		try {
			DocQuery docQuery = new DocQuery( request.getRequestURI() );
			VKCDocument doc = VKCDocumentSerializer.retrieveDocument( docQuery.getDocumentId() );

			VKCUser user = ServletUtils.getUser( request );

			if (user == null || !hasReadPermission( doc, request ) ) {
			    
			    VKCLogManager.accessLog(request.getRemoteHost(), null, user == null? null:user.getUser(), 
	    	    request.getContextPath()+SysLinkForm.getDocumentSysLink(docQuery.getDocumentId(), SysLinkForm.LOGINTYPE_NORMAL_USER), 403, doc.getDocSize().longValue());
			    
				response.sendError( HttpServletResponse.SC_FORBIDDEN, docQuery.getFileName() );
				
				return;
			}
			
			// das tdf-format wird geladen
			VKCAdditionalDocumentFormat tdfFormat = getTdfFormat( doc, zipFile, docQuery.getFileName() );				

			if ( tdfFormat == null ) {
			    VKCLogManager.accessLog(request.getRemoteHost(), null, user.getUser(), 
			    request.getContextPath()+ SysLinkForm.getDocumentSysLink(docQuery.getDocumentId(), SysLinkForm.LOGINTYPE_NORMAL_USER), 404, doc.getDocSize().longValue());
			    
				response.sendError( HttpServletResponse.SC_NOT_FOUND, docQuery.getFileName() );

				return;
			}
							
			tdfStream = (VKCInputStream)tdfFormat.getInputStream();
			
            // now we have the tdf input stream, now we can covert it to ascii
            DocConverter converter = DocConverter.createConverter( tdfStream, tdfFormat.getDocTypeId().intValue() );
            converter.convert( tdfStream, null );
			
	        // display the document as ascii 
			displayDocument( converter.getAsciiStream(), mimeType, response, doc, user );
			
			//cClient.close();
			
			updateAccess( doc, request );
			updateHistory( doc, request );
			VKCLogManager.accessLog(request.getRemoteHost(), null, user.getUser(), 
			request.getContextPath()+SysLinkForm.getDocumentSysLink(docQuery.getDocumentId(), SysLinkForm.LOGINTYPE_NORMAL_USER), 200, doc.getDocSize().longValue());
		    
			
		} catch ( Exception ex ) {
			VKCLogManager.errorLog(this, "", ex.getMessage(),ex);
		} finally {
			FileUtils.closeInputStream( tdfStream );

			if ( zipFile != null ) {
				try {
					zipFile.close();
				} catch ( Exception e ) {
					VKCLogManager.errorLog(this, "", e.getMessage(),e);
				}
			}
		}
	}

	/**
	 * Gibt entsprechend der Dokumentenformat ID die Referenz auf das Objekt
	 * von VKCAdditionalDocumentFormat zurück
	 *
	 * @param document Formate dieses Dokumentes
	 *
	 * @return Referenz auf das Objekt von VKCAdditionalDocumentFormat
	 */
	private VKCAdditionalDocumentFormat getTdfFormat( VKCDocument document, ZipFile zipFile, String rootFilename ) {
		Collection formats = document.getAdditionalDocumentFormats();

		for ( Iterator i = formats.iterator(); i.hasNext(); ) {
			VKCAdditionalDocumentFormat f = (VKCAdditionalDocumentFormat) i.next();

			if ( f.getDocTypeId().equals( new Integer( DocConverter.tdf ) ) ) {
				// tdfFormat found						
				boolean zipped = new Integer( 1 ).equals( f.getZipped() );
				String archiveId = f.getArchiveId();
				
				try {
					if ( zipped ) {
						File zipedFile = WebShare.archive.getFile( archiveId );
						zipFile = new ZipFile( zipedFile );
						f.setInputStream( ZipUtils.getUnzippedStream( zipFile, rootFilename ) );
					} else {					
						f.setInputStream( WebShare.archive.getInputStream( archiveId ) );
					}
				} catch ( Exception ex ) {
					VKCLogManager.errorLog( this, "", ex.getMessage(), ex );					
				}
				
				return f;
			}
		}

		return null;

	}
}
