source: 3thparty/jupload/src/main/java/wjhk/jupload2/gui/JUploadTextArea.java @ 3951

Revision 3951, 9.0 KB checked in by alexandrecorreia, 13 years ago (diff)

Ticket #1709 - Adicao de codigo fonte java do componente jupload

Line 
1//
2// $Id: JUploadTextArea.java 95 2007-05-02 03:27:05Z
3// /C=DE/ST=Baden-Wuerttemberg/O=ISDN4Linux/OU=Fritz
4// Elfert/CN=svn-felfert@isdn4linux.de/emailAddress=fritz@fritz-elfert.de $
5//
6// jupload - A file upload applet.
7// Copyright 2007 The JUpload Team
8//
9// Created: ?
10// Creator: William JinHua Kwong
11// Last modified: $Date: 2010-06-29 16:47:31 -0300 (Ter, 29 Jun 2010) $
12//
13// This program is free software; you can redistribute it and/or modify it under
14// the terms of the GNU General Public License as published by the Free Software
15// Foundation; either version 2 of the License, or (at your option) any later
16// version. This program is distributed in the hope that it will be useful, but
17// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19// details. You should have received a copy of the GNU General Public License
20// along with this program; if not, write to the Free Software Foundation, Inc.,
21// 675 Mass Ave, Cambridge, MA 02139, USA.
22
23package wjhk.jupload2.gui;
24
25import java.awt.Color;
26import java.text.SimpleDateFormat;
27import java.util.Date;
28import java.util.concurrent.BlockingQueue;
29import java.util.concurrent.LinkedBlockingQueue;
30
31import javax.swing.JTextArea;
32
33import wjhk.jupload2.policies.UploadPolicy;
34
35/**
36 * This class represents the text area for debug output.
37 */
38@SuppressWarnings("serial")
39public class JUploadTextArea extends JTextArea {
40
41        /**
42         * Maximum number of characters in the logWindow.
43         */
44        public final static int MAX_LOG_WINDOW_LENGTH = 800000;
45
46        /**
47         * The size we truncate the output to, when the maximum size of debug output
48         * is reach. We remove 20%.
49         */
50        public final static int SIZE_TO_TRUNCATE_TO = (int) (MAX_LOG_WINDOW_LENGTH * 0.8);
51
52        /**
53         * The current upload policy
54         */
55        UploadPolicy uploadPolicy;
56
57        /**
58         * Indicates whether the logging in the LogMessageThread is active or not.
59         * It's marked as active before starting this thread. It's marked as
60         * non-active, when this thread is interrupted, in {@link #unload()}
61         */
62        boolean loggingActive = false;
63
64        /**
65         * The ConcurrentLinkedQueue that'll contain the messages.
66         */
67        private BlockingQueue<String> messages;
68
69        /**
70         * This value is logged in the debug file, and in the debug output, for each
71         * line. This allows to sort the outputed line correctly.
72         *
73         * @see #displayMsg(String, String)
74         */
75        private int messageId = 1;
76
77        /**
78         * A thread, that will be called in the EventDispatcherThread, to have a
79         * tread-safe update of the GUI. This thread is responsible to display one
80         * String.
81         */
82        static class LogMessageThread extends Thread {
83
84                /**
85                 * The text area that'll contain the messages.
86                 */
87                private JUploadTextArea textArea;
88
89                /**
90                 * @param textArea
91                 */
92                LogMessageThread(JUploadTextArea textArea) {
93                        this.textArea = textArea;
94                        setDaemon(true);
95                }
96
97                /** The run method of the Runnable Interface */
98                @Override
99                public void run() {
100                        String nextMessage = null;
101
102                        if (this.textArea.uploadPolicy.getDebugLevel() >= 30) {
103                                int messageBackup = this.textArea.messageId;
104                                this.textArea.messageId = 0;
105                                this.textArea.setText(this.textArea.formatMessageOutput(
106                                                "[DEBUG]", "Logging system is initialized\n"));
107                                this.textArea.messageId = messageBackup;
108                        }
109
110                        while (this.textArea.loggingActive) {
111                                try {
112                                        nextMessage = this.textArea.messages.take() + "\n";
113
114                                        // Ah, a new message has been delivered...
115
116                                        synchronized (this.textArea) {
117                                                String content = this.textArea.getText();
118                                                int contentLength = content.length();
119                                                // If the current content is too long, we truncate it.
120                                                if (contentLength > JUploadTextArea.MAX_LOG_WINDOW_LENGTH) {
121                                                        content += nextMessage;
122                                                        String newContent = content.substring(content
123                                                                        .length()
124                                                                        - SIZE_TO_TRUNCATE_TO, content.length());
125                                                        this.textArea.setText(newContent);
126                                                        contentLength = SIZE_TO_TRUNCATE_TO;
127                                                } else {
128                                                        // The result is not too long
129                                                        this.textArea.append(nextMessage);
130                                                        contentLength += nextMessage.length();
131                                                }
132                                                this.textArea.setCaretPosition(contentLength - 1);
133                                        } // synchronized
134                                } catch (InterruptedException e) {
135                                        // If we're not running any more, then this 'stop' is
136                                        // not a
137                                        // problem any more. We're then just notified we must
138                                        // stop
139                                        // the thread.
140                                        if (this.textArea.loggingActive) {
141                                                // This should not happen, and we can not put in the
142                                                // standard JUpload output, as this thread is
143                                                // responsible for it.
144                                                e.printStackTrace();
145                                        }
146                                }// try
147                        }// while
148                }
149        }
150
151        /**
152         * The thread, that will put messages in the debug log.
153         */
154        LogMessageThread logMessageThread = null;
155
156        /**
157         * Constructs a new empty TextArea with the specified number of rows and
158         * columns.
159         *
160         * @param rows
161         *            The desired number of text rows (lines).
162         * @param columns
163         *            The desired number of columns.
164         * @param uploadPolicy
165         *            The current uploadPolicy
166         */
167        public JUploadTextArea(int rows, int columns, UploadPolicy uploadPolicy) {
168                super(rows, columns);
169                this.uploadPolicy = uploadPolicy;
170                this.messages = new LinkedBlockingQueue<String>();
171                setBackground(new Color(255, 255, 203));
172                setEditable(false);
173                setLineWrap(true);
174                setWrapStyleWord(true);
175
176                // The queue, where messages to display will be posted.
177                this.logMessageThread = new LogMessageThread(this);
178                this.logMessageThread.setName(this.logMessageThread.getClass()
179                                .getName());
180                // NO START HERE: the logMessageThread needs to know the upload policy,
181                // to run properly. The thread is started in the setUploadPolicy method.
182
183                // The unload callback will be registered, once the uploadPolicy has
184                // been built, by DefaultJUploadContext.init(JUploadApplet)
185        }
186
187        /**
188         * Add a string to the queue of string to be added to the logWindow. This is
189         * necessary, to manage the non-thread-safe Swing environment.
190         *
191         * @param tag
192         *            The tag (eg: INFO, DEBUG...)
193         * @param msg
194         *            The message to add, at the end of the JUploadTextArea.
195         * @return The formatted text that was added to the log window.
196         */
197        public final String displayMsg(String tag, String msg) {
198                String fullMessage = formatMessageOutput(tag, msg);
199
200                try {
201                        // messages is a BlockingQueue. So the next line may 'block' the
202                        // applet main thread. But, we're optimistic: this should not happen
203                        // as we instanciate an unbound LinkedBlockingQueue. We'll be
204                        // blocked at Integer.MAX_VALUE, that is ... much after an
205                        // OutOfMemory is thrown !
206                        this.messages.put(fullMessage);
207                } catch (InterruptedException e) {
208                        System.out.println("WARNING - [" + this.getClass().getName()
209                                        + "] Message lost due to " + e.getClass().getName() + " ("
210                                        + fullMessage + ")");
211                }
212                return fullMessage;
213        }
214
215        /**
216         * This call must be synchronized, so that there is no interaction with the
217         * LogMessageThread thread.
218         *
219         * @see JTextArea#append(String)
220         */
221        synchronized public void append(String t) {
222                super.append(t);
223        }
224
225        /**
226         * This call must be synchronized, so that there is no interaction with the
227         * LogMessageThread thread.
228         *
229         * @see JTextArea#insert(String, int)
230         */
231        synchronized public void insert(String str, int pos) {
232                super.insert(str, pos);
233        }
234
235        /**
236         * This call must be synchronized, so that there is no interaction with the
237         * LogMessageThread thread.
238         *
239         * @see JTextArea#replaceRange(String, int, int)
240         */
241        synchronized public void replaceRange(String str, int start, int end) {
242                super.replaceRange(str, start, end);
243        }
244
245        /**
246         * This call must be synchronized, so that there is no interaction with the
247         * LogMessageThread thread.
248         *
249         * @see JTextArea#setText(String)
250         */
251        synchronized public void setText(String t) {
252                super.setText(t);
253        }
254
255        /**
256         * @param uploadPolicy
257         *            the uploadPolicy to set
258         */
259        public void setUploadPolicy(UploadPolicy uploadPolicy) {
260                this.uploadPolicy = uploadPolicy;
261                this.uploadPolicy.getContext().registerUnload(this, "unload");
262                // We can now start the log thread.
263                this.loggingActive = true;
264                this.logMessageThread.start();
265        }
266
267        /**
268         * Free any used ressources. Actually close the LogMessageThread thread.
269         */
270        public synchronized void unload() {
271                this.loggingActive = false;
272                this.logMessageThread.interrupt();
273        }
274
275        /**
276         * Format the message, with the given tag. This method also add the time and
277         * the Thread name.<BR>
278         * e.g.:<BR>
279         * messageId[tab]14:04:30.718[tab]FileUploadManagerThread[tab][DEBUG][tab]
280         * Found one reader for jpg extension
281         *
282         * @param tag
283         *            The tag ([WARN], [ERROR]...)
284         * @param msg
285         *            The message to format.
286         * @return The formatted message, without trailing EOL character.
287         */
288        String formatMessageOutput(String tag, String msg) {
289                final String stamp = String.format("%1$05d", this.messageId++) + " \t"
290                                + new SimpleDateFormat("HH:mm:ss.SSS ").format(new Date())
291                                + "\t" + Thread.currentThread().getName() + "\t" + tag + " \t";
292                while (msg.endsWith("\n")) {
293                        msg = msg.substring(0, msg.length() - 1);
294                }
295                return (stamp + msg.replaceAll("\n", "\n" + stamp));
296        }
297
298}
Note: See TracBrowser for help on using the repository browser.