]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/dev/tool/tzu/ICUJarFinder.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / dev / tool / tzu / ICUJarFinder.java
1 /*\r
2  * ******************************************************************************\r
3  * Copyright (C) 2007, International Business Machines Corporation and others.\r
4  * All Rights Reserved.\r
5  * ******************************************************************************\r
6  */\r
7 package com.ibm.icu.dev.tool.tzu;\r
8 \r
9 import java.io.File;\r
10 import java.io.IOException;\r
11 import java.util.ArrayList;\r
12 import java.util.Iterator;\r
13 import java.util.List;\r
14 \r
15 /**\r
16  * Finds all updatable ICU4J jars in a set of specified directories.\r
17  */\r
18 public class ICUJarFinder {\r
19 \r
20     /**\r
21      * The delay in milliseconds between showing directories to the command line user.\r
22      */\r
23     public static final long DELAY = 5000; // 5 seconds\r
24 \r
25     /**\r
26      * The delay in milliseconds between showing directories to the command line user.\r
27      */\r
28     public static long lastShowtime = 0; // 5 seconds\r
29 \r
30     /**\r
31      * Searchs the directories / files represented in <code>paths</code> for valid ICU4J jars. The\r
32      * logic for determining if a file is an ICU4J jar is taken care of by the constructor of\r
33      * ICUFile. The resulting ICUFile's are then added to the result model.\r
34      * \r
35      * @param resultModel\r
36      *            The result model to add any discovered ICU4J jars to.\r
37      * @param logger\r
38      *            The current logger.\r
39      * @param paths\r
40      *            The list of paths to include to and exclude from the search.\r
41      * @param subdirs\r
42      *            Whether to include subdirectories in the search.\r
43      * @param curDir\r
44      *            The base directory of the tool.\r
45      * @param backupDir\r
46      *            The backup directory, or null if none. The backup directory is excluded from the\r
47      *            search\r
48      * @return The same result model as given.\r
49      * @throws InterruptedException\r
50      */\r
51     public static ResultModel search(ResultModel resultModel, Logger logger, IncludePath[] paths,\r
52             boolean subdirs, File curDir, File backupDir) throws InterruptedException {\r
53         // sift the included / excluded paths into two seperate arraylists\r
54         List included = new ArrayList();\r
55         List excluded = new ArrayList();\r
56         for (int i = 0; i < paths.length; i++) {\r
57             IncludePath path = paths[i];\r
58             File file = path.getPath();\r
59             try {\r
60                 file = file.getCanonicalFile();\r
61             } catch (IOException ex) {\r
62                 // recover in the simplest way, but report the error\r
63                 file = file.getAbsoluteFile();\r
64                 logger.errorln(ex.getMessage());\r
65             }\r
66             if (path.isIncluded())\r
67                 included.add(file);\r
68             else\r
69                 excluded.add(file);\r
70         }\r
71 \r
72         // if the backup dir is specified, don't search it\r
73         if (backupDir != null) {\r
74             File file = backupDir;\r
75             try {\r
76                 file = file.getCanonicalFile();\r
77             } catch (IOException ex) {\r
78                 // recover in the simplest way, but report the error\r
79                 file = file.getAbsoluteFile();\r
80                 logger.errorln(ex.getMessage());\r
81             }\r
82             excluded.add(file);\r
83         }\r
84 \r
85         // exclude the icu4j.jar that comes with this tool\r
86         File file = new File(curDir.getPath(), "icu4j.jar");\r
87         try {\r
88             file = file.getCanonicalFile();\r
89         } catch (IOException ex) {\r
90             // recover in the simplest way, but report the error\r
91             file = file.getAbsoluteFile();\r
92             logger.errorln(ex.getMessage());\r
93         }\r
94         excluded.add(file);\r
95 \r
96         // search each of the included files/directories\r
97         for (int i = 0; i < included.size(); i++)\r
98             search(resultModel, logger, (File) included.get(i), excluded, subdirs, 0);\r
99 \r
100         // chain the result model\r
101         return resultModel;\r
102     }\r
103 \r
104     /**\r
105      * Checks a specific file. If the file is an ICU4J jar that can be updated, then the ICUFile\r
106      * representing that file is added to the result model. If the file is a directory, the\r
107      * directory is then recursed.\r
108      * \r
109      * @param resultModel\r
110      *            The result model to add any discovered ICU4J jars to.\r
111      * @param logger\r
112      *            The current logger.\r
113      * @param statusBar\r
114      *            The status bar for status-bar messages, or null if none is present.\r
115      * @param file\r
116      *            The current file to check or directory to search.\r
117      * @param excluded\r
118      *            The list of all directories excluded in the search.\r
119      * @param subdirs\r
120      *            Whether to include subdirectories in the search.\r
121      * @param depth\r
122      *            The current depth of the search.\r
123      * @return The same result model as given.\r
124      * @throws InterruptedException\r
125      */\r
126     private static ResultModel search(ResultModel resultModel, Logger logger, File file,\r
127             List excluded, boolean subdirs, int depth) throws InterruptedException {\r
128         // ensure we are not following a symbolic link\r
129         if (isSymbolic(file))\r
130             return resultModel;\r
131 \r
132         // ensure that the file is in canonical form\r
133         try {\r
134             file = file.getCanonicalFile();\r
135         } catch (IOException ex) {\r
136             logger.errorln(ex.getMessage());\r
137             return resultModel;\r
138         }\r
139 \r
140         // check for interruptions\r
141         if (Thread.currentThread().isInterrupted())\r
142             throw new InterruptedException();\r
143 \r
144         // make sure the current file/directory isn't excluded\r
145         Iterator iter = excluded.iterator();\r
146         while (iter.hasNext())\r
147             if (file.equals(((File) iter.next())))\r
148                 return resultModel;\r
149 \r
150         if ((subdirs || depth == 0) && file.isDirectory()) {\r
151             // recurse through each file/directory inside this directory\r
152             File[] dirlist = file.listFiles();\r
153             if (dirlist != null && dirlist.length > 0) {\r
154                 // notify the user that something is happening\r
155                 long curTime = System.currentTimeMillis();\r
156                 if (depth <= 1 || curTime - lastShowtime > DELAY) {\r
157                     lastShowtime = curTime;\r
158                     logger.printlnToScreen(file.getPath());\r
159 \r
160                     // give a chance for the UI to display the message\r
161                     if (Thread.currentThread().isInterrupted())\r
162                         throw new InterruptedException();\r
163                     Thread.sleep(0);\r
164                 }\r
165 \r
166                 // recurse\r
167                 for (int i = 0; i < dirlist.length; i++)\r
168                     search(resultModel, logger, dirlist[i], excluded, subdirs, depth + 1);\r
169             }\r
170         } else {\r
171             // attempt to create an ICUFile object on the current file and add\r
172             // it to the result model if possible\r
173             try {\r
174                 // if the file/directory is an ICU jar file that we can\r
175                 // update, add it to the results\r
176                 resultModel.add(new ICUFile(file, logger));\r
177                 logger.printlnToBoth("Added " + file.getPath());\r
178             } catch (IOException ex) {\r
179                 // if it's not an ICU jar file that we can update, ignore it\r
180             }\r
181         }\r
182 \r
183         // chain the result model\r
184         return resultModel;\r
185     }\r
186 \r
187     /**\r
188      * Tests whether a file is a symbolic link by comparing the absolute path with the canonical\r
189      * path.\r
190      * \r
191      * @param file\r
192      *            The file to check.\r
193      * @return Whether the file is a symbolic link.\r
194      */\r
195     private static boolean isSymbolic(File file) {\r
196         try {\r
197             File parent = file.getParentFile();\r
198             if (parent == null)\r
199                 parent = new File(".");\r
200             File betterFile = new File(parent.getCanonicalPath(), file.getName());\r
201             return !betterFile.getAbsoluteFile().equals(betterFile.getCanonicalFile());\r
202         } catch (IOException ex) {\r
203             // if getCanonicalFile throws an IOException for this file, we won't\r
204             // want to dig into this path\r
205             return false;\r
206         }\r
207     }\r
208 \r
209     /**\r
210      * An empty constructor that restricts construction.\r
211      */\r
212     private ICUJarFinder() {\r
213     }\r
214 }\r