/* @(#)PicturePages.java 1.0 24 September 2004 */ /* Useful imports */ import edu.neu.ccs.*; import edu.neu.ccs.gui.*; import edu.neu.ccs.codec.*; import edu.neu.ccs.console.*; import edu.neu.ccs.filter.*; import edu.neu.ccs.jpf.*; import edu.neu.ccs.parser.*; import edu.neu.ccs.pedagogy.*; import edu.neu.ccs.quick.*; import edu.neu.ccs.util.*; import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.awt.font.*; import java.awt.image.*; import javax.swing.*; import javax.swing.border.*; import java.io.*; import java.util.*; import java.math.*; import java.beans.*; import java.lang.reflect.*; import java.net.URL; import java.util.regex.*; // import java.text.*; public class PicturePages extends JPF { public static void main(String[] args) { // To optionally adjust the look and feel, // remove the comments from one of the two statements below. // LookAndFeelTools.showSelectLookAndFeelDialog(); LookAndFeelTools.adjustAllDefaultFontSizes(10); new PicturePages(); } // member variables /** The image directory. */ private String directory = null; /** The web site title. */ private String pagetitle = null; /** The list of image file names in the image directory. */ private String[] files = new String[0]; /** The length of the files list. */ private int length = 0; // constants /** The doctype string. */ private final String doctype = "\n\n"; /** The css file name. */ private final String cssname = "pictures_style.css"; /** The css link string. */ private final String csslink = "\n\n"; /** The html string. */ private final String html = "\n"; /** The end html string. */ private final String endhtml = "\n\n"; /** The head string. */ private final String head = "\n\n"; /** The end head string. */ private final String endhead = "\n\n"; /** The title string. */ private final String title = "\n"; /** The end title string. */ private final String endtitle = "\n\n"; /** The body string. */ private final String body = "\n\n"; /** The end body string. */ private final String endbody = "\n\n"; /** The paragraph string. */ private final String paragraph = "

\n"; /** The end paragraph string. */ private final String endparagraph = "\n

