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  
18  /*
19   */
20  package org.apache.log4j.chainsaw;
21  
22  import java.beans.PropertyChangeListener;
23  import java.beans.PropertyChangeSupport;
24  import java.io.Serializable;
25  import java.util.ArrayList;
26  import java.util.Collection;
27  import java.util.Collections;
28  import java.util.HashSet;
29  import java.util.Iterator;
30  import java.util.List;
31  import java.util.Map;
32  import java.util.Properties;
33  
34  import javax.swing.table.TableColumn;
35  
36  import org.apache.log4j.LogManager;
37  import org.apache.log4j.Logger;
38  import org.apache.log4j.chainsaw.prefs.SettingsManager;
39  
40  
41  /***
42   *  Used to encapsulate all the preferences for a given LogPanel
43   * @author Paul Smith
44   */
45  public class LogPanelPreferenceModel implements Serializable{
46    public static final String ISO8601 = "ISO8601";
47    public static final Collection DATE_FORMATS;
48    private static final Logger logger = LogManager.getLogger(LogPanelPreferenceModel.class);
49  
50    static {
51      Collection list = new ArrayList();
52  
53      Properties properties = SettingsManager.getInstance().getDefaultSettings();
54  
55      for (Iterator iter = properties.entrySet().iterator(); iter.hasNext();) {
56        Map.Entry entry = (Map.Entry) iter.next();
57  
58        if (entry.getKey().toString().startsWith("DateFormat")) {
59          list.add(entry.getValue());
60        }
61      }
62  
63      DATE_FORMATS = Collections.unmodifiableCollection(list);
64    }
65  
66    private transient final PropertyChangeSupport propertySupport =
67      new PropertyChangeSupport(this);
68    private String dateFormatPattern = ISO8601;
69    private boolean levelIcons;
70    private List allColumns = new ArrayList();
71    private List visibleColumns = new ArrayList();
72    private List visibleColumnOrder = new ArrayList();
73    private boolean detailPaneVisible;
74    private boolean toolTips;
75    private boolean scrollToBottom;
76    private boolean logTreePanelVisible;
77    private String loggerPrecision = "";
78  
79    private Collection hiddenLoggers = new HashSet();
80    
81    /***
82     * Returns an <b>unmodifiable</b> list of the columns.
83     * 
84     * The reason it is unmodifiable is to enforce the requirement that
85     * the List is actually unique columns.  IT _could_ be a set,
86     * but we need to maintain the order of insertion.
87     * 
88     * @return
89     */
90    public List getColumns() {
91        return Collections.unmodifiableList(allColumns);
92    }
93    
94    /***
95     * Returns an <b>unmodifiable</b> list of the visible columns.
96     * 
97     * The reason it is unmodifiable is to enforce the requirement that
98     * the List is actually unique columns.  IT _could_ be a set,
99     * but we need to maintain the order of insertion.
100    * 
101    * @return
102    */
103   public List getVisibleColumns() {
104       return Collections.unmodifiableList(visibleColumns);
105   }
106   
107   public void clearColumns(){
108       Object oldValue = this.allColumns;
109       allColumns = new ArrayList();
110       propertySupport.firePropertyChange("columns", oldValue, allColumns);
111   }
112   
113   private TableColumn findColumnByHeader(List list, String header) {
114 	  for (Iterator iter = list.iterator();iter.hasNext();) {
115 		  TableColumn c = (TableColumn)iter.next();
116 		  if (c.getHeaderValue().equals(header)) {
117 			  return c;
118 		  }
119 	  }
120 	  return null;
121   }
122   
123   public void setVisibleColumnOrder(List visibleColumnOrder) {
124 	  this.visibleColumnOrder = visibleColumnOrder;
125   }
126   
127   public List getVisibleColumnOrder() {
128 	  return visibleColumnOrder;
129   }
130   
131   public boolean addColumn(TableColumn column){
132 	  if (findColumnByHeader(allColumns, column.getHeaderValue().toString()) != null) {
133 		  return false;
134 	  }
135 	  
136       Object oldValue = allColumns;
137       allColumns = new ArrayList(allColumns);
138       allColumns.add(column);
139       
140       propertySupport.firePropertyChange("columns", oldValue, allColumns);
141       return true;
142   }
143   
144   private void setColumns(List columns) {
145       Object oldValue = allColumns;
146       allColumns = new ArrayList(columns);
147       propertySupport.firePropertyChange("columns", oldValue, columns);
148   }
149 
150 /***
151    * Returns the Date Pattern string for the alternate date formatter.
152    * @return date pattern
153    */
154   public final String getDateFormatPattern() {
155     return dateFormatPattern;
156   }
157 
158   public final void setDefaultDatePatternFormat() {
159 	    String oldVal = this.dateFormatPattern;
160 	    this.dateFormatPattern = ISO8601;
161 	    propertySupport.firePropertyChange(
162 	    	      "dateFormatPattern", oldVal, this.dateFormatPattern);
163   }
164   /***
165    * @param dateFormatPattern
166    */
167   public final void setDateFormatPattern(String dateFormatPattern) {
168     String oldVal = this.dateFormatPattern;
169     this.dateFormatPattern = dateFormatPattern;
170     propertySupport.firePropertyChange(
171       "dateFormatPattern", oldVal, this.dateFormatPattern);
172   }
173 
174   /***
175    * @param listener
176    */
177   public synchronized void addPropertyChangeListener(
178     PropertyChangeListener listener) {
179     propertySupport.addPropertyChangeListener(listener);
180   }
181 
182   /***
183    * @param propertyName
184    * @param listener
185    */
186   public synchronized void addPropertyChangeListener(
187     String propertyName, PropertyChangeListener listener) {
188     propertySupport.addPropertyChangeListener(propertyName, listener);
189   }
190 
191   /***
192    * @param listener
193    */
194   public synchronized void removePropertyChangeListener(
195     PropertyChangeListener listener) {
196     propertySupport.removePropertyChangeListener(listener);
197   }
198 
199   /***
200    * @param propertyName
201    * @param listener
202    */
203   public synchronized void removePropertyChangeListener(
204     String propertyName, PropertyChangeListener listener) {
205     propertySupport.removePropertyChangeListener(propertyName, listener);
206   }
207 
208   /***
209    * Applies all the properties of another model to this model
210    *
211    * @param model the model to copy
212    * all the properties from
213    */
214   public void apply(LogPanelPreferenceModel model) {
215     setLoggerPrecision(model.getLoggerPrecision());
216     setDateFormatPattern(model.getDateFormatPattern());
217     setLevelIcons(model.isLevelIcons());
218     setToolTips(model.isToolTips());
219     setScrollToBottom(model.isScrollToBottom());
220     setDetailPaneVisible(model.isDetailPaneVisible());
221     setLogTreePanelVisible(model.isLogTreePanelVisible());
222     setVisibleColumnOrder(model.getVisibleColumnOrder());
223 
224     // we have to copy the list, because getColumns() is unmodifiable
225     setColumns(model.getColumns());
226     
227     setVisibleColumns(model.getVisibleColumns());
228     setHiddenLoggers(model.getHiddenLoggers());
229   }
230 
231   /***
232    * Returns true if this the fast ISO8601DateFormat object
233    * should be used instead of SimpleDateFormat
234    * @return use ISO8601 format flag
235    */
236   public boolean isUseISO8601Format() {
237     return getDateFormatPattern().equals(ISO8601);
238   }
239 
240   /***
241    * @return level icons flag
242    */
243   public boolean isLevelIcons() {
244     return levelIcons;
245   }
246 
247   /***
248    * @param levelIcons
249    */
250   public void setLevelIcons(boolean levelIcons) {
251     this.levelIcons = levelIcons;
252     propertySupport.firePropertyChange("levelIcons", !levelIcons, levelIcons);
253   }
254 
255   /***
256    * @param loggerPrecision - an integer representing the number of packages to display, 
257    * or an empty string representing 'display all packages' 
258    */
259   public void setLoggerPrecision(String loggerPrecision) {
260     String oldVal = this.loggerPrecision;
261     this.loggerPrecision = loggerPrecision;
262     propertySupport.firePropertyChange("loggerPrecision", oldVal, this.loggerPrecision);      
263   }
264   
265   /***
266    * Returns the Logger precision.
267    * @return logger precision
268    */
269   public final String getLoggerPrecision() {
270     return loggerPrecision;
271   }
272 
273   /***
274    * Returns true if the named column should be made visible otherwise
275    * false.
276    * @param columnName
277    * @return column visible flag
278    */
279   public boolean isColumnVisible(TableColumn column) {
280 	  return (visibleColumns.contains(column));
281   }
282 
283   private void setVisibleColumns(List visibleColumns) {
284       Object oldValue = new ArrayList();
285       this.visibleColumns = new ArrayList(visibleColumns);
286       
287       propertySupport.firePropertyChange("visibleColumns", oldValue, this.visibleColumns);
288   }
289 
290   public void setColumnVisible(String columnName, boolean isVisible) {
291     boolean wasVisible = findColumnByHeader(visibleColumns, columnName) != null;
292     boolean newVisible = isVisible;
293 
294     //because we're a list and not a set, ensure we keep at most
295     //one entry for a tablecolumn
296     Object col = findColumnByHeader(allColumns, columnName);
297     if (newVisible && !wasVisible) {
298 		visibleColumns.add(col);
299 		visibleColumnOrder.add(col);
300 	    propertySupport.firePropertyChange("visibleColumns", new Boolean(newVisible), new Boolean(wasVisible));      
301 	}
302     if (!newVisible && wasVisible) {
303 		visibleColumns.remove(col);
304 		visibleColumnOrder.remove(col);
305 	    propertySupport.firePropertyChange("visibleColumns", new Boolean(newVisible), new Boolean(wasVisible));      
306 	}
307   }
308   
309   /***
310    * Toggles the state between visible, non-visible for a particular Column name
311    * @param column
312    */
313   public void toggleColumn(TableColumn column) {
314     setColumnVisible(column.getHeaderValue().toString(), !isColumnVisible(column));
315   }
316 
317   /***
318    * @return detail pane visible flag
319    */
320   public final boolean isDetailPaneVisible() {
321     return detailPaneVisible;
322   }
323 
324   /***
325    * @param detailPaneVisible
326    */
327   public final void setDetailPaneVisible(boolean detailPaneVisible) {
328     boolean oldValue = this.detailPaneVisible;
329     this.detailPaneVisible = detailPaneVisible;
330     propertySupport.firePropertyChange(
331       "detailPaneVisible", oldValue, this.detailPaneVisible);
332   }
333 
334   /***
335    * @return scroll to bottom flag
336    */
337   public final boolean isScrollToBottom() {
338     return scrollToBottom;
339   }
340 
341   /***
342    * @param scrollToBottom
343    */
344   public final void setScrollToBottom(boolean scrollToBottom) {
345     boolean oldValue = this.scrollToBottom;
346     this.scrollToBottom = scrollToBottom;
347     propertySupport.firePropertyChange(
348       "scrollToBottom", oldValue, this.scrollToBottom);
349   }
350 
351   /***
352    * @return tool tips enabled flag
353    */
354   public final boolean isToolTips() {
355     return toolTips;
356   }
357 
358   /***
359    * @param toolTips
360    */
361   public final void setToolTips(boolean toolTips) {
362     boolean oldValue = this.toolTips;
363     this.toolTips = toolTips;
364     propertySupport.firePropertyChange("toolTips", oldValue, this.toolTips);
365   }
366 
367   /***
368    * @return log tree panel visible flag
369    */
370   public final boolean isLogTreePanelVisible() {
371     return logTreePanelVisible;
372   }
373 
374   /***
375    * @param logTreePanelVisible
376    */
377   public final void setLogTreePanelVisible(boolean logTreePanelVisible) {
378     boolean oldValue = this.logTreePanelVisible;
379     this.logTreePanelVisible = logTreePanelVisible;
380     propertySupport.firePropertyChange(
381       "logTreePanelVisible", oldValue, this.logTreePanelVisible);
382   }
383 
384   /***
385    * @return custom date format flag
386    */
387   public boolean isCustomDateFormat()
388   {
389     return !DATE_FORMATS.contains(getDateFormatPattern()) && !isUseISO8601Format();
390   }
391 
392   public void setHiddenLoggers(Collection hiddenSet) {
393       Object oldValue = this.hiddenLoggers;
394       this.hiddenLoggers = hiddenSet;
395       propertySupport.firePropertyChange("hiddenLoggers", oldValue, this.hiddenLoggers);
396   }
397 
398 public Collection getHiddenLoggers() {
399     return hiddenLoggers;
400 }
401 }