001/* 002 Licensed to the Apache Software Foundation (ASF) under one 003 or more contributor license agreements. See the NOTICE file 004 distributed with this work for additional information 005 regarding copyright ownership. The ASF licenses this file 006 to you under the Apache License, Version 2.0 (the 007 "License"); you may not use this file except in compliance 008 with the License. You may obtain a copy of the License at 009 010 http://www.apache.org/licenses/LICENSE-2.0 011 012 Unless required by applicable law or agreed to in writing, 013 software distributed under the License is distributed on an 014 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 KIND, either express or implied. See the License for the 016 specific language governing permissions and limitations 017 under the License. 018 */ 019 020package org.apache.wiki.plugin; 021 022import java.util.ArrayList; 023import java.util.Iterator; 024import java.util.List; 025import java.util.Map; 026import java.util.Set; 027import java.util.regex.Pattern; 028 029import org.apache.log4j.Logger; 030import org.apache.wiki.WikiContext; 031import org.apache.wiki.api.exceptions.PluginException; 032import org.apache.wiki.api.exceptions.ProviderException; 033import org.apache.wiki.api.plugin.WikiPlugin; 034import org.jdom2.Element; 035import org.jdom2.Namespace; 036import org.jdom2.output.Format; 037import org.jdom2.output.XMLOutputter; 038 039/** 040 * A WikiPlugin that creates an index of pages according to a certain pattern. 041 * <br /> 042 * The default is to include all pages. 043 * <p> 044 * This is a rewrite of the earlier JSPWiki IndexPlugin using JDOM2. 045 8 </p> 046 * <p> 047 * Parameters (from AbstractReferralPlugin): 048 * </p> 049 * <ul> 050 * <li><b>include</b> - A regexp pattern for marking which pages should be included.</li> 051 * <li><b>exclude</b> - A regexp pattern for marking which pages should be excluded.</li> 052 * </ul> 053 * 054 * @author Ichiro Furusato 055 */ 056public class IndexPlugin extends AbstractReferralPlugin implements WikiPlugin 057{ 058 private static Logger log = Logger.getLogger(IndexPlugin.class); 059 060 private Namespace xmlns_XHTML = Namespace.getNamespace("http://www.w3.org/1999/xhtml"); 061 062 /** 063 * {@inheritDoc} 064 */ 065 public String execute( WikiContext context, Map<String,String> params ) throws PluginException 066 { 067 String include = params.get(PARAM_INCLUDE); 068 String exclude = params.get(PARAM_EXCLUDE); 069 070 Element masterDiv = getElement("div","index"); 071 Element indexDiv = getElement("div","header"); 072 masterDiv.addContent(indexDiv); 073 try { 074 List<String> pages = listPages(context,include,exclude); 075 context.getEngine().getPageManager().getPageSorter().sort(pages); 076 char initialChar = ' '; 077 Element currentDiv = new Element("div",xmlns_XHTML); 078 for ( String name : pages ) { 079 if ( name.charAt(0) != initialChar ) { 080 if ( initialChar != ' ' ) { 081 indexDiv.addContent(" - "); 082 } 083 initialChar = name.charAt(0); 084 masterDiv.addContent(makeHeader(String.valueOf(initialChar))); 085 currentDiv = getElement("div","body"); 086 masterDiv.addContent(currentDiv); 087 indexDiv.addContent(getLink("#"+initialChar,String.valueOf(initialChar))); 088 } else { 089 currentDiv.addContent(", "); 090 } 091 currentDiv.addContent(getLink(context.getURL(WikiContext.VIEW,name),name)); 092 } 093 094 } catch( ProviderException e ) { 095 log.warn("could not load page index",e); 096 throw new PluginException( e.getMessage() ); 097 } 098 // serialize to raw format string (no changes to whitespace) 099 XMLOutputter out = new XMLOutputter(Format.getRawFormat()); 100 return out.outputString(masterDiv); 101 } 102 103 104 private Element getLink( String href, String content ) 105 { 106 Element a = new Element("a",xmlns_XHTML); 107 a.setAttribute("href",href); 108 a.addContent(content); 109 return a; 110 } 111 112 113 private Element makeHeader( String initialChar ) 114 { 115 Element span = getElement("span","section"); 116 Element a = new Element("a",xmlns_XHTML); 117 a.setAttribute("id",initialChar); 118 a.addContent(initialChar); 119 span.addContent(a); 120 return span; 121 } 122 123 124 private Element getElement( String gi, String classValue ) 125 { 126 Element elt = new Element(gi,xmlns_XHTML); 127 elt.setAttribute("class",classValue); 128 return elt; 129 } 130 131 132 /** 133 * Grabs a list of all pages and filters them according to the include/exclude patterns. 134 * 135 * @param context 136 * @param include 137 * @param exclude 138 * @return A list containing page names which matched the filters. 139 * @throws ProviderException 140 */ 141 private List<String> listPages( WikiContext context, String include, String exclude ) throws ProviderException { 142 Pattern includePtrn = include != null ? Pattern.compile( include ) : Pattern.compile(".*"); 143 Pattern excludePtrn = exclude != null ? Pattern.compile( exclude ) : Pattern.compile("\\p{Cntrl}"); // there are no control characters in page names 144 List< String > result = new ArrayList<>(); 145 Set< String > pages = context.getEngine().getReferenceManager().findCreated(); 146 for ( Iterator<String> i = pages.iterator(); i.hasNext(); ) { 147 String pageName = i.next(); 148 if ( excludePtrn.matcher( pageName ).matches() ) continue; 149 if ( includePtrn.matcher( pageName ).matches() ) { 150 result.add( pageName ); 151 } 152 } 153 return result; 154 } 155 156}