\n\n"; /** The open link string. */ private final String openlink = "\n"; /** The end link string. */ private final String endlink = "\n"; /** The open image string. */ private final String openimage = "\n\n"; /** The filter to pick out jpg, gif, and png files. */ private final FilenameFilter filter = new FilenameFilter() { public boolean accept(File dir, String name) { if (name == null) return false; return name.startsWith(".jpg", name.length() - 4) || name.startsWith(".JPG", name.length() - 4) || name.startsWith(".gif", name.length() - 4) || name.startsWith(".GIF", name.length() - 4) || name.startsWith(".png", name.length() - 4) || name.startsWith(".PNG", name.length() - 4); } }; /** * Build a GUI to input the image directory and page title that * calls the master method to build the image web site. * */ public void makePictureWebSiteGUI() { // define the input text fields for directory and page title final TextFieldView directoryView = new TextFieldView(600); final TextFieldView pagetitleView = new TextFieldView(600); // define the panel to annotate and display input text fields TablePanel viewPanel = new TablePanel( new Object[][] { { "Images Directory" , directoryView }, { "Web Page Title", pagetitleView } }, 10, 10, WEST); // define the action that will make the site using the directory // and page title SimpleAction makeSite = new SimpleAction("Make Web Site") { public void perform() { directory = directoryView.getViewState(); pagetitle = pagetitleView.getViewState(); makePictureWebSite(); } }; // define the panel to hold the input text fields and the button // that executes the make site action TablePanel mainPanel = new TablePanel( new Object[] { viewPanel, makeSite }, VERTICAL, 10, 10, CENTER); // place the main panel in a frame that is centered on screen JPTFrame.createQuickJPTFrame("Make Picture Web Site", mainPanel); } /** Master method to build the image web site. */ private void makePictureWebSite() { // copy the default cascading style sheet file to the directory copyCSS(); // read the images file names from the directory readImageFileNames(); // create the htm files in the directory createPictureWebSite(); } /** The method that reads the file names of the image files. */ private void readImageFileNames() { // open File object to access the directory with images File imagesDirectory = new File(directory); // obtain array of file names for image files in directory files = imagesDirectory.list(filter); // save count of image file names length = files.length; } /** * Extracts a picture label from an image file name. * * Removes file extension. * Skips leading digits and underscores. * Replaces later underscores with spaces. * Adds spaces before initial digits and initial uppercase letters */ private String refineFileName(String name) { // eliminate image file extension from name name = name.substring(0, name.length() - 4); // test string size int size = name.length(); if (size == 0) return name; // skip leading digits and underscores as long as this does not // make the string empty int index = 0; while (index < size) { char next = name.charAt(index); if (Character.isDigit(next)) index++; else if (next == '_') index++; else break; } if ((index > 0) && (index < (length - 1))) name = name.substring(index); size = name.length(); // replace later underscores with spaces // add spaces before initial digits or initial uppercase letters // // use a StringBuffer to collect characters StringBuffer buffer = new StringBuffer(128); buffer.append(name.charAt(0)); for (index = 1; index < size; index++) { char c = name.charAt(index); char d = name.charAt(index - 1); if (Character.isDigit(c)) { if (! Character.isDigit(d)) { buffer.append(' '); } } if (Character.isUpperCase(c)) { if (! Character.isUpperCase(d)) { buffer.append(' '); } } if (c == '_') buffer.append(' '); else buffer.append(c); } // convert the buffer back to a string and return it name = buffer.toString(); return name; } /** Create the web site by creating each page. */ private void createPictureWebSite() { // build the site page by page for (int i = 0; i < length; i++) createPictureWebPage(i); // print confirmation message in text console console.out.println("Web Site Done: " + length + " Image Files"); } /** Create the i-th page of the web site. */ private void createPictureWebPage(int i) { // use StringBuffer to collect characters StringBuffer buffer = new StringBuffer(1024); // standard web page opening buffer.append(doctype); buffer.append(html); // web page head buffer.append(head); buffer.append(title); buffer.append(pagetitle); buffer.append(endtitle); buffer.append(csslink); buffer.append(endhead); // web page body buffer.append(body); // repeat page title in window buffer.append(paragraph); buffer.append(pagetitle); buffer.append(endparagraph); // make links First Back Next Last appendSideLinks(buffer, i); // make link that brings in picture with its caption makePictureLink(buffer, files[i]); // standard web page closing buffer.append(endbody); buffer.append(endhtml); // convert the buffer back to a string to get page text String page = buffer.toString(); // send the i-th page text to the i-th web site file try { // use pattern: open file; write page; close file FileWriter writer = new FileWriter(createWebPagePathName(i)); writer.write(page); writer.close(); } catch (IOException ex) { // print messages if IO errors happen console.out.println("IO failure for web page: " + i); console.out.println("Message: " + ex.getMessage()); // exit since things are not OK throw new RuntimeException("Exiting due to IO Failure"); } } /** * Append to the buffer the html code that links one picture page to * the first page, the back page, the next page, and the last page. */ private void appendSideLinks(StringBuffer buffer, int i) { // start paragraph buffer.append(paragraph); // make link to first page unless we are the first page if (i > 0) linkTo(buffer, "First", 0); else buffer.append("First"); buffer.append("\n"); // make link to back page unless we are the first page if (i > 0) linkTo(buffer, "Back", (i-1)); else buffer.append("Back"); buffer.append("\n"); // make link to next page unless we are the last page if (i < (length - 1)) linkTo(buffer, "Next", (i+1)); else buffer.append("Next"); buffer.append("\n"); // make link to last page unless we are the last page if (i < (length - 1)) linkTo(buffer, "Last", (length - 1)); else buffer.append("Last"); buffer.append("\n"); // finish paragraph buffer.append(endparagraph); } /** Create html for a link to the k-th page with given link text. */ private void linkTo(StringBuffer buffer, String text, int k) { if ((k < 0) || (k >= length)) return; buffer.append(openlink); buffer.append(createWebPageName(k)); buffer.append(shutlink); buffer.append(text); buffer.append(endlink); } /** * Create the file name for the i-th web page. * * If i equals zero use "index.htm". * * If i is positive use "pictureXXX.htm" where XXX is the * three digit represention of (i+1) in digit characters. * * This convention means that the file names start with * "image.htm" and continue with "picture002.htm" etc. */ private String createWebPageName(int i) { // for i equal to zero return "index.htm" if (i == 0) return "index.htm"; // otherwise build "pictureXXX.htm" return "picture" + threeChars(i + 1) + ".htm"; } /** Create the full path name for the i-th web page. */ private String createWebPagePathName(int i) { return directory + File.separatorChar + createWebPageName(i); } /** Returns the integer i represented as XXX. */ private String threeChars(int i) { if (i < 10) return "00" + i; if (i < 100) return "0" + i; return "" + i; } /** Create html for the link to the image and for its caption. */ private void makePictureLink(StringBuffer buffer, String name) { String caption = refineFileName(name); buffer.append(paragraph); buffer.append(openimage); buffer.append(name); buffer.append(shutimage); buffer.append(endparagraph); buffer.append(paragraph); buffer.append(caption); buffer.append(endparagraph); } /** Copy the pictures css file target directory. */ private void copyCSS() { String oldPath = "./" + cssname; String newPath = directory + File.separatorChar + cssname; copySmallFile(oldPath, newPath); } /** * Copy a small text file from one place to another. * * Assumes that the entire file can be read into memory at once. */ private void copySmallFile(String oldPath, String newPath) { if ((oldPath == null) || (newPath == null)) return; int bufferSize = 8092; StringBuffer buffer = new StringBuffer(bufferSize); char[] data = new char[bufferSize]; // read file try { // use pattern: open file; read file; close file FileReader reader = new FileReader(oldPath); while(true) { int count = reader.read(data); if (count > 0) buffer.append(data, 0, count); else break; } reader.close(); } catch (IOException ex) { // print messages if IO errors happen console.out.println("IO failure reading: " + oldPath); console.out.println("Message: " + ex.getMessage()); // exit since things are not OK throw new RuntimeException("Exiting due to IO Failure"); } // copy file try { // use pattern: open file; write page; close file FileWriter writer = new FileWriter(newPath); writer.write(buffer.toString()); writer.close(); } catch (IOException ex) { // print messages if IO errors happen console.out.println("IO failure writing: " + newPath); console.out.println("Message: " + ex.getMessage()); // exit since things are not OK throw new RuntimeException("Exiting due to IO Failure"); } } /** TEST CODE: Test the reading of file names. */ private void printRawFileNames() { console.out.println("Image Directory:" + directory + "\n"); console.out.println("Image File Count: " + length + "\n"); for (int i = 0; i < length; i++) console.out.println(files[i]); console.out.println(); } /** TEST CODE: Test the conversion of file names to picture labels. */ private void printRefinedFileNames() { console.out.println("Image Directory:" + directory + "\n"); console.out.println("Image File Count: " + length + "\n"); for (int i = 0; i < length; i++) console.out.println(refineFileName(files[i])); console.out.println(); } }