View Javadoc
1   package net.sf.logdistiller.gui;
2   
3   /*
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  import java.awt.BorderLayout;
18  import java.awt.Component;
19  import java.awt.Container;
20  import java.awt.Frame;
21  import java.awt.LayoutManager;
22  import java.awt.event.ActionEvent;
23  import java.io.*;
24  import java.util.HashMap;
25  import java.util.List;
26  import java.util.Map;
27  import javax.swing.*;
28  
29  import com.jgoodies.forms.factories.ButtonBarFactory;
30  import com.jgoodies.forms.factories.DefaultComponentFactory;
31  import org.apache.commons.io.IOUtils;
32  
33  import net.sf.logdistiller.LogType;
34  import net.sf.logdistiller.LogTypes;
35  import net.sf.logdistiller.util.FormatUtil;
36  import net.sf.logdistiller.util.PropertiesReplacer;
37  
38  /**
39   * Dialog to create a new rules configuration file: you select the log type and give some basic information (an id, STMP
40   * server, url), and it generates a new rules configuration. Then you just need to refine the rules.
41   */
42  public class NewDialog
43  {
44      private File currentDir;
45  
46      public NewDialog( File directory )
47      {
48          currentDir = directory;
49      }
50  
51      protected JPanel panel = new JPanel();
52  
53      private JTextField tfId = new JTextField( "rules-id", 15 );
54  
55      private JTextField tfDescription = new JTextField( "rules description" );
56  
57      private JComboBox cbLogtype;
58  
59      private JTextField tfSmtp = new JTextField( "smtp.provider.com" );
60  
61      private JTextField tfMailTo = new JTextField( "admin@localhost" );
62  
63      private JTextField tfHttp = new JTextField( "http://mysite.com/logdistiller/logs" );
64  
65      private JButton btSaveAs = new JButton( "save as..." );
66  
67      private JButton btCancel = new JButton( "cancel" );
68  
69      public static JComboBox createCbLogtype( boolean withUndefined )
70      {
71          List<LogType> logtypes = LogTypes.getAllLogTypes();
72          int len = logtypes.size();
73          String[] logtypeIds = new String[len];
74          for ( int i = 0; i < len; i++ )
75          {
76              logtypeIds[i] = logtypes.get( i ).getId();
77          }
78          JComboBox cb = new JComboBox( logtypeIds );
79          if ( withUndefined )
80          {
81              cb.insertItemAt( "undefined", 0 );
82              cb.setSelectedIndex( 0 );
83          }
84          return cb;
85      }
86  
87      private void initComponents()
88      {
89          cbLogtype = createCbLogtype( false );
90  
91          btSaveAs.addActionListener( SwingAdapter.getActionListener( this, "btSaveAsActionPerformed" ) );
92          btCancel.addActionListener( SwingAdapter.getActionListener( this, "btCancelActionPerformed" ) );
93      }
94  
95      private void addLabel( String label, String id )
96      {
97          panel.add( new JLabel( label ), id );
98      }
99  
100     private void addSeparator( String label, String id )
101     {
102         panel.add( DefaultComponentFactory.getInstance().createSeparator( label ), id );
103     }
104 
105     public LayoutManager createLayout( String layoutId )
106     {
107         return MainPanel.SIMPLE_LAYOUT_CONSTRAINTS_MANAGER.getLayout( layoutId );
108     }
109 
110     public JComponent buildPanel()
111     {
112         initComponents();
113 
114         panel.setBorder( com.jgoodies.forms.factories.Borders.DIALOG_BORDER );
115         panel.setLayout( createLayout( "newDialog" ) );
116 
117         addSeparator( "main parameters", "sepMain" );
118         addLabel( "configuration id:", "lblId" );
119         panel.add( tfId, "tfId" );
120         addLabel( "configuration description:", "lblDescription" );
121         panel.add( tfDescription, "tfDescription" );
122         addLabel( "logtype:", "lblLogtype" );
123         panel.add( cbLogtype, "cbLogtype" );
124 
125         addSeparator( "advanced parameters", "sepOptions" );
126         addLabel( "SMTP host:", "lblSmtp" );
127         panel.add( tfSmtp, "tfSmtp" );
128         addLabel( "mail reports to:", "lblMailTo" );
129         panel.add( tfMailTo, "tfMailTo" );
130         addLabel( "reports publication URL:", "lblHttp" );
131         panel.add( tfHttp, "tfHttp" );
132 
133         Component bbar = ButtonBarFactory.buildRightAlignedBar( new JButton[] { btSaveAs, btCancel } );
134         panel.add( bbar, "bbar" );
135 
136         return panel;
137     }
138 
139     private JDialog createDialog( Component parent )
140     {
141         Frame frame =
142             parent instanceof Frame ? (Frame) parent : (Frame) SwingUtilities.getAncestorOfClass( Frame.class, parent );
143         JDialog dialog = new JDialog( frame, "new classification rules configuration", true );
144 
145         Container contentPane = dialog.getContentPane();
146         contentPane.setLayout( new BorderLayout() );
147         contentPane.add( buildPanel(), BorderLayout.CENTER );
148 
149         dialog.pack();
150         dialog.setLocationRelativeTo( parent );
151         return dialog;
152     }
153 
154     private JDialog dialog;
155 
156     public File showNewConfigurationDialog( Component parent )
157     {
158         dialog = createDialog( parent );
159         dialog.setVisible( true );
160         dialog.dispose();
161         dialog = null;
162         return configurationFile;
163     }
164 
165     private File configurationFile;
166 
167     public void btSaveAsActionPerformed( ActionEvent ae )
168     {
169         JFileChooser fc = new JFileChooser( currentDir );
170         fc.setFileFilter( new XmlFileFilter() );
171         fc.setSelectedFile( new File( currentDir, tfId.getText() + ".xml" ) );
172         int ret = fc.showSaveDialog( dialog );
173         if ( ret == JFileChooser.APPROVE_OPTION )
174         {
175             saveConfigurationFile( fc.getSelectedFile() );
176             configurationFile = fc.getSelectedFile();
177             if ( dialog != null )
178             {
179                 dialog.setVisible( false );
180             }
181         }
182     }
183 
184     /**
185      * Saves a new rules configuration to a file.
186      *
187      * @param fileTo the file to save to
188      */
189     private void saveConfigurationFile( File fileTo )
190     {
191         try
192         {
193             PrintWriter out = new PrintWriter( new OutputStreamWriter( new FileOutputStream( fileTo ), "utf-8" ) );
194             generateConfiguration( out );
195             out.close();
196         }
197         catch ( FileNotFoundException fnfe )
198         {
199             fnfe.printStackTrace();
200         }
201         catch ( UnsupportedEncodingException uee )
202         {
203             uee.printStackTrace();
204         }
205     }
206 
207     /**
208      * Generate a new configuration stream by filling <code>reference-rules.xml</code> with values taken from the GUI.
209      *
210      * @param out the stream to write to (in UTF-8 encoding)
211      */
212     private void generateConfiguration( PrintWriter out )
213     {
214         LogType logtype = LogTypes.getLogType( (String) cbLogtype.getSelectedItem() );
215         LogType.Description description = logtype.newDescription( new HashMap<String, String>() );
216 
217         String logeventAttributes = FormatUtil.join( ",", description.getAttributeNames() );
218         int dateAttributeIndex = description.getTimestampAttribute();
219 
220         try
221         {
222             String reference = IOUtils.toString( MainPanel.class.getResourceAsStream( "reference-rules.xml" ), "UTF-8" );
223 
224             Map<String, String> properties = new HashMap<String, String>();
225             properties.put( "id", tfId.getText() );
226             properties.put( "description", tfDescription.getText() );
227             properties.put( "logtype", (String) cbLogtype.getSelectedItem() );
228             properties.put( "logtype.attributes", logeventAttributes );
229             properties.put( "mail.to", tfMailTo.getText() );
230             properties.put( "mail.smtp.host", tfSmtp.getText() );
231             properties.put( "logs.url", tfHttp.getText() );
232             properties.put( "logtype.groups", description.getDefaultSpecificGroups() );
233 
234             String skipCondition = // default matching condition for skip group, if no timestamp available
235                 "      <!-- this logtype does not have a timestamp: we can't really skip events with bad date -->\n"
236                     + "      <match attribute=\"logSource\" type=\"equals\"></match>\n"
237                     + "      <!-- if this logtype had a timestamp, the condition would look like the following: -->\n"
238                     + "      <!--match attribute=\"(timestamp attribute?)\" type=\"!contains\">${date}</match!-->";
239             if ( dateAttributeIndex >= 0 )
240             {
241                 skipCondition =
242                     "      <match attribute=\"" + description.getAttributeName( dateAttributeIndex )
243                         + "\" type=\"!contains\">${date}</match>";
244             }
245             properties.put( "skip.condition", skipCondition );
246 
247             // let's compute the sampling.rule property for this LogType
248             String samplingAttributes = description.getDefaultSamplingAttributes();
249             String samplingRule = // default comment when no sampling attributes defined
250                 "\n    <!--plugin type=\"sampling\">\n"
251                 + "      <param name=\"attributes\">most discriminating attribute</param>\n"
252                 + "    </plugin-->";
253             if ( samplingAttributes.length() > 0 )
254             {
255                 // ok, there are sampling attributes
256                 samplingRule =
257                     "\n    <plugin type=\"sampling\">\n"
258                     + "      <param name=\"attributes\">" + samplingAttributes + "</param>\n"
259                     + "    </plugin>";
260             }
261             properties.put( "sampling.rule", samplingRule );
262 
263             PropertiesReplacer repl = new PropertiesReplacer( properties, "#(", ")" );
264 
265             out.print( repl.replaceProperties( reference ) );
266         }
267         catch ( IOException ioe )
268         {
269             ioe.printStackTrace();
270         }
271     }
272 
273     public void btCancelActionPerformed( ActionEvent ae )
274     {
275         configurationFile = null;
276         if ( dialog != null )
277         {
278             dialog.setVisible( false );
279         }
280     }
281 }