001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet.wiki.engines.mediawiki;
016    
017    import com.liferay.portal.kernel.exception.SystemException;
018    import com.liferay.portal.kernel.util.StringPool;
019    import com.liferay.portal.kernel.util.StringUtil;
020    import com.liferay.portlet.wiki.PageContentException;
021    import com.liferay.portlet.wiki.engines.WikiEngine;
022    import com.liferay.portlet.wiki.engines.mediawiki.matchers.EditURLMatcher;
023    import com.liferay.portlet.wiki.engines.mediawiki.matchers.ImageURLMatcher;
024    import com.liferay.portlet.wiki.engines.mediawiki.matchers.ViewURLMatcher;
025    import com.liferay.portlet.wiki.model.WikiPage;
026    import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
027    
028    import java.util.HashMap;
029    import java.util.Map;
030    
031    import javax.portlet.PortletURL;
032    
033    import org.apache.commons.lang.LocaleUtils;
034    
035    import org.jamwiki.model.WikiUser;
036    import org.jamwiki.parser.ParserException;
037    import org.jamwiki.parser.ParserInput;
038    import org.jamwiki.parser.ParserOutput;
039    import org.jamwiki.parser.ParserUtil;
040    import org.jamwiki.parser.TableOfContents;
041    
042    /**
043     * @author Jonathan Potter
044     */
045    public class MediaWikiEngine implements WikiEngine {
046    
047            public String convert(
048                            WikiPage page, PortletURL viewPageURL, PortletURL editPageURL,
049                            String attachmentURLPrefix)
050                    throws PageContentException {
051    
052                    String html = parsePage(page, new ParserOutput());
053    
054                    html = postParsePage(
055                            html, viewPageURL, editPageURL, attachmentURLPrefix);
056    
057                    return html;
058            }
059    
060            public Map<String, Boolean> getOutgoingLinks(WikiPage page)
061                    throws PageContentException {
062    
063                    ParserOutput parserOutput = getParserOutput(page);
064    
065                    Map<String, Boolean> outgoingLinks = new HashMap<String, Boolean>();
066    
067                    for (String title : parserOutput.getLinks()) {
068                            Boolean existsObj = outgoingLinks.get(title);
069    
070                            if (existsObj == null) {
071                                    int pagesCount = 0;
072    
073                                    try {
074                                            pagesCount = WikiPageLocalServiceUtil.getPagesCount(
075                                                    page.getNodeId(), title, true);
076                                    }
077                                    catch (SystemException se) {
078                                            throw new PageContentException(se);
079                                    }
080    
081                                    if (pagesCount > 0) {
082                                            existsObj = Boolean.TRUE;
083                                    }
084                                    else {
085                                            existsObj = Boolean.FALSE;
086    
087                                            // JAMWiki turns images into links. The postProcess method
088                                            // turns them back to images, but the getOutgoingLinks does
089                                            // not call postProcess, so we must manual process this
090                                            // case.
091    
092                                            if (StringUtil.startsWith(title, "image:")) {
093                                                    continue;
094                                            }
095                                    }
096    
097                                    outgoingLinks.put(title.toLowerCase(), existsObj);
098                            }
099                    }
100    
101                    return outgoingLinks;
102            }
103    
104            public void setInterWikiConfiguration(String interWikiConfiguration) {
105            }
106    
107            public void setMainConfiguration(String mainConfiguration) {
108            }
109    
110            public boolean validate(long nodeId, String content) {
111                    return true;
112            }
113    
114            protected ParserInput getParserInput(long nodeId, String topicName) {
115                    ParserInput parserInput = new ParserInput();
116    
117                    // Dummy values
118    
119                    parserInput.setContext("/wiki");
120                    parserInput.setLocale(LocaleUtils.toLocale("en_US"));
121                    parserInput.setUserDisplay("0.0.0.0");
122                    parserInput.setWikiUser(new WikiUser("DummyUser"));
123    
124                    // Useful values
125    
126                    parserInput.setAllowSectionEdit(false);
127                    parserInput.setTopicName(topicName);
128    
129                    // Encode node id
130    
131                    parserInput.setVirtualWiki("Special:Node:" + nodeId);
132    
133                    // Table of contents
134    
135                    TableOfContents tableOfContents = new TableOfContents();
136    
137                    tableOfContents.setForceTOC(true);
138    
139                    parserInput.setTableOfContents(tableOfContents);
140    
141                    return parserInput;
142            }
143    
144            protected ParserOutput getParserOutput(WikiPage page)
145                    throws PageContentException {
146    
147                    ParserInput parserInput = getParserInput(
148                            page.getNodeId(), page.getTitle());
149    
150                    ParserOutput parserOutput = null;
151    
152                    try {
153                            parserOutput = ParserUtil.parseMetadata(
154                                    parserInput, page.getContent());
155                    }
156                    catch (ParserException pe) {
157                            throw new PageContentException(pe);
158                    }
159    
160                    return parserOutput;
161            }
162    
163            protected String parsePage(WikiPage page, ParserOutput parserOutput)
164                    throws PageContentException {
165    
166                    ParserInput parserInput = getParserInput(
167                            page.getNodeId(), page.getTitle());
168    
169                    String html = StringPool.BLANK;
170    
171                    try {
172                            html = ParserUtil.parse(
173                                    parserInput, parserOutput, page.getContent());
174                    }
175                    catch (ParserException pe) {
176                            throw new PageContentException(pe);
177                    }
178    
179                    return html;
180            }
181    
182            protected String postParsePage(
183                    String content, PortletURL viewPageURL, PortletURL editPageURL,
184                    String attachmentURLPrefix) {
185    
186                    EditURLMatcher editURLMatcher = new EditURLMatcher(editPageURL);
187    
188                    content = editURLMatcher.replaceMatches(content);
189    
190                    ImageURLMatcher imageURLMatcher = new ImageURLMatcher(
191                            attachmentURLPrefix);
192    
193                    content = imageURLMatcher.replaceMatches(content);
194    
195                    ViewURLMatcher viewURLMatcher = new ViewURLMatcher(viewPageURL);
196    
197                    content = viewURLMatcher.replaceMatches(content);
198    
199                    return content;
200            }
201    
202    }