[jboss-cvs] jboss-seam/examples/wiki/src/org/jboss/seam/wiki/core/links ...
Christian Bauer
christian.bauer at jboss.com
Thu Feb 1 02:08:28 EST 2007
User: cbauer
Date: 07/02/01 02:08:28
Added: examples/wiki/src/org/jboss/seam/wiki/core/links
WikiLinkResolver.java WikiTextParser.java
Log:
Committed first (broken) wiki implementation
Revision Changes Path
1.1 date: 2007/02/01 07:08:28; author: cbauer; state: Exp;jboss-seam/examples/wiki/src/org/jboss/seam/wiki/core/links/WikiLinkResolver.java
Index: WikiLinkResolver.java
===================================================================
package org.jboss.seam.wiki.core.links;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.wiki.core.node.Document;
import org.jboss.seam.wiki.core.node.Directory;
import org.jboss.seam.wiki.core.node.Node;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.NoResultException;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.Map;
import java.net.URLEncoder;
import java.io.UnsupportedEncodingException;
@Name("wikiLinkResolver")
public class WikiLinkResolver {
// Prepended to primary keys in the database, e.g. [This is a stored link=>wiki://5]
public static final String WIKI_PROTOCOL = "wiki://";
// Used against page names, wimply remove everything that is not alphanumeric, should do for most strings
public static final String WIKINAME_REMOVECHARACTERS = "[^\\p{Alnum}]+";
// Render this string whenever [=>wiki://123] needs to be resolved but can't
public static final String BROKENLINK_MARKER = "BROKEN LINK";
// Match [GROUP1=>GROUP2], used to replace links from user input with wiki:// URLs
public static final String WIKILINK_REGEX_FORWARD =
Pattern.quote("[") + "([^" + Pattern.quote("]") + "|" + Pattern.quote("[") + "]*)" +
"=>([^(?://|@|" + Pattern.quote("]") + "|" + Pattern.quote("[") + ")]+)" + Pattern.quote("]");
// Match [GROUP1=>wiki://GROUP2], used to replace wiki:// URLs with page names
public static final String WIKILINK_REGEX_REVERSE =
Pattern.quote("[") + "([^" + Pattern.quote("]") + "|" + Pattern.quote("[") + "]*)" +
"=>" + WIKI_PROTOCOL + "([0-9]+)" + Pattern.quote("]");
@In(create = true)
protected EntityManager entityManager;
@In(required = false)
private Document currentDocument;
@In(required = false)
private Directory currentDirectory;
public static String convertToWikiName(String realName) {
return realName.replaceAll(WIKINAME_REMOVECHARACTERS, "");
}
public String convertToWikiLinks(Directory area, String wikiText) {
StringBuffer replacedWikiText = new StringBuffer(wikiText.length());
Pattern pattern = Pattern.compile(WIKILINK_REGEX_FORWARD);
Matcher matcher = pattern.matcher(wikiText);
// Replace with [Link Text=>wiki://<node id>] or leave as is if not found
while (matcher.find()) {
Node node = findNodeInArea(area, convertToWikiName(matcher.group(2)));
if (node != null) {
matcher.appendReplacement(replacedWikiText, "[$1=>wiki://" + node.getId() + "]");
}
}
matcher.appendTail(replacedWikiText);
return replacedWikiText.toString();
}
public String convertFromWikiLinks(String wikiText) {
if (wikiText == null) return null;
StringBuffer replacedWikiText = new StringBuffer(wikiText.length());
Pattern pattern = Pattern.compile(WIKILINK_REGEX_REVERSE);
Matcher matcher = pattern.matcher(wikiText);
// Replace with [Link Text=>Page Name] or replace with BROKEN LINK marker
while (matcher.find()) {
// Find the node by PK
Node node = findNode(Long.valueOf(matcher.group(2)));
if (node != null) {
matcher.appendReplacement(replacedWikiText, "[$1=>" + node.getName() + "]");
} else {
matcher.appendReplacement(replacedWikiText, "[$1=>" + BROKENLINK_MARKER + "]");
}
}
matcher.appendTail(replacedWikiText);
return replacedWikiText.toString();
}
@Transactional
public void resolveWikiLink(Map<String, WikiLink> links, String linkText) {
// Don't resolve twice
if (links.containsKey(linkText)) return;
Pattern pattern = Pattern.compile(WIKI_PROTOCOL + "([0-9]+)");
Matcher matcher = pattern.matcher(linkText);
WikiLink wikiLink = null;
// Check if its a common protocol
if ("http://".equals(linkText.substring(0, 6)) ||
"https://".equals(linkText.substring(0,7)) ||
"mailto://".equals(linkText.substring(0,8)) ||
"ftp://".equals(linkText.substring(0,5))
) {
wikiLink = new WikiLink(null, false, linkText, linkText);
// Check if it is a wiki protocol
} else if (matcher.find()) {
// Find the node by PK
Node node = findNode(Long.valueOf(matcher.group(1)));
if (node != null) {
wikiLink = new WikiLink(node.getId(), false, node.getId() + ".html", node.getName());
} else {
wikiLink = new WikiLink(Long.valueOf(matcher.group(1)), true, BROKENLINK_MARKER, BROKENLINK_MARKER);
}
// Try a WikiWord search in the current area
} else {
Node node = findNodeInArea(currentDirectory, convertToWikiName(linkText));
if (node!=null) {
wikiLink = new WikiLink(node.getId(), false, node.getId() + ".html", node.getName());
// Run the converter again and UPDATE the currentDocument (yes, not the best solution)
currentDocument.setContent(convertToWikiLinks(currentDirectory, currentDocument.getContent()));
// This should be updated in the database during the next flush()
}
}
// Let's assume its a page name and render a real /Area/WikiLink (but encoded, so it gets transported fully)
if (wikiLink == null) {
try {
String encodedPagename = currentDirectory.getWikiname() + "/" + URLEncoder.encode(linkText, "UTF-8");
wikiLink = new WikiLink(null, true, encodedPagename, linkText);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e); // Java is so great...
}
}
links.put(linkText, wikiLink);
}
public class WikiLink {
Long nodeId;
boolean broken = false;
String url;
String description;
public WikiLink(Long nodeId, boolean broken, String url, String description) {
this.nodeId = nodeId;
this.broken = broken;
this.url = url;
this.description = description;
}
public String toString() {
return "Description: " + description + " URL: " + url;
}
}
// Convenience methods
@Transactional
public Node findNode(Long nodeId) {
entityManager.joinTransaction();
try {
return entityManager.find(Node.class, nodeId);
} catch (EntityNotFoundException ex) {
}
return null;
}
@Transactional
public Node findNodeInArea(Directory area, String wikiname) {
entityManager.joinTransaction();
try {
return (Node) entityManager
.createQuery("select n from Node n where n.areaNumber = :areaNumber and n.wikiname = :wikiname")
.setParameter("areaNumber", area.getAreaNumber())
.setParameter("wikiname", wikiname)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {
}
return null;
}
@Transactional
public Document findDocumentInArea(Directory area, String wikiname) {
entityManager.joinTransaction();
try {
return (Document) entityManager
.createQuery("select d from Document d where d.areaNumber = :areaNumber and d.wikiname = :wikiname")
.setParameter("areaNumber", area.getAreaNumber())
.setParameter("wikiname", wikiname)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {
}
return null;
}
@Transactional
public Directory findDirectoryInArea(Directory area, String wikiname) {
entityManager.joinTransaction();
try {
return (Directory) entityManager
.createQuery("select d from Directory d where d.areaNumber = :areaNumber and d.wikiname = :wikiname")
.setParameter("areaNumber", area.getAreaNumber())
.setParameter("wikiname", wikiname)
.getSingleResult();
} catch (EntityNotFoundException ex) {
} catch (NoResultException ex) {
}
return null;
}
}
1.1 date: 2007/02/01 07:08:28; author: cbauer; state: Exp;jboss-seam/examples/wiki/src/org/jboss/seam/wiki/core/links/WikiTextParser.java
Index: WikiTextParser.java
===================================================================
package org.jboss.seam.wiki.core.links;
import org.jboss.seam.text.SeamTextParser;
import org.jboss.seam.Component;
import antlr.TokenStream;
import java.util.Map;
import java.util.HashMap;
public class WikiTextParser extends SeamTextParser {
private Map<String, WikiLinkResolver.WikiLink> links = new HashMap<String, WikiLinkResolver.WikiLink>();
private WikiLinkResolver resolver;
public WikiTextParser(TokenStream tokenStream, String linkClass, String brokenLinkClass) {
super(tokenStream);
resolver = (WikiLinkResolver)Component.getInstance(WikiLinkResolver.class);
}
protected String linkUrl(String linkText) {
resolver.resolveWikiLink(links, linkText.trim());
return links.get(linkText).url;
}
protected String linkDescription(String descriptionText, String linkText) {
return links.get(linkText).description;
}
protected String linkClass(String linkText) {
return links.get(linkText).broken ? "foo" : "bar";
}
}
More information about the jboss-cvs-commits
mailing list