import java.applet.*; import javax.mail.*; import java.security.*; import com.sun.mail.imap.*; import java.io.*; import java.util.*; /** * Create Haiku from a list of phrases, loaded from an IMAP folder or File. * Can be run as an applet (if signed) or application. * * Created by Mike Bremford, 2009-05-18. Use as you like so long as I'm * acknowledged as the author. */ public class Haiku extends Applet { private Collection fives, sevens; private Random random = new Random(); /** * Possibly add a phrase to generator. If the phrase is in latin script * and has 5 or 7 syllables it is accepted and this method returns true. * @param phrase the phrase * @return true if the phrase was accepted, false otherwise */ public boolean addPhrase(String phrase) { for (int i=0;i=0 || (c>=0x370 && c<=0x900)) { return false; } } phrase = phrase.toLowerCase(); phrase = phrase.trim().replaceAll("\\s+", " "); String[] words = getWords(phrase); int num = 0; for (int i=0;i= getCount()) { throw new IllegalArgumentException(i+" outside range 0-"+(getCount()-1)); } if (!(fives instanceof List)) { if (fives.size()==1 || sevens.size()==0) { throw new IllegalStateException("Not enough phrases"); } fives = new ArrayList(fives); sevens = new ArrayList(sevens); } int n1 = i; int n3 = n1 % (fives.size()-1); n1 /= (fives.size()-1); int n2 = n1 % sevens.size(); n1 /= sevens.size(); if (n3>=n1) n3++; Object p1 = ((List)fives).get(n1); Object p2 = ((List)sevens).get(n2); Object p3 = ((List)fives).get(n3); String haiku = p1 + "\n" + p2 + "\n" + p3; // haiku += " (i="+i+" n1="+n1+"/"+fives.size()+" n2="+n2+"/"+sevens.size()+" n3="+n3+"/"+fives.size()+")"; return haiku; } catch (RuntimeException e) { e.printStackTrace(); throw e; } } /** * Return a random Haiku */ public String getRandomHaiku() { if (getCount()==0) { return "lacking in data\ni have no useful results\nhaiku disappoints?"; } else { return getHaiku(random.nextInt(getCount())); } } /** * Given a one-line phrase, split it into individual words */ private static String[] getWords(String phrase) { phrase = phrase.replaceAll("'", ""); phrase = phrase.replaceAll("[^A-Za-z]", " "); return phrase.split(" +"); } /** * Algorithm from Dr. Rudolph Flesch (1949) * http://portal.acm.org/citation.cfm?id=10583 */ private static int getNumSyllables(String word) { int count = 0; if (word.length()>2) { if (word.endsWith("ed") || word.endsWith("es")) { word = word.substring(0, word.length()-2); } else if (word.endsWith("e") && !word.endsWith("le")) { word = word.substring(0, word.length()-1); } } boolean lastvowel = false; for (int i=0;i= 0; if (vowel && !lastvowel) { count++; } lastvowel = vowel; } if (count==0) { count= 1; } return count; } /** * Load the like of phrases from the specified File, which should have a list * of lines containing 5 or 7 syllables each (any that don't are ignored). * @param file the File to load the phrases from */ public void loadFromFile(File file) throws IOException { if (!(fives instanceof Set)) { fives = new HashSet(); sevens = new HashSet(); } BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(file)); String s; while ((s=reader.readLine())!=null) { addPhrase(s); } } finally { try { if (reader!=null) reader.close(); } catch (Exception e) {} } } /** * Load phrases from the Subject field of the specified IMAP URL. This method * is privileged, and so can be called from a digitally-signed Applet. * @param urlstring the URL to connect to * @param max the number of messages to load (0 for all of them, which can be slow) */ public void loadFromIMAP(final String urlstring, final int max) throws Exception { Exception e = (Exception)AccessController.doPrivileged(new PrivilegedAction() { public Object run() { try { loadFromIMAP(urlstring, max, null); } catch (Exception e) { return e; } return null; } }); if (e!=null) { e.printStackTrace(); throw e; } } /** * Load phrases from the Subject field of the specified IMAP URL * @param urlstring the URL to connect to * @param max the number of messages to load (0 for all of them, which can be slow) * @param file if not null, the File to write the header responses to */ public void loadFromIMAP(final String urlstring, final int max, final File file) throws Exception { if (!(fives instanceof Set)) { fives = new HashSet(); sevens = new HashSet(); } Properties props = new Properties(); URLName url = new URLName(urlstring); if ("imaps".equals(url.getProtocol())) { url = new URLName("imap", url.getHost(), url.getPort(), url.getFile(), url.getUsername(), url.getPassword()); props.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.setProperty("mail.imap.socketFactory.fallback", "false"); props.setProperty("mail.imap.port", "993"); props.setProperty("mail.imap.socketFactory.port", "993"); } Session session = Session.getInstance(props); Store store = new IMAPStore(session, url); PrintStream out = null; try { store.connect(); IMAPFolder folder = (IMAPFolder)store.getFolder(url); folder.open(Folder.READ_ONLY); Message[] msgs = folder.getMessages(); System.out.print("Reading "+(max==0 ? "all" : Integer.toString(Math.min(msgs.length, max)))+" of "+msgs.length+" messages from \""+url.getFile()+"\"..."); if (max!=0 && max < msgs.length) { List l = new ArrayList(Arrays.asList(msgs)); Collections.shuffle(l); Message[] newmsgs = new Message[max]; for (int i=0;i count) { num = count; } for (int i=0;i