001 package net.sf.logdistiller.gui;
002
003 /*
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 import java.awt.BorderLayout;
018 import java.awt.Component;
019 import java.awt.Container;
020 import java.awt.Frame;
021 import java.awt.LayoutManager;
022 import java.awt.event.ActionEvent;
023 import java.io.*;
024 import java.util.HashMap;
025 import java.util.List;
026 import java.util.Map;
027 import javax.swing.*;
028
029 import com.jgoodies.forms.factories.ButtonBarFactory;
030 import com.jgoodies.forms.factories.DefaultComponentFactory;
031 import org.apache.commons.io.IOUtils;
032 import org.apache.commons.lang.StringUtils;
033
034 import net.sf.logdistiller.LogType;
035 import net.sf.logdistiller.LogTypes;
036 import net.sf.logdistiller.util.FormatUtil;
037 import net.sf.logdistiller.util.PropertiesReplacer;
038
039 /**
040 * Dialog to create a new rules configuration file: you select the log type and give some basic information (an id, STMP
041 * server, url), and it generates a new rules configuration. Then you just need to refine the rules.
042 */
043 public class NewDialog
044 {
045 private File currentDir;
046
047 public NewDialog( File directory )
048 {
049 currentDir = directory;
050 }
051
052 protected JPanel panel = new JPanel();
053
054 private JTextField tfId = new JTextField( "rules-id", 15 );
055
056 private JTextField tfDescription = new JTextField( "rules description" );
057
058 private JComboBox cbLogtype;
059
060 private JTextField tfSmtp = new JTextField( "smtp.provider.com" );
061
062 private JTextField tfMailTo = new JTextField( "admin@localhost" );
063
064 private JTextField tfHttp = new JTextField( "http://mysite.com/logdistiller/logs" );
065
066 private JButton btSaveAs = new JButton( "save as..." );
067
068 private JButton btCancel = new JButton( "cancel" );
069
070 public static JComboBox createCbLogtype( boolean withUndefined )
071 {
072 List logtypes = LogTypes.getAllLogTypes();
073 int len = logtypes.size();
074 String[] logtypeIds = new String[len];
075 for ( int i = 0; i < len; i++ )
076 {
077 logtypeIds[i] = ( (LogType) logtypes.get( i ) ).getId();
078 }
079 JComboBox cb = new JComboBox( logtypeIds );
080 if ( withUndefined )
081 {
082 cb.insertItemAt( "undefined", 0 );
083 cb.setSelectedIndex( 0 );
084 }
085 return cb;
086 }
087
088 private void initComponents()
089 {
090 cbLogtype = createCbLogtype( false );
091
092 btSaveAs.addActionListener( SwingAdapter.getActionListener( this, "btSaveAsActionPerformed" ) );
093 btCancel.addActionListener( SwingAdapter.getActionListener( this, "btCancelActionPerformed" ) );
094 }
095
096 private void addLabel( String label, String id )
097 {
098 panel.add( new JLabel( label ), id );
099 }
100
101 private void addSeparator( String label, String id )
102 {
103 panel.add( DefaultComponentFactory.getInstance().createSeparator( label ), id );
104 }
105
106 public LayoutManager createLayout( String layoutId )
107 {
108 return MainPanel.SIMPLE_LAYOUT_CONSTRAINTS_MANAGER.getLayout( layoutId );
109 }
110
111 public JComponent buildPanel()
112 {
113 initComponents();
114
115 panel.setBorder( com.jgoodies.forms.factories.Borders.DIALOG_BORDER );
116 panel.setLayout( createLayout( "newDialog" ) );
117
118 addSeparator( "main parameters", "sepMain" );
119 addLabel( "configuration id:", "lblId" );
120 panel.add( tfId, "tfId" );
121 addLabel( "configuration description:", "lblDescription" );
122 panel.add( tfDescription, "tfDescription" );
123 addLabel( "logtype:", "lblLogtype" );
124 panel.add( cbLogtype, "cbLogtype" );
125
126 addSeparator( "advanced parameters", "sepOptions" );
127 addLabel( "SMTP host:", "lblSmtp" );
128 panel.add( tfSmtp, "tfSmtp" );
129 addLabel( "mail reports to:", "lblMailTo" );
130 panel.add( tfMailTo, "tfMailTo" );
131 addLabel( "reports publication URL:", "lblHttp" );
132 panel.add( tfHttp, "tfHttp" );
133
134 Component bbar = ButtonBarFactory.buildRightAlignedBar( new JButton[] { btSaveAs, btCancel } );
135 panel.add( bbar, "bbar" );
136
137 return panel;
138 }
139
140 private JDialog createDialog( Component parent )
141 {
142 Frame frame =
143 parent instanceof Frame ? (Frame) parent : (Frame) SwingUtilities.getAncestorOfClass( Frame.class, parent );
144 JDialog dialog = new JDialog( frame, "new classification rules configuration", true );
145
146 Container contentPane = dialog.getContentPane();
147 contentPane.setLayout( new BorderLayout() );
148 contentPane.add( buildPanel(), BorderLayout.CENTER );
149
150 dialog.pack();
151 dialog.setLocationRelativeTo( parent );
152 return dialog;
153 }
154
155 private JDialog dialog;
156
157 public File showNewConfigurationDialog( Component parent )
158 {
159 dialog = createDialog( parent );
160 dialog.show();
161 dialog.dispose();
162 dialog = null;
163 return configurationFile;
164 }
165
166 private File configurationFile;
167
168 public void btSaveAsActionPerformed( ActionEvent ae )
169 {
170 JFileChooser fc = new JFileChooser( currentDir );
171 fc.setFileFilter( new XmlFileFilter() );
172 fc.setSelectedFile( new File( currentDir, tfId.getText() + ".xml" ) );
173 int ret = fc.showSaveDialog( dialog );
174 if ( ret == JFileChooser.APPROVE_OPTION )
175 {
176 saveConfigurationFile( fc.getSelectedFile() );
177 configurationFile = fc.getSelectedFile();
178 if ( dialog != null )
179 {
180 dialog.setVisible( false );
181 }
182 }
183 }
184
185 /**
186 * Saves a new rules configuration to a file.
187 *
188 * @param fileTo the file to save to
189 */
190 private void saveConfigurationFile( File fileTo )
191 {
192 try
193 {
194 PrintWriter out = new PrintWriter( new OutputStreamWriter( new FileOutputStream( fileTo ), "utf-8" ) );
195 generateConfiguration( out );
196 out.close();
197 }
198 catch ( FileNotFoundException fnfe )
199 {
200 fnfe.printStackTrace();
201 }
202 catch ( UnsupportedEncodingException uee )
203 {
204 uee.printStackTrace();
205 }
206 }
207
208 /**
209 * Generate a new configuration stream by filling <code>reference-rules.xml</code> with values taken from the GUI.
210 *
211 * @param out the stream to write to (in UTF-8 encoding)
212 */
213 private void generateConfiguration( PrintWriter out )
214 {
215 LogType logtype = LogTypes.getLogType( (String) cbLogtype.getSelectedItem() );
216 LogType.Description description = logtype.newDescription( new HashMap() );
217
218 String logeventAttributes = FormatUtil.join( ",", description.getAttributeNames() );
219 int dateAttributeIndex = description.getTimestampAttribute();
220
221 try
222 {
223 String reference = IOUtils.toString( MainPanel.class.getResourceAsStream( "reference-rules.xml" ), "UTF-8" );
224
225 Map properties = new HashMap();
226 properties.put( "id", tfId.getText() );
227 properties.put( "description", tfDescription.getText() );
228 properties.put( "logtype", cbLogtype.getSelectedItem() );
229 properties.put( "logtype.attributes", logeventAttributes );
230 properties.put( "mail.to", tfMailTo.getText() );
231 properties.put( "mail.smtp.host", tfSmtp.getText() );
232 properties.put( "logs.url", tfHttp.getText() );
233 properties.put( "logtype.groups", description.getDefaultSpecificGroups() );
234
235 String skipCondition = // default matching condition for skip group, if no timestamp available
236 " <!-- this logtype does not have a timestamp: we can't really skip events with bad date -->\n"
237 + " <match attribute=\"logSource\" type=\"equals\"></match>\n"
238 + " <!-- if this logtype had a timestamp, the condition would look like the following: -->\n"
239 + " <!--match attribute=\"(timestamp attribute?)\" type=\"!contains\">${date}</match!-->";
240 if ( dateAttributeIndex >= 0 )
241 {
242 skipCondition =
243 " <match attribute=\"" + description.getAttributeName( dateAttributeIndex )
244 + "\" type=\"!contains\">${date}</match>";
245 }
246 properties.put( "skip.condition", skipCondition );
247
248 // let's compute the sampling.rule property for this LogType
249 String samplingAttributes = description.getDefaultSamplingAttributes();
250 String samplingRule = // default comment when no sampling attributes defined
251 "\n <!--plugin type=\"sampling\">\n"
252 + " <param name=\"attributes\">most discriminating attribute</param>\n"
253 + " </plugin-->";
254 if ( samplingAttributes.length() > 0 )
255 {
256 // ok, there are sampling attributes
257 samplingRule =
258 "\n <plugin type=\"sampling\">\n"
259 + " <param name=\"attributes\">" + samplingAttributes + "</param>\n"
260 + " </plugin>";
261 }
262 properties.put( "sampling.rule", samplingRule );
263
264 PropertiesReplacer repl = new PropertiesReplacer( properties, "#(", ")" );
265
266 out.print( repl.replaceProperties( reference ) );
267 }
268 catch ( IOException ioe )
269 {
270 ioe.printStackTrace();
271 }
272 }
273
274 public void btCancelActionPerformed( ActionEvent ae )
275 {
276 configurationFile = null;
277 if ( dialog != null )
278 {
279 dialog.setVisible( false );
280 }
281 }
282 }