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
020 package org.apache.wiki.plugin;
021
022 import org.apache.log4j.Logger;
023 import org.apache.wiki.WikiContext;
024 import org.apache.wiki.api.exceptions.PluginException;
025 import org.apache.wiki.api.exceptions.ProviderException;
026 import org.apache.wiki.api.plugin.WikiPlugin;
027 import org.apache.wiki.plugin.AbstractReferralPlugin;
028 import org.jdom2.Element;
029 import org.jdom2.Namespace;
030 import org.jdom2.output.Format;
031 import org.jdom2.output.XMLOutputter;
032
033 import java.util.ArrayList;
034 import java.util.Collection;
035 import java.util.Iterator;
036 import java.util.List;
037 import java.util.Map;
038 import java.util.regex.Pattern;
039
040 /**
041 * A WikiPlugin that creates an index of pages according to a certain pattern.
042 * <br />
043 * The default is to include all pages.
044 * <p>
045 * This is a rewrite of the earlier JSPWiki IndexPlugin using JDOM2.
046 8 </p>
047 * <p>
048 * Parameters (from AbstractReferralPlugin):
049 * </p>
050 * <ul>
051 * <li><b>include</b> - A regexp pattern for marking which pages should be included.</li>
052 * <li><b>exclude</b> - A regexp pattern for marking which pages should be excluded.</li>
053 * </ul>
054 *
055 * @author Ichiro Furusato
056 */
057 public class IndexPlugin extends AbstractReferralPlugin implements WikiPlugin
058 {
059 private static Logger log = Logger.getLogger(IndexPlugin.class);
060
061 private Namespace xmlns_XHTML = Namespace.getNamespace("http://www.w3.org/1999/xhtml");
062
063 /**
064 * {@inheritDoc}
065 */
066 public String execute( WikiContext context, Map<String,String> params ) throws PluginException
067 {
068 String include = params.get(PARAM_INCLUDE);
069 String exclude = params.get(PARAM_EXCLUDE);
070
071 Element masterDiv = getElement("div","index");
072 Element indexDiv = getElement("div","header");
073 masterDiv.addContent(indexDiv);
074 try {
075 List<String> pages = listPages(context,include,exclude);
076 context.getEngine().getPageSorter().sort(pages);
077 char initialChar = ' ';
078 Element currentDiv = new Element("div",xmlns_XHTML);
079 for ( String name : pages ) {
080 if ( name.charAt(0) != initialChar ) {
081 if ( initialChar != ' ' ) {
082 indexDiv.addContent(" - ");
083 }
084 initialChar = name.charAt(0);
085 masterDiv.addContent(makeHeader(String.valueOf(initialChar)));
086 currentDiv = getElement("div","body");
087 masterDiv.addContent(currentDiv);
088 indexDiv.addContent(getLink("#"+initialChar,String.valueOf(initialChar)));
089 } else {
090 currentDiv.addContent(", ");
091 }
092 currentDiv.addContent(getLink(context.getURL(WikiContext.VIEW,name),name));
093 }
094
095 } catch( ProviderException e ) {
096 log.warn("could not load page index",e);
097 throw new PluginException( e.getMessage() );
098 }
099 // serialize to raw format string (no changes to whitespace)
100 XMLOutputter out = new XMLOutputter(Format.getRawFormat());
101 return out.outputString(masterDiv);
102 }
103
104
105 private Element getLink( String href, String content )
106 {
107 Element a = new Element("a",xmlns_XHTML);
108 a.setAttribute("href",href);
109 a.addContent(content);
110 return a;
111 }
112
113
114 private Element makeHeader( String initialChar )
115 {
116 Element span = getElement("span","section");
117 Element a = new Element("a",xmlns_XHTML);
118 a.setAttribute("id",initialChar);
119 a.addContent(initialChar);
120 span.addContent(a);
121 return span;
122 }
123
124
125 private Element getElement( String gi, String classValue )
126 {
127 Element elt = new Element(gi,xmlns_XHTML);
128 elt.setAttribute("class",classValue);
129 return elt;
130 }
131
132
133 /**
134 * Grabs a list of all pages and filters them according to the include/exclude patterns.
135 *
136 * @param context
137 * @param include
138 * @param exclude
139 * @return A list containing page names which matched the filters.
140 * @throws ProviderException
141 */
142 private List<String> listPages( WikiContext context, String include, String exclude )
143 throws ProviderException
144 {
145 Pattern includePtrn = include != null
146 ? Pattern.compile( include )
147 : Pattern.compile(".*");
148 Pattern excludePtrn = exclude != null
149 ? Pattern.compile( exclude )
150 : Pattern.compile("\\p{Cntrl}"); // there are no control characters in page names
151 List<String> result = new ArrayList<String>();
152 @SuppressWarnings("unchecked")
153 Collection<String> pages = (Collection<String>)context.getEngine().getReferenceManager().findCreated();
154 for ( Iterator<String> i = pages.iterator(); i.hasNext(); ) {
155 String pageName = (String) i.next();
156 if ( excludePtrn.matcher( pageName ).matches() ) continue;
157 if ( includePtrn.matcher( pageName ).matches() ) {
158 result.add( pageName );
159 }
160 }
161 return result;
162 }
163
164 }