View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.log4j.chainsaw;
18  
19  import java.awt.Color;
20  import java.beans.PropertyChangeListener;
21  import java.beans.PropertyChangeSupport;
22  import java.util.ArrayList;
23  import java.util.List;
24  import java.util.Vector;
25  
26  import javax.swing.UIManager;
27  
28  /**
29   * Encapsulates the Chainsaw Application wide properties
30   *
31   * @author Paul Smith <psmith@apache.org>
32   *
33   */
34  public class ApplicationPreferenceModel {
35  
36      private boolean showNoReceiverWarning = true;
37      private boolean statusBar = true;
38      private boolean toolbar = true;
39      private boolean receivers = false; //setting this to true will cause the receivers panel to be displayed by default
40      private boolean confirmExit = true;
41      private boolean showSplash = true;
42      private String lookAndFeelClassName = "";
43      private int toolTipDisplayMillis = 4000;
44      private int cyclicBufferSize = 50000;
45      private String lastUsedVersion = "";
46      private int responsiveness = 3;
47      private Color searchBackgroundColor = ChainsawConstants.FIND_LOGGER_BACKGROUND;
48      private Color searchForegroundColor = ChainsawConstants.FIND_LOGGER_FOREGROUND;
49      private Color alternatingColorForegroundColor = ChainsawConstants.COLOR_ODD_ROW_FOREGROUND;
50      private Color alternatingColorBackgroundColor = ChainsawConstants.COLOR_ODD_ROW_BACKGROUND;
51  
52      private String identifierExpression = "PROP.hostname - PROP.application";
53  
54      private transient final PropertyChangeSupport propertySupport =
55          new PropertyChangeSupport(this);
56      
57      private int tabPlacement = 3;
58      
59      /**
60       * If not 'empty', this property will be used as the URL to load log4j configuration at startup
61       */
62      private Vector configurationURLs=new Vector();
63  
64      private String configurationURL = "";
65  
66      /**
67       * Remember current config if provided via means other than configurationURL (command line arg, etc)
68       */
69      private transient String bypassConfigurationURL = null;
70      /**
71       *    this means for Receivers that require optional jars that can't be delivered
72       *    by the Web start classloader, we need to be able to remove the SecurityManager in place
73       */
74      private boolean okToRemoveSecurityManager = false;
75      private static final int CONFIGURATION_URL_ENTRY_COUNT = 10;
76      private List defaultColumnNames = new ArrayList();
77      private boolean defaultColumnsSet;
78      private boolean bypassSearchColors = false;
79  
80    /**
81       * @param listener
82       */
83      public void addPropertyChangeListener(PropertyChangeListener listener) {
84          propertySupport.addPropertyChangeListener(listener);
85      }
86  
87      /**
88       * @param propertyName
89       * @param listener
90       */
91      public void addPropertyChangeListener(String propertyName,
92          PropertyChangeListener listener) {
93          propertySupport.addPropertyChangeListener(propertyName, listener);
94      }
95  
96      /**
97       * @param propertyName
98       * @param oldValue
99       * @param newValue
100      */
101     private void firePropertyChange(String propertyName, boolean oldValue,
102         boolean newValue) {
103         propertySupport.firePropertyChange(propertyName, oldValue, newValue);
104     }
105 
106     /**
107      * @param propertyName
108      * @param oldValue
109      * @param newValue
110      */
111     private void firePropertyChange(String propertyName, int oldValue,
112         int newValue) {
113         propertySupport.firePropertyChange(propertyName, oldValue, newValue);
114     }
115 
116     /**
117      * @param propertyName
118      * @param oldValue
119      * @param newValue
120      */
121     private void firePropertyChange(String propertyName, Object oldValue,
122         Object newValue) {
123         propertySupport.firePropertyChange(propertyName, oldValue, newValue);
124     }
125 
126     /**
127      * @param propertyName
128      * @return listeners flag
129      */
130     public boolean hasListeners(String propertyName) {
131         return propertySupport.hasListeners(propertyName);
132     }
133 
134     /**
135      * @param listener
136      */
137     public void removePropertyChangeListener(PropertyChangeListener listener) {
138         propertySupport.removePropertyChangeListener(listener);
139     }
140 
141     /**
142      * @return Returns the showNoReceiverWarning.
143      */
144     public final boolean isShowNoReceiverWarning() {
145 
146         return showNoReceiverWarning;
147     }
148     
149     public final String getIdentifierExpression() {
150         return identifierExpression;
151     }
152 
153     public final void setCyclicBufferSize(int newCyclicBufferSize) {
154         int oldCyclicBufferSize = cyclicBufferSize;
155         cyclicBufferSize = newCyclicBufferSize;
156         firePropertyChange("cyclicBufferSize", oldCyclicBufferSize, newCyclicBufferSize);
157     }
158     
159     public final int getCyclicBufferSize() {
160         return cyclicBufferSize;
161     }
162 
163     public final void setToolTipDisplayMillis(int newToolTipDisplayMillis) {
164         int oldToolTipDisplayMillis = toolTipDisplayMillis;
165         toolTipDisplayMillis = newToolTipDisplayMillis;
166         firePropertyChange("toolTipDisplayMillis", oldToolTipDisplayMillis, newToolTipDisplayMillis);
167     }
168     
169     public final int getToolTipDisplayMillis() {
170         return toolTipDisplayMillis;
171     }
172 
173     public final void setIdentifierExpression(String newIdentifierExpression) {
174         String oldIdentifierExpression=identifierExpression;
175         this.identifierExpression = newIdentifierExpression;
176         firePropertyChange("identifierExpression", oldIdentifierExpression, newIdentifierExpression);
177     }
178 
179     /**
180      * @param newShowNoReceiverWarning The showNoReceiverWarning to set.
181      */
182     public final void setShowNoReceiverWarning(boolean newShowNoReceiverWarning) {
183         boolean oldShowNoReceiverWarning=showNoReceiverWarning;
184         this.showNoReceiverWarning = newShowNoReceiverWarning;
185         firePropertyChange("showNoReceiverWarning", oldShowNoReceiverWarning, newShowNoReceiverWarning);
186     }
187 
188 
189     /**
190      * Takes another model and copies all the values into this model
191      * @param model
192      */
193     public void apply(ApplicationPreferenceModel model)
194     {
195       setIdentifierExpression(model.getIdentifierExpression());
196       setShowNoReceiverWarning(model.isShowNoReceiverWarning() || (model.getConfigurationURL() == null || model.getConfigurationURL().trim().equals("")));
197       setResponsiveness(model.getResponsiveness());
198       setTabPlacement(model.getTabPlacement());
199       setStatusBar(model.isStatusBar());
200       setToolbar(model.isToolbar());
201       setReceivers(model.isReceivers());
202       if (model.getLookAndFeelClassName() != null && !model.getLookAndFeelClassName().trim().equals("")) {
203           setLookAndFeelClassName(model.getLookAndFeelClassName());
204       } else {
205           //ensure current look and feel is selected
206           setLookAndFeelClassName(UIManager.getLookAndFeel().getClass().getName());
207       }
208       setConfirmExit(model.isConfirmExit());
209       setShowSplash(model.isShowSplash());
210       setToolTipDisplayMillis(model.getToolTipDisplayMillis());
211       setCyclicBufferSize(model.getCyclicBufferSize());
212       Vector configurationURLs = model.getConfigurationURLs();
213       if (configurationURLs != null) {
214         setConfigurationURLs(configurationURLs);
215       }
216       //only set current config URL if bypass is null
217       if (model.getBypassConfigurationURL() == null) {
218         setConfigurationURL(model.getConfigurationURL());
219       }
220       setLastUsedVersion(model.getLastUsedVersion());
221       setOkToRemoveSecurityManager(model.isOkToRemoveSecurityManager());
222       Color searchForeground = model.getSearchForegroundColor();
223       Color searchBackground = model.getSearchBackgroundColor();
224       if (searchForeground != null && searchBackground != null) {
225         setSearchBackgroundColor(searchBackground);
226         setSearchForegroundColor(searchForeground);
227       }
228 
229       Color alternatingForeground = model.getAlternatingColorForegroundColor();
230       Color alternatingBackground = model.getAlternatingColorBackgroundColor();
231       if (alternatingForeground != null && alternatingBackground != null) {
232         setAlternatingBackgroundColor(alternatingBackground);
233         setAlternatingForegroundColor(alternatingForeground);
234       }
235       if (model.isDefaultColumnsSet()) {
236         setDefaultColumnNames(model.getDefaultColumnNames());
237       }
238       setBypassSearchColors(model.isBypassSearchColors());
239     }
240 
241     //use a lighter version of search color as the delta color
242     public Color getDeltaColor() {
243         float factor = 1.3F;
244         Color search = getSearchBackgroundColor();
245 
246         return new Color(boundColorValue((int)(search.getRed() * factor)),
247                 boundColorValue((int)(search.getGreen() * factor)),
248                 boundColorValue((int)(search.getBlue() * factor)));
249     }
250 
251     private int boundColorValue(int colorValue) {
252       return Math.min(Math.max(0, colorValue), 255);
253     }
254 
255 
256     /**
257      * @return Returns the responsiveness.
258      */
259     public final int getResponsiveness()
260     {
261       return responsiveness;
262     }
263     /**
264      * @param newValue The responsiveness to set.
265      */
266     public final void setResponsiveness(int newValue)
267     {
268       int oldvalue = responsiveness;
269       
270       if (newValue >= 1000) {
271         responsiveness = (newValue - 750) / 1000;
272       } else {
273         responsiveness = newValue;
274       }
275       firePropertyChange("responsiveness", oldvalue, responsiveness);
276     }
277 
278     /**
279      * @param i
280      */
281     public void setTabPlacement(int i) {
282       int oldValue = this.tabPlacement;
283        this.tabPlacement = i;
284        firePropertyChange("tabPlacement",oldValue,this.tabPlacement);
285     }
286     /**
287      * @return Returns the tabPlacement.
288      */
289     public final int getTabPlacement() {
290       return tabPlacement;
291     }
292 
293     /**
294      * @return Returns the statusBar.
295      */
296     public final boolean isStatusBar() {
297       return statusBar;
298     }
299 
300     public Vector getConfigurationURLs() {
301         return configurationURLs;
302     }
303 
304     public void setConfigurationURLs(Vector urls) {
305         if (urls != null) {
306             configurationURLs = urls;
307         }
308     }
309 
310     /**
311      * @param statusBar The statusBar to set.
312      */
313     public final void setStatusBar(boolean statusBar) {
314       boolean oldValue = this.statusBar;
315       this.statusBar = statusBar;
316       firePropertyChange("statusBar", oldValue, this.statusBar);
317     }
318 
319     public void setAlternatingForegroundColor(Color alternatingColorForegroundColor) {
320         this.alternatingColorForegroundColor = alternatingColorForegroundColor;
321         firePropertyChange("alternatingColor", true, false);
322     }
323 
324     public void setAlternatingBackgroundColor(Color alternatingColorBackgroundColor) {
325         this.alternatingColorBackgroundColor = alternatingColorBackgroundColor;
326         firePropertyChange("alternatingColor", true, false);
327     }
328 
329     public void setSearchForegroundColor(Color searchForegroundColor) {
330         this.searchForegroundColor = searchForegroundColor;
331         firePropertyChange("searchColor", true, false);
332     }
333 
334     public void setSearchBackgroundColor(Color searchBackgroundColor) {
335         this.searchBackgroundColor = searchBackgroundColor;
336         firePropertyChange("searchColor", true, false);
337     }
338 
339     public Color getAlternatingColorBackgroundColor() {
340         return alternatingColorBackgroundColor;
341     }
342 
343     public Color getAlternatingColorForegroundColor() {
344         return alternatingColorForegroundColor;
345     }
346 
347     public Color getSearchBackgroundColor() {
348         return searchBackgroundColor;
349     }
350 
351     public Color getSearchForegroundColor() {
352         return searchForegroundColor;
353     }
354 
355     /**
356      * @return Returns the receivers.
357      */
358     public final boolean isReceivers()
359     {
360       return receivers;
361     }
362     /**
363      * @param receivers The receivers to set.
364      */
365     public final void setReceivers(boolean receivers)
366     {
367       boolean oldValue = this.receivers;
368       this.receivers = receivers;
369       firePropertyChange("receivers", oldValue, this.receivers);
370     }
371     /**
372      * @return Returns the toolbar.
373      */
374     public final boolean isToolbar()
375     {
376       return toolbar;
377     }
378     /**
379      * @param toolbar The toolbar to set.
380      */
381     public final void setToolbar(boolean toolbar)
382     {
383       boolean oldValue = this.toolbar;
384       this.toolbar = toolbar;
385       firePropertyChange("toolbar", oldValue, this.toolbar);
386     }
387     /**
388      * @return Returns the lookAndFeelClassName.
389      */
390     public final String getLookAndFeelClassName() {
391       return lookAndFeelClassName;
392     }
393 
394     /**
395      * @param lookAndFeelClassName The lookAndFeelClassName to set.
396      */
397     public final void setLookAndFeelClassName(String lookAndFeelClassName) {
398       String oldValue = this.lookAndFeelClassName;
399       this.lookAndFeelClassName = lookAndFeelClassName;
400       firePropertyChange("lookAndFeelClassName", oldValue, this.lookAndFeelClassName);
401     }
402 
403     /**
404      * @return Returns the confirmExit.
405      */
406     public final boolean isConfirmExit() {
407       return confirmExit;
408     }
409 
410     /**
411      * @param confirmExit The confirmExit to set.
412      */
413     public final void setConfirmExit(boolean confirmExit) {
414       boolean oldValue = this.confirmExit;
415       this.confirmExit = confirmExit;
416       firePropertyChange("confirmExit", oldValue, this.confirmExit);
417     }
418 
419     /**
420      * @return Returns the showSplash.
421      */
422     public final boolean isShowSplash() {
423       return showSplash;
424     }
425     /**
426      * @param showSplash The showSplash to set.
427      */
428     public final void setShowSplash(boolean showSplash) {
429       boolean oldValue = this.showSplash;
430       this.showSplash = showSplash;
431       firePropertyChange("showSplash", oldValue,this.showSplash);
432     }
433     /**
434      * @return Returns the configurationURL.
435      */
436     public final String getConfigurationURL()
437     {
438         return this.configurationURL;
439     }
440 
441     public final String getBypassConfigurationURL() {
442         return bypassConfigurationURL;
443     }
444     /*
445       Set to null to un-bypass
446      */
447     public void setBypassConfigurationURL(String bypassConfigurationURL) {
448         //don't change configuration URL..configurationURL is persisted on app exit
449         if (bypassConfigurationURL != null && bypassConfigurationURL.trim().equals("")) {
450             this.bypassConfigurationURL = null;
451         }
452         this.bypassConfigurationURL = bypassConfigurationURL;
453     }
454 
455     /**
456      * @param configurationURL The configurationURL to set.
457      */
458     public final void setConfigurationURL(String configurationURL)
459     {
460         //don't add empty entries, but allow the current configuration URL to be set to an empty string
461         Object oldValue = this.bypassConfigurationURL != null? this.bypassConfigurationURL:this.configurationURL;
462         bypassConfigurationURL = null;
463         if (configurationURL == null || configurationURL.trim().equals("")) {
464             this.configurationURL = "";
465             firePropertyChange("configurationURL", oldValue, this.configurationURL);
466             return;
467         }
468         //add entry to MRU list
469         if (!configurationURLs.contains(configurationURL)) {
470           if (configurationURLs.size() == CONFIGURATION_URL_ENTRY_COUNT) {
471               configurationURLs.remove(CONFIGURATION_URL_ENTRY_COUNT - 1);
472           }
473           configurationURLs.add(0, configurationURL);
474         }
475       this.configurationURL = configurationURL;
476       firePropertyChange("configurationURL", oldValue, this.configurationURL);
477     }
478     /**
479      * @return Returns the lastUsedVersion.
480      */
481     public final String getLastUsedVersion()
482     {
483         return this.lastUsedVersion;
484     }
485     /**
486      * @param lastUsedVersion The lastUsedVersion to set.
487      */
488     public final void setLastUsedVersion(String lastUsedVersion)
489     {
490         String oldValue = this.lastUsedVersion;
491         this.lastUsedVersion = lastUsedVersion;
492         firePropertyChange("lastUsedVersion", oldValue, this.lastUsedVersion);
493     }
494 
495 	/**
496 	 * @return ok to remove security manager flag
497 	 */
498 	public final boolean isOkToRemoveSecurityManager() {
499 		return this.okToRemoveSecurityManager;
500 	}
501 	/**
502 	 * @param okToRemoveSecurityManager The okToRemoveSecurityManager to set.
503 	 */
504 	public final void setOkToRemoveSecurityManager(boolean okToRemoveSecurityManager) {
505 		boolean oldValue = this.okToRemoveSecurityManager;
506         this.okToRemoveSecurityManager = okToRemoveSecurityManager;
507         firePropertyChange("okToRemoveSecurityManager", oldValue, this.okToRemoveSecurityManager);
508 	}
509 
510   public void setDefaultColumnNames(List defaultColumnNames) {
511     defaultColumnsSet = true;
512     this.defaultColumnNames.clear();
513     this.defaultColumnNames.addAll(defaultColumnNames);
514   }
515 
516   public boolean isDefaultColumnsSet() {
517     return defaultColumnsSet;
518   }
519 
520   public List getDefaultColumnNames() {
521     return defaultColumnNames;
522   }
523 
524   public void setBypassSearchColors(boolean bypassSearchColors) {
525     this.bypassSearchColors = bypassSearchColors;
526   }
527 
528   public boolean isBypassSearchColors() {
529     return bypassSearchColors;
530   }
531 }