0001: /**
0002: * @author Tobias Schulz-Hess (sourceforge@schulz-hess.de)
0003: * 12/04/2003 20:33:31
0004: */package vqwiki.servlets;
0005:
0006: import java.io.BufferedInputStream;
0007: import java.io.BufferedOutputStream;
0008: import java.io.ByteArrayOutputStream;
0009: import java.io.File;
0010: import java.io.FileInputStream;
0011: import java.io.FileNotFoundException;
0012: import java.io.FileOutputStream;
0013: import java.io.IOException;
0014: import java.io.InputStream;
0015: import java.io.OutputStream;
0016: import java.io.StringReader;
0017: import java.text.DateFormat;
0018: import java.util.ArrayList;
0019: import java.util.Calendar;
0020: import java.util.Collection;
0021: import java.util.HashMap;
0022: import java.util.Iterator;
0023: import java.util.List;
0024: import java.util.ResourceBundle;
0025: import java.util.StringTokenizer;
0026: import java.util.Vector;
0027: import java.util.jar.JarEntry;
0028: import java.util.jar.JarOutputStream;
0029: import java.util.zip.ZipEntry;
0030: import java.util.zip.ZipOutputStream;
0031:
0032: import javax.servlet.ServletContext;
0033: import javax.servlet.ServletException;
0034: import javax.servlet.http.HttpServletRequest;
0035: import javax.servlet.http.HttpServletResponse;
0036:
0037: import org.apache.log4j.Logger;
0038:
0039: import vqwiki.Change;
0040: import vqwiki.ChangeLog;
0041: import vqwiki.Environment;
0042: import vqwiki.PseudoTopicHandler;
0043: import vqwiki.SearchEngine;
0044: import vqwiki.SearchResultEntry;
0045: import vqwiki.Topic;
0046: import vqwiki.WikiBase;
0047: import vqwiki.servlets.beans.SitemapLineBean;
0048: import vqwiki.utils.JSPUtils;
0049: import vqwiki.utils.Utilities;
0050: import TemplateEngine.Template;
0051:
0052: /*
0053: * Very Quick Wiki - WikiWikiWeb clone Copyright (C) 2001-2002 Gareth Cronin
0054: *
0055: * This program is free software; you can redistribute it and/or modify it under
0056: * the terms of the latest version of the GNU Lesser General Public License as
0057: * published by the Free Software Foundation;
0058: *
0059: * This program is distributed in the hope that it will be useful, but WITHOUT
0060: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
0061: * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
0062: * details.
0063: *
0064: * You should have received a copy of the GNU Lesser General Public License
0065: * along with this program (gpl.txt); if not, write to the Free Software
0066: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
0067: */
0068:
0069: /**
0070: * This servlet exports all pages as static HTML-pages. You can add a parameter
0071: * "virutal-wiki", which then generates the HTML pages on a particular virtual
0072: * wiki.
0073: * <p>
0074: *
0075: * @author Tobias Schulz-Hess (sourceforge@schulz-hess.de)
0076: */
0077: public class ExportHTMLServlet extends LongLastingOperationServlet {
0078:
0079: /** The serial UID of this servlet */
0080: private static final long serialVersionUID = "$Id: ExportHTMLServlet.java 680 2006-05-27 16:17:18Z wrh2 $"
0081: .hashCode();
0082: private File tempFile;
0083: private String tempdir;
0084: /** Logging */
0085: private static final Logger logger = Logger
0086: .getLogger(ExportHTMLServlet.class);
0087: private String virtualWiki = null;
0088: private String imageDir = null;
0089: private Exception exception;
0090:
0091: /**
0092: * Handle post request. Generate a node file and send it back as text.
0093: *
0094: * @param request
0095: * The current http request
0096: * @param response
0097: * What the servlet will send back as response
0098: *
0099: * @throws ServletException
0100: * If something goes wrong during servlet execution
0101: * @throws IOException
0102: * If the output stream cannot be accessed
0103: *
0104: */
0105: protected void doPost(HttpServletRequest request,
0106: HttpServletResponse response) throws ServletException,
0107: IOException {
0108: if (virtualWiki == null) {
0109: try {
0110: virtualWiki = Utilities.extractVirtualWiki(request);
0111: } catch (Exception e) {
0112: e.printStackTrace();
0113: virtualWiki = WikiBase.DEFAULT_VWIKI;
0114: }
0115: ServletContext ctx = getServletContext();
0116: try {
0117: File tmpDir = (File) ctx
0118: .getAttribute("javax.servlet.context.tempdir");
0119: tempdir = tmpDir.getPath();
0120: } catch (Throwable t) {
0121: logger
0122: .warn(
0123: "'javax.servlet.context.tempdir' attribute undefined or invalid, using java.io.tmpdir",
0124: t);
0125: tempdir = System.getProperty("java.io.tmpdir");
0126: }
0127: }
0128: imageDir = getServletContext().getRealPath("/images");
0129: super .doPost(request, response);
0130: }
0131:
0132: /**
0133: * Do the long lasting operation
0134: */
0135: public void run() {
0136: Environment en = Environment.getInstance();
0137: exception = null;
0138: BufferedOutputStream fos = null;
0139: try {
0140: tempFile = File.createTempFile("htmlexport", "zip",
0141: new File(tempdir));
0142: fos = new BufferedOutputStream(new FileOutputStream(
0143: tempFile));
0144: // bos = new ByteArrayOutputStream();
0145: ZipOutputStream zipout = new ZipOutputStream(fos);
0146: zipout.setMethod(ZipOutputStream.DEFLATED);
0147: addAllTopics(en, zipout, 0, 80);
0148: addAllSpecialPages(en, zipout, 80, 10);
0149: addAllUploadedFiles(en, zipout, 90, 5);
0150: addAllImages(en, zipout, 95, 5);
0151: zipout.close();
0152: logger.debug("Closing zip and sending to user");
0153: } catch (Exception e) {
0154: logger.fatal("Exception", e);
0155: exception = e;
0156: }
0157: progress = PROGRESS_DONE;
0158: }
0159:
0160: /**
0161: *
0162: */
0163: private void addAllTopics(Environment en, ZipOutputStream zipout,
0164: int progressStart, int progressLength) throws Exception,
0165: IOException {
0166: HashMap containingTopics = new HashMap();
0167: if (virtualWiki == null || virtualWiki.length() < 1) {
0168: virtualWiki = WikiBase.DEFAULT_VWIKI;
0169: }
0170: SearchEngine sedb = WikiBase.getInstance()
0171: .getSearchEngineInstance();
0172: Collection all = sedb.getAllTopicNames(virtualWiki);
0173: String defaultTopic = en
0174: .getStringSetting(Environment.PROPERTY_DEFAULT_TOPIC);
0175: if (defaultTopic == null || defaultTopic.length() < 2) {
0176: defaultTopic = "StartingPoints";
0177: }
0178: Template tpl;
0179: logger.debug("Logging Wiki " + virtualWiki + " starting at "
0180: + defaultTopic);
0181: List ignoreTheseTopicsList = new ArrayList();
0182: ignoreTheseTopicsList.add("WikiSearch");
0183: ignoreTheseTopicsList.add("RecentChanges");
0184: ignoreTheseTopicsList.add("WikiSiteMap");
0185: ignoreTheseTopicsList.add("WikiSiteMapIE");
0186: ignoreTheseTopicsList.add("WikiSiteMapNS");
0187: Iterator allIterator = all.iterator();
0188: int count = 0;
0189: while (allIterator.hasNext()) {
0190: progress = Math
0191: .min(
0192: progressStart
0193: + (int) ((double) count
0194: * (double) progressLength / (double) all
0195: .size()), 99);
0196: count++;
0197: String topicname = (String) allIterator.next();
0198: try {
0199: addTopicToZip(en, zipout, containingTopics, sedb,
0200: defaultTopic, ignoreTheseTopicsList, topicname);
0201: } catch (Exception e) {
0202: logger.fatal("Exception while adding a topic ", e);
0203: }
0204: }
0205: logger.debug("Done adding all topics.");
0206: // now build sitemap
0207: List sitemapLines = new ArrayList();
0208: Vector visitedPages = new Vector();
0209: List startingList = new ArrayList(1);
0210: startingList.add(SitemapServlet.LAST_IN_LIST);
0211: parsePages(defaultTopic, containingTopics, startingList, "1",
0212: sitemapLines, visitedPages);
0213: // create sitemap view
0214: StringBuffer ieView = new StringBuffer();
0215: StringBuffer nsView = new StringBuffer();
0216: // IE view
0217: Vector childNodes = new Vector();
0218: // ieView.append(" <b><f:message key="sitemap.head"><f:param
0219: // value="${vwiki.name}"/><f:param
0220: // value="${vwiki.numpages}"/></f:message></b>\n");
0221: for (Iterator lineIterator = sitemapLines.iterator(); lineIterator
0222: .hasNext();) {
0223: SitemapLineBean line = (SitemapLineBean) lineIterator
0224: .next();
0225: if (childNodes.size() > 0) {
0226: String myGroup = line.getGroup();
0227: String lastNode = (String) childNodes.get(childNodes
0228: .size() - 1);
0229: while (myGroup.length() <= (lastNode.length() + 1)
0230: && childNodes.size() > 0) {
0231: ieView.append("</div><!-- " + lastNode + "-->");
0232: childNodes.remove(childNodes.size() - 1);
0233: if (childNodes.size() > 0) {
0234: lastNode = (String) childNodes.get(childNodes
0235: .size() - 1);
0236: }
0237: }
0238: }
0239: ieView.append("<div id=\"node_" + line.getGroup()
0240: + "_Parent\" class=\"parent\">");
0241: for (Iterator levelsIterator = line.getLevels().iterator(); levelsIterator
0242: .hasNext();) {
0243: String level = (String) levelsIterator.next();
0244: if (line.isHasChildren()) {
0245: if ("x".equalsIgnoreCase(level)) {
0246: ieView
0247: .append("<a href=\"#\" onClick=\"expandIt('node_"
0248: + line.getGroup()
0249: + "_'); return false;\"><img src=\"images/x-.png\" widht=\"30\" height=\"30\" align=\"top\" name=\"imEx\" border=\"0\"></a>");
0250: } else if ("e".equalsIgnoreCase(level)) {
0251: ieView
0252: .append("<a href=\"#\" onClick=\"expandItE('node_"
0253: + line.getGroup()
0254: + "_'); return false;\"><img src=\"images/e-.png\" widht=\"30\" height=\"30\" align=\"top\" name=\"imEx\" border=\"0\"></a>");
0255: } else {
0256: ieView
0257: .append("<img src=\"images/"
0258: + level
0259: + ".png\" widht=\"30\" height=\"30\" align=\"top\">");
0260: }
0261: } else {
0262: ieView
0263: .append("<img src=\"images/"
0264: + level
0265: + ".png\" widht=\"30\" height=\"30\" align=\"top\">");
0266: }
0267: }
0268: ieView.append("<a href=\"" + safename(line.getTopic())
0269: + ".html\">" + line.getTopic() + "</a></div>\n");
0270: if (line.isHasChildren()) {
0271: ieView.append("<div id=\"node_" + line.getGroup()
0272: + "_Child\" class=\"child\">");
0273: childNodes.add(line.getGroup());
0274: }
0275: }
0276: for (int i = childNodes.size() - 1; i >= 0; i--) {
0277: ieView.append("</div><!-- " + (String) childNodes.get(i)
0278: + "-->");
0279: }
0280: // Netscape or non scripting
0281: nsView
0282: .append("<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n");
0283: // nsView.append(" <tr><td><b><f:message key="sitemap.head"><f:param
0284: // value="${vwiki.name}"/><f:param
0285: // value="${vwiki.numpages}"/></f:message></b></td></tr>\n");
0286: for (Iterator lineIterator = sitemapLines.iterator(); lineIterator
0287: .hasNext();) {
0288: SitemapLineBean line = (SitemapLineBean) lineIterator
0289: .next();
0290: nsView.append("<tr><td height=\"30\" valign=\"top\">");
0291: for (Iterator levelsIterator = line.getLevels().iterator(); levelsIterator
0292: .hasNext();) {
0293: String level = (String) levelsIterator.next();
0294: nsView
0295: .append("<img src=\"images/"
0296: + level
0297: + ".png\" widht=\"30\" height=\"30\" align=\"top\">");
0298: }
0299: nsView
0300: .append("<a href=\"" + safename(line.getTopic())
0301: + ".html\">" + line.getTopic()
0302: + "</a></td></tr>\n");
0303: }
0304: nsView.append("</table>\n");
0305: // add sitemap to zip
0306: tpl = getTemplateFilledWithContent("sitemap");
0307: tpl.setFieldGlobal("TOPICNAME", "WikiSiteMap");
0308: ZipEntry entry = new ZipEntry("WikiSiteMap.html");
0309: StringReader strin = new StringReader(Utilities.replaceString(
0310: tpl.getContent(), "@@NSVIEW@@", nsView.toString()));
0311: // Add new entry to zip archive
0312: zipout.putNextEntry(entry);
0313: // Add data to new entry
0314: int read;
0315: while ((read = strin.read()) != -1) {
0316: zipout.write(read);
0317: }
0318: zipout.closeEntry(); // Close this entry
0319: zipout.flush();
0320: tpl = getTemplateFilledWithContent("sitemap_ie");
0321: tpl.setFieldGlobal("TOPICNAME", "WikiSiteMap");
0322: entry = new ZipEntry("WikiSiteMapIE.html");
0323: strin = new StringReader(Utilities.replaceString(tpl
0324: .getContent(), "@@IEVIEW@@", ieView.toString()));
0325: // Add new entry to zip archive
0326: zipout.putNextEntry(entry);
0327: // Add data to new entry
0328: while ((read = strin.read()) != -1) {
0329: zipout.write(read);
0330: }
0331: zipout.closeEntry(); // Close this entry
0332: zipout.flush();
0333: tpl = getTemplateFilledWithContent("sitemap_ns");
0334: tpl.setFieldGlobal("TOPICNAME", "WikiSiteMap");
0335: entry = new ZipEntry("WikiSiteMapNS.html");
0336: strin = new StringReader(Utilities.replaceString(tpl
0337: .getContent(), "@@NSVIEW@@", nsView.toString()));
0338: // Add new entry to zip archive
0339: zipout.putNextEntry(entry);
0340: // Add data to new entry
0341: while ((read = strin.read()) != -1) {
0342: zipout.write(read);
0343: }
0344: zipout.closeEntry(); // Close this entry
0345: zipout.flush();
0346: }
0347:
0348: /**
0349: * Add a single topic to the Zip stream
0350: *
0351: * @param en The current environment
0352: * @param zipout The Zip to add the topic to
0353: * @param containingTopics List of all containing topic
0354: * @param sedb The search engine
0355: * @param defaultTopic The default topics
0356: * @param ignoreTheseTopicsList Ignore these topics
0357: * @param topicname The name of this topic
0358: * @throws Exception
0359: * @throws IOException
0360: */
0361: private void addTopicToZip(Environment en, ZipOutputStream zipout,
0362: HashMap containingTopics, SearchEngine sedb,
0363: String defaultTopic, List ignoreTheseTopicsList,
0364: String topicname) throws Exception, IOException {
0365: WikiBase wb = WikiBase.getInstance();
0366: Template tpl;
0367: // FIXME: hard coding is evil
0368: tpl = new Template(this .getServletContext().getRealPath(
0369: "/WEB-INF/classes/export2html/mastertemplate.tpl"));
0370: tpl.setFieldGlobal("VERSION", Environment.WIKI_VERSION);
0371: StringBuffer oneline = new StringBuffer();
0372: if (!ignoreTheseTopicsList.contains(topicname)) {
0373: oneline.append(topicname);
0374: tpl.setFieldGlobal("TOPICNAME", topicname);
0375: Topic topicObject = new Topic(topicname);
0376: logger.debug("Adding topic " + topicname);
0377: String author = null;
0378: java.util.Date lastRevisionDate = null;
0379: if (Environment.getInstance().isVersioningOn()) {
0380: lastRevisionDate = topicObject
0381: .getMostRecentRevisionDate(virtualWiki);
0382: author = topicObject.getMostRecentAuthor(virtualWiki);
0383: if (author != null || lastRevisionDate != null) {
0384: tpl.setField("SHOWVERSIONING1", "-->");
0385: if (author != null)
0386: tpl.setField("AUTHOR", author);
0387: if (lastRevisionDate != null)
0388: tpl.setField("MODIFYDATE", Utilities
0389: .formatDate(lastRevisionDate));
0390: tpl.setField("SHOWVERSIONING2", "<!--");
0391: }
0392: }
0393: // get content
0394: StringBuffer content = new StringBuffer();
0395: // FIXME (PARSER_TEMP) - update after parser conversion is complete
0396: content
0397: .append(wb
0398: .readCooked(
0399: virtualWiki,
0400: topicname,
0401: en
0402: .getStringSetting(Environment.PROPERTY_FORMAT_LEXER),
0403: en
0404: .getStringSetting(Environment.PROPERTY_LAYOUT_LEXER),
0405: "vqwiki.lex.HTMLLinkLex", true));
0406: // handle redirects
0407: String redirect = "redirect:";
0408: if (content.toString().startsWith(redirect)) {
0409: StringBuffer link = new StringBuffer(content.toString()
0410: .substring(redirect.length()).trim());
0411: // remove all tags:
0412: while (link.toString().indexOf("<") != -1) {
0413: int startpos = link.toString().indexOf("<");
0414: int endpos = link.toString().indexOf(">");
0415: if (endpos == -1) {
0416: endpos = link.length();
0417: } else {
0418: endpos++;
0419: }
0420: link.delete(startpos, endpos);
0421: }
0422: link = new StringBuffer(
0423: safename(link.toString().trim()));
0424: link = link.append(".html");
0425: String nl = System.getProperty("line.separator");
0426: tpl.setFieldGlobal("REDIRECT", "<script>" + nl
0427: + "location.replace(\"" + link.toString()
0428: + "\");" + nl + "</script>" + nl
0429: + "<meta http-equiv=\"refresh\" content=\"1; "
0430: + link.toString() + "\">" + nl);
0431: } else {
0432: tpl.setFieldGlobal("REDIRECT", "");
0433: }
0434: // add referrer pages
0435: Collection searchresult = sedb.find(virtualWiki, topicname,
0436: false);
0437: if (searchresult != null && searchresult.size() > 0) {
0438: Iterator it = searchresult.iterator();
0439: String divider = "";
0440: StringBuffer backlinks = new StringBuffer();
0441: for (; it.hasNext();) {
0442: SearchResultEntry result = (SearchResultEntry) it
0443: .next();
0444: if (!result.getTopic().equals(topicname)) {
0445: backlinks.append(divider);
0446: backlinks.append("<a href=\"");
0447: backlinks.append(safename(result.getTopic()));
0448: backlinks.append(".html\">");
0449: backlinks.append(result.getTopic());
0450: backlinks.append("</a>");
0451: divider = " | ";
0452: // add this topic to the containingTopics Map:
0453: List l = (List) containingTopics.get(result
0454: .getTopic());
0455: if (l == null) {
0456: l = new ArrayList();
0457: }
0458: if (!l.contains(topicname)) {
0459: l.add(topicname);
0460: }
0461: containingTopics.put(result.getTopic(), l);
0462: }
0463: }
0464: if (backlinks.length() > 0) {
0465: ResourceBundle messages = ResourceBundle.getBundle(
0466: "ApplicationResources", locale);
0467: content
0468: .append("<br /><br /><span class=\"backlinks\">");
0469: content.append(topicname);
0470: content.append(" ");
0471: content.append(messages
0472: .getString("topic.ismentionedon"));
0473: content.append(" ");
0474: content.append(backlinks.toString());
0475: content.append("</span>");
0476: }
0477: }
0478: tpl.setFieldGlobal("CONTENTS", content.toString());
0479: ZipEntry entry = new ZipEntry(safename(topicname) + ".html");
0480: StringReader in = new StringReader(tpl.getContent());
0481: // Add new entry to zip archive
0482: zipout.putNextEntry(entry);
0483: // Hinzuf?gen der Daten zum neuen Eintrag
0484: int read = 0;
0485: while ((read = in.read()) != -1) {
0486: zipout.write(read);
0487: }
0488: zipout.closeEntry(); // Neuen Eintrag abschlie?en
0489: zipout.flush();
0490: if (topicname.equals(defaultTopic)) {
0491: entry = new ZipEntry("index.html");
0492: in = new StringReader(tpl.getContent());
0493: zipout.putNextEntry(entry);
0494: read = 0;
0495: while ((read = in.read()) != -1) {
0496: zipout.write(read);
0497: }
0498: zipout.closeEntry(); // Neuen Eintrag abschlie?en
0499: zipout.flush();
0500: }
0501: }
0502: }
0503:
0504: /**
0505: * Create a safe name of this topic for the file system.
0506: *
0507: * @param topic
0508: * The original topic name
0509: * @return The safe topic name
0510: */
0511: private String safename(String topic) {
0512: return Utilities.encodeSafeExportFileName(topic);
0513: }
0514:
0515: /**
0516: * Parse the pages starting with startTopic. The results are stored in the
0517: * list sitemapLines. This functions is called recursivly, but the list is
0518: * filled in the correct order.
0519: *
0520: * @param currentWiki
0521: * name of the wiki to refer to
0522: * @param startTopic
0523: * Start with this page
0524: * @param level
0525: * A list indicating the images to use to represent certain
0526: * levels
0527: * @param group
0528: * The group, we are representing
0529: * @param sitemapLines
0530: * A list of all lines, which results in the sitemap
0531: * @param visitedPages
0532: * A vector of all pages, which already have been visited
0533: * @param endString
0534: * Beyond this text we do not search for links
0535: */
0536: private void parsePages(String topic, HashMap wiki, List levelsIn,
0537: String group, List sitemapLines, Vector visitedPages) {
0538: try {
0539: List result = new ArrayList();
0540: List levels = new ArrayList(levelsIn.size());
0541: for (int i = 0; i < levelsIn.size(); i++) {
0542: if ((i + 1) < levelsIn.size()) {
0543: if (SitemapServlet.MORE_TO_COME
0544: .equals((String) levelsIn.get(i))) {
0545: levels.add(SitemapServlet.HORIZ_LINE);
0546: } else if (SitemapServlet.LAST_IN_LIST
0547: .equals((String) levelsIn.get(i))) {
0548: levels.add(SitemapServlet.NOTHING);
0549: } else {
0550: levels.add(levelsIn.get(i));
0551: }
0552: } else {
0553: levels.add(levelsIn.get(i));
0554: }
0555: }
0556: List l = (List) wiki.get(topic);
0557: if (l == null) {
0558: // topic is empty, but need to be shown!
0559: l = new ArrayList();
0560: }
0561: for (Iterator listIterator = l.iterator(); listIterator
0562: .hasNext();) {
0563: String link = (String) listIterator.next();
0564: if (link.indexOf('&') > -1) {
0565: link = link.substring(0, link.indexOf('&'));
0566: }
0567: if (link.length() > 3
0568: && !link.startsWith("topic=")
0569: && !link.startsWith("action=")
0570: && !visitedPages.contains(link)
0571: && !PseudoTopicHandler.getInstance()
0572: .isPseudoTopic(link)) {
0573: result.add(link);
0574: visitedPages.add(link);
0575: }
0576: }
0577: // add a sitemap line
0578: SitemapLineBean slb = new SitemapLineBean();
0579: slb.setTopic(topic);
0580: slb.setLevels(new ArrayList(levels));
0581: slb.setGroup(group);
0582: slb.setHasChildren(result.size() > 0);
0583: sitemapLines.add(slb);
0584: for (int i = 0; i < result.size(); i++) {
0585: String link = (String) result.get(i);
0586: String newGroup = group + "_" + String.valueOf(i);
0587: boolean isLast = ((i + 1) == result.size());
0588: if (isLast) {
0589: levels.add(SitemapServlet.LAST_IN_LIST);
0590: } else {
0591: levels.add(SitemapServlet.MORE_TO_COME);
0592: }
0593: parsePages(link, wiki, levels, newGroup, sitemapLines,
0594: visitedPages);
0595: levels.remove(levels.size() - 1);
0596: }
0597: } catch (Exception e) {
0598: logger.fatal("Exception", e);
0599: }
0600: }
0601:
0602: /**
0603: *
0604: */
0605: private void addAllSpecialPages(Environment en,
0606: ZipOutputStream zipout, int progressStart,
0607: int progressLength) throws Exception, IOException {
0608: if (virtualWiki == null || virtualWiki.length() < 1) {
0609: virtualWiki = WikiBase.DEFAULT_VWIKI;
0610: }
0611: ResourceBundle messages = ResourceBundle.getBundle(
0612: "ApplicationResources", locale);
0613:
0614: WikiBase wb = WikiBase.getInstance();
0615: SearchEngine sedb = wb.getSearchEngineInstance();
0616: Template tpl;
0617: int count = 0;
0618: int numberOfSpecialPages = 7;
0619: int bytesRead = 0;
0620: byte[] byteArray = new byte[4096];
0621: // -----------------------------------------------------------
0622: // add style sheet
0623: progress = Math
0624: .min(
0625: progressStart
0626: + (int) ((double) count
0627: * (double) progressLength / (double) numberOfSpecialPages),
0628: 99);
0629: count++;
0630: ZipEntry entry = new ZipEntry("vqwiki.css");
0631: zipout.putNextEntry(entry);
0632: InputStream in = new BufferedInputStream(new FileInputStream(
0633: this .getServletContext().getRealPath("/vqwiki.css")));
0634: // Read in bytes through file stream, and write out through servlet
0635: // stream
0636: while (in.available() > 0) {
0637: bytesRead = in.read(byteArray, 0, Math.min(4096, in
0638: .available()));
0639: zipout.write(byteArray, 0, bytesRead);
0640: }
0641: zipout.closeEntry();
0642: zipout.flush();
0643: // -----------------------------------------------------------
0644: // add search page
0645: progress = Math
0646: .min(
0647: progressStart
0648: + (int) ((double) count
0649: * (double) progressLength / (double) numberOfSpecialPages),
0650: 99);
0651: count++;
0652: tpl = getTemplateFilledWithContent("search");
0653: tpl.setFieldGlobal("TOPICNAME", "WikiSearch");
0654: entry = new ZipEntry("WikiSearch.html");
0655: StringReader strin = new StringReader(tpl.getContent());
0656: // Add new entry to zip archive
0657: zipout.putNextEntry(entry);
0658: // Add data to new entry
0659: while ((bytesRead = strin.read()) != -1) {
0660: zipout.write(bytesRead);
0661: }
0662: zipout.closeEntry(); // Close this entry
0663: zipout.flush();
0664: // -----------------------------------------------------------
0665: // add index page
0666: progress = Math
0667: .min(
0668: progressStart
0669: + (int) ((double) count
0670: * (double) progressLength / (double) numberOfSpecialPages),
0671: 99);
0672: count++;
0673: entry = new ZipEntry("applets/vqapplets.jar");
0674: zipout.putNextEntry(entry);
0675: in = new BufferedInputStream(new FileInputStream(this
0676: .getServletContext().getRealPath(
0677: "/WEB-INF/classes/export2html/vqapplets.jar")));
0678: // Read in bytes through file stream, and write out through servlet
0679: // stream
0680: while (in.available() > 0) {
0681: bytesRead = in.read(byteArray, 0, Math.min(4096, in
0682: .available()));
0683: zipout.write(byteArray, 0, bytesRead);
0684: }
0685: zipout.closeEntry();
0686: zipout.flush();
0687: entry = new ZipEntry("applets/log4j.jar");
0688: zipout.putNextEntry(entry);
0689: in = new BufferedInputStream(new FileInputStream(this
0690: .getServletContext().getRealPath(
0691: "/WEB-INF/lib/log4j.jar")));
0692: // Read in bytes through file stream, and write out through servlet
0693: // stream
0694: while (in.available() > 0) {
0695: bytesRead = in.read(byteArray, 0, Math.min(4096, in
0696: .available()));
0697: zipout.write(byteArray, 0, bytesRead);
0698: }
0699: zipout.closeEntry();
0700: zipout.flush();
0701: entry = new ZipEntry("applets/lucene-1.2a.jar");
0702: zipout.putNextEntry(entry);
0703: in = new BufferedInputStream(new FileInputStream(this
0704: .getServletContext().getRealPath(
0705: "/WEB-INF/lib/lucene-1.2a.jar")));
0706: // Read in bytes through file stream, and write out through servlet
0707: // stream
0708: while (in.available() > 0) {
0709: bytesRead = in.read(byteArray, 0, Math.min(4096, in
0710: .available()));
0711: zipout.write(byteArray, 0, bytesRead);
0712: }
0713: zipout.closeEntry();
0714: zipout.flush();
0715: entry = new ZipEntry("applets/commons-httpclient-2.0.jar");
0716: zipout.putNextEntry(entry);
0717: in = new BufferedInputStream(new FileInputStream(this
0718: .getServletContext().getRealPath(
0719: "/WEB-INF/lib/commons-httpclient-2.0.jar")));
0720: // Read in bytes through file stream, and write out through servlet
0721: // stream
0722: while (in.available() > 0) {
0723: bytesRead = in.read(byteArray, 0, Math.min(4096, in
0724: .available()));
0725: zipout.write(byteArray, 0, bytesRead);
0726: }
0727: zipout.closeEntry();
0728: zipout.flush();
0729: try {
0730: ByteArrayOutputStream bos = new ByteArrayOutputStream();
0731: JarOutputStream indexjar = new JarOutputStream(bos);
0732: JarEntry jarEntry;
0733: File searchDir = new File(WikiBase.getInstance()
0734: .getSearchEngineInstance().getSearchIndexPath(
0735: virtualWiki));
0736: String files[] = searchDir.list();
0737: StringBuffer listOfAllFiles = new StringBuffer();
0738: for (int i = 0; i < files.length; i++) {
0739: if (listOfAllFiles.length() > 0) {
0740: listOfAllFiles.append(",");
0741: }
0742: listOfAllFiles.append(files[i]);
0743: jarEntry = new JarEntry("lucene/index/" + files[i]);
0744: indexjar.putNextEntry(jarEntry);
0745: in = new FileInputStream(new File(searchDir, files[i]));
0746: // Read in bytes through file stream, and write out through
0747: // servlet stream
0748: while (in.available() > 0) {
0749: bytesRead = in.read(byteArray, 0, Math.min(4096, in
0750: .available()));
0751: indexjar.write(byteArray, 0, bytesRead);
0752: }
0753: indexjar.closeEntry();
0754: }
0755: indexjar.flush();
0756: jarEntry = new JarEntry("lucene/index.dir");
0757: strin = new StringReader(listOfAllFiles.toString());
0758: indexjar.putNextEntry(jarEntry);
0759: while ((bytesRead = strin.read()) != -1) {
0760: indexjar.write(bytesRead);
0761: }
0762: indexjar.closeEntry();
0763: indexjar.flush();
0764: indexjar.close();
0765: entry = new ZipEntry("applets/index.jar");
0766: zipout.putNextEntry(entry);
0767: zipout.write(bos.toByteArray());
0768: zipout.closeEntry();
0769: zipout.flush();
0770: bos.reset();
0771: } catch (Exception e) {
0772: logger.debug("Exception while adding lucene index: ", e);
0773: }
0774: // -----------------------------------------------------------
0775: // add recent changes
0776: progress = Math
0777: .min(
0778: progressStart
0779: + (int) ((double) count
0780: * (double) progressLength / (double) numberOfSpecialPages),
0781: 99);
0782: count++;
0783: // FIXME - hard coding is evil
0784: tpl = new Template(this .getServletContext().getRealPath(
0785: "/WEB-INF/classes/export2html/mastertemplate.tpl"));
0786: tpl.setFieldGlobal("VERSION", Environment.WIKI_VERSION);
0787: StringBuffer content = new StringBuffer();
0788: content.append("<table><tr><th>"
0789: + messages.getString("common.date") + "</th><th>"
0790: + messages.getString("common.topic") + "</th><th>"
0791: + messages.getString("common.user") + "</th></tr>\n");
0792: Collection all = null;
0793: try {
0794: Calendar cal = Calendar.getInstance();
0795: ChangeLog cl = WikiBase.getInstance()
0796: .getChangeLogInstance();
0797: int n = Environment.getInstance().getIntSetting(
0798: Environment.PROPERTY_RECENT_CHANGES_DAYS);
0799: if (n == 0) {
0800: n = 5;
0801: }
0802: all = new ArrayList();
0803: for (int i = 0; i < n; i++) {
0804: Collection col = cl.getChanges(virtualWiki, cal
0805: .getTime());
0806: if (col != null) {
0807: all.addAll(col);
0808: }
0809: cal.add(Calendar.DATE, -1);
0810: }
0811: } catch (Exception e) {
0812: ;
0813: }
0814: DateFormat df = DateFormat.getDateTimeInstance(
0815: DateFormat.SHORT, DateFormat.SHORT, locale);
0816: for (Iterator iter = all.iterator(); iter.hasNext();) {
0817: Change change = (Change) iter.next();
0818: content.append("<tr><td class=\"recent\">"
0819: + df.format(change.getTime())
0820: + "</td><td class=\"recent\"><a href=\""
0821: + safename(change.getTopic()) + ".html\">"
0822: + change.getTopic()
0823: + "</a></td><td class=\"recent\">"
0824: + change.getUser() + "</td></tr>");
0825: }
0826: content.append("</table>\n");
0827: tpl.setFieldGlobal("TOPICNAME", "RecentChanges");
0828: tpl.setFieldGlobal("VERSION", Environment.WIKI_VERSION);
0829: tpl.setFieldGlobal("CONTENTS", content.toString());
0830: entry = new ZipEntry("RecentChanges.html");
0831: strin = new StringReader(tpl.getContent());
0832: // Add new entry to zip archive
0833: zipout.putNextEntry(entry);
0834: // Add data to new entry
0835: int read;
0836: while ((read = strin.read()) != -1) {
0837: zipout.write(read);
0838: }
0839: zipout.closeEntry(); // Close this entry
0840: zipout.flush();
0841: logger.debug("Done adding all special topics.");
0842: }
0843:
0844: /**
0845: *
0846: */
0847: private void addAllImages(Environment en, ZipOutputStream zipout,
0848: int progressStart, int progressLength) throws IOException {
0849: // add images
0850: String[] files = new File(imageDir).list();
0851: int bytesRead = 0;
0852: byte byteArray[] = new byte[4096];
0853: FileInputStream in = null;
0854: for (int i = 0; i < files.length; i++) {
0855: progress = Math
0856: .min(
0857: progressStart
0858: + (int) ((double) i
0859: * (double) progressLength / (double) files.length),
0860: 99);
0861: File fileToHandle = new File(imageDir, files[i]);
0862: if (fileToHandle.isFile() && fileToHandle.canRead()) {
0863: try {
0864: logger.debug("Adding image file " + files[i]);
0865: ZipEntry entry = new ZipEntry("images/" + files[i]);
0866: zipout.putNextEntry(entry);
0867: in = new FileInputStream(fileToHandle);
0868: // Read in bytes through file stream, and write out through
0869: // servlet stream
0870: while (in.available() > 0) {
0871: bytesRead = in.read(byteArray, 0, Math.min(
0872: 4096, in.available()));
0873: zipout.write(byteArray, 0, bytesRead);
0874: }
0875: } catch (FileNotFoundException e) {
0876: ;
0877: } catch (IOException e) {
0878: ;
0879: } finally {
0880: try {
0881: zipout.closeEntry();
0882: } catch (IOException e1) {
0883: ;
0884: }
0885: try {
0886: zipout.flush();
0887: } catch (IOException e1) {
0888: ;
0889: }
0890: try {
0891: if (in != null) {
0892: in.close();
0893: in = null;
0894: }
0895: } catch (IOException e1) {
0896: ;
0897: }
0898: }
0899: }
0900: }
0901: }
0902:
0903: /**
0904: *
0905: */
0906: private void addAllUploadedFiles(Environment en,
0907: ZipOutputStream zipout, int progressStart,
0908: int progressLength) throws IOException,
0909: FileNotFoundException {
0910: // add all attachments
0911: File uploadPath = en.uploadPath(virtualWiki, "");
0912: String[] files = uploadPath.list();
0913: int bytesRead = 0;
0914: byte byteArray[] = new byte[4096];
0915: for (int i = 0; i < files.length; i++) {
0916: progress = Math
0917: .min(
0918: progressStart
0919: + (int) ((double) i
0920: * (double) progressLength / (double) files.length),
0921: 99);
0922: logger.debug("Adding uploaded file " + files[i]);
0923: ZipEntry entry = new ZipEntry(files[i]);
0924: try {
0925: FileInputStream in = new FileInputStream(en.uploadPath(
0926: virtualWiki, files[i]));
0927: zipout.putNextEntry(entry);
0928: // Read in bytes through file stream, and write out through
0929: // servlet stream
0930: while (in.available() > 0) {
0931: bytesRead = in.read(byteArray, 0, Math.min(4096, in
0932: .available()));
0933: zipout.write(byteArray, 0, bytesRead);
0934: }
0935: zipout.closeEntry();
0936: zipout.flush();
0937: } catch (FileNotFoundException e) {
0938: logger.warn("Could not open file!", e);
0939: } catch (IOException e) {
0940: logger.warn("IOException!", e);
0941: try {
0942: zipout.closeEntry();
0943: zipout.flush();
0944: } catch (IOException e1) {
0945: ;
0946: }
0947: }
0948: }
0949: }
0950:
0951: /**
0952: *
0953: */
0954: private Template getTemplateFilledWithContent(String contentName)
0955: throws Exception {
0956: // FIXME - hard coding is evil
0957: Template tpl = new Template(
0958: this
0959: .getServletContext()
0960: .getRealPath(
0961: "/WEB-INF/classes/export2html/mastertemplate.tpl"));
0962: tpl.setFieldGlobal("VERSION", Environment.WIKI_VERSION);
0963: StringBuffer content = readFile("/WEB-INF/classes/export2html/"
0964: + contentName + ".content");
0965: tpl.setFieldGlobal("CONTENTS", content.toString());
0966: return tpl;
0967: }
0968:
0969: /**
0970: * Read a file from a resource inside the classpath
0971: *
0972: * @param filename
0973: * The file to read
0974: * @return The content of the file as StringBuffer
0975: */
0976: private StringBuffer readFile(String filename) {
0977: // get content
0978: return Utilities.readFile(new File(this .getServletContext()
0979: .getRealPath(filename)));
0980: }
0981:
0982: /**
0983: * We are done. Go to result page.
0984: *
0985: * @see vqwiki.servlets.LongLastingOperationServlet#dispatchDone(javax.servlet.http.HttpServletRequest,
0986: * javax.servlet.http.HttpServletResponse)
0987: */
0988: protected void dispatchDone(HttpServletRequest request,
0989: HttpServletResponse response) {
0990: if (exception != null) {
0991: error(request, response, new ServletException(exception
0992: .getMessage(), exception));
0993: return;
0994: }
0995: try {
0996: response.setContentType("application/zip");
0997: response.setHeader("Expires", "0");
0998: response.setHeader("Pragma", "no-cache");
0999: response.setHeader("Keep-Alive", "timeout=15, max=100");
1000: response.setHeader("Connection", "Keep-Alive");
1001: response.setHeader("Content-Disposition", "attachment"
1002: + ";filename=HTMLExportOf" + virtualWiki + ".zip;");
1003: FileInputStream in = new FileInputStream(tempFile);
1004: response.setContentLength((int) tempFile.length());
1005: OutputStream out = response.getOutputStream();
1006: int bytesRead = 0;
1007: byte byteArray[] = new byte[4096];
1008: while (in.available() > 0) {
1009: bytesRead = in.read(byteArray, 0, Math.min(4096, in
1010: .available()));
1011: out.write(byteArray, 0, bytesRead);
1012: }
1013: out.flush();
1014: out.close();
1015: tempFile.delete();
1016: } catch (Exception e) {
1017: logger.fatal("Exception", e);
1018: error(request, response, new ServletException(e
1019: .getMessage(), e));
1020: }
1021: }
1022: }
|