~ubuntu-branches/ubuntu/quantal/netbeans/quantal

« back to all changes in this revision

Viewing changes to junit/src/org/netbeans/modules/junit/MessageStack.java

  • Committer: Bazaar Package Importer
  • Author(s): Marek Slama
  • Date: 2008-01-29 14:11:22 UTC
  • Revision ID: james.westby@ubuntu.com-20080129141122-fnzjbo11ntghxfu7
Tags: upstream-6.0.1
ImportĀ upstreamĀ versionĀ 6.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 
3
 *
 
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 
5
 *
 
6
 * The contents of this file are subject to the terms of either the GNU
 
7
 * General Public License Version 2 only ("GPL") or the Common
 
8
 * Development and Distribution License("CDDL") (collectively, the
 
9
 * "License"). You may not use this file except in compliance with the
 
10
 * License. You can obtain a copy of the License at
 
11
 * http://www.netbeans.org/cddl-gplv2.html
 
12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 
13
 * specific language governing permissions and limitations under the
 
14
 * License.  When distributing the software, include this License Header
 
15
 * Notice in each file and include the License file at
 
16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 
17
 * particular file as subject to the "Classpath" exception as provided
 
18
 * by Sun in the GPL Version 2 section of the License file that
 
19
 * accompanied this code. If applicable, add the following below the
 
20
 * License Header, with the fields enclosed by brackets [] replaced by
 
21
 * your own identifying information:
 
22
 * "Portions Copyrighted [year] [name of copyright owner]"
 
23
 *
 
24
 * Contributor(s):
 
25
 *
 
26
 * The Original Software is NetBeans. The Initial Developer of the Original
 
27
 * Software is Sun Microsystems, Inc. Portions Copyright 2004 Sun
 
28
 * Microsystems, Inc. All Rights Reserved.
 
29
 *
 
30
 * If you wish your version of this file to be governed by only the CDDL
 
31
 * or only the GPL Version 2, indicate your decision by adding
 
32
 * "[Contributor] elects to include this software in this distribution
 
33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 
34
 * single choice of license, a recipient has the option to distribute
 
35
 * your version of this file under either the CDDL, the GPL Version 2 or
 
36
 * to extend the choice of license to its licensees as provided above.
 
37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 
38
 * Version 2 license, then the option applies only if the new code is
 
39
 * made subject to such option by the copyright holder.
 
40
 */
 
41
 
 
42
package org.netbeans.modules.junit;
 
43
 
 
44
/**
 
45
 * Manager of layered messages.
 
46
 * It serves for management of messages layered over. When a message is to be
 
47
 * displayed, it is put into a certain layer. When there is another message
 
48
 * set in an upper layer, the topmost message does not change. Conversely,
 
49
 * when the topmost message is cleared, another message becomes the topmost
 
50
 * message and needs to be displayed. This class handles all these changes
 
51
 * and returns information what message needs to be displayed after each
 
52
 * addition/removal of message.
 
53
 * <p>
 
54
 * The stack has a fixed number of layers
 
55
 * (specified by calling the constructor). Each layer has its number,
 
56
 * beginning with <code>0</code> (the topmost layer) and ending with
 
57
 * <code><var>n</var> - 1</code> where <code><var>n</var></code>
 
58
 * is the number of layers.
 
59
 * <p>
 
60
 * There is one special layer for displaying volatile messages.
 
61
 * Volatile messages are those messages that are always displayed
 
62
 * on the top of all other messages but are cleared/overwritten
 
63
 * as soon as another message is to be displayed.
 
64
 *
 
65
 * @see  #setMessage
 
66
 * @author Marian Petras
 
67
 */
 
