Java tutorial
/* * 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; } }