[jboss-svn-commits] JBL Code SVN: r20759 - in labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss: labs and 1 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Wed Jun 25 08:16:29 EDT 2008


Author: szimano
Date: 2008-06-25 08:16:28 -0400 (Wed, 25 Jun 2008)
New Revision: 20759

Added:
   labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/
   labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/
   labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/CSMigration.java
   labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/CSMigrationStarter.java
   labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/JSP2CSMarkupTranslator.java
   labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/migration-howto.txt
   labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/sql-script.txt
Log:
clearspace migration files

Added: labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/CSMigration.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/CSMigration.java	                        (rev 0)
+++ labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/CSMigration.java	2008-06-25 12:16:28 UTC (rev 20759)
@@ -0,0 +1,505 @@
+package org.jboss.labs.clearspace;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.activation.MimetypesFileTypeMap;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.ws.soap.SOAPFaultException;
+
+import org.jboss.wiki.WikiAttachment;
+import org.jboss.wiki.WikiEngine;
+import org.jboss.wiki.WikiPage;
+import org.jboss.wiki.configuration.ConfigurationParser;
+import org.w3c.dom.Text;
+
+import com.jivesoftware.base.UnauthorizedException;
+import com.jivesoftware.base.User;
+import com.jivesoftware.base.UserAlreadyExistsException;
+import com.jivesoftware.base.UserManager;
+import com.jivesoftware.base.UserNotFoundException;
+import com.jivesoftware.base.UserTemplate;
+import com.jivesoftware.base.wiki.WikiContentHelper;
+import com.jivesoftware.community.AttachmentException;
+import com.jivesoftware.community.AttachmentManager;
+import com.jivesoftware.community.Community;
+import com.jivesoftware.community.CommunityManager;
+import com.jivesoftware.community.CommunityNotFoundException;
+import com.jivesoftware.community.Document;
+import com.jivesoftware.community.DocumentAlreadyExistsException;
+import com.jivesoftware.community.DocumentManager;
+import com.jivesoftware.community.DocumentObjectNotFoundException;
+import com.jivesoftware.community.DocumentState;
+import com.jivesoftware.community.DocumentTypeManager;
+import com.jivesoftware.community.DuplicateIDException;
+import com.jivesoftware.community.JiveIterator;
+import com.jivesoftware.community.RejectedException;
+import com.jivesoftware.community.util.WikiUtils;
+
+public class CSMigration {
+
+	private static final String CS_HREF = "http://localhost:8080";
+	private static final String COMM_NAME = "JBossWiki";
+	private User unknownUser;
+	private Map<String, User> users;
+
+	private MimetypesFileTypeMap mimeTypes;
+
+	private UserManager userManager;
+	private DocumentManager documentManager;
+	private CommunityManager communityManager;
+	private DocumentTypeManager documentTypeManager;
+	private AttachmentManager attachmentManager;
+
+	private String dbCSUserName = "cs";
+	private String dbCSPass = "cs";
+	private String dbCSUrl = "jdbc:mysql://localhost:3306/cs";
+
+	private String dbNukesUserName = "portal";
+	private String dbNukesPass = "portalpassword";
+	private String dbNukesUrl = "jdbc:mysql://localhost:3306/nukes3";
+
+	private Map<String, String> pageDictionary;
+	private Map<String, String> pageDictionaryRev;
+	private Community jbossWikiCom;
+	private WikiEngine we;
+	private Set<String> pages;
+
+	private final static Map parameters = new HashMap();
+	private User adminUser;
+	private JSP2CSMarkupTranslator translator = new JSP2CSMarkupTranslator();
+	private FileWriter sqlScript;
+	private FileWriter log;
+
+	public CSMigration() {
+
+	}
+
+	private void init() throws CommunityNotFoundException,
+			UserNotFoundException {
+		we = new WikiEngine();
+		pages = we.getAllPageNames(ConfigurationParser.getDefaultLangugeCode());
+		pageDictionary = new HashMap<String, String>();
+		pageDictionaryRev = new HashMap<String, String>();
+		adminUser = userManager.getUser("admin");
+
+		JiveIterator<Community> communities = communityManager
+				.getCommunities(communityManager.getRootCommunity());
+
+		jbossWikiCom = null;
+		for (Community community : communities) {
+			if (community.getName().equals(COMM_NAME)) {
+				System.out.println("Found community: "
+						+ community.getDisplayName());
+				communityManager.deleteCommunity(community);
+				System.out.println("Community deleted");
+			}
+		}
+
+		if (jbossWikiCom == null) {
+			jbossWikiCom = communityManager.createCommunity(communityManager
+					.getRootCommunity(), COMM_NAME, COMM_NAME,
+					"JBoss Wiki migration");
+			System.out.println("Community JBossWiki created");
+		}
+		mimeTypes = new MimetypesFileTypeMap(CSMigration.class
+				.getResourceAsStream("/org/jboss/wiki/fileaccess/mime.types"));
+
+		try {
+			unknownUser = userManager.getUser("unknown");
+		} catch (UserNotFoundException e) {
+			try {
+				UserTemplate ut = new UserTemplate("unknown");
+				ut.setPassword("Un4N0w&");
+				ut.setEmail("unknown at nowhere.org");
+
+				ut.setFederated(true);
+
+				userManager.createApplicationUser(ut);
+
+				System.out.println("User unknown added");
+
+				unknownUser = userManager.getUser("unknown");
+			} catch (UserAlreadyExistsException e1) {
+				// not going to happen
+			}
+		}
+
+	}
+
+	private void importAllPages(Set<String> toTransform) throws IOException {
+		// prepare dictionary
+		for (String pageName : toTransform) {
+			try {
+				Document wsd = documentManager.createDocument(adminUser,
+						documentTypeManager.getDefaultDocumentType(), null,
+						pageName, "");
+
+				WikiPage page = we.getByName(pageName, null, 1,
+						ConfigurationParser.getDefaultLangugeCode());
+
+				String content = translator.parse(page.getContent(),
+						pageDictionary, pageDictionaryRev);
+
+				org.w3c.dom.Document body = WikiContentHelper
+						.wikiToJiveDocument(content);
+
+				wsd.setBody(body);
+
+				wsd.setDocumentState(DocumentState.PUBLISHED);
+				wsd.save();
+
+				documentManager.addDocument(jbossWikiCom, wsd, parameters);
+
+				pageDictionary.put(pageName, wsd.getDocumentID());
+				pageDictionaryRev.put(wsd.getDocumentID(), pageName);
+				System.out.println("Added page: " + pageName + "  as "
+						+ wsd.getDocumentID());
+			} catch (DocumentAlreadyExistsException e) {
+				// ignore
+				e.printStackTrace();
+			} catch (SOAPFaultException e) {
+				e.printStackTrace();
+				System.out.println("Error while processing page: " + pageName);
+
+			} catch (DuplicateIDException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (RejectedException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+	}
+
+	private void importVersionsAndAttachments(Set<String> toTransform)
+			throws Exception {
+		// Connection c = getCSConnection();
+
+		byte[] bytes = new byte[1024 * 1024 * 100]; // 100 MB
+		try {
+			for (String pageName : toTransform) {
+
+				WikiPage page = we.getByName(pageName, null,
+						ConfigurationParser.getDefaultLangugeCode());
+
+				Document original = documentManager.getDocument(pageDictionary
+						.get(pageName));
+
+				// add attachments
+
+				Set<String> atts = we.getAttachmentsSet(page,
+						ConfigurationParser.getDefaultLangugeCode());
+
+				if (atts != null)
+					for (String att : atts) {
+						try {
+							WikiAttachment wa = we.getAttachment(
+									page.getName(), att, ConfigurationParser
+											.getDefaultLangugeCode());
+
+							attachmentManager.createAttachment(original, att,
+									mimeTypes.getContentType(att), wa
+											.getInputStream(), null);
+
+							wa.getInputStream().close();
+
+							System.out.println("Attachment " + att
+									+ " added for " + page.getName());
+						} catch (AttachmentException e) {
+							System.err
+									.println("Problem with adding attachment "
+											+ att + " for page " + pageName);
+							e.printStackTrace();
+						}
+					}
+
+				// add versions
+				for (int ver = 1; ver <= page.getLastVersion(); ver++) {
+					WikiPage pageVer = we.getByName(pageName, null, ver,
+							ConfigurationParser.getDefaultLangugeCode());
+
+					String content = translator.parse(pageVer.getContent(),
+							pageDictionary, pageDictionaryRev);
+
+					org.w3c.dom.Document body = WikiContentHelper
+							.wikiToJiveDocument(content);
+
+					original.setBody(body);
+					original.setCreationDate(pageVer.getEditDate());
+					original.setModificationDate(pageVer.getEditDate());
+
+					User user = getUser(pageVer.getLastAuthor().getName());
+
+					original.setUser(user);
+
+					// original.addAuthor(user);
+
+					original.save();
+
+					long creation = pageVer.getEditDate().getTime();
+
+					// update user and last modification date
+
+					String sql = "UPDATE jiveDocVersion j SET modificationDate='"
+							+ creation
+							+ "', userID='"
+							+ user.getID()
+							+ "' WHERE j.internalDocID='"
+							+ original.getID()
+							+ "' and j.versionID='" + (ver + 1) + "';";
+					// System.out.println("SQL: " + sql);
+
+					sqlScript.write(sql + "\n");
+
+					// c.createStatement().execute(sql);
+
+					original = documentManager.getDocument(original
+							.getDocumentID());
+
+					System.out.println("Version " + ver + " updated for "
+							+ pageVer.getName());
+				}
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			/*
+			 * if (c != null) { c.close(); }
+			 */
+		}
+
+	}
+
+	/**
+	 * @param args
+	 * @throws Exception
+	 * @throws DocumentAlreadyExistsException
+	 */
+	public void migrate() throws Exception {
+
+		try {
+			Date start = new Date();
+
+			init();
+
+			Set<String> toTransform = new TreeSet<String>();
+
+			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm");
+
+			File fSqlScript = new File("versions_and_users-" + sdf.format(start)
+					+ ".sql");
+
+			sqlScript = new FileWriter(fSqlScript);
+
+			log = new FileWriter(new File("log-" + sdf.format(start) + ".sql"));
+			for (String pageName : pages) {
+				if (pageName.matches("[JT].*")) {
+					toTransform.add(pageName);
+				}
+			}
+
+			importAllPages(toTransform);
+
+			importVersionsAndAttachments(toTransform);
+
+			Date end = new Date();
+
+			createMigrationInfoPage(start, end);
+
+			System.out
+					.println("Migration DONE ! Please stop clearspace and run script "
+							+ fSqlScript.getAbsolutePath());
+		} finally {
+			sqlScript.close();
+			log.close();
+		}
+	}
+
+	private void createMigrationInfoPage(Date start, Date end)
+			throws DuplicateIDException, UnauthorizedException,
+			DocumentAlreadyExistsException, RejectedException {
+		// save dictionary
+		Properties p = new Properties();
+		p.putAll(pageDictionary);
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm");
+
+		try {
+			p.store(new FileOutputStream("pages-" + sdf.format(start)
+					+ ".properties"), "migration from " + end.toString());
+		} catch (FileNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		StringBuffer migration = new StringBuffer();
+
+		migration.append("h3. Migration from JSPWiki to Clearspace\n").append(
+				"Started on ").append(start.toString())
+				.append(" and ended on ").append(end.toString()).append(
+						" taking ").append(
+						(end.getTime() - start.getTime()) / 1000).append(
+						" seconds\n\n").append("h3. List of pages\n").append(
+						"||Original||Clearspace ID||\n");
+
+		for (String key : pageDictionary.keySet()) {
+			migration.append("|").append(key).append("|").append(
+					pageDictionary.get(key)).append("|\n");
+		}
+
+		migration.append("\n\n");
+
+		Document d = documentManager.createDocument(adminUser,
+				documentTypeManager.getDefaultDocumentType(), null,
+				"JSPWikiToClearspaceMigrationDetails", migration.toString());
+		d.setDocumentState(DocumentState.PUBLISHED);
+		d.setBody(WikiContentHelper.wikiToJiveDocument(migration.toString()));
+		d.save();
+
+		documentManager.addDocument(jbossWikiCom, d, parameters);
+
+		System.out.println("Page JSPWikiToClearspaceMigrationDetails added as "
+				+ d.getDocumentID());
+
+	}
+
+	private User getUser(String userName) {
+		if (users == null) {
+			users = new HashMap<String, User>();
+		}
+
+		// maybe we know it already
+		if (users.containsKey(userName)) {
+			return users.get(userName);
+		}
+
+		User user = null;
+		Connection c = null;
+
+		// try to get from clearspace
+		try {
+			user = userManager.getUser(userName);
+		} catch (UserNotFoundException e) {
+			// there's no user - try to migrate it
+			try {
+				c = getNukesConnection();
+				ResultSet rs = c.createStatement().executeQuery(
+						"SELECT * FROM nuke_users WHERE pn_uname='" + userName
+								+ "';");
+				if (rs.next()) {
+					LabsUser nukeUser = new LabsUser(rs);
+
+					try {
+						UserTemplate ut = new UserTemplate(userName);
+						ut.setFederated(true);
+
+						ut = mapDetails(ut, nukeUser);
+						userManager.createApplicationUser(ut);
+
+						user = userManager.getUser(userName);
+						users.put(userName, user);
+
+						return user;
+					} catch (Exception ex) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+				} else {
+					users.put(userName, unknownUser);
+					return unknownUser;
+				}
+			} catch (SQLException e1) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (Exception e1) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		} finally {
+			if (c != null) {
+				try {
+					c.close();
+				} catch (SQLException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+		}
+
+		users.put(userName, user);
+
+		return user;
+	}
+
+	private UserTemplate mapDetails(UserTemplate ut, LabsUser nukeUser) {
+		ut.setEmail(nukeUser.getEmail());
+		ut.setName(nukeUser.getName());
+		ut.setPasswordHash(nukeUser.getPasswordHash());
+
+		return ut;
+	}
+
+	private Connection getCSConnection() throws Exception {
+		Class.forName("com.mysql.jdbc.Driver").newInstance();
+		return DriverManager.getConnection(dbCSUrl, dbCSUserName, dbCSPass);
+	}
+
+	private Connection getNukesConnection() throws Exception {
+		Class.forName("com.mysql.jdbc.Driver").newInstance();
+		return DriverManager.getConnection(dbNukesUrl, dbNukesUserName,
+				dbNukesPass);
+	}
+
+	public void setUserManager(UserManager userManager) {
+		this.userManager = userManager;
+		checkIfCanStart();
+	}
+
+	public void setDocumentManager(DocumentManager documentManager) {
+		this.documentManager = documentManager;
+		checkIfCanStart();
+	}
+
+	public void setCommunityManager(CommunityManager communityManager) {
+		this.communityManager = communityManager;
+		checkIfCanStart();
+	}
+
+	public void setDocumentTypeManager(DocumentTypeManager documentTypeManager) {
+		this.documentTypeManager = documentTypeManager;
+		checkIfCanStart();
+	}
+
+	public void setAttachmentManager(AttachmentManager attachmentManager) {
+		this.attachmentManager = attachmentManager;
+		checkIfCanStart();
+	}
+
+	private void checkIfCanStart() {
+		/*
+		 * if (userManager != null && documentManager != null &&
+		 * communityManager != null && documentTypeManager != null &&
+		 * attachmentManager != null) { System.out.println("\n\nMigration
+		 * started"); try {
+		 * 
+		 * migrate(); } catch (Exception e) { // TODO Auto-generated catch block
+		 * e.printStackTrace(); } System.out.println("Migration finished\n\n"); }
+		 */
+	}
+}

Added: labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/CSMigrationStarter.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/CSMigrationStarter.java	                        (rev 0)
+++ labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/CSMigrationStarter.java	2008-06-25 12:16:28 UTC (rev 20759)
@@ -0,0 +1,38 @@
+package org.jboss.labs.clearspace;
+
+import org.acegisecurity.Authentication;
+import org.acegisecurity.AuthenticationException;
+import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
+
+public class CSMigrationStarter implements
+		org.acegisecurity.providers.AuthenticationProvider {
+	private CSMigration migration;
+
+	public CSMigrationStarter() {
+
+	}
+
+	public void setMigration(CSMigration migration) {
+		this.migration = migration;
+	}
+
+	public Authentication authenticate(Authentication authentication)
+			throws AuthenticationException {
+
+		try {
+			if (System.getenv("MIGRATE") != null) {
+				migration.migrate();
+			}
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+		return null;
+	}
+
+	public boolean supports(Class authentication) {
+		return authentication == UsernamePasswordAuthenticationToken.class;
+	}
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/JSP2CSMarkupTranslator.java
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/JSP2CSMarkupTranslator.java	                        (rev 0)
+++ labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/JSP2CSMarkupTranslator.java	2008-06-25 12:16:28 UTC (rev 20759)
@@ -0,0 +1,1049 @@
+/**************************************************
+ *                                                *
+ *  JBoss Labs: Creating Professional Open Source *
+ *                                                *
+ *   Distributable under LGPL license.            *
+ *   See terms of license at gnu.org.             *
+ *                                                *
+ *************************************************/
+
+/*
+ Copyright (C) 2005  Damon Sicore,
+ Rali Genova,
+ Tomasz Szymanski,
+ Adam Warski,
+ JBoss, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+ */
+
+/**
+ * Portions of this work are based on the work
+ * of Janne Jalkanen of the JSPWiki project. 
+ * 
+ * Marked Portions are Copyright (C) 2001-2002 Janne Jalkanen (Janne.Jalkanen at iki.fi)
+ *
+ * Those portions are marked by the 'author' javadoc tag
+ * and list Janne Jalkanen as the author of that method.
+ * 
+ * This class is based on the JSPWiki 2.0 version
+ * of the TranslatorReader.java class.  The original 
+ * version of that class can be found here:
+ * 
+ * http://anonsvn.labs.jboss.com/branches/forge/archives/jspwiki/src/com/ecyrd/jspwiki/TranslatorReader.java
+ * 
+ */
+package org.jboss.labs.clearspace;
+
+/**
+ * @author <a href="mailto:rali.genova at jboss.org">Rali Genova </a>
+ * @author <a href="mailto:tomasz.szymanski at jboss.org">Tomasz Szymanski </a>
+ * 
+ */
+import java.io.*;
+import java.util.regex.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.log4j.Logger;
+import org.jboss.wiki.WikiCommon;
+import org.jboss.wiki.WikiPage;
+import org.jboss.wiki.WikiPlugin;
+import org.jboss.wiki.WikiSession;
+import org.jboss.wiki.configuration.ConfigurationParser;
+
+public class JSP2CSMarkupTranslator {
+
+	private Logger log;
+
+	private static String mediaPatterns;
+
+	/* formatting variables */
+
+	private boolean m_allowHTML = true;
+
+	private boolean m_isbold = false;
+
+	private boolean m_isitalic = false;
+
+	private boolean m_isTypedText = false;
+
+	private boolean m_istable = false;
+
+	private boolean m_isPre = false;
+
+	private boolean m_isdefinition = false;
+
+	private int m_listlevel = 0;
+
+	private int m_numlistlevel = 0;
+
+	private boolean m_camelCaseLinks = true; // camelCase enabled
+
+	/** Tag that gets closed at EOL. */
+	private String m_closeTag = null;
+
+	/** Allow this many characters to be pushed back in the stream. */
+	private static final int PUSHBACK_BUFFER_SIZE = 8;
+
+	/**
+	 * These characters constitute word separators when trying to find CamelCase
+	 * links.
+	 */
+	private static final String WORD_SEPARATORS = ",.|:;+=&";
+
+	private PushbackReader m_in;
+
+	// stores the name of the wiki page we are currently processing
+	private String pageName = "";
+
+	private Map<String, String> linkDictRev;
+
+	private Map<String, String> linkDict;
+
+	public JSP2CSMarkupTranslator() {
+
+	}
+
+	/**
+	 * Push back any character to the current input. Does not push back a read
+	 * EOF, though.
+	 * 
+	 * @author Janne Jalkanen
+	 */
+	private void pushBack(int c) throws IOException {
+		if (c != -1) {
+			m_in.unread(c);
+		}
+	}
+
+	/**
+	 * Wiki to HTML transformation method, plain URIs transformation not
+	 * implemented
+	 * 
+	 * @param page
+	 *            The String representation of a wiki page's content
+	 * @return The final transformed into HTML string
+	 * @author Janne Jalkanen
+	 * @author Rali Genova
+	 */
+	public String parseLinks(String page) throws IOException {
+		m_in = new PushbackReader(new StringReader(page), PUSHBACK_BUFFER_SIZE);
+		StringBuffer buf = new StringBuffer();
+		StringBuffer word = null;
+		int previousCh = -2;
+		int start = 0;
+		boolean quitReading = false;
+		boolean newLine = true; // FIXME: not true if reading starts in middle
+		// of buffer
+
+		while (!quitReading) {
+			int ch = nextToken();
+			String s = null;
+
+			// begin of HTML transformation
+			if (m_isPre) {
+				if (ch == '}') {
+					buf.append(handleClosebrace());
+					/*
+					 * } else if (ch == '<') { buf.append("&lt;"); } else if
+					 * (ch == '>') { buf.append("&gt;");
+					 */
+				} else if (ch == -1) {
+					quitReading = true;
+				} else {
+					buf.append((char) ch);
+				}
+
+				continue;
+			}
+			/*
+			 * CamelCase detection, a non-trivial endeavour. We keep track of
+			 * all white-space separated entities, which we hereby refer to as
+			 * "words". We then check for an existence of a CamelCase format
+			 * text string inside the "word", and if one exists, we replace it
+			 * with a proper link.
+			 */
+
+			if (m_camelCaseLinks) {
+				// Quick parse of start of a word boundary.
+
+				if (word == null
+						&& (Character.isWhitespace((char) previousCh)
+								|| WORD_SEPARATORS.indexOf((char) previousCh) != -1 || newLine)
+						&& !Character.isWhitespace((char) ch)) {
+					word = new StringBuffer();
+				}
+
+				// Are we currently tracking a word?
+				if (word != null) {
+					//
+					// Check for the end of the word.
+					//
+
+					// We don't want automatic link creation
+					/*
+					 * if (Character.isWhitespace((char) ch) || ch == -1 ||
+					 * WORD_SEPARATORS.indexOf((char) ch) != -1) { String
+					 * potentialLink = word.toString();
+					 * 
+					 * String camelCase = parseCamelCase(potentialLink);
+					 * 
+					 * if (camelCase != null) { start =
+					 * buf.toString().lastIndexOf(camelCase); buf.replace(start,
+					 * start + camelCase.length(), handleHyperlinks(camelCase)); } //
+					 * We've ended a word boundary, so time to reset. word =
+					 * null; } else {
+					 */
+					// This should only be appending letters and digits.
+					word.append((char) ch);
+					// } // if end of word
+				} // if word's not null
+
+				// Always set the previous character to test for word starts.
+				previousCh = ch;
+
+			} // if m_camelCaseLinks
+			//
+			// Check if any lists need closing down.
+			//
+
+			if (newLine && ch != '*' && ch != ' ' && m_listlevel > 0) {
+				buf.append("</LI>\n");
+				for (; m_listlevel > 0; m_listlevel--) {
+					buf.append("</UL>\n");
+				}
+			}
+
+			if (newLine && ch != '#' && ch != ' ' && m_numlistlevel > 0) {
+				buf.append("</LI>\n");
+				for (; m_numlistlevel > 0; m_numlistlevel--) {
+					buf.append("</OL>\n");
+				}
+			}
+
+			if (newLine && ch != '|' && m_istable) {
+				buf.append("</TABLE>\n");
+				m_istable = false;
+				m_closeTag = null;
+			}
+
+			switch (ch) {
+			case '\r':
+				// DOS linefeeds we forget
+				s = null;
+				break;
+
+			case '\n':
+				//
+				// Close things like headings, etc.
+				//
+				if (m_closeTag != null) {
+					buf.append(m_closeTag);
+					m_closeTag = null;
+				}
+
+				m_isdefinition = false;
+
+				if (newLine) {
+					// Paragraph change.
+
+					buf.append("\n");
+				} else {
+					buf.append("\n");
+					newLine = true;
+				}
+				/*
+				 * wiki syntax handling, later to be refactored so multiple wiki
+				 * syntax is supported
+				 */
+
+				break;
+			case '\\':
+				s = handleBackslash();
+				break;
+
+			case '_':
+				s = handleUnderscore();
+				break;
+
+			case '\'':
+				s = handleApostrophe();
+				break;
+
+			case '{':
+				s = handleOpenbrace();
+				break;
+
+			case '}':
+				s = handleClosebrace();
+				break;
+
+			case '-':
+				s = handleDash();
+				break;
+
+			case '!':
+				if (newLine) {
+					s = handleHeading();
+				} else {
+					s = "!";
+				}
+				break;
+
+			case ';':
+				if (newLine) {
+					s = handleDefinitionList();
+				} else {
+					s = ";";
+				}
+				break;
+
+			case ':':
+				if (m_isdefinition) {
+					s = "}";
+					m_isdefinition = false;
+				} else {
+					s = ":";
+				}
+				break;
+
+			case '[':
+				s = handleOpenbracket();
+				break;
+
+			case '*':
+				if (newLine) {
+					int chn = nextToken();
+					buf.append("*");
+
+					if (chn != '*') {
+						buf.append(" ");
+					}
+
+					if (chn != ' ') {
+						pushBack(chn);
+					}
+				}
+				break;
+
+			case '#':
+				if (newLine) {
+					int chn = nextToken();
+					buf.append("#");
+
+					if (chn != '#') {
+						buf.append(" ");
+					}
+
+					if (chn != ' ') {
+						pushBack(chn);
+					}
+				}
+				break;
+
+			/*
+			 * case '|': s = handleBar(newLine); break;
+			 */
+
+			case '<':
+				s = m_allowHTML ? "<" : "&lt;";
+				break;
+
+			case '>':
+				s = m_allowHTML ? ">" : "&gt;";
+				break;
+
+			case '\"':
+				s = m_allowHTML ? "\"" : "&quot;";
+				break;
+
+			case '~':
+				s = handleTilde();
+				break;
+			case -1:
+				quitReading = true;
+				break;
+
+			default:
+				buf.append((char) ch);
+				newLine = false;
+				break;
+			}
+			if (s != null) {
+				buf.append(s);
+
+				newLine = false;
+			}
+
+		}
+
+		return buf.toString();
+	}
+
+	/**
+	 * @param link -
+	 *            potential camel case link to be tested
+	 * @return the string itself if not a camel case, and a proper link
+	 *         otherwise
+	 * @author Rali Genova
+	 * @author Janne Jalkanen
+	 */
+	public static String parseCamelCase(String link) {
+		String camelCasepattern = "^([^\\p{Alnum}]*|\\~)([\\p{Upper}]+[\\p{Lower}]+[\\p{Upper}]+[\\p{Alnum}]*)[^\\p{Alnum}]*$";
+		Pattern camelCase = Pattern.compile(camelCasepattern);
+		Matcher camelMatch = camelCase.matcher(link);
+		if (camelMatch.matches()) {
+			String result = camelMatch.group(2); // get the camel case words
+			if (camelMatch.group(1) != null) {
+				if ((camelMatch.group(1).equals("~"))
+						|| (camelMatch.group(1).indexOf('[') != -1)) {
+					return null; // this is camelCase escape or [...] link
+				}
+			}
+			return result;
+
+		}// if match
+		return null;
+	}
+
+	/* a collection of all media formats allowed on wiki */
+	private static Collection getImagePatterns() {
+		ArrayList patt = new ArrayList();
+		String imagepattern = mediaPatterns;
+		String[] elem = imagepattern.split(",");
+		for (int i = 0; i < elem.length; i++) {
+			patt.add(elem[i].trim());
+		}
+
+		return patt;
+	}
+
+	public static boolean checkImageLink(String text) {
+		ArrayList ptrns = (ArrayList) getImagePatterns();
+		for (int i = 0; i < ptrns.size(); i++) {
+			if (text.endsWith((String) ptrns.get(i))) {
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	 * Generic escape of next character or entity.
+	 */
+	private String handleTilde() throws IOException {
+		int ch = nextToken();
+
+		if (ch == '|')
+			return "|";
+
+		if (Character.isUpperCase((char) ch)) {
+			return String.valueOf((char) ch);
+		}
+
+		// No escape.
+		pushBack(ch);
+
+		return "~";
+	}
+
+	private String handleUnderscore() throws IOException {
+		int ch = nextToken();
+		String res = "_";
+
+		if (ch == '_') {
+			res = m_isbold ? "*" : "*";
+			m_isbold = !m_isbold;
+		} else {
+			pushBack(ch);
+		}
+
+		return res;
+	}
+
+	/**
+	 * For example: italics.
+	 */
+	private String handleApostrophe() throws IOException {
+		int ch = nextToken();
+		String res = "'";
+
+		if (ch == '\'') {
+			res = m_isitalic ? "+" : "+";
+			m_isitalic = !m_isitalic;
+		} else {
+			m_in.unread(ch);
+		}
+
+		return res;
+	}
+
+	private String handleDash() throws IOException {
+		int ch = nextToken();
+
+		if (ch == '-') {
+			int ch2 = nextToken();
+
+			if (ch2 == '-') {
+				int ch3 = nextToken();
+
+				if (ch3 == '-') {
+					// Empty away all the rest of the dashes.
+					// Do not forget to return the first non-match back.
+					while ((ch = nextToken()) == '-')
+						;
+
+					pushBack(ch);
+					return "-----";
+				}
+
+				pushBack(ch3);
+			}
+			pushBack(ch2);
+		}
+
+		pushBack(ch);
+
+		return "-";
+	}
+
+	private String handleHeading() throws IOException {
+		StringBuffer buf = new StringBuffer();
+
+		int ch = nextToken();
+
+		if (ch == '!') {
+			int ch2 = nextToken();
+
+			if (ch2 == '!') {
+				buf.append("h2. ");
+				m_closeTag = "";
+			} else {
+				buf.append("h3. ");
+				m_closeTag = "";
+				pushBack(ch2);
+			}
+		} else {
+			buf.append("h4. ");
+			m_closeTag = "";
+			pushBack(ch);
+		}
+
+		return buf.toString();
+	}
+
+	// TODO handle list
+	private String handleUnorderedList() throws IOException {
+		StringBuffer buf = new StringBuffer();
+
+		if (m_listlevel > 0) {
+			buf.append("</LI>\n");
+		}
+
+		int numBullets = countChars(m_in, '*') + 1;
+
+		if (numBullets > m_listlevel) {
+			for (; m_listlevel < numBullets; m_listlevel++)
+				buf.append("<UL>\n");
+		} else if (numBullets < m_listlevel) {
+			for (; m_listlevel > numBullets; m_listlevel--)
+				buf.append("</UL>\n");
+		}
+
+		buf.append("<LI>");
+
+		return buf.toString();
+	}
+
+	// TODO handle list
+	private String handleOrderedList() throws IOException {
+		StringBuffer buf = new StringBuffer();
+
+		if (m_numlistlevel > 0) {
+			buf.append("</LI>\n");
+		}
+
+		int numBullets = countChars(m_in, '#') + 1;
+
+		if (numBullets > m_numlistlevel) {
+			for (; m_numlistlevel < numBullets; m_numlistlevel++)
+				buf.append("<OL>\n");
+		} else if (numBullets < m_numlistlevel) {
+			for (; m_numlistlevel > numBullets; m_numlistlevel--)
+				buf.append("</OL>\n");
+		}
+
+		buf.append("<LI>");
+
+		return buf.toString();
+
+	}
+
+	private int countChars(PushbackReader in, char c) throws IOException {
+		int count = 0;
+		int ch;
+
+		while ((ch = in.read()) != -1) {
+			if ((char) ch == c) {
+				count++;
+			} else {
+				in.unread(ch);
+				break;
+			}
+		}
+
+		return count;
+	}
+
+	private String handleBar(boolean newLine) throws IOException {
+		StringBuffer sb = new StringBuffer();
+
+		if (!m_istable && !newLine) {
+			return "|";
+		}
+
+		if (newLine) {
+			if (!m_istable) {
+				sb.append("<TABLE CLASS=\"wikitable\" BORDER=\"1\">\n");
+				m_istable = true;
+			}
+
+			sb.append("<TR>");
+			m_closeTag = "</TD></TR>";
+		}
+
+		int ch = nextToken();
+
+		if (ch == '|') {
+			if (!newLine) {
+				sb.append("</TH>");
+			}
+			sb.append("<TH>");
+			m_closeTag = "</TH></TR>";
+		} else {
+			if (!newLine) {
+				sb.append("</TD>");
+			}
+			sb.append("<TD>");
+			pushBack(ch);
+		}
+
+		return sb.toString();
+	}
+
+	private String handleDefinitionList() throws IOException {
+		if (!m_isdefinition) {
+			m_isdefinition = true;
+
+			m_closeTag = "{quote}";
+
+			return "{quote:title=";
+		}
+
+		return ";";
+	}
+
+	private String handleBackslash() throws IOException {
+		int ch = nextToken();
+
+		if (ch == '\\') {
+			int ch2 = nextToken();
+
+			if (ch2 == '\\') {
+				int ch3 = nextToken();
+
+				if (ch3 == '\\') {
+					// TODO handle backbackslash
+					// return "<p style='page-break-before: always' />";
+				}
+
+				pushBack(ch3);
+
+				//TODO page break for printer
+				return "\\";
+			}
+
+			pushBack(ch2);
+
+			return "\\";
+		}
+
+		pushBack(ch);
+
+		return "\\";
+	}
+
+	private String handleOpenbracket() throws IOException {
+		StringBuffer sb = new StringBuffer();
+		int ch;
+		boolean isPlugin = false;
+
+		while ((ch = nextToken()) == '[') {
+			sb.append((char) ch);
+		}
+
+		if (sb.length() > 0) {
+			return sb.toString();// not a link
+		}
+
+		//
+		// Find end of hyperlink
+		//
+		pushBack(ch);
+		ch = nextToken();
+
+		while (ch != -1) {
+			if (ch == ']')// && (!isPlugin || sb.charAt( sb.length()-1 ) ==
+			// '}'
+			// ) )
+			{
+				break;
+			}
+
+			sb.append((char) ch);
+
+			ch = nextToken();
+		}
+
+		if (ch == -1) {
+
+			return sb.toString();
+		}
+
+		return handleHyperlinks(sb.toString());
+	}
+
+	private String handleOpenbrace() throws IOException {
+		int ch = nextToken();
+		String res = "{";
+
+		if (ch == '{') {
+			int ch2 = nextToken();
+
+			if (ch2 == '{') {
+				res = "{code}";
+				m_isPre = true;
+			} else {
+				pushBack(ch2);
+				// TODO <TT> truetype
+				res = "{font:courier new}";
+				m_isTypedText = true;
+			}
+		} else {
+			pushBack(ch);
+		}
+
+		return res;
+	}
+
+	/**
+	 * Handles both }} and }}}
+	 */
+	private String handleClosebrace() throws IOException {
+		String res = "}";
+
+		int ch2 = nextToken();
+
+		if (ch2 == '}') {
+			int ch3 = nextToken();
+
+			if (ch3 == '}') {
+				if (m_isPre) {
+					m_isPre = false;
+					res = "{code}";
+				} else {
+					res = "}}}";
+				}
+			} else {
+				pushBack(ch3);
+				// TODO truetype
+				if (!m_isPre) {
+					res = "{font}";
+					m_isTypedText = false;
+				} else {
+					pushBack(ch2);
+				}
+			}
+		} else {
+			pushBack(ch2);
+		}
+
+		return res;
+	}
+
+	/**
+	 * Returns true if the link is really command to insert a plugin.
+	 * <P>
+	 * Currently we just check if the link starts with "{INSERT", or just plain
+	 * "{" but not "{$".
+	 * 
+	 * @author Janne Jalkanen
+	 * 
+	 * @param link
+	 *            Link text, i.e. the contents of text between [].
+	 * @return True, if this link seems to be a command to insert a plugin here.
+	 */
+	public static boolean isPluginLink(String link) {
+		return link.startsWith("{INSERT")
+				|| (link.startsWith("{") && !link.startsWith("{$"));
+	}
+
+	/**
+	 * method to create links for external pages of Wiki pages
+	 * 
+	 * @param string
+	 * @return the HTML link representation of the wiki page/external link
+	 * @author Rali Genova
+	 */
+	private String handleHyperlinks(String link) {
+		String result = "";
+		String text = "";
+		String wikiPage = "";
+
+		if (isPluginLink(link)) {
+			// return null; // we do not include plugin links for now
+			// TODO make those CS macros
+
+			return link;
+		}
+		int border = link.indexOf('|');
+		if (border != -1) // [text|link] case
+		{
+			text = link.substring(0, border);
+			link = link.substring(border + 1);
+
+		} else // [link] case
+		{
+			if (!isExternalLink(link)) {
+				text = cleanLink(link);
+			} else {
+				text = link;
+			}
+		}
+		
+		/* can't be longer then 255 chars
+		if (text.length() > 255) {
+			System.out.println("Text longer !");
+			text = text.substring(0, 254);
+		}
+		
+		if (link.length() > 255) {
+			System.out.println("Link longer !");
+		}*/
+
+		// external link
+		if (isExternalLink(link)) {
+			if (checkImageLink(link)) {
+				result = "!" + link + "!";// external
+				// image
+			} else
+				result = "[" + text + "|" + link + "]";
+		}
+		// internal link
+		else {
+			// check if a footnote
+			if (link.startsWith("#"))// footnote reference
+			{// TODO handle footnote def
+				// http://labs.jboss.com/JSPWiki/Wiki.jsp?page=TextFormattingRules#ref-TextFormattingRules-1
+				result = "{FOOTNOTE RED " + link + " " + text + "}";
+
+			} else if (isNumber(link))// defines footnote
+			{// TODO handle footnote ref
+				result = "{FOOTNOTE DEF " + link + " " + text + "}";
+			}
+
+			// check if not an image link as well
+			else if (checkImageLink(link)) {
+				result = "!" + link + "!";
+
+			}
+			// check for attachments later on //TODO hanle attachments
+			else {
+
+				/*
+				 * wikiPage = wikiEngine.getRealName(cleanLink(link), wPage
+				 * .getLangCode()); if (wikiEngine.pageExists(wikiPage,
+				 * wPage.getLangCode())) { result = "<a href=\"" + portalHome +
+				 * wikiHome + page + wikiPage + language + wPage.getLangCode() +
+				 * "\">" + text + "</a>"; } else result = "<u>" + text + "</u>" + "<a
+				 * href=\"" + portalHome + wikiHome + page + wikiPage + language +
+				 * wPage.getLangCode() + "\">" + "?" + "</a>";
+				 */
+				return "[" + text + "|" + linkDict.get(link) + "]";
+			}
+		}
+
+		return result;
+	}
+
+	/**
+	 * Figures out if a link is an off-site link. This recognizes the most
+	 * common protocols by checking how it starts. (clears all white space in
+	 * case the link starts with '\n' or [space]
+	 * 
+	 * @author Janne Jalkanen
+	 */
+	public static boolean isExternalLink(String link) {
+		link = link.trim();
+		return link.startsWith("http:") || link.startsWith("ftp:")
+				|| link.startsWith("https:") || link.startsWith("mailto:")
+				|| link.startsWith("news:") || link.startsWith("file:");
+	}
+
+	private int nextToken() throws IOException {
+		return m_in.read();
+	}
+
+	/**
+	 * Push back any character to the current input. Does not push back a read
+	 * EOF, though.
+	 */
+
+	/**
+	 * Cleans a Wiki name.
+	 * <P>[ This is a link ] -&gt; ThisIsALink
+	 * 
+	 * @param link
+	 *            Link to be cleared. Null is safe, and causes this to return
+	 *            null.
+	 * @return A cleaned link.
+	 * 
+	 * @since 2.0
+	 * @author Janne Jalkanen
+	 */
+	public static String cleanLink(String link) {
+		StringBuffer clean = new StringBuffer();
+
+		if (link == null)
+			return null;
+
+		//
+		// Compress away all whitespace and capitalize
+		// all words in between.
+		//
+
+		StringTokenizer st = new StringTokenizer(link, " -");
+
+		while (st.hasMoreTokens()) {
+			StringBuffer component = new StringBuffer(st.nextToken());
+
+			component.setCharAt(0, Character.toUpperCase(component.charAt(0)));
+
+			//
+			// We must do this, because otherwise compiling on JDK 1.4 causes
+			// a downwards incompatibility to JDK 1.3.
+			//
+			clean.append(component.toString());
+		}
+
+		//
+		// Remove non-alphanumeric characters that should not
+		// be put inside WikiNames. Note that all valid
+		// Unicode letters are considered okay for WikiNames.
+		// It is the problem of the WikiPageProvider to take
+		// care of actually storing that information.
+		//
+
+		for (int i = 0; i < clean.length(); i++) {
+			if ((clean.charAt(i) != '/')
+					&& !(Character.isLetterOrDigit(clean.charAt(i))
+							|| clean.charAt(i) == '_' || clean.charAt(i) == '.')) {
+				clean.deleteCharAt(i);
+				--i; // We just shortened this buffer.
+			}
+		}
+
+		//
+		// Capitalise words in subpages
+		//
+
+		for (int i = 0; i < clean.length() - 1; i++) {
+			if ((clean.charAt(i) == '/')
+					&& (Character.isLowerCase(clean.charAt(i + 1)))) {
+				clean.setCharAt(i + 1, Character.toUpperCase(clean
+						.charAt(i + 1)));
+			}
+		}
+
+		return clean.toString();
+	}
+
+	/**
+	 * Returns true, if the argument contains a number, otherwise false. In a
+	 * quick test this is roughly the same speed as Integer.parseInt() if the
+	 * argument is a number, and roughly ten times the speed, if the argument is
+	 * NOT a number.
+	 */
+
+	public static boolean isNumber(String s) {
+		if (s == null)
+			return false;
+
+		if (s.length() > 1 && s.charAt(0) == '-')
+			s = s.substring(1);
+
+		for (int i = 0; i < s.length(); i++) {
+			if (!Character.isDigit(s.charAt(i)))
+				return false;
+		}
+
+		return true;
+	}
+
+	// not sure what it is supposed to do but neccessary to compile
+	public void next() {
+	}
+
+	public void initTranslator() {
+		m_allowHTML = true;
+		m_isbold = false;
+		m_isitalic = false;
+		m_isTypedText = false;
+		m_istable = false;
+		m_isPre = false;
+		m_isdefinition = false;
+		m_listlevel = 0;
+		m_numlistlevel = 0;
+		m_camelCaseLinks = true; // camelCase enabled
+		/** Tag that gets closed at EOL. */
+		m_closeTag = null;
+
+		mediaPatterns = ".png , .jpeg, .jpg , .gif , .bmp";
+	}
+
+	public String parse(String pageContent, Map<String, String> linkDict,
+			Map<String, String> linkDictRev) throws IOException {
+
+		this.linkDict = linkDict;
+		this.linkDictRev = linkDictRev;
+
+		initTranslator();
+
+		String replace = parseLinks(pageContent);
+
+		return replace;
+
+	}
+
+	protected boolean executePlugins() {
+		return true;
+	}
+
+}

Added: labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/migration-howto.txt
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/migration-howto.txt	                        (rev 0)
+++ labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/migration-howto.txt	2008-06-25 12:16:28 UTC (rev 20759)
@@ -0,0 +1,11 @@
+Clearspace Migration HOWTO
+
+1. Install clearspace
+2. create db with default charset utf default collate utf8_general_ci (//TODO)
+3. setup cs with db created
+4. run sql-script.txt (change db name if needed)
+ALTER TABLE `cs`.`jiveWikiLink` MODIFY COLUMN `targetText` LONGTEXT CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL;
+5. set envirnment MIGRATE to true export MIGRATE=true
+6. run clearspace, login -> migration will start
+7. Stop clearspace, run generated sql script in mysql (see clearspace log) versions_and_users-${DATE}.sql
+8. remove MIGRATE env from environment. start clearspace. check the migration

Added: labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/sql-script.txt
===================================================================
--- labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/sql-script.txt	                        (rev 0)
+++ labs/jbosslabs/trunk/portal-extensions/jbosswiki/wiki-common/src/java/org/jboss/labs/clearspace/sql-script.txt	2008-06-25 12:16:28 UTC (rev 20759)
@@ -0,0 +1 @@
+ALTER TABLE `cs`.`jiveWikiLink` MODIFY COLUMN `targetText` LONGTEXT CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL;




More information about the jboss-svn-commits mailing list