예제 #1
0
  /**
   * 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;
  }
예제 #2
0
  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;
  }
예제 #3
0
  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;
  }
예제 #4
0
  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;
  }
예제 #6
0
    /**
     * 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;
    }
예제 #7
0
  /**
   * 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;
  }
예제 #8
0
  /**
   * 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);
        }
      }
    }
  }