/** * Creates a deep clone of a WikiPage. Strings are not cloned, since they're immutable. Attributes * are not cloned, only the internal HashMap (so if you modify the contents of a value of an * attribute, these will reflect back to everyone). * * @return A deep clone of the WikiPage */ public Object clone() { WikiPage p = new WikiPage(m_engine, m_name); p.m_wiki = m_wiki; p.m_author = m_author; p.m_version = m_version; p.m_lastModified = m_lastModified != null ? (Date) m_lastModified.clone() : null; p.m_fileSize = m_fileSize; for (Map.Entry<String, Object> entry : m_attributes.entrySet()) { p.m_attributes.put(entry.getKey(), entry.getValue()); } if (m_accessList != null) { p.m_accessList = new AclImpl(); for (Enumeration entries = m_accessList.entries(); entries.hasMoreElements(); ) { AclEntry e = (AclEntry) entries.nextElement(); p.m_accessList.addEntry(e); } } return p; }
public final int doWikiStartTag() throws IOException { WikiEngine engine = m_wikiContext.getEngine(); WikiPage page = m_wikiContext.getPage(); try { if (page != null) { long size = page.getSize(); if (size == -1 && engine.pageExists(page)) // should never happen // with attachments { size = engine.getPureText(page.getName(), page.getVersion()).length(); page.setSize(size); } pageContext.getOut().write(Long.toString(size)); } } catch (ProviderException e) { log.warn("Providers did not work: ", e); pageContext.getOut().write("Error determining page size: " + e.getMessage()); } return SKIP_BODY; }
private Set<String> getReferencesToChange(WikiPage fromPage, WikiEngine engine) { Set<String> referrers = new TreeSet<String>(); Collection<String> r = engine.getReferenceManager().findReferrers(fromPage.getName()); if (r != null) referrers.addAll(r); try { Collection<Attachment> attachments = engine.getAttachmentManager().listAttachments(fromPage); for (Attachment att : attachments) { Collection<String> c = engine.getReferenceManager().findReferrers(att.getName()); if (c != null) referrers.addAll(c); } } catch (ProviderException e) { // We will continue despite this error log.error("Provider error while fetching attachments for rename", e); } return referrers; }
protected void exportPage(WikiEngine engine, WikiPage p) throws IOException, ProviderException { String name = p.getName(); String title = name; boolean isAttachment = p instanceof Attachment; title = generateTitle(name, title, isAttachment); exportPageHeader(p.getName(), p.getWiki(), p.getAuthor(), p.getLastModified(), isAttachment); Map<String, Object> attrMap = p.getAttributes(); exportAttributes(attrMap); // // ACLs // Acl acl = p.getAcl(); exportAcl(acl); // // Export page content // exportProperty("wiki:content", engine.getPureText(p), STRING); // // Finally, list attachment. According to JCR rules, these must be last. // /* Collection<Attachment> atts = m_engine.getAttachmentManager().listAttachments( p ); for( Attachment a : atts ) { exportPage( a ); } */ exportPageFooter(); }
/** * Filters a collection according to the include and exclude parameters. * * @param c The collection to filter. * @return A filtered collection. */ protected Collection filterCollection(Collection c) { ArrayList<Object> result = new ArrayList<Object>(); PatternMatcher pm = new Perl5Matcher(); for (Iterator i = c.iterator(); i.hasNext(); ) { String pageName = null; Object objectje = i.next(); if (objectje instanceof WikiPage) { pageName = ((WikiPage) objectje).getName(); } else { pageName = (String) objectje; } // // If include parameter exists, then by default we include only those // pages in it (excluding the ones in the exclude pattern list). // // include='*' means the same as no include. // boolean includeThis = m_include == null; if (m_include != null) { for (int j = 0; j < m_include.length; j++) { if (pm.matches(pageName, m_include[j])) { includeThis = true; break; } } } if (m_exclude != null) { for (int j = 0; j < m_exclude.length; j++) { if (pm.matches(pageName, m_exclude[j])) { includeThis = false; break; // The inner loop, continue on the next item } } } if (includeThis) { if (objectje instanceof WikiPage) { result.add(objectje); } else { result.add(pageName); } // // if we want to show the last modified date of the most recently change page, we keep a // "high watermark" here: WikiPage page = null; if (m_lastModified) { page = m_engine.getPage(pageName); if (page != null) { Date lastModPage = page.getLastModified(); if (log.isDebugEnabled()) { log.debug("lastModified Date of page " + pageName + " : " + m_dateLastModified); } if (lastModPage.after(m_dateLastModified)) { m_dateLastModified = lastModPage; } } } } } return result; }
/** * Count a page hit, present a pages' counter or output a list of pagecounts. * * @param context * @param params * @throws com.ecyrd.jspwiki.plugin.PluginException * @return String Wiki page snippet * @throws PluginException Malformed pattern parameter. * @concurrency concurrent */ public String execute(WikiContext context, Map params) throws PluginException { WikiEngine engine = context.getEngine(); WikiPage page = context.getPage(); String result = STR_EMPTY; if (null != page) { // get parameters String pagename = page.getName(); String count = (String) params.get(PARAM_COUNT); String show = (String) params.get(PARAM_SHOW); int entries = TextUtil.parseIntParameter((String) params.get(PARAM_MAX_ENTRIES), Integer.MAX_VALUE); final int max = TextUtil.parseIntParameter((String) params.get(PARAM_MAX_COUNT), Integer.MAX_VALUE); final int min = TextUtil.parseIntParameter((String) params.get(PARAM_MIN_COUNT), Integer.MIN_VALUE); String sort = (String) params.get(PARAM_SORT); String body = (String) params.get(PluginManager.PARAM_BODY); Pattern[] exclude = compileGlobs(PARAM_EXCLUDE, (String) params.get(PARAM_EXCLUDE)); Pattern[] include = compileGlobs(PARAM_INCLUDE, (String) params.get(PARAM_INCLUDE)); Pattern[] refer = compileGlobs(PARAM_REFER, (String) params.get(PARAM_REFER)); PatternMatcher matcher = (null != exclude || null != include || null != refer) ? new Perl5Matcher() : null; boolean increment = false; // increment counter? if (STR_YES.equals(count)) { increment = true; } else { count = null; } // default increment counter? if ((null == show || STR_NONE.equals(show)) && null == count) { increment = true; } // filter on referring pages? Collection referrers = null; if (null != refer) { ReferenceManager refManager = engine.getReferenceManager(); Iterator iter = refManager.findCreated().iterator(); while (null != iter && iter.hasNext()) { String name = (String) iter.next(); boolean use = false; for (int n = 0; !use && n < refer.length; n++) { use = matcher.matches(name, refer[n]); } if (use) { Collection refs = engine.getReferenceManager().findReferrers(name); if (null != refs && !refs.isEmpty()) { if (null == referrers) { referrers = new HashSet(); } referrers.addAll(refs); } } } } synchronized (this) { Counter counter = (Counter) counters.get(pagename); // only count in view mode, keep storage values in sync if (increment && WikiContext.VIEW.equalsIgnoreCase(context.getRequestContext())) { if (null == counter) { counter = new Counter(); counters.put(pagename, counter); } counter.increment(); storage.setProperty(pagename, counter.toString()); dirty = true; } if (null == show || STR_NONE.equals(show)) { // nothing to show } else if (PARAM_COUNT.equals(show)) { // show page count result = counter.toString(); } else if (null != body && 0 < body.length() && STR_LIST.equals(show)) { // show list of counts String header = STR_EMPTY; String line = body; String footer = STR_EMPTY; int start = body.indexOf(STR_SEPARATOR); // split body into header, line, footer on ---- // separator if (0 < start) { header = body.substring(0, start); start = skipWhitespace(start + STR_SEPARATOR.length(), body); int end = body.indexOf(STR_SEPARATOR, start); if (start >= end) { line = body.substring(start); } else { line = body.substring(start, end); end = skipWhitespace(end + STR_SEPARATOR.length(), body); footer = body.substring(end); } } // sort on name or count? Map sorted = counters; if (null != sort && PARAM_COUNT.equals(sort)) { sorted = new TreeMap(compareCountDescending); sorted.putAll(counters); } // build a messagebuffer with the list in wiki markup StringBuffer buf = new StringBuffer(header); MessageFormat fmt = new MessageFormat(line); Object[] args = new Object[] {pagename, STR_EMPTY, STR_EMPTY}; Iterator iter = sorted.entrySet().iterator(); while (null != iter && 0 < entries && iter.hasNext()) { Entry entry = (Entry) iter.next(); String name = (String) entry.getKey(); // check minimum count final int value = ((Counter) entry.getValue()).getValue(); boolean use = min <= value && value <= max; // did we specify a refer-to page? if (use && null != referrers) { use = referrers.contains(name); } // did we specify what pages to include? if (use && null != include) { use = false; for (int n = 0; !use && n < include.length; n++) { use = matcher.matches(name, include[n]); } } // did we specify what pages to exclude? if (use && null != exclude) { for (int n = 0; use && n < exclude.length; n++) { use &= !matcher.matches(name, exclude[n]); } } if (use) { args[1] = engine.beautifyTitle(name); args[2] = entry.getValue(); fmt.format(args, buf, null); entries--; } } buf.append(footer); // let the engine render the list result = engine.textToHTML(context, buf.toString()); } } } return result; }
/** * Renames a page. * * @param context The current context. * @param renameFrom The name from which to rename. * @param renameTo The new name. * @param changeReferrers If true, also changes all the referrers. * @return The final new name (in case it had to be modified) * @throws WikiException If the page cannot be renamed. */ public String renamePage( WikiContext context, String renameFrom, String renameTo, boolean changeReferrers) throws WikiException { // // Sanity checks first // if (renameFrom == null || renameFrom.length() == 0) { throw new WikiException("From name may not be null or empty"); } if (renameTo == null || renameTo.length() == 0) { throw new WikiException("To name may not be null or empty"); } // // Clean up the "to" -name so that it does not contain anything illegal // renameTo = MarkupParser.cleanLink(renameTo.trim()); if (renameTo.equals(renameFrom)) { throw new WikiException("You cannot rename the page to itself"); } // // Preconditions: "from" page must exist, and "to" page must not yet exist. // WikiEngine engine = context.getEngine(); WikiPage fromPage = engine.getPage(renameFrom); if (fromPage == null) { throw new WikiException("No such page " + renameFrom); } WikiPage toPage = engine.getPage(renameTo); if (toPage != null) { throw new WikiException("Page already exists " + renameTo); } // // Options // m_camelCase = TextUtil.getBooleanProperty( engine.getWikiProperties(), JSPWikiMarkupParser.PROP_CAMELCASELINKS, m_camelCase); Set<String> referrers = getReferencesToChange(fromPage, engine); // // Do the actual rename by changing from the frompage to the topage, including // all of the attachments // engine.getPageManager().getProvider().movePage(renameFrom, renameTo); if (engine.getAttachmentManager().attachmentsEnabled()) { engine .getAttachmentManager() .getCurrentProvider() .moveAttachmentsForPage(renameFrom, renameTo); } // // Add a comment to the page notifying what changed. This adds a new revision // to the repo with no actual change. // toPage = engine.getPage(renameTo); if (toPage == null) throw new InternalWikiException( "Rename seems to have failed for some strange reason - please check logs!"); toPage.setAttribute(WikiPage.CHANGENOTE, fromPage.getName() + " ==> " + toPage.getName()); toPage.setAuthor(context.getCurrentUser().getName()); engine.getPageManager().putPageText(toPage, engine.getPureText(toPage)); // // Update the references // engine.getReferenceManager().pageRemoved(fromPage); engine.updateReferences(toPage); // // Update referrers // if (changeReferrers) { updateReferrers(context, fromPage, toPage, referrers); } // // re-index the page // engine.getSearchManager().reindexPage(toPage); Collection<Attachment> attachments = engine.getAttachmentManager().listAttachments(toPage); for (Attachment att : attachments) { engine.getSearchManager().reindexPage(att); } // // Done, return the new name. // return renameTo; }
/** * This method finds all the pages which have anything to do with the fromPage and change any * referrers it can figure out in that page. * * @param context WikiContext in which we operate * @param fromPage The old page * @param toPage The new page */ @SuppressWarnings("unchecked") private void updateReferrers( WikiContext context, WikiPage fromPage, WikiPage toPage, Set<String> referrers) { WikiEngine engine = context.getEngine(); if (referrers.isEmpty()) return; // No referrers for (String pageName : referrers) { // In case the page was just changed from under us, let's do this // small kludge. if (pageName.equals(fromPage.getName())) { pageName = toPage.getName(); } WikiPage p = engine.getPage(pageName); String sourceText = engine.getPureText(p); String newText = replaceReferrerString(context, sourceText, fromPage.getName(), toPage.getName()); if (m_camelCase) newText = replaceCCReferrerString(context, newText, fromPage.getName(), toPage.getName()); if (!sourceText.equals(newText)) { p.setAttribute(WikiPage.CHANGENOTE, fromPage.getName() + " ==> " + toPage.getName()); p.setAuthor(context.getCurrentUser().getName()); try { engine.getPageManager().putPageText(p, newText); engine.updateReferences(p); } catch (ProviderException e) { // // We fail with an error, but we will try to continue to rename // other referrers as well. // log.error("Unable to perform rename.", e); } } } }