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"
|
<bean id="transformer.MediaWikiParser"
|
||||||
class="org.alfresco.repo.content.transform.MediaWikiContentTransformer"
|
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"
|
<bean id="transformer.OpenOffice"
|
||||||
class="org.alfresco.repo.content.transform.OpenOfficeContentTransformer"
|
class="org.alfresco.repo.content.transform.OpenOfficeContentTransformer"
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
<extension>shtml</extension>
|
<extension>shtml</extension>
|
||||||
<extension>body</extension>
|
<extension>body</extension>
|
||||||
</mimetype>
|
</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">
|
<mimetype mimetype="application/xhtml+xml" text="true" display="XHTML">
|
||||||
<extension default="true">xhtml</extension>
|
<extension default="true">xhtml</extension>
|
||||||
</mimetype>
|
</mimetype>
|
||||||
|
@ -24,7 +24,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.action.executer;
|
package org.alfresco.repo.action.executer;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.action.ParameterDefinitionImpl;
|
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_ASSOC_QNAME = "assoc-name";
|
||||||
public static final String PARAM_OVERWRITE_COPY = "overwrite-copy";
|
public static final String PARAM_OVERWRITE_COPY = "overwrite-copy";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injected services
|
||||||
|
*/
|
||||||
private DictionaryService dictionaryService;
|
private DictionaryService dictionaryService;
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
private ContentService contentService;
|
private ContentService contentService;
|
||||||
@ -281,7 +286,7 @@ public class TransformActionExecuter extends ActionExecuterAbstractBase
|
|||||||
// TODO: Check failure patterns for actions.
|
// TODO: Check failure patterns for actions.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
doTransform(ruleAction, contentReader, contentWriter);
|
doTransform(ruleAction, actionedUponNodeRef, contentReader, copyNodeRef, contentWriter);
|
||||||
}
|
}
|
||||||
catch(NoTransformerException e)
|
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.
|
* 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
|
// try to pre-empt the lack of a transformer
|
||||||
if (!this.contentService.isTransformable(contentReader, contentWriter))
|
if (!this.contentService.isTransformable(contentReader, contentWriter))
|
||||||
{
|
{
|
||||||
throw new NoTransformerException(contentReader.getMimetype(), contentWriter.getMimetype());
|
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 EXTENSION_BINARY = "bin";
|
||||||
|
|
||||||
public static final String MIMETYPE_TEXT_PLAIN = "text/plain";
|
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_CSS = "text/css";
|
||||||
public static final String MIMETYPE_TEXT_JAVASCRIPT = "text/javascript";
|
public static final String MIMETYPE_TEXT_JAVASCRIPT = "text/javascript";
|
||||||
public static final String MIMETYPE_XML = "text/xml";
|
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.ContentTransformerRegistry
|
||||||
* @see org.alfresco.repo.content.transform.ContentTransformer
|
* @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)
|
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
|
throws NoTransformerException, ContentIOException
|
||||||
{
|
{
|
||||||
// check that source and target mimetypes are available
|
// check that source and target mimetypes are available
|
||||||
@ -466,7 +477,7 @@ public class RoutingContentService implements ContentService
|
|||||||
throw new NoTransformerException(sourceMimetype, targetMimetype);
|
throw new NoTransformerException(sourceMimetype, targetMimetype);
|
||||||
}
|
}
|
||||||
// we have a transformer, so do it
|
// we have a transformer, so do it
|
||||||
transformer.transform(reader, writer);
|
transformer.transform(reader, writer, options);
|
||||||
// done
|
// done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,16 @@ import org.alfresco.service.cmr.repository.ContentWriter;
|
|||||||
*/
|
*/
|
||||||
public interface ContentTransformer extends ContentWorker
|
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
|
* Provides the approximate accuracy with which this transformer can
|
||||||
* transform from one mimetype to another.
|
* transform from one mimetype to another.
|
||||||
|
@ -24,13 +24,21 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.content.transform;
|
package org.alfresco.repo.content.transform;
|
||||||
|
|
||||||
|
import info.bliki.wiki.filter.Encoder;
|
||||||
import info.bliki.wiki.model.WikiModel;
|
import info.bliki.wiki.model.WikiModel;
|
||||||
|
import info.bliki.wiki.tags.ATag;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.repo.content.MimetypeMap;
|
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.ContentReader;
|
||||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
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.
|
* MediaWiki content transformer. Converts mediawiki markup into HTML.
|
||||||
@ -41,17 +49,41 @@ import org.alfresco.service.cmr.repository.ContentWriter;
|
|||||||
*/
|
*/
|
||||||
public class MediaWikiContentTransformer extends AbstractContentTransformer
|
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)
|
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))
|
!MimetypeMap.MIMETYPE_HTML.equals(targetMimetype))
|
||||||
{
|
{
|
||||||
// only support TEXT -> HTML
|
// only support MEDIAWIKI -> HTML
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -66,10 +98,60 @@ public class MediaWikiContentTransformer extends AbstractContentTransformer
|
|||||||
public void transformInternal(ContentReader reader, ContentWriter writer, Map<String, Object> options)
|
public void transformInternal(ContentReader reader, ContentWriter writer, Map<String, Object> options)
|
||||||
throws Exception
|
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
|
// 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
|
// Render the wiki content as HTML
|
||||||
writer.putContent(wikiModel.render(reader.getContentString()));
|
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
|
public void checkReliability() throws Exception
|
||||||
{
|
{
|
||||||
// check reliability
|
// 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%
|
assertEquals("Reliability incorrect", 1.0, reliability); // plain text to html is 100%
|
||||||
|
|
||||||
// check other way around
|
// 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%
|
assertEquals("Reliability incorrect", 0.0, reliability); // html to plain text is 0%
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMediaWikiToHTML() throws Exception
|
public void testMediaWikiToHTML() throws Exception
|
||||||
{
|
{
|
||||||
File input = File.createTempFile("mediaWikiTest", ".txt");
|
File input = File.createTempFile("mediaWikiTest", ".mw");
|
||||||
FileOutputStream fos = new FileOutputStream(input);
|
FileOutputStream fos = new FileOutputStream(input);
|
||||||
fos.write(WIKI_TEXT.getBytes());
|
fos.write(WIKI_TEXT.getBytes());
|
||||||
fos.close();
|
fos.close();
|
||||||
@ -106,7 +106,7 @@ public class MediaWikiContentTransformerTest extends AbstractContentTransformerT
|
|||||||
File output = File.createTempFile("mediaWikiTest", ".htm");
|
File output = File.createTempFile("mediaWikiTest", ".htm");
|
||||||
|
|
||||||
ContentReader contentReader = new FileContentReader(input);
|
ContentReader contentReader = new FileContentReader(input);
|
||||||
contentReader.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
contentReader.setMimetype(MimetypeMap.MIMETYPE_TEXT_MEDIAWIKI);
|
||||||
contentReader.setEncoding("UTF-8");
|
contentReader.setEncoding("UTF-8");
|
||||||
|
|
||||||
ContentWriter contentWriter = new FileContentWriter(output);
|
ContentWriter contentWriter = new FileContentWriter(output);
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.service.cmr.repository;
|
package org.alfresco.service.cmr.repository;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.repo.content.transform.ContentTransformer;
|
import org.alfresco.repo.content.transform.ContentTransformer;
|
||||||
import org.alfresco.service.Auditable;
|
import org.alfresco.service.Auditable;
|
||||||
import org.alfresco.service.PublicService;
|
import org.alfresco.service.PublicService;
|
||||||
@ -142,6 +144,23 @@ public interface ContentService
|
|||||||
public void transform(ContentReader reader, ContentWriter writer)
|
public void transform(ContentReader reader, ContentWriter writer)
|
||||||
throws NoTransformerException, ContentIOException;
|
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
|
* Fetch the transformer that is capable of transforming the content in the
|
||||||
* given source mimetype to the given target mimetype.
|
* given source mimetype to the given target mimetype.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user