Java tutorial
/* * Copyright 2011 Axis Data Management Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.admc.jcreole; import java.io.File; import java.io.FileFilter; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.List; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.Arrays; import java.util.Collections; import java.util.Formatter; import org.apache.commons.lang.StringEscapeUtils; import java.text.SimpleDateFormat; import com.admc.util.FileComparator; /** * @author Blaine Simpson (blaine dot simpson at admc dot com) * @since 1.2.0 */ public class Indexer { private Pattern namePattern; private String nameFormatString; private FileFilter filter; private static SimpleDateFormat isoDateTimeFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); private static Pattern tailStripperPattern = Pattern.compile("[^/]+/?$"); /** * @param filter If null, then all files in the specified dir will be * included. */ public void setFilter(FileFilter filter) { this.filter = filter; } /** * @param namePatternString name*Translation* params must both be null * or both be non-null. */ public void setNameTranslationMatchPat(String namePatternString) { namePattern = Pattern.compile(namePatternString); } /** * @param nameFormatString name*Translation* params must both be null * or both be non-null. */ public void setNameTranslationFormat(String nameFormatString) { this.nameFormatString = nameFormatString; } /** * This is a highly-modified fork of Tomcat's method * DefaultServlet.renderHtml(). * * @param directory Will throw an IllegalArgumentException if this is not * a real directory. * @param listUp Generate an entry for "..". * @return HTML fragment that is a HTML table element. */ public StringBuilder generateTable(File directory, String displayName, boolean listUp, FileComparator.SortBy sortBy, boolean ascendSort) { /* * TODO: Use an EnumMap or something to cache FileComparators instead * of instantiating one for every method call. */ Matcher matcher = null; if (!directory.isDirectory()) throw new IllegalArgumentException("Not a directory: " + directory.getAbsolutePath()); if ((namePattern == null && nameFormatString != null) || (namePattern != null && nameFormatString == null)) throw new IllegalStateException( "'namePattern' and 'nameFormatString' must either both be " + "set or both be null"); StringBuilder sb = new StringBuilder(); Formatter formatter = new Formatter(sb); String name = displayName; sb.append("<table class=\"jcreole_dirindex\" width=\"100%\" " + "cellspacing=\"0\" cellpadding=\"5\" align=\"center\">\r\n"); // Render the column headings sb.append("<tr>\r\n"); sb.append("<td align=\"left\"><font size=\"+1\"><strong>"); sb.append("<a href=\"?sort="); try { sb.append(URLEncoder.encode((sortBy == FileComparator.SortBy.NAME && ascendSort) ? "-" : "+", "UTF-8")); sb.append("NAME\">Nodename</a>"); if (sortBy == FileComparator.SortBy.NAME) sb.append("<sup>").append(ascendSort ? '+' : '-').append("</sup>"); sb.append("</strong></font></td>\r\n"); sb.append("<td align=\"center\"><font size=\"+1\"><strong>"); sb.append("<a href=\"?sort="); sb.append(URLEncoder.encode((sortBy == FileComparator.SortBy.SIZE && ascendSort) ? "-" : "+", "UTF-8")); sb.append("SIZE\">Size</a>"); if (sortBy == FileComparator.SortBy.SIZE) sb.append("<sup>").append(ascendSort ? '+' : '-').append("</sup>"); sb.append("</strong></font></td>\r\n"); sb.append("<td align=\"right\"><font size=\"+1\"><strong>"); sb.append("<a href=\"?sort="); sb.append(URLEncoder.encode((sortBy == FileComparator.SortBy.MODIFIED && ascendSort) ? "-" : "+", "UTF-8")); } catch (UnsupportedEncodingException uee) { throw new RuntimeException("Unable to encode to UTF-8"); } sb.append("MODIFIED\">Last Modified</a>"); if (sortBy == FileComparator.SortBy.MODIFIED) sb.append("<sup>").append(ascendSort ? '+' : '-').append("</sup>"); sb.append("</strong></font></td>\r\n"); sb.append("</tr>"); boolean shade = true; // DIR ENTRY: if (listUp) { sb.append("<tr"); sb.append(" bgcolor=\"#eeeeee\""); sb.append(">\r\n"); sb.append("<td align=\"left\"> \r\n"); sb.append("<a href=\"../\"><tt><strong>..</strong> ("); sb.append(StringEscapeUtils.escapeHtml(tailStripperPattern.matcher(displayName).replaceFirst(""))); sb.append(")</tt></a></td>\r\n"); sb.append("<td align=\"right\"><tt>"); sb.append(" "); sb.append("</tt></td>\r\n"); sb.append("<td align=\"right\"><tt>"); sb.append(StringEscapeUtils .escapeHtml(isoDateTimeFormatter.format(directory.getParentFile().lastModified()))); sb.append("</tt></td>\r\n"); sb.append("</tr>\r\n"); } // END DIR ENTRY List<File> fileList = Arrays.asList(directory.listFiles(filter)); Collections.sort(fileList, new FileComparator(sortBy, ascendSort)); // Render the directory entries within this directory for (File file : fileList) { String nodeName = file.getName(); if (namePattern != null) { if (file.isFile()) { matcher = namePattern.matcher(nodeName); if (!matcher.matches()) continue; } else { matcher = null; } } shade = !shade; sb.append("<tr"); if (shade) sb.append(" bgcolor=\"#eeeeee\""); sb.append(">\r\n"); sb.append("<td align=\"left\"> \r\n"); sb.append("<a href=\""); if (matcher == null) { sb.append(nodeName); } else { // Terrible hack dur to terrible Java varargs limitation: switch (matcher.groupCount()) { case 1: formatter.format(nameFormatString, matcher.group(1)); break; case 2: formatter.format(nameFormatString, matcher.group(1), matcher.group(2)); break; case 3: formatter.format(nameFormatString, matcher.group(1), matcher.group(2), matcher.group(3)); break; case 4: formatter.format(nameFormatString, matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(4)); break; case 5: formatter.format(nameFormatString, matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(4), matcher.group(5)); break; case 6: formatter.format(nameFormatString, matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(4), matcher.group(5), matcher.group(6)); break; case 7: formatter.format(nameFormatString, matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(4), matcher.group(5), matcher.group(6), matcher.group(7)); break; case 8: formatter.format(nameFormatString, matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(4), matcher.group(5), matcher.group(6), matcher.group(7), matcher.group(8)); break; case 9: formatter.format(nameFormatString, matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(4), matcher.group(5), matcher.group(6), matcher.group(7), matcher.group(8), matcher.group(9)); break; default: throw new IllegalArgumentException( "Pattern captured too many (" + matcher.groupCount() + ") groups: " + namePattern); } } if (file.isDirectory()) sb.append('/'); sb.append("\"><tt>"); sb.append(StringEscapeUtils.escapeHtml(nodeName)); if (file.isDirectory()) sb.append('/'); sb.append("</tt></a></td>\r\n"); sb.append("<td align=\"right\"><tt>"); if (file.isDirectory()) sb.append(" "); else if (file.isFile()) sb.append(file.length()); sb.append("</tt></td>\r\n"); sb.append("<td align=\"right\"><tt>"); sb.append(StringEscapeUtils.escapeHtml(isoDateTimeFormatter.format(file.lastModified()))); sb.append("</tt></td>\r\n"); sb.append("</tr>\r\n"); } // Render the page footer sb.append("</table>\r\n"); return sb; } }