001package 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 017import java.awt.BorderLayout; 018import java.awt.Component; 019import java.awt.Container; 020import java.awt.Frame; 021import java.awt.LayoutManager; 022import java.awt.event.ActionEvent; 023import java.io.*; 024import java.util.HashMap; 025import java.util.List; 026import java.util.Map; 027import javax.swing.*; 028 029import com.jgoodies.forms.factories.ButtonBarFactory; 030import com.jgoodies.forms.factories.DefaultComponentFactory; 031import org.apache.commons.io.IOUtils; 032 033import net.sf.logdistiller.LogType; 034import net.sf.logdistiller.LogTypes; 035import net.sf.logdistiller.util.FormatUtil; 036import net.sf.logdistiller.util.PropertiesReplacer; 037 038/** 039 * Dialog to create a new rules configuration file: you select the log type and give some basic information (an id, STMP 040 * server, url), and it generates a new rules configuration. Then you just need to refine the rules. 041 */ 042public class NewDialog 043{ 044 private File currentDir; 045 046 public NewDialog( File directory ) 047 { 048 currentDir = directory; 049 } 050 051 protected JPanel panel = new JPanel(); 052 053 private JTextField tfId = new JTextField( "rules-id", 15 ); 054 055 private JTextField tfDescription = new JTextField( "rules description" ); 056 057 private JComboBox cbLogtype; 058 059 private JTextField tfSmtp = new JTextField( "smtp.provider.com" ); 060 061 private JTextField tfMailTo = new JTextField( "admin@localhost" ); 062 063 private JTextField tfHttp = new JTextField( "http://mysite.com/logdistiller/logs" ); 064 065 private JButton btSaveAs = new JButton( "save as..." ); 066 067 private JButton btCancel = new JButton( "cancel" ); 068 069 public static JComboBox createCbLogtype( boolean withUndefined ) 070 { 071 List<LogType> logtypes = LogTypes.getAllLogTypes(); 072 int len = logtypes.size(); 073 String[] logtypeIds = new String[len]; 074 for ( int i = 0; i < len; i++ ) 075 { 076 logtypeIds[i] = logtypes.get( i ).getId(); 077 } 078 JComboBox cb = new JComboBox( logtypeIds ); 079 if ( withUndefined ) 080 { 081 cb.insertItemAt( "undefined", 0 ); 082 cb.setSelectedIndex( 0 ); 083 } 084 return cb; 085 } 086 087 private void initComponents() 088 { 089 cbLogtype = createCbLogtype( false ); 090 091 btSaveAs.addActionListener( SwingAdapter.getActionListener( this, "btSaveAsActionPerformed" ) ); 092 btCancel.addActionListener( SwingAdapter.getActionListener( this, "btCancelActionPerformed" ) ); 093 } 094 095 private void addLabel( String label, String id ) 096 { 097 panel.add( new JLabel( label ), id ); 098 } 099 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}