PatternPackage.java

00001 package edu.stanford.hci.r3.pattern;
00002 
00003 import java.io.BufferedReader;
00004 import java.io.File;
00005 import java.io.FileInputStream;
00006 import java.io.FileNotFoundException;
00007 import java.io.FileReader;
00008 import java.io.IOException;
00009 import java.io.LineNumberReader;
00010 import java.util.HashMap;
00011 import java.util.InvalidPropertiesFormatException;
00012 import java.util.List;
00013 import java.util.Map;
00014 import java.util.Properties;
00015 
00016 import edu.stanford.hci.r3.pattern.coordinates.CoordinateTranslator;
00017 import edu.stanford.hci.r3.units.PatternDots;
00018 import edu.stanford.hci.r3.units.Units;
00019 import edu.stanford.hci.r3.units.coordinates.StreamedPatternCoordinates;
00020 import edu.stanford.hci.r3.util.DebugUtils;
00021 import edu.stanford.hci.r3.util.files.FileUtils;
00022 
00043 public class PatternPackage {
00044 
00050         public static Map<String, PatternPackage> getAvailablePatternPackages(File patternLocation) {
00051                 final HashMap<String, PatternPackage> packages = new HashMap<String, PatternPackage>();
00052 
00053                 // list the available directories
00054                 final List<File> visibleDirs = FileUtils.listVisibleDirs(patternLocation);
00055                 // System.out.println(visibleDirs);
00056 
00057                 // create new PatternPackage objects from the directories
00058                 for (final File f : visibleDirs) {
00059                         final PatternPackage patternPackage = new PatternPackage(f);
00060                         packages.put(patternPackage.getName(), patternPackage);
00061                 }
00062 
00063                 // return the list of packages
00064                 return packages;
00065         }
00066 
00071         private static final String MIN_PATTERN_X = "minPatternX";
00072 
00076         private static final String MIN_PATTERN_Y = "minPatternY";
00077 
00081         private static final String NUM_HORIZ_DOTS_BETWEEN_PAGES = "numHorizontalDotsBetweenOriginOfPages";
00082 
00086         private static final String NUM_VERT_DOTS_BETWEEN_PAGES = "numVerticalDotsBetweenOriginOfPages";
00087 
00091         private static final String PATTERN_FILE_EXTENSION = ".pattern";
00092 
00096         private PatternDots minPatternX;
00097 
00101         private PatternDots minPatternY;
00102 
00106         private String name;
00107 
00111         private double numDotsHorizontalBetweenOriginOfPages;
00112 
00118         private double numDotsVerticalBetweenOriginOfPages;
00119 
00123         private int numPatternColsPerFile;
00124 
00131         private int numPatternFiles;
00132 
00136         private int numPatternRowsPerFile;
00137 
00141         private Map<Integer, File> numToPatternFile;
00142 
00146         private File patternDefinitionPath;
00147 
00151         private List<File> patternFiles;
00152 
00156         private CoordinateTranslator coordinateTranslator;
00157 
00164         public PatternPackage(File location) {
00165                 patternDefinitionPath = location;
00166 
00167                 name = location.getName();
00168 
00169                 // look at the directory to see how many pattern files are available
00170                 // System.out.println(patternDefinitionPath.getAbsolutePath());
00171                 final List<File> visibleFiles = FileUtils.listVisibleFiles(patternDefinitionPath,
00172                                 new String[] { "pattern" });
00173 
00174                 numPatternFiles = visibleFiles.size();
00175 
00176                 DebugUtils.println("There are " + numPatternFiles + " pattern files in " + location);
00177                 if (numPatternFiles == 0) {
00178                         DebugUtils.println("This pattern package is not usable.");
00179                         return;
00180                 } else {
00181                         DebugUtils.println("Loading pattern package information.");
00182                 }
00183 
00184                 patternFiles = visibleFiles;
00185 
00186                 // populate the map from page number --> pattern file
00187                 numToPatternFile = new HashMap<Integer, File>();
00188                 for (File f : patternFiles) {
00189                         String fileName = f.getName();
00190                         // get the number in the name
00191                         Integer num = Integer.parseInt(fileName.substring(0, fileName
00192                                         .indexOf(PATTERN_FILE_EXTENSION)));
00193                         numToPatternFile.put(num, f);
00194                 }
00195 
00196                 // open a .pattern file to see how many dots tall/across each .pattern file is
00197                 File patternFile = patternFiles.get(0);
00198                 BufferedReader br = null;
00199                 try {
00200                         br = new BufferedReader(new FileReader(patternFile));
00201                 } catch (FileNotFoundException e) {
00202                         e.printStackTrace();
00203                 }
00204 
00205                 // start a linenumberreader and check how many rows we have
00206                 // potentially spin this off into the FileUtil class
00207                 LineNumberReader lnr = new LineNumberReader(br);
00208                 String firstLine = null;
00209                 try {
00210                         firstLine = lnr.readLine();
00211                         lnr.skip(patternFile.length() - firstLine.length());
00212                 } catch (IOException e) {
00213                         e.printStackTrace();
00214                 }
00215 
00216                 // see how many dots tall each file is by checking how many lines there are in the file
00217                 // see how many dots across each .pattern file is by checking length of the first line
00218                 numPatternColsPerFile = firstLine.length();
00219                 numPatternRowsPerFile = lnr.getLineNumber();
00220 
00221                 // close this file
00222                 try {
00223                         lnr.close();
00224                         br.close();
00225                 } catch (IOException e) {
00226                         e.printStackTrace();
00227                 }
00228 
00229                 // read in the config.xml file
00230                 // parse the entries that look like this:
00231                 // <entry key="minPatternX">184022418.0</entry>
00232                 // <entry key="minPatternY">7187.0</entry>
00233                 // <entry key="numHorizontalDotsBetweenOriginOfPages">1330</entry>
00234                 readPropertiesFromConfigFile(new File(patternDefinitionPath, "config.xml"));
00235         }
00236 
00240         public PatternDots getMinPatternX() {
00241                 return minPatternX;
00242         }
00243 
00247         public PatternDots getMinPatternY() {
00248                 return minPatternY;
00249         }
00250 
00254         public String getName() {
00255                 return name;
00256         }
00257 
00261         public double getNumDotsHorizontalBetweenPages() {
00262                 return numDotsHorizontalBetweenOriginOfPages;
00263         }
00264 
00268         public double getNumDotsVerticalBetweenPages() {
00269                 return numDotsVerticalBetweenOriginOfPages;
00270         }
00271 
00275         public int getNumPatternColsPerFile() {
00276                 return numPatternColsPerFile;
00277         }
00278 
00282         public int getNumPatternRowsPerFile() {
00283                 return numPatternRowsPerFile;
00284         }
00285 
00293         public StreamedPatternCoordinates getPatternCoordinateOfOriginOfFile(int patternFileNumber) {
00294                 final PatternDots x = new PatternDots(minPatternX.getValue() + patternFileNumber
00295                                 * numDotsHorizontalBetweenOriginOfPages);
00296                 final PatternDots y = new PatternDots(minPatternY.getValue() + patternFileNumber
00297                                 * numDotsVerticalBetweenOriginOfPages);
00298                 return new StreamedPatternCoordinates(x, y);
00299         }
00300 
00324         public String[] readPatternFromFile(int numPatternFile, Units originX, Units originY,
00325                         Units width, Units height) {
00326 
00327                 // regardless of the units, convert them to pattern dots
00328                 int startDotsX = (int) Math.round(originX.getValueInPatternDots());
00329                 int startDotsY = (int) Math.round(originY.getValueInPatternDots());
00330                 int numDotsAcross = (int) Math.round(width.getValueInPatternDots());
00331                 int numDotsDown = (int) Math.round(height.getValueInPatternDots());
00332 
00333                 // ///////////////////////////////////////
00334                 // begin: making sure the units make sense
00335                 if (startDotsX < 0) {
00336                         startDotsX = 0;
00337                 }
00338                 if (startDotsX > numPatternColsPerFile - 1) {
00339                         startDotsX = numPatternColsPerFile - 1;
00340                 }
00341                 if (startDotsY < 0) {
00342                         startDotsY = 0;
00343                 }
00344                 if (startDotsY > numPatternRowsPerFile - 1) {
00345                         startDotsY = numPatternRowsPerFile - 1;
00346                 }
00347                 if (numDotsAcross < 0) {
00348                         numDotsAcross = 0;
00349                 }
00350                 // if the position of the rightmost dot is greater than the number of dots available, we
00351                 // adjust the requested number.
00352                 // 
00353                 // for example, if the startDotsX is index 12 (counting from 0), and we are requesting 8
00354                 // dots across, we will need dots 12, 13, 14, 15, 16, 17, 18, 19.
00355                 // 
00356                 // if this file only has 15 dots across, we calculate that 12 + 8 = 20
00357                 // 20 > 15 is bad... and 20-15 is 5.
00358                 // we can request at max 8-5=3 dots.
00359                 // So we can get dots numbered 12, 13, and 14... which makes sense in a 15-dot wide file
00360                 // indexed from 0
00361                 int rightMostDot = startDotsX + numDotsAcross;
00362                 if (rightMostDot > numPatternColsPerFile) {
00363                         numDotsAcross = numDotsAcross - (rightMostDot - numPatternColsPerFile);
00364                         rightMostDot = startDotsX + numDotsAcross; // ends up being startDotsX + numDotsAcross
00365                         // - rightMostDot + numPatternColsPerFile
00366                 }
00367 
00368                 if (numDotsDown < 0) {
00369                         numDotsDown = 0;
00370                 }
00371                 // same reasoning as above
00372                 final int bottomMostDot = startDotsY + numDotsDown;
00373                 if (bottomMostDot > numPatternRowsPerFile) {
00374                         numDotsDown -= (bottomMostDot - numPatternRowsPerFile);
00375                 }
00376                 // end: making sure the units make sense
00377                 // /////////////////////////////////////
00378 
00379                 // create a data structure large enough to store however many dots we need
00380                 final String[] pattern = new String[numDotsDown];
00381 
00382                 // we are asking for pattern from an invalid file.
00383                 if (numPatternFile < 0 || numPatternFile >= numPatternFiles) {
00384                         DebugUtils.println("Pattern File " + numPatternFile
00385                                         + " does not exist in this package.");
00386                         return pattern;
00387                 }
00388 
00389                 // read the file and populate the array with jitter directions
00390                 // open up file numPatternFile
00391                 final File patternFile = numToPatternFile.get(numPatternFile);
00392 
00393                 BufferedReader br = null;
00394                 try {
00395                         br = new BufferedReader(new FileReader(patternFile));
00396 
00397                         // skip the requested number of vertical lines
00398                         while (startDotsY > 0) {
00399                                 br.readLine();
00400                                 startDotsY--;
00401                         }
00402 
00403                         // for each of the remaining lines, crop out the requested part of the string
00404                         for (int i = 0; i < numDotsDown; i++) {
00405                                 String line = br.readLine();
00406                                 pattern[i] = line.substring(startDotsX, rightMostDot);
00407                         }
00408 
00409                 } catch (FileNotFoundException e) {
00410                         e.printStackTrace();
00411                 } catch (IOException e) {
00412                         e.printStackTrace();
00413                 }
00414                 return pattern;
00415         }
00416 
00422         private void readPropertiesFromConfigFile(File configFile) {
00423                 Properties props = new Properties();
00424                 try {
00425                         // NOTE: If this line fails, check to make sure gnujaxp.jar is not on your classpath
00426                         // With JFreeChart, and some other includes, gnujaxp will actually BREAK this line.
00427                         // Remove gnujaxp and you should be fine.
00428                         props.loadFromXML(new FileInputStream(configFile));
00429                 } catch (InvalidPropertiesFormatException e) {
00430                         e.printStackTrace();
00431                 } catch (FileNotFoundException e) {
00432                         e.printStackTrace();
00433                 } catch (IOException e) {
00434                         e.printStackTrace();
00435                 }
00436                 minPatternX = new PatternDots(Double.parseDouble(props.getProperty(MIN_PATTERN_X)));
00437                 minPatternY = new PatternDots(Double.parseDouble(props.getProperty(MIN_PATTERN_Y)));
00438                 numDotsHorizontalBetweenOriginOfPages = Double.parseDouble(props
00439                                 .getProperty(NUM_HORIZ_DOTS_BETWEEN_PAGES));
00440                 numDotsVerticalBetweenOriginOfPages = Double.parseDouble(props
00441                                 .getProperty(NUM_VERT_DOTS_BETWEEN_PAGES));
00442 
00443                 // System.out.println("PatternPackage: minPatternX=" + minPatternX + " minPatternY="
00444                 // + minPatternY + " numHorizDotsBetweenPages="
00445                 // + numHorizontalDotsBetweenOriginOfPages);
00446         }
00447 
00451         public String toString() {
00452                 return "PatternPackage: {" + patternDefinitionPath + "}";
00453         }
00454 }

Generated on Sat Apr 14 18:21:36 2007 for R3 Paper Toolkit by  doxygen 1.4.7