]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/dev/demo/charsetdet/DetectingViewer.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / dev / demo / charsetdet / DetectingViewer.java
1 /*\r
2  **************************************************************************\r
3  * Copyright (C) 2005-2007, International Business Machines Corporation   *\r
4  * and others. All Rights Reserved.                                       *\r
5  **************************************************************************\r
6  *\r
7  */\r
8 \r
9 package com.ibm.icu.dev.demo.charsetdet;\r
10 \r
11 import java.awt.event.*;\r
12 import java.awt.*;\r
13 import java.io.*;\r
14 import java.net.URL;\r
15 import java.nio.ByteBuffer;\r
16 import java.nio.charset.Charset;\r
17 import java.security.AccessControlException;\r
18 \r
19 import javax.swing.*;\r
20 \r
21 import com.ibm.icu.charset.CharsetICU;\r
22 import com.ibm.icu.dev.demo.impl.DemoApplet;\r
23 import com.ibm.icu.text.CharsetDetector;\r
24 import com.ibm.icu.text.CharsetMatch;\r
25 \r
26 /**\r
27  * This simple application demonstrates how to use the CharsetDetector API. It\r
28  * opens a file or web page, detects the encoding, and then displays it using that\r
29  * encoding.\r
30  */\r
31 public class DetectingViewer extends JFrame implements ActionListener\r
32 {\r
33     \r
34     /**\r
35      * For serialization\r
36      */\r
37     private static final long serialVersionUID = -2307065724464747775L;\r
38     private JTextPane text;\r
39     private JFileChooser fileChooser;\r
40     \r
41     /**\r
42      * @throws java.awt.HeadlessException\r
43      */\r
44     public DetectingViewer()\r
45     {\r
46         super();\r
47         DemoApplet.demoFrameOpened();\r
48         \r
49         try {\r
50             fileChooser = new JFileChooser();\r
51         } catch (AccessControlException ace) {\r
52             System.err.println("no file chooser - access control exception. Continuing without file browsing. "+ace.toString());\r
53             fileChooser = null; //\r
54         }\r
55         \r
56 //        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\r
57         setSize(800, 800);\r
58 \r
59         setJMenuBar(makeMenus());\r
60         text = new JTextPane();\r
61         text.setContentType("text/plain");\r
62         text.setText("");\r
63         text.setSize(800, 800);\r
64         \r
65         Font font = new Font("Arial Unicode MS", Font.PLAIN, 24);\r
66         text.setFont(font);\r
67         \r
68         JScrollPane scrollPane = new JScrollPane(text);\r
69         \r
70         getContentPane().add(scrollPane);\r
71         setVisible(true);\r
72 \r
73         addWindowListener(\r
74                 new WindowAdapter() {\r
75                     public void windowClosing(WindowEvent e) {\r
76 //                        setVisible(false);\r
77 //                        dispose();\r
78 \r
79                           doQuit();\r
80                     }\r
81                 } );\r
82 \r
83     \r
84     }\r
85 \r
86     public void actionPerformed(ActionEvent event)\r
87     {\r
88         String cmd = event.getActionCommand();\r
89         \r
90         if (cmd.equals("New...")) {\r
91            doNew();\r
92         } else if (cmd.equals("Open File...")) {\r
93            doOpenFile();\r
94         } else if (cmd.equals("Open URL...")) {\r
95             doOpenURL();\r
96         } else if (cmd.equals("Quit")) {\r
97            doQuit();\r
98         }\r
99     }\r
100 \r
101     public static void main(String[] args)\r
102     {\r
103         new DetectingViewer();\r
104     }\r
105     \r
106     private void errorDialog(String title, String msg)\r
107     {\r
108         JOptionPane.showMessageDialog(this, msg, title, JOptionPane.ERROR_MESSAGE);\r
109     }\r
110     \r
111     private BufferedInputStream openFile(File file)\r
112     {\r
113         FileInputStream fileStream = null;\r
114         \r
115         try {\r
116             fileStream = new FileInputStream(file);\r
117         } catch (Exception e) {\r
118             errorDialog("Error Opening File", e.getMessage());\r
119             return null;\r
120         }\r
121         \r
122         return new BufferedInputStream(fileStream);\r
123     }\r
124     \r
125 //    private void openFile(String directory, String filename)\r
126 //    {\r
127 //        openFile(new File(directory, filename));\r
128 //    }\r
129     \r
130     \r
131     private BufferedInputStream openURL(String url)\r
132     {\r
133         InputStream s = null;\r
134 \r
135         try {\r
136             URL aURL = new URL(url);\r
137             s = aURL.openStream();\r
138         } catch (Exception e) {\r
139             errorDialog("Error Opening URL", e.getMessage());\r
140             return null;\r
141         }\r
142         \r
143         return new BufferedInputStream(s);\r
144     }\r
145     \r
146     private String encodingName(CharsetMatch match)\r
147     {\r
148         return match.getName() + " (" + match.getLanguage() + ")";\r
149     }\r
150     \r
151     private void setMatchMenu(CharsetMatch[] matches)\r
152     {\r
153         JMenu menu = getJMenuBar().getMenu(1);\r
154         JMenuItem menuItem;\r
155         \r
156         menu.removeAll();\r
157         \r
158         for (int i = 0; i < matches.length; i += 1) {\r
159             CharsetMatch match = matches[i];\r
160             \r
161             menuItem = new JMenuItem(encodingName(match) + " " + match.getConfidence());\r
162             \r
163             menu.add(menuItem);\r
164         }\r
165     }\r
166     \r
167     private byte[] scriptTag = {(byte) 's', (byte) 'c', (byte) 'r', (byte) 'i', (byte) 'p', (byte) 't'};\r
168     private byte[] styleTag  = {(byte) 's', (byte) 't', (byte) 'y', (byte) 'l', (byte) 'e'};\r
169     private static int BUFFER_SIZE = 100000;\r
170     \r
171     private boolean openTag(byte[] buffer, int offset, int length, byte[] tag)\r
172     {\r
173         int tagLen = tag.length;\r
174         int bufRem = length - offset;\r
175         int b;\r
176         \r
177         for (b = 0; b < tagLen && b < bufRem; b += 1) {\r
178             if (buffer[b + offset] != tag[b]) {\r
179                 return false;\r
180             }\r
181         }\r
182         \r
183         return b == tagLen;\r
184     }\r
185     \r
186     private boolean closedTag(byte[] buffer, int offset, int length, byte[] tag)\r
187     {\r
188         if (buffer[offset] != (byte) '/') {\r
189             return false;\r
190         }\r
191         \r
192         return openTag(buffer, offset + 1, length, tag);\r
193     }\r
194     \r
195     private byte[] filter(InputStream in)\r
196     {\r
197         byte[] buffer = new byte[BUFFER_SIZE];\r
198         int bytesRemaining = BUFFER_SIZE;\r
199         int bufLen = 0;\r
200         \r
201         in.mark(BUFFER_SIZE);\r
202         \r
203         try {\r
204             while (bytesRemaining > 0) {\r
205                 int bytesRead = in.read(buffer, bufLen, bytesRemaining);\r
206                 \r
207                 if (bytesRead <= 0) {\r
208                     break;\r
209                 }\r
210                 \r
211                 bufLen += bytesRead;\r
212                 bytesRemaining -= bytesRead;\r
213             }\r
214         } catch (Exception e) {\r
215             // TODO: error handling?\r
216             return null;\r
217         }\r
218         \r
219         boolean inTag = false;\r
220         boolean skip  = false;\r
221         int out = 0;\r
222         \r
223         for (int i = 0; i < bufLen; i += 1) {\r
224             byte b = buffer[i];\r
225             \r
226             if (b == (byte) '<') {\r
227                 inTag = true;\r
228                 \r
229                 if (openTag(buffer, i + 1, bufLen, scriptTag) ||\r
230                     openTag(buffer, i + 1, bufLen, styleTag)) {\r
231                     skip = true;\r
232                 } else if (closedTag(buffer, i + 1, bufLen, scriptTag) ||\r
233                            closedTag(buffer, i + 1, bufLen, styleTag)) {\r
234                     skip = false;\r
235                 }\r
236             } else if (b == (byte) '>') {\r
237                 inTag = false;\r
238             } else if (! (inTag || skip)) {\r
239                 buffer[out++] = b;\r
240             }\r
241         }\r
242 \r
243         byte[] filtered = new byte[out];\r
244         \r
245         System.arraycopy(buffer, 0, filtered, 0, out);\r
246         return filtered;\r
247     }\r
248     \r
249     private CharsetMatch[] detect(byte[] bytes)\r
250     {\r
251         CharsetDetector det = new CharsetDetector();\r
252         \r
253         det.setText(bytes);\r
254         \r
255         return det.detectAll();\r
256     }\r
257     \r
258     private CharsetMatch[] detect(BufferedInputStream inputStream)\r
259     {\r
260         CharsetDetector det    = new CharsetDetector();\r
261         \r
262         try {\r
263             det.setText(inputStream);\r
264             \r
265             return det.detectAll();\r
266         } catch (Exception e) {\r
267             // TODO: error message?\r
268             return null;\r
269         }\r
270     }\r
271     \r
272     private void show(InputStream inputStream, CharsetMatch[] matches, String title)\r
273     {\r
274         InputStreamReader isr;\r
275         char[] buffer = new char[1024];\r
276         int bytesRead = 0;\r
277         \r
278         if (matches == null || matches.length == 0) {\r
279             errorDialog("Match Error", "No matches!");\r
280             return;\r
281         }\r
282         \r
283         try {\r
284             StringBuffer sb = new StringBuffer();\r
285             String encoding = matches[0].getName();\r
286             \r
287             inputStream.reset();\r
288             \r
289             if (encoding.startsWith("UTF-32")) {\r
290                 byte[] bytes = new byte[1024];\r
291                 int offset = 0;\r
292                 int chBytes = 0;\r
293                 Charset utf32 = CharsetICU.forNameICU(encoding);\r
294                 \r
295                 while ((bytesRead = inputStream.read(bytes, offset, 1024)) >= 0) {\r
296                     offset  = bytesRead % 4;\r
297                     chBytes = bytesRead - offset;\r
298                     \r
299                     sb.append(utf32.decode(ByteBuffer.wrap(bytes)).toString());\r
300                     \r
301                     if (offset != 0) {\r
302                         for (int i = 0; i < offset; i += 1) {\r
303                             bytes[i] = bytes[chBytes + i];\r
304                         }\r
305                     }\r
306                 }\r
307             } else {\r
308                 isr = new InputStreamReader(inputStream, encoding);\r
309                 \r
310                 while ((bytesRead = isr.read(buffer, 0, 1024)) >= 0) {\r
311                     sb.append(buffer, 0, bytesRead);\r
312                 }\r
313                 \r
314                 isr.close();\r
315             }\r
316             \r
317             this.setTitle(title + " - " + encodingName(matches[0]));\r
318             \r
319             setMatchMenu(matches);\r
320             text.setText(sb.toString());\r
321         } catch (IOException e) {\r
322             errorDialog("IO Error", e.getMessage());\r
323         } catch (Exception e) {\r
324             errorDialog("Internal Error", e.getMessage());\r
325         }\r
326     }\r
327     \r
328     private void doNew()\r
329     {\r
330         // open a new window...\r
331     }\r
332     \r
333     private void doOpenFile()\r
334     {\r
335         int retVal = fileChooser.showOpenDialog(this);\r
336         \r
337         if (retVal == JFileChooser.APPROVE_OPTION) {\r
338             File file = fileChooser.getSelectedFile();\r
339             BufferedInputStream inputStream = openFile(file);\r
340             \r
341             if (inputStream != null) {\r
342                 CharsetMatch[] matches = detect(inputStream);\r
343                 \r
344                 show(inputStream, matches, file.getName());                \r
345             }\r
346         }\r
347     }\r
348     \r
349     private void doOpenURL()\r
350     {\r
351         String url = (String) JOptionPane.showInputDialog(this, "URL to open:", "Open URL", JOptionPane.PLAIN_MESSAGE,\r
352                 null, null, null);\r
353         \r
354         if (url != null && url.length() > 0) {\r
355             BufferedInputStream inputStream = openURL(url);\r
356             \r
357             if (inputStream != null) {\r
358                 byte[] filtered = filter(inputStream);\r
359                 CharsetMatch[] matches = detect(filtered);\r
360                 \r
361                 show(inputStream, matches, url);                \r
362             }\r
363         }\r
364 }\r
365     \r
366     private void doQuit()\r
367     {\r
368         DemoApplet.demoFrameClosed();\r
369         this.setVisible(false);\r
370         this.dispose();\r
371     }\r
372     \r
373     private JMenuBar makeMenus()\r
374     {\r
375         JMenu menu = new JMenu("File");\r
376         JMenuItem mi;\r
377         \r
378         mi = new JMenuItem("Open File...");\r
379         mi.setAccelerator((KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK)));\r
380         mi.addActionListener(this);\r
381         menu.add(mi);\r
382         if(fileChooser == null) {\r
383             mi.setEnabled(false); // no file chooser.\r
384         }\r
385         \r
386         mi = new JMenuItem("Open URL...");\r
387         mi.setAccelerator((KeyStroke.getKeyStroke(KeyEvent.VK_U, ActionEvent.CTRL_MASK)));\r
388         mi.addActionListener(this);\r
389         menu.add(mi);\r
390         \r
391         mi = new JMenuItem("Quit");\r
392         mi.setAccelerator((KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK)));\r
393         mi.addActionListener(this);\r
394         menu.add(mi);\r
395         \r
396         JMenuBar mbar = new JMenuBar();\r
397         mbar.add(menu);\r
398         \r
399         menu = new JMenu("Detected Encodings");\r
400         mbar.add(menu);\r
401         \r
402         return mbar;\r
403     }\r
404 }\r