com.concursive.connect.web.modules.wiki.utils.WikiUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.concursive.connect.web.modules.wiki.utils.WikiUtils.java

Source

/*
 * ConcourseConnect
 * Copyright 2009 Concursive Corporation
 * http://www.concursive.com
 *
 * This file is part of ConcourseConnect, an open source social business
 * software and community platform.
 *
 * Concursive ConcourseConnect is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, version 3 of the License.
 *
 * Under the terms of the GNU Affero General Public License you must release the
 * complete source code for any application that uses any part of ConcourseConnect
 * (system header files and libraries used by the operating system are excluded).
 * These terms must be included in any work that has ConcourseConnect components.
 * If you are developing and distributing open source applications under the
 * GNU Affero General Public License, then you are free to use ConcourseConnect
 * under the GNU Affero General Public License.
 *
 * If you are deploying a web site in which users interact with any portion of
 * ConcourseConnect over a network, the complete source code changes must be made
 * available.  For example, include a link to the source archive directly from
 * your web site.
 *
 * For OEMs, ISVs, SIs and VARs who distribute ConcourseConnect with their
 * products, and do not license and distribute their source code under the GNU
 * Affero General Public License, Concursive provides a flexible commercial
 * license.
 *
 * To anyone in doubt, we recommend the commercial license. Our commercial license
 * is competitively priced and will eliminate any confusion about how
 * ConcourseConnect can be used and distributed.
 *
 * ConcourseConnect is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with ConcourseConnect.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Attribution Notice: ConcourseConnect is an Original Work of software created
 * by Concursive Corporation
 */

package com.concursive.connect.web.modules.wiki.utils;

import com.concursive.connect.Constants;
import com.concursive.connect.web.modules.documents.dao.ImageInfo;
import com.concursive.connect.web.modules.wiki.dao.Wiki;
import com.concursive.connect.web.modules.wiki.dao.WikiList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

/**
 * Class to manipulate wiki objects
 *
 * @author matt rajkowski
 * @version $Id$
 * @created February 7, 2006
 */
public class WikiUtils {

    private static Log LOG = LogFactory.getLog(WikiUtils.class);

    public static void countDiff(DiffCounter counter, String diff) {
        int UNDEFINED = -1;
        int DELETE = 1;
        int CHANGE_TO = 2;
        int INSERT = 3;
        int CHANGE_FROM = 4;
        int MOVED = 5;
        int mode = UNDEFINED;
        String line = null;
        int method = 1;
        int count = 0;
        try {
            BufferedReader in = new BufferedReader(new StringReader(diff));
            while ((line = in.readLine()) != null) {
                ++count;
                if (count == 1 && line.startsWith(">>>>")) {
                    method = 2;
                }
                if (method == 1) {
                    // Unix normal diff format
                    if (!line.startsWith("> ") && !line.startsWith("< ") && !line.startsWith("---")) {
                        /*
                        if (line.indexOf("a") > -1) {
                          int added = 1;
                          String range = line.substring(line.indexOf("a") + 1);
                          if (range.indexOf(",") > -1) {
                            added += (Integer.parseInt(range.indexOf(",") + 1));
                          }
                            
                            
                          counter.lineAdded();
                        } else if (line.indexOf("c") > -1) {
                            
                        } else if (line.indexOf("d") > -1) {
                            
                        }
                        */

                    }

                } else {
                    // JDiff format
                    if (line.startsWith(">>>> DELETE AT ")) {
                        mode = DELETE;
                        counter.update();
                        continue;
                    } else if (line.startsWith(">>>> ") && line.endsWith(" CHANGED FROM")) {
                        mode = CHANGE_FROM;
                        counter.update();
                        continue;
                    } else if (line.startsWith(">>>>     CHANGED TO")) {
                        mode = CHANGE_TO;
                        continue;
                    } else if (line.startsWith(">>>> INSERT BEFORE ")) {
                        mode = INSERT;
                        counter.update();
                        continue;
                    } else if (line.startsWith(">>>> ") && line.indexOf(" THRU ") > 0
                            && line.indexOf(" MOVED TO BEFORE ") > 0) {
                        mode = MOVED;
                        counter.update();
                        continue;
                    } else if (line.startsWith(">>>> End of differences.")) {
                        break;
                    }
                    if (mode == DELETE) {
                        counter.lineDeleted(1);
                    } else if (mode == INSERT) {
                        counter.lineAdded(1);
                    } else if (mode == CHANGE_FROM) {
                        counter.lineChangedFrom();
                    } else if (mode == CHANGE_TO) {
                        counter.lineChangedTo();
                    }
                }
            }
            counter.update();
            in.close();
        } catch (Exception e) {
            LOG.error("countDiff error", e);
        }
    }

