/* @(#)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();
}
}