mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-16 17:55:15 +00:00
MediaWiki markup transformer now generates internal links that work
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8416 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
parent
428e92479a
commit
085c402290
@ -235,7 +235,14 @@
|
||||
|
||||
<bean id="transformer.MediaWikiParser"
|
||||
class="org.alfresco.repo.content.transform.MediaWikiContentTransformer"
|
||||
parent="baseContentTransformer" />
|
||||
parent="baseContentTransformer">
|
||||
<property name="nodeService">
|
||||
<ref bean="NodeService" />
|
||||
</property>
|
||||
<property name="fileFolderService">
|
||||
<ref bean="FileFolderService" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="transformer.OpenOffice"
|
||||
class="org.alfresco.repo.content.transform.OpenOfficeContentTransformer"
|
||||
|
@ -22,6 +22,9 @@
|
||||
<extension>shtml</extension>
|
||||
<extension>body</extension>
|
||||
</mimetype>
|
||||
<mimetype mimetype="text/mediawiki" text="true" display="MediaWiki Markup">
|
||||
<extension display="MediaWiki Markup" default="true">mw</extension>
|
||||
</mimetype>
|
||||
<mimetype mimetype="application/xhtml+xml" text="true" display="XHTML">
|
||||
<extension default="true">xhtml</extension>
|
||||
</mimetype>
|
||||
|
@ -24,7 +24,9 @@
|
||||
*/
|
||||
package org.alfresco.repo.action.executer;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.action.ParameterDefinitionImpl;
|
||||
@ -73,6 +75,9 @@ public class TransformActionExecuter extends ActionExecuterAbstractBase
|
||||
public static final String PARAM_ASSOC_QNAME = "assoc-name";
|
||||
public static final String PARAM_OVERWRITE_COPY = "overwrite-copy";
|
||||
|
||||
/**
|
||||
* Injected services
|
||||
*/
|
||||
private DictionaryService dictionaryService;
|
||||
private NodeService nodeService;
|
||||
private ContentService contentService;
|
||||
@ -281,7 +286,7 @@ public class TransformActionExecuter extends ActionExecuterAbstractBase
|
||||
// TODO: Check failure patterns for actions.
|
||||
try
|
||||
{
|
||||
doTransform(ruleAction, contentReader, contentWriter);
|
||||
doTransform(ruleAction, actionedUponNodeRef, contentReader, copyNodeRef, contentWriter);
|
||||
}
|
||||
catch(NoTransformerException e)
|
||||
{
|
||||
@ -299,14 +304,23 @@ public class TransformActionExecuter extends ActionExecuterAbstractBase
|
||||
/**
|
||||
* Executed in a new transaction so that failures don't cause the entire transaction to rollback.
|
||||
*/
|
||||
protected void doTransform(Action ruleAction, ContentReader contentReader, ContentWriter contentWriter)
|
||||
protected void doTransform( Action ruleAction,
|
||||
NodeRef sourceNodeRef, ContentReader contentReader,
|
||||
NodeRef destinationNodeRef, ContentWriter contentWriter)
|
||||
{
|
||||
// try to pre-empt the lack of a transformer
|
||||
if (!this.contentService.isTransformable(contentReader, contentWriter))
|
||||
{
|
||||
throw new NoTransformerException(contentReader.getMimetype(), contentWriter.getMimetype());
|
||||
}
|
||||
this.contentService.transform(contentReader, contentWriter);
|
||||
|
||||
// build map of options
|
||||
Map<String, Object> options = new HashMap<String, Object>(2);
|
||||
options.put(ContentTransformer.OPT_SOURCE_NODEREF, sourceNodeRef);
|
||||
options.put(ContentTransformer.OPT_DESTINATION_NODEREF, destinationNodeRef);
|
||||
|
||||
// transform
|
||||
this.contentService.transform(contentReader, contentWriter, options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,6 +56,7 @@ public class MimetypeMap implements MimetypeService
|
||||
public static final String EXTENSION_BINARY = "bin";
|
||||
|
||||
public static final String MIMETYPE_TEXT_PLAIN = "text/plain";
|
||||
public static final String MIMETYPE_TEXT_MEDIAWIKI = "text/mediawiki";
|
||||
public static final String MIMETYPE_TEXT_CSS = "text/css";
|
||||
public static final String MIMETYPE_TEXT_JAVASCRIPT = "text/javascript";
|
||||
public static final String MIMETYPE_XML = "text/xml";
|
||||
|
@ -444,8 +444,19 @@ public class RoutingContentService implements ContentService
|
||||
/**
|
||||
* @see org.alfresco.repo.content.transform.ContentTransformerRegistry
|
||||
* @see org.alfresco.repo.content.transform.ContentTransformer
|
||||
* @see org.alfresco.service.cmr.repository.ContentService#transform(org.alfresco.service.cmr.repository.ContentReader, org.alfresco.service.cmr.repository.ContentWriter)
|
||||
*/
|
||||
public void transform(ContentReader reader, ContentWriter writer)
|
||||
{
|
||||
// Call transform with not options
|
||||
this.transform(reader, writer, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.content.transform.ContentTransformerRegistry
|
||||
* @see org.alfresco.repo.content.transform.ContentTransformer
|
||||
*/
|
||||
public void transform(ContentReader reader, ContentWriter writer, Map<String, Object> options)
|
||||
throws NoTransformerException, ContentIOException
|
||||
{
|
||||
// check that source and target mimetypes are available
|
||||
@ -466,7 +477,7 @@ public class RoutingContentService implements ContentService
|
||||
throw new NoTransformerException(sourceMimetype, targetMimetype);
|
||||
}
|
||||
// we have a transformer, so do it
|
||||
transformer.transform(reader, writer);
|
||||
transformer.transform(reader, writer, options);
|
||||
// done
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,16 @@ import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
*/
|
||||
public interface ContentTransformer extends ContentWorker
|
||||
{
|
||||
/**
|
||||
* Transform option constants
|
||||
*
|
||||
* It is up to the transformation implementation whether these
|
||||
* options are used, but they should be considered optional and their absence
|
||||
* should not interfere with the execution of the transformer.
|
||||
*/
|
||||
public static final String OPT_SOURCE_NODEREF = "sourceNodeRef";
|
||||
public static final String OPT_DESTINATION_NODEREF = "destinationNodeRef";
|
||||
|
||||
/**
|
||||
* Provides the approximate accuracy with which this transformer can
|
||||
* transform from one mimetype to another.
|
||||
|
@ -24,13 +24,21 @@
|
||||
*/
|
||||
package org.alfresco.repo.content.transform;
|
||||
|
||||
import info.bliki.wiki.filter.Encoder;
|
||||
import info.bliki.wiki.model.WikiModel;
|
||||
import info.bliki.wiki.tags.ATag;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.htmlcleaner.ContentToken;
|
||||
|
||||
/**
|
||||
* MediaWiki content transformer. Converts mediawiki markup into HTML.
|
||||
@ -41,17 +49,41 @@ import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
*/
|
||||
public class MediaWikiContentTransformer extends AbstractContentTransformer
|
||||
{
|
||||
//private static final Log logger = LogFactory.getLog(MediaWikiContentTransformer.class);
|
||||
/** The file folder service */
|
||||
private FileFolderService fileFolderService;
|
||||
|
||||
/** The node service */
|
||||
private NodeService nodeService;
|
||||
|
||||
/**
|
||||
* Only support TEXT to HTML
|
||||
* Sets the file folder service
|
||||
*
|
||||
* @param fileFolderService the file folder service
|
||||
*/
|
||||
public void setFileFolderService(FileFolderService fileFolderService)
|
||||
{
|
||||
this.fileFolderService = fileFolderService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the node service
|
||||
*
|
||||
* @param nodeService the node service
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only support MEDIAWIKI to HTML
|
||||
*/
|
||||
public double getReliability(String sourceMimetype, String targetMimetype)
|
||||
{
|
||||
if (!MimetypeMap.MIMETYPE_TEXT_PLAIN.equals(sourceMimetype) ||
|
||||
if (!MimetypeMap.MIMETYPE_TEXT_MEDIAWIKI.equals(sourceMimetype) ||
|
||||
!MimetypeMap.MIMETYPE_HTML.equals(targetMimetype))
|
||||
{
|
||||
// only support TEXT -> HTML
|
||||
// only support MEDIAWIKI -> HTML
|
||||
return 0.0;
|
||||
}
|
||||
else
|
||||
@ -66,10 +98,60 @@ public class MediaWikiContentTransformer extends AbstractContentTransformer
|
||||
public void transformInternal(ContentReader reader, ContentWriter writer, Map<String, Object> options)
|
||||
throws Exception
|
||||
{
|
||||
String imageURL = "{$image}";
|
||||
String pageURL = "${title}";
|
||||
|
||||
if (options.containsKey(ContentTransformer.OPT_DESTINATION_NODEREF) == true)
|
||||
{
|
||||
NodeRef destinationNodeRef = (NodeRef)options.get(ContentTransformer.OPT_DESTINATION_NODEREF);
|
||||
NodeRef parentNodeRef = this.nodeService.getPrimaryParent(destinationNodeRef).getParentRef();
|
||||
|
||||
StringBuffer folderPath = new StringBuffer(256);
|
||||
List<FileInfo> fileInfos = this.fileFolderService.getNamePath(null, parentNodeRef);
|
||||
for (FileInfo fileInfo : fileInfos)
|
||||
{
|
||||
folderPath.append(fileInfo.getName()).append("/");
|
||||
}
|
||||
|
||||
pageURL = "/alfresco/d/d?path=" + folderPath + "${title}.html";
|
||||
imageURL = "/alfresco/d/d?path=" + folderPath + "Images/${image}";
|
||||
}
|
||||
|
||||
// Create the wikiModel and set the title and image link URL's
|
||||
WikiModel wikiModel = new WikiModel("${image}", "${title}");
|
||||
AlfrescoWikiModel wikiModel = new AlfrescoWikiModel(imageURL, pageURL);
|
||||
|
||||
// Render the wiki content as HTML
|
||||
writer.putContent(wikiModel.render(reader.getContentString()));
|
||||
}
|
||||
|
||||
private class AlfrescoWikiModel extends WikiModel
|
||||
{
|
||||
public AlfrescoWikiModel(String imageBaseURL, String linkBaseURL)
|
||||
{
|
||||
super(imageBaseURL, linkBaseURL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendInternalLink(String link, String hashSection, String linkText)
|
||||
{
|
||||
link = link.replaceAll(":", " - ");
|
||||
String encodedtopic = Encoder.encodeTitleUrl(link);
|
||||
encodedtopic = encodedtopic.replaceAll("_", " ");
|
||||
|
||||
String hrefLink = fExternalWikiBaseURL.replace("${title}", encodedtopic);
|
||||
|
||||
ATag aTagNode = new ATag();
|
||||
append(aTagNode);
|
||||
aTagNode.addAttribute("id", "w");
|
||||
String href = hrefLink;
|
||||
if (hashSection != null) {
|
||||
href = href + '#' + hashSection;
|
||||
}
|
||||
aTagNode.addAttribute("href", href);
|
||||
aTagNode.addObjectAttribute("wikilink", hrefLink);
|
||||
|
||||
ContentToken text = new ContentToken(linkText);
|
||||
aTagNode.addChild(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -88,17 +88,17 @@ public class MediaWikiContentTransformerTest extends AbstractContentTransformerT
|
||||
public void checkReliability() throws Exception
|
||||
{
|
||||
// check reliability
|
||||
double reliability = transformer.getReliability(MimetypeMap.MIMETYPE_TEXT_PLAIN, MimetypeMap.MIMETYPE_HTML);
|
||||
double reliability = transformer.getReliability(MimetypeMap.MIMETYPE_TEXT_MEDIAWIKI, MimetypeMap.MIMETYPE_HTML);
|
||||
assertEquals("Reliability incorrect", 1.0, reliability); // plain text to html is 100%
|
||||
|
||||
// check other way around
|
||||
reliability = transformer.getReliability(MimetypeMap.MIMETYPE_HTML, MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||
reliability = transformer.getReliability(MimetypeMap.MIMETYPE_HTML, MimetypeMap.MIMETYPE_TEXT_MEDIAWIKI);
|
||||
assertEquals("Reliability incorrect", 0.0, reliability); // html to plain text is 0%
|
||||
}
|
||||
|
||||
public void testMediaWikiToHTML() throws Exception
|
||||
{
|
||||
File input = File.createTempFile("mediaWikiTest", ".txt");
|
||||
File input = File.createTempFile("mediaWikiTest", ".mw");
|
||||
FileOutputStream fos = new FileOutputStream(input);
|
||||
fos.write(WIKI_TEXT.getBytes());
|
||||
fos.close();
|
||||
@ -106,7 +106,7 @@ public class MediaWikiContentTransformerTest extends AbstractContentTransformerT
|
||||
File output = File.createTempFile("mediaWikiTest", ".htm");
|
||||
|
||||
ContentReader contentReader = new FileContentReader(input);
|
||||
contentReader.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||
contentReader.setMimetype(MimetypeMap.MIMETYPE_TEXT_MEDIAWIKI);
|
||||
contentReader.setEncoding("UTF-8");
|
||||
|
||||
ContentWriter contentWriter = new FileContentWriter(output);
|
||||
|
@ -24,6 +24,8 @@
|
||||
*/
|
||||
package org.alfresco.service.cmr.repository;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.content.transform.ContentTransformer;
|
||||
import org.alfresco.service.Auditable;
|
||||
import org.alfresco.service.PublicService;
|
||||
@ -142,6 +144,23 @@ public interface ContentService
|
||||
public void transform(ContentReader reader, ContentWriter writer)
|
||||
throws NoTransformerException, ContentIOException;
|
||||
|
||||
|
||||
/**
|
||||
* @see org.aflresco.service.cmr.repository.ContentService.transform(ContentReader, ContentReader)
|
||||
*
|
||||
* A map of transform options can be provided.
|
||||
*
|
||||
* @param reader the source content location and mimetype
|
||||
* @param writer the target content location and mimetype
|
||||
* @param options the options for the transformation
|
||||
* @throws NoTransformerException if no transformer exists for the
|
||||
* given source and target mimetypes of the reader and writer
|
||||
* @throws ContentIOException if the transformation fails
|
||||
*/
|
||||
@Auditable(parameters = {"reader", "writer", "options"})
|
||||
public void transform(ContentReader reader, ContentWriter writer, Map<String, Object> options)
|
||||
throws NoTransformerException, ContentIOException;
|
||||
|
||||
/**
|
||||
* Fetch the transformer that is capable of transforming the content in the
|
||||
* given source mimetype to the given target mimetype.
|
||||
|
Loading…
x
Reference in New Issue
Block a user