    public static HashMap<String, ImageInfo> buildImageInfo(Connection db, int projectId) throws SQLException {
        HashMap<String, ImageInfo> images = new HashMap<String, ImageInfo>();
        // Full size image
        PreparedStatement pst = db
                .prepareStatement("SELECT client_filename, filename, image_width, image_height, version "
                        + "FROM project_files " + "WHERE link_module_id = ? " + "AND link_item_id = ? ");
        pst.setInt(1, Constants.PROJECT_WIKI_FILES);
        pst.setInt(2, projectId);
        ResultSet rs = pst.executeQuery();
        while (rs.next()) {
            ImageInfo image = new ImageInfo(rs);
            images.put(image.getFilename(), image);
        }
        rs.close();
        pst.close();
        return images;
    }

    public static void updatePageLinks(Connection db, Wiki wiki) throws SQLException {
        // Delete any items that no longer exist
        // Add any new items
        ArrayList pageList = getPageLinks(wiki);
        Iterator i = pageList.iterator();
        while (i.hasNext()) {
            String subject = (String) i.next();
            LOG.debug("updatePageLinks - PageLink: " + subject);
        }
    }

    /**
     * Recursively determine the latest modified date
     *
     * @param wiki
     * @param traverse
     * @param db
     * @return the latest modification date of associated wikis
     * @throws SQLException
     */
    public static Timestamp getLatestModifiedDate(Wiki wiki, boolean traverse, Connection db) throws SQLException {
        if (!traverse) {
            return wiki.getModified();
        }
        Timestamp latest = wiki.getModified();
        ArrayList children = getPageLinks(wiki);
        ArrayList scanned = new ArrayList();
        return getLatestModifiedDate(wiki, db, children, latest, scanned);
    }

    private static Timestamp getLatestModifiedDate(Wiki wiki, Connection db, ArrayList children, Timestamp latest,
            ArrayList scanned) throws SQLException {
        Iterator i = children.iterator();
        while (i.hasNext()) {
            String pageLink = (String) i.next();
            LOG.debug("Checking getLatestModifiedDate: " + pageLink);
            if (!scanned.contains(pageLink)) {
                scanned.add(pageLink);
                Wiki thisWiki = WikiList.queryBySubject(db, pageLink, wiki.getProjectId());
                if (thisWiki.getId() != -1) {
                    if (thisWiki.getModified().after(latest)) {
                        latest = thisWiki.getModified();
                    }
                    latest = getLatestModifiedDate(thisWiki, db, getPageLinks(thisWiki), latest, scanned);
                }
            }
        }
        return latest;
    }

    public static ArrayList getPageLinks(Wiki wiki) {
        ArrayList pageList = new ArrayList();
        // Read the lines and grab the [[ ]] strings.  For each, if not an image
        // then get the first phrase if more than 1 separated by a |
        try {
            BufferedReader in = new BufferedReader(new StringReader(wiki.getContent()));
            String line = null;
            int startIndex = -1;
            int endIndex = -1;
            while ((line = in.readLine()) != null) {

                startIndex = line.indexOf("[[");
                if (startIndex > -1) {
                    endIndex = line.indexOf("]]", startIndex);
                }
                while (endIndex > -1) {
                    String link = line.substring(startIndex + 2, endIndex);
                    if (!link.startsWith("Image:") && !link.startsWith("image:") && !link.startsWith("http://")
                            && !link.startsWith("https://")) {
                        if (link.indexOf("|") > -1) {
                            link = link.substring(0, link.indexOf("|"));
                        }
                        pageList.add(link);
                    }
                    startIndex = line.indexOf("[[", endIndex);
                    if (startIndex > -1) {
                        endIndex = line.indexOf("]]", startIndex);
                    } else {
                        endIndex = -1;
                    }
                }
            }
            in.close();
        } catch (Exception e) {
            return null;
        }
        return pageList;
    }

