private void updateStack(ParserInput parserInput, Stack stack, String stackName) { if (stack.empty()) { parserInput.getTempParams().remove(stackName); } else { parserInput.getTempParams().put(stackName, stack); } }
private String linkHtml( ParserInput parserInput, ParserOutput parserOutput, int mode, String link, String text, String punctuation, boolean numberedCaption) throws ParserException { if (link.toLowerCase().startsWith("mailto://")) { // fix bad mailto syntax link = "mailto:" + link.substring("mailto://".length()); } String caption = link; if (!StringUtils.isBlank(text)) { // pass a parameter via the parserInput to prevent nested links from being generated parserInput.getTempParams().put(HTML_LINK_CAPTION, true); caption = JFlexParserUtil.parseFragment(parserInput, parserOutput, text, mode); parserInput.getTempParams().remove(HTML_LINK_CAPTION); } else if (numberedCaption) { // set the caption of the form "[1]" int counter = 1; if (parserInput.getTempParams().get(HTML_LINK_CAPTION_COUNTER) != null) { counter = (Integer) parserInput.getTempParams().get(HTML_LINK_CAPTION_COUNTER); } parserInput.getTempParams().put(HTML_LINK_CAPTION_COUNTER, counter + 1); caption = "[" + counter + "]"; } return LinkUtil.buildExternalLinkHtml(link, "externallink", caption) + punctuation; }
/** * Retrieve the content of a topic from the cache, or if it is not yet in the cache then add it to * the cache. * * @param context The servlet context for the topic being retrieved. May be <code>null</code> if * the <code>cook</code> parameter is set to <code>false</code>. * @param locale The locale for the topic being retrieved. May be <code>null</code> if the <code> * cook</code> parameter is set to <code>false</code>. * @param virtualWiki The virtual wiki for the topic being retrieved. * @param topicName The name of the topic being retrieved. * @param cook A parameter indicating whether or not the content should be parsed before it is * added to the cache. Stylesheet content (CSS) is not parsed, but most other content is * parsed. * @return The parsed or unparsed (depending on the <code>cook</code> parameter) topic content. */ protected static String cachedContent( String context, Locale locale, String virtualWiki, String topicName, boolean cook) { String content = null; String key = WikiCache.key(virtualWiki, topicName); Element cacheElement = WikiCache.retrieveFromCache(WikiBase.CACHE_PARSED_TOPIC_CONTENT, key); if (cacheElement != null) { content = (String) cacheElement.getObjectValue(); return (content == null) ? null : new String(content); } try { Topic topic = WikiBase.getDataHandler().lookupTopic(virtualWiki, topicName, false, null); content = topic.getTopicContent(); if (cook) { ParserInput parserInput = new ParserInput(); parserInput.setContext(context); parserInput.setLocale(locale); parserInput.setVirtualWiki(virtualWiki); parserInput.setTopicName(topicName); content = Utilities.parse(parserInput, null, content); } WikiCache.addToCache(WikiBase.CACHE_PARSED_TOPIC_CONTENT, key, content); } catch (Exception e) { logger.warning("error getting cached page " + virtualWiki + " / " + topicName, e); return null; } return content; }
private static String getContent(final WikiPage wikiPage) { try { final ParserInput input = new ParserInput(); input.setWikiUser(null); input.setAllowSectionEdit(false); input.setDepth(2); input.setContext(""); input.setLocale(Locale.ENGLISH); input.setTopicName("dummy"); input.setUserIpAddress("0.0.0.0"); input.setDataHandler(DUMMY_DATA_HANDLER); input.setVirtualWiki("/olat"); final AbstractParser parser = new JFlexParser(input); final ParserDocument parsedDoc = parser.parseHTML(wikiPage.getContent()); final String parsedContent = parsedDoc.getContent(); final String filteredContent = FilterFactory.getHtmlTagAndDescapingFilter().filter(parsedContent); return filteredContent; } catch (final Exception e) { e.printStackTrace(); log.error("", e); return wikiPage.getContent(); } }
private Stack retrieveStack(ParserInput parserInput, String stackName) { Stack stack = (Stack) parserInput.getTempParams().get(stackName); if (stack == null) { stack = new Stack(); parserInput.getTempParams().put(stackName, stack); } return stack; }
private String updateToc(ParserInput parserInput, String name, String text, int level) { String output = ""; if (parserInput.getTableOfContents().getStatus() == TableOfContents.STATUS_TOC_UNINITIALIZED) { output += "__TOC__"; } parserInput.getTableOfContents().addEntry(name, text, level); return output; }
/** * During parsing the reference objects will be stored as a temporary array. This method parses * that array and returns the reference objects. * * @param parserInput The current ParserInput object for the topic that is being parsed. * @return A list of reference objects (never <code>null</code>) for the current topic that is * being parsed. */ protected static List<WikiReference> retrieveReferences(ParserInput parserInput) { List<WikiReference> references = (List<WikiReference>) parserInput.getTempParams().get(WikiReferenceTag.REFERENCES_PARAM); if (references == null) { references = new ArrayList<WikiReference>(); parserInput.getTempParams().put(WikiReferenceTag.REFERENCES_PARAM, references); } return references; }
@Override public void appendInterWikiLink(String namespace, String title, String topicDescription) { String hrefLink = getInterwikiMap().get(namespace.toLowerCase()); if (hrefLink != null) { String virtualWiki = fParserInput.getVirtualWiki(); WikiLink wikiLink = LinkUtil.parseWikiLink( virtualWiki, namespace + Namespace.SEPARATOR + title + "|" + topicDescription); String destination = wikiLink.getDestination(); destination = destination.substring( wikiLink.getNamespace().getLabel(virtualWiki).length() + Namespace.SEPARATOR.length()); hrefLink = hrefLink.replace("${title}", Utilities.encodeAndEscapeTopicName(title)); TagNode aTagNode = new TagNode("a"); aTagNode.addAttribute("href", hrefLink, true); aTagNode.addAttribute("class", "interwiki", false); pushNode(aTagNode); WikipediaParser.parseRecursive(topicDescription.trim(), this, false, true); popNode(); } else { append(new ContentToken(topicDescription)); } }
private String buildSectionEditLink(ParserInput parserInput, int section) throws ParserException { if (!parserInput.getAllowSectionEdit()) { return ""; } if (parserInput.getLocale() == null) { logger.info( "Unable to build section edit links for " + parserInput.getTopicName() + " - locale is empty"); return ""; } // FIXME - template inclusion causes section edits to break, so disable for now Integer inclusion = (Integer) parserInput.getTempParam(TemplateTag.TEMPLATE_INCLUSION); boolean disallowInclusion = (inclusion != null && inclusion > 0); if (disallowInclusion) { return ""; } String url = ""; try { url = LinkUtil.buildEditLinkUrl( parserInput.getContext(), parserInput.getVirtualWiki(), parserInput.getTopicName(), null, section); } catch (DataAccessException e) { logger.error( "Failure while building link for topic " + parserInput.getVirtualWiki() + " / " + parserInput.getTopicName(), e); } // arguments are edit link URL and edit label text Object[] args = new Object[2]; args[0] = url; args[1] = Utilities.formatMessage("common.sectionedit", parserInput.getLocale()); try { return WikiUtil.formatFromTemplate(TEMPLATE_HEADER_EDIT_LINK, args); } catch (IOException e) { throw new ParserException(e); } }
@Override public boolean isTemplateTopic() { String topicName = fParserInput.getTopicName(); int index = topicName.indexOf(':'); if (index > 0) { String namespace = topicName.substring(0, index); if (isTemplateNamespace(namespace)) { return true; } } return false; }
/** * Parse a raw Wiki link of the form "[[link|text]]", and return a WikiLink object representing * the link. * * @param parserInput Input configuration settings for this parser instance. * @param raw The raw Wiki link text. * @return A WikiLink object that represents the link. */ protected static WikiLink parseWikiLink( ParserInput parserInput, ParserOutput parserOutput, String raw) throws ParserException { if (StringUtils.isBlank(raw)) { return new WikiLink(); } raw = raw.trim(); String suffix = ((!raw.endsWith("]]")) ? raw.substring(raw.lastIndexOf("]]") + 2) : null); // for performance reasons use String methods rather than regex // private static final Pattern WIKI_LINK_PATTERN = // Pattern.compile("\\[\\[\\s*(\\:\\s*)?\\s*(.+?)(\\s*\\|\\s*(.+))?\\s*\\]\\]([a-z]*)"); raw = raw.substring(raw.indexOf("[[") + 2, raw.lastIndexOf("]]")).trim(); // parse in case there is a template or magic word - [[{{PAGENAME}}]] raw = JFlexParserUtil.parseFragment(parserInput, parserOutput, raw, JFlexParser.MODE_TEMPLATE); boolean colon = false; if (raw.startsWith(":")) { colon = true; raw = raw.substring(1).trim(); } String text = null; int pos = raw.indexOf('|'); if (pos != -1 && pos != (raw.length() - 1)) { text = raw.substring(pos + 1).trim(); raw = raw.substring(0, pos).trim(); } String virtualWiki = parserInput.getVirtualWiki(); WikiLink wikiLink = LinkUtil.parseWikiLink(virtualWiki, raw); if (!colon && wikiLink.getNamespace().getId().equals(Namespace.CATEGORY_ID)) { // do not set default text for categories wikiLink.setText(null); } if (wikiLink.getVirtualWiki() != null && !StringUtils.equals(wikiLink.getVirtualWiki().getName(), virtualWiki) && StringUtils.isBlank(wikiLink.getDestination())) { // use the root topic name as the destination wikiLink.setDestination(wikiLink.getVirtualWiki().getRootTopicName()); if (StringUtils.isBlank(wikiLink.getText())) { wikiLink.setText(wikiLink.getVirtualWiki().getName() + Namespace.SEPARATOR); } } if (wikiLink.getInterwiki() != null && StringUtils.isBlank(wikiLink.getDestination()) && StringUtils.isBlank(wikiLink.getText())) { wikiLink.setText(wikiLink.getInterwiki().getInterwikiPrefix() + Namespace.SEPARATOR); } wikiLink.setColon(colon); if (text != null) { wikiLink.setText(text); } if (!StringUtils.isBlank(suffix)) { wikiLink.setText(wikiLink.getText() + suffix); } return wikiLink; }
@Override public void appendInternalLink( String topic, String hashSection, String topicDescription, String cssClass, boolean parseRecursive) { try { String virtualWiki = fParserInput.getVirtualWiki(); WikiLink wikiLink; if (hashSection != null) { wikiLink = LinkUtil.parseWikiLink(virtualWiki, topic + "#" + hashSection); } else { wikiLink = LinkUtil.parseWikiLink(virtualWiki, topic); } String destination = wikiLink.getDestination(); String section = wikiLink.getSection(); String query = wikiLink.getQuery(); String href = buildTopicUrlNoEdit(fContextPath, virtualWiki, destination, section, query); String style = ""; if (StringUtils.isBlank(topic) && !StringUtils.isBlank(section)) { // do not check existence for section links } else { String articleName = topic.replace('_', ' '); if (LinkUtil.isExistingArticle(virtualWiki, articleName) == null) { style = "edit"; href = LinkUtil.buildEditLinkUrl(fContextPath, virtualWiki, topic, query, -1); } } WPATag aTagNode = new WPATag(); aTagNode.addAttribute("href", href, true); aTagNode.addAttribute("class", style, true); aTagNode.addObjectAttribute("wikilink", topic); pushNode(aTagNode); if (parseRecursive) { WikipediaParser.parseRecursive(topicDescription.trim(), this, false, true); } else { aTagNode.addChild(new ContentToken(topicDescription)); } popNode(); } catch (DataAccessException e1) { e1.printStackTrace(); append(new ContentToken(topicDescription)); } }
@Override public String getRawWikiContent( String namespace, String topicName, Map<String, String> templateParameters) { String result = super.getRawWikiContent(namespace, topicName, templateParameters); if (result != null) { return result; } try { topicName = topicName.replaceAll("_", " "); Topic topic = WikiBase.getDataHandler() .lookupTopic(fParserInput.getVirtualWiki(), namespace + ':' + topicName, false, null); if (topic == null) { return null; } return topic.getTopicContent(); } catch (Exception e) { e.printStackTrace(); } return result; }
@Override public void buildEditLinkUrl(int section) { if (fParserInput.getAllowSectionEdit()) { TagNode divTagNode = new TagNode("div"); divTagNode.addAttribute("style", "font-size:90%;float:right;margin-left:5px;", false); divTagNode.addChild(new ContentToken("[")); append(divTagNode); String url = ""; try { // Use correct section number. // Bliki starts with offset 0 so it must be "section+1" url = LinkUtil.buildEditLinkUrl( fParserInput.getContext(), fParserInput.getVirtualWiki(), fParserInput.getTopicName(), null, section + 1); } catch (Exception e) { logger.error( "Failure while building link for topic " + fParserInput.getVirtualWiki() + " / " + fParserInput.getTopicName(), e); } TagNode aTagNode = new TagNode("a"); aTagNode.addAttribute("href", url, false); aTagNode.addChild( new ContentToken( Utilities.formatMessage("common.sectionedit", fParserInput.getLocale()))); divTagNode.addChild(aTagNode); divTagNode.addChild(new ContentToken("]")); } }
private void save(HttpServletRequest request, ModelAndView next, WikiPageInfo pageInfo) throws Exception { String topicName = JAMWikiServlet.getTopicFromRequest(request); String virtualWiki = JAMWikiServlet.getVirtualWikiFromURI(request); Topic topic = loadTopic(virtualWiki, topicName); TopicVersion lastTopicVersion = WikiBase.getHandler().lookupLastTopicVersion(virtualWiki, topicName); if (lastTopicVersion != null && lastTopicVersion.getTopicVersionId() != retrieveLastTopicVersionId(request, virtualWiki, topicName)) { // someone else has edited the topic more recently resolve(request, next, pageInfo); return; } String contents = request.getParameter("contents"); if (StringUtils.hasText(request.getParameter("section"))) { // load section of topic int section = (new Integer(request.getParameter("section"))).intValue(); ParserDocument parserDocument = Utilities.parseSplice(request, virtualWiki, topicName, section, contents); contents = parserDocument.getContent(); } if (contents == null) { logger.warning("The topic " + topicName + " has no content"); throw new WikiException(new WikiMessage("edit.exception.nocontent", topicName)); } if (lastTopicVersion != null && lastTopicVersion.getVersionContent().equals(contents)) { viewTopic(request, next, pageInfo, topicName); return; } // parse for signatures and other syntax that should not be saved in raw form WikiUser user = Utilities.currentUser(request); ParserInput parserInput = new ParserInput(); parserInput.setContext(request.getContextPath()); parserInput.setLocale(request.getLocale()); parserInput.setWikiUser(user); parserInput.setTopicName(topicName); parserInput.setUserIpAddress(request.getRemoteAddr()); parserInput.setVirtualWiki(virtualWiki); ParserDocument parserDocument = Utilities.parseSave(parserInput, contents); contents = parserDocument.getContent(); topic.setTopicContent(contents); if (StringUtils.hasText(parserDocument.getRedirect())) { // set up a redirect topic.setRedirectTo(parserDocument.getRedirect()); topic.setTopicType(Topic.TYPE_REDIRECT); } else if (topic.getTopicType() == Topic.TYPE_REDIRECT) { // no longer a redirect topic.setRedirectTo(null); topic.setTopicType(Topic.TYPE_ARTICLE); } TopicVersion topicVersion = new TopicVersion( user, request.getRemoteAddr(), request.getParameter("editComment"), contents); if (request.getParameter("minorEdit") != null) { topicVersion.setEditType(TopicVersion.EDIT_MINOR); } WikiBase.getHandler().writeTopic(topic, topicVersion, parserDocument); // a save request has been made JAMWikiServlet.removeCachedContents(); viewTopic(request, next, pageInfo, topicName); }
/** Functionality to handle the "Save" button being clicked. */ private void save(HttpServletRequest request, ModelAndView next, WikiPageInfo pageInfo) throws Exception { String topicName = WikiUtil.getTopicFromRequest(request); String virtualWiki = pageInfo.getVirtualWikiName(); Topic topic = loadTopic(virtualWiki, topicName); Topic lastTopic = WikiBase.getDataHandler().lookupTopic(virtualWiki, topicName, false, null); if (lastTopic != null && !lastTopic.getCurrentVersionId().equals(retrieveLastTopicVersionId(request, topic))) { // someone else has edited the topic more recently resolve(request, next, pageInfo); return; } String contents = request.getParameter("contents"); String sectionName = ""; if (!StringUtils.isBlank(request.getParameter("section"))) { // load section of topic int section = Integer.valueOf(request.getParameter("section")); ParserOutput parserOutput = new ParserOutput(); String[] spliceResult = ParserUtil.parseSplice( parserOutput, request.getContextPath(), request.getLocale(), virtualWiki, topicName, section, contents); contents = spliceResult[1]; sectionName = parserOutput.getSectionName(); } if (contents == null) { logger.warning("The topic " + topicName + " has no content"); throw new WikiException(new WikiMessage("edit.exception.nocontent", topicName)); } // strip line feeds contents = StringUtils.remove(contents, '\r'); String lastTopicContent = (lastTopic != null) ? StringUtils.remove(lastTopic.getTopicContent(), '\r') : ""; if (lastTopic != null && StringUtils.equals(lastTopicContent, contents)) { // topic hasn't changed. redirect to prevent user from refreshing and re-submitting ServletUtil.redirect(next, virtualWiki, topic.getName()); return; } String editComment = request.getParameter("editComment"); if (handleSpam(request, next, topicName, contents, editComment)) { this.loadEdit(request, next, pageInfo, contents, virtualWiki, topicName, false); return; } // parse for signatures and other syntax that should not be saved in raw form WikiUser user = ServletUtil.currentWikiUser(); ParserInput parserInput = new ParserInput(); parserInput.setContext(request.getContextPath()); parserInput.setLocale(request.getLocale()); parserInput.setWikiUser(user); parserInput.setTopicName(topicName); parserInput.setUserDisplay(ServletUtil.getIpAddress(request)); parserInput.setVirtualWiki(virtualWiki); ParserOutput parserOutput = ParserUtil.parseMetadata(parserInput, contents); // parse signatures and other values that need to be updated prior to saving contents = ParserUtil.parseMinimal(parserInput, contents); topic.setTopicContent(contents); if (!StringUtils.isBlank(parserOutput.getRedirect())) { // set up a redirect topic.setRedirectTo(parserOutput.getRedirect()); topic.setTopicType(TopicType.REDIRECT); } else if (topic.getTopicType() == TopicType.REDIRECT) { // no longer a redirect topic.setRedirectTo(null); topic.setTopicType(TopicType.ARTICLE); } int charactersChanged = StringUtils.length(contents) - StringUtils.length(lastTopicContent); TopicVersion topicVersion = new TopicVersion( user, ServletUtil.getIpAddress(request), editComment, contents, charactersChanged); if (request.getParameter("minorEdit") != null) { topicVersion.setEditType(TopicVersion.EDIT_MINOR); } WikiBase.getDataHandler() .writeTopic(topic, topicVersion, parserOutput.getCategories(), parserOutput.getLinks()); // update watchlist WikiUserDetailsImpl userDetails = ServletUtil.currentUserDetails(); if (!userDetails.hasRole(Role.ROLE_ANONYMOUS)) { Watchlist watchlist = ServletUtil.currentWatchlist(request, virtualWiki); boolean watchTopic = (request.getParameter("watchTopic") != null); if (watchlist.containsTopic(topicName) != watchTopic) { WikiBase.getDataHandler() .writeWatchlistEntry(watchlist, virtualWiki, topicName, user.getUserId()); } } // redirect to prevent user from refreshing and re-submitting String target = topic.getName(); if (!StringUtils.isBlank(sectionName)) { target += "#" + sectionName; } ServletUtil.redirect(next, virtualWiki, target); }
/** * Utility method used when viewing a topic. * * @param request The current servlet request object. * @param next The current Spring ModelAndView object. * @param pageInfo The current WikiPageInfo object, which contains information needed for * rendering the final JSP page. * @param pageTitle The title of the page being rendered. * @param topic The Topic object for the topic being displayed. * @param sectionEdit Set to <code>true</code> if edit links should be displayed for each section * of the topic. * @throws Exception Thrown if any error occurs during processing. */ protected static void viewTopic( HttpServletRequest request, ModelAndView next, WikiPageInfo pageInfo, WikiMessage pageTitle, Topic topic, boolean sectionEdit) throws Exception { // FIXME - what should the default be for topics that don't exist? if (topic == null) { throw new WikiException(new WikiMessage("common.exception.notopic")); } WikiUtil.validateTopicName(topic.getName()); if (topic.getTopicType() == Topic.TYPE_REDIRECT && (request.getParameter("redirect") == null || !request.getParameter("redirect").equalsIgnoreCase("no"))) { Topic child = Utilities.findRedirectedTopic(topic, 0); if (!child.getName().equals(topic.getName())) { pageInfo.setRedirectName(topic.getName()); pageTitle = new WikiMessage("topic.title", child.getName()); topic = child; } } String virtualWiki = topic.getVirtualWiki(); String topicName = topic.getName(); WikiUser user = Utilities.currentUser(); if (sectionEdit && !ServletUtil.isEditable(virtualWiki, topicName, user)) { sectionEdit = false; } ParserInput parserInput = new ParserInput(); parserInput.setContext(request.getContextPath()); parserInput.setLocale(request.getLocale()); parserInput.setWikiUser(user); parserInput.setTopicName(topicName); parserInput.setUserIpAddress(request.getRemoteAddr()); parserInput.setVirtualWiki(virtualWiki); parserInput.setAllowSectionEdit(sectionEdit); ParserDocument parserDocument = new ParserDocument(); String content = Utilities.parse(parserInput, parserDocument, topic.getTopicContent()); // FIXME - the null check should be unnecessary if (parserDocument != null && parserDocument.getCategories().size() > 0) { LinkedHashMap categories = new LinkedHashMap(); for (Iterator iterator = parserDocument.getCategories().keySet().iterator(); iterator.hasNext(); ) { String key = (String) iterator.next(); String value = key.substring( NamespaceHandler.NAMESPACE_CATEGORY.length() + NamespaceHandler.NAMESPACE_SEPARATOR.length()); categories.put(key, value); } next.addObject("categories", categories); } topic.setTopicContent(content); if (topic.getTopicType() == Topic.TYPE_CATEGORY) { loadCategoryContent(next, virtualWiki, topic.getName()); } if (topic.getTopicType() == Topic.TYPE_IMAGE || topic.getTopicType() == Topic.TYPE_FILE) { Collection fileVersions = WikiBase.getDataHandler().getAllWikiFileVersions(virtualWiki, topicName, true); for (Iterator iterator = fileVersions.iterator(); iterator.hasNext(); ) { // update version urls to include web root path WikiFileVersion fileVersion = (WikiFileVersion) iterator.next(); String url = FilenameUtils.normalize( Environment.getValue(Environment.PROP_FILE_DIR_RELATIVE_PATH) + "/" + fileVersion.getUrl()); url = FilenameUtils.separatorsToUnix(url); fileVersion.setUrl(url); } next.addObject("fileVersions", fileVersions); if (topic.getTopicType() == Topic.TYPE_IMAGE) { next.addObject("topicImage", new Boolean(true)); } else { next.addObject("topicFile", new Boolean(true)); } } pageInfo.setSpecial(false); pageInfo.setTopicName(topicName); next.addObject(ServletUtil.PARAMETER_TOPIC_OBJECT, topic); if (pageTitle != null) { pageInfo.setPageTitle(pageTitle); } }