68
public final class MessageStack {
 
69
    
 
70
    /*
 
71
     * The class is final only for performance reasons.
 
72
     */
 
73
    
 
74
    /** layer number of the special layer for volatile messages */
 
75
    public static final int LAYER_VOLATILE = -1;
 
76
    
 
77
    /**
 
78
     * messages in layers (index <code>0</code> means the topmost layer)
 
79
     */
 
80
    private final String[] messageLayers;
 
81
    /**
 
82
     * index of the visible (topmost non-empty) layer.
 
83
     * If the stack is empty, it has value <code>-1</code>.
 
84
     */
 
85
    private int visibleLayerIndex = -1;
 
86
    /** currently displayed volatile message (or <code>null</code>) */
 
87
    private String volatileMsg;
 
88
    
 
89
    /**
 
90
     * Creates a new <code>MessageStack</code> with a given number of layers.
 
91
     *
 
92
     * @param  size  number of layers in the stack
 
93
     */
 
94
    public MessageStack(int size) {
 
95
        if (size <= 0) {
 
96
            throw new IllegalArgumentException(
 
97
                    "number of layers must be positive");               //NOI18N
 
98
        }
 
99
        messageLayers = new String[size];
 
100
    }
 
101
 
 
102
    /**
 
103
     * Returns the currently &quot;displayed&quot; message.
 
104
     *
 
105
     * @return  message that should be currently displayed according to
 
106
     *          performed display modifications;
 
107
     *          or <code>null</code> if no message should be displayed
 
108
     */
 
109
    public String getDisplayedMessage() {
 
110
        return volatileMsg != null ? volatileMsg
 
111
                                   : getTopmostStackMessage();
 
112
    }
 
113
    
 
114
    /**
 
115
     * Returns the topmost message on the stack.
 
116
     *
 
117
     * @return  the topmost non-empty message on the stack;
 
118
     *          or <code>null</code> if the stack is empty
 
119
     */
 
120
    private String getTopmostStackMessage() {
 
121
        return visibleLayerIndex != -1 ? messageLayers[visibleLayerIndex]
 
122
                                       : null;
 
123
    }
 
124
    
 
125
    /**
 
126
     * Clears this message stack.
 
127
     * After cleaning, both volatile message and all of the stack messages
 
128
     * are empty.
 
129
     */
 
130
    public void clear() {
 
131
        volatileMsg = null;
 
132
        if (visibleLayerIndex != -1) {
 
133
            for (int i = visibleLayerIndex; i < messageLayers.length; i++) {
 
134
                messageLayers[i] = null;
 
135
            }
 
136
            visibleLayerIndex = -1;
 
137
        }
 
138
    }
 
139
 
 
140
    /**
 
141
     * Puts a message on the given layer of the stack.
 
142
     * Putting a message on the special layer for volatile messages
 
143
     * (layer number <code>LAYER_VOLATILE</code>) has the same effect
 
144
     * as calling {@link #setVolatileMessage(String)}.
 
145
     *
 
146
     * @param  layer  layer number
 
147
     * @param  message  message to be displayed, or <code>null</code>
 
148
     *                  if the existing message should be removed from the layer
 
149
     * @return  message that needs to be displayed in order to show the topmost
 
150
     *          message of the (updated) stack, or <code>null</code> if no
 
151
     *          change of display is necessary
 
152
     * @exception  java.lang.IllegalArgumentException
 
153
     *             if value of the <code>msgType</code> parameter is illegal
 
154
     */
 
155
    public String setMessage(final int layer, String message)
 
156
            throws IllegalArgumentException {
 
157
        
 
158
        /* check parameters: */
 
159
        if (layer == LAYER_VOLATILE) {
 
160
            return setVolatileMessage(message);
 
161
        }
 
162
        if (layer < 0 || layer >= messageLayers.length) {
 
163
            throw new IllegalArgumentException(
 
164
                    java.text.MessageFormat.format(
 
165
                        "Message type out of bounds (0 .. {1}): {0}",   //NOI18N
 
166
                        new Object[] { new Integer(layer),
 
167
                                       new Integer(messageLayers.length) }));
 
168
        }
 
169
        
 
170
        /* unify parameters: */
 
171
        if ((message != null) && (message.trim().length() == 0)) {
 
172
            message = null;
 
173
        }
 
174
 
 
175
        final String oldDisplayed = getDisplayedMessage();
 
176
 
 
177
        /* update the register of messages: */
 
178
        volatileMsg = null;
 
179
        messageLayers[layer] = message;
 
180
 
 
181
        /* update the visible layer index: */
 
182
        if (message != null) {
 
183
            if ((visibleLayerIndex == -1) || (layer < visibleLayerIndex)) {
 
184
                visibleLayerIndex = layer;
 
185
            }
 
186
        } else if (layer == visibleLayerIndex) {
 
187
            for (int i = layer + 1; i < messageLayers.length; i++) {
 
188
                if (messageLayers[i] != null) {
 
189
                    visibleLayerIndex = i;
 
190
                    break;
 
191
                }
 
192
            }
 
193
            if (visibleLayerIndex == layer) {    //no visible layer found
 
194
                visibleLayerIndex = -1;
 
195
            }
 
196
        }
 
197
 
 
198
        /* compare the old and new display: */
 
199
        return checkDisplayModified(oldDisplayed, getDisplayedMessage());
 
200
    }
 
201
 
 
202
    /**
 
203
     * Clears a message on the given layer of the stack.
 
204
     * Calling this method has the same effect as calling
 
205
     * <code>setMessage(layer, null)</code> (on the same layer).
 
206
     *
 
207
     * @param  layer  layer number
 
208
     * @return  message that needs to be displayed in order to show the topmost
 
209
     *          message of the (updated) stack, or <code>null</code> if no
 
210
     *          change of display is necessary
 
211
     * @see  #setMessage
 
212
     */
 
213
    public String clearMessage(final int layer) {
 
214
        return setMessage(layer, null);
 
215
    }
 
216
    
 
217
    /**
 
218
     * Displays a volatile message on top of all existing messages.
 
219
     *
 
220
     * @param  message to be displayed, or <code>null</code>
 
221
     *         if the previous volatile message should be removed
 
222
     * @return  message that needs to be displayed in order to show the message
 
223
     *          on the top of the stack, or <code>null</code> if no change
 
224
     *          of display is necessary
 
225
     */
 
226
    public String setVolatileMessage(String message) {
 
227
        
 
228
        /* unify parameters: */
 
229
        if ((message != null) && (message.trim().length() == 0)) {
 
230
            message = null;
 
231
        }
 
232
 
 
233
        final String oldDisplayed = getDisplayedMessage();
 
234
 
 
235
        /* update the register of messages: */
 
236
        volatileMsg = message;
 
237
 
 
238
        /* compare the old and new display: */
 
239
        return checkDisplayModified(oldDisplayed, getDisplayedMessage());
 
240
    }
 
241
    
 
242
    /**
 
243
     * Clears the previous volatile message (if any).
 
244
     * Calling this method has the same effect as calling
 
245
     * <code>setVolatileMessage(null)</code>.
 
246
     *
 
247
     * @return  message that needs to be displayed in order to show the message
 
248
     *          on the top of the stack or an empty string
 
249
     *          (<code>&quot;&quot;</code>) if no message should be displayed
 
250
     * @see  #setVolatileMessage
 
251
     */
 
252
    public String clearVolatileMessage() {
 
253
        return setVolatileMessage(null);
 
254
    }
 
255
 
 
256
    /**
 
257
     * Compares the previous and the new displayed message.
 
258
     *
 
259
     * @return <code>null</code> if both messages are the same (possibly empty),
 
260
     *         an empty string (<code>&quot;&quot;</code>) if the previous
 
261
     *         message was non-empty and the new message is empty,
 
262
     *         or the new message if it is non-empty and different from
 
263
     *         the old message
 
264
     */
 
265
    private String checkDisplayModified(String oldDisplay, String newDisplay) {
 
266
        if ((newDisplay == null) && (oldDisplay != null)) {
 
267
            return "";                                                  //NOI18N
 
268
        }
 
269
        if ((newDisplay != null) && !newDisplay.equals(oldDisplay)) {
 
270
            return newDisplay;
 
271
        }
 
272
        return null;
 
273
    }
 
274
    
 
275
}