    public static String merge(Wiki wiki, String sectionMarkup, int editSectionId) throws IOException {
        // Track the line reading
        int sectionIdCount = 0;
        int currentHeaderLevel = 1;
        int editSectionHeaderLevel = -1;
        boolean canAppend = true;
        boolean firstLine = true;

        // Hold the merged result
        StringBuffer sb = new StringBuffer();

        // Find the headers
        BufferedReader in = new BufferedReader(new StringReader(wiki.getContent()));
        String line = null;
        while ((line = in.readLine()) != null) {
            if (!firstLine) {
                if (canAppend) {
                    sb.append(WikiToHTMLUtils.CRLF);
                }
            } else {
                firstLine = false;
            }
            if (line.startsWith("=") && line.endsWith("=")) {
                // determine the header level
                int hCount = WikiToHTMLUtils.parseHCount(line, "=");
                if (hCount > 6) {
                    hCount = 6;
                }
                // Keep track of which header was found
                sectionIdCount += 1;
                currentHeaderLevel = hCount;
                if (editSectionId > 0) {
                    if (editSectionId == sectionIdCount) {
                        editSectionHeaderLevel = currentHeaderLevel;
                        sb.append(sectionMarkup).append(WikiToHTMLUtils.CRLF);
                        canAppend = false;
                    }
                    if (sectionIdCount > editSectionId && currentHeaderLevel <= editSectionHeaderLevel) {
                        canAppend = true;
                    }
                }
            }
            if (canAppend) {
                sb.append(line);
            }
        }
        return (sb.toString());
    }

    /**
     * Merge the forms from the original wiki into the modified markup
     *
     * @param wiki
     * @param wikiMarkup
     * @return
     * @throws IOException
     */
    public static String merge(Wiki wiki, String wikiMarkup) throws IOException {
        // Hold the merged result
        StringBuffer sb = new StringBuffer();
        if (wiki.getContent().startsWith("[{form")) {
            // Copy the form, then append the content
            sb.append(wiki.getContent().substring(0, wiki.getContent().indexOf("+++") + 3));
            sb.append("\n");
            sb.append(wikiMarkup);
        } else {
            // Copy the content, then append the form
            sb.append(wikiMarkup);
            if (!wikiMarkup.endsWith("\n")) {
                sb.append("\n");
            }
            sb.append(wiki.getContent().substring(wiki.getContent().indexOf("[{form")));
            if (!sb.toString().endsWith("\n")) {
                sb.append("\n");
            }
        }
        return sb.toString();
    }

    /**
     * Takes a string of text and if there are any http:// or https:// links, then turns them
     * into wiki links.
     *
     * @param content
     * @return
     */
    public static String addWikiLinks(String content) {
        // Convert links to wiki links...
        ArrayList<String> terms = new ArrayList<String>();
        terms.add("http://");
        terms.add("https://");
        // Parse through and add the wiki links...
        int begin = -1;
        for (String term : terms) {
            while ((begin = content.indexOf(term, begin)) > -1) {
                int end = content.indexOf(" ", begin);
                if (end == -1) {
                    // content goes to the length of the string
                    end = content.length();
                }

                // Determine the URL rendering
                String url = content.substring(begin, end);
                // If the URL is lengthy, shorten it...
                String displayUrl = "";
                if (url.length() > 30) {
                    displayUrl = url;
                    int slash = displayUrl.indexOf("/", 9);
                    if (slash > -1 && slash < 29) {
                        displayUrl = " " + displayUrl.substring(0, slash + 2) + "...";
                    } else {
                        displayUrl = " " + displayUrl.substring(0, 28) + "...";
                    }
                }

                // Insert the wiki brackets around the link
                if (begin == 0) {
                    content = "[[" + url + displayUrl + "]]" + content.substring(end);
                } else {
                    content = content.substring(0, begin) + "[[" + url + displayUrl + "]]" + content.substring(end);
                }
                // Reset the begin position and account for the new brackets
                begin = (end + 4);
            }
        }
        return content;
    }
}