diff --git a/src/main/java/logback.xml b/src/main/java/logback.xml index 4e1fe43..29e9e1e 100644 --- a/src/main/java/logback.xml +++ b/src/main/java/logback.xml @@ -5,8 +5,12 @@ %d{HH:mm:ss.SSS} %-5level - %msg%n - + + + + + \ No newline at end of file diff --git a/src/main/java/pro/litvinovg/w2phtml/LogMapAppender.java b/src/main/java/pro/litvinovg/w2phtml/LogMapAppender.java new file mode 100644 index 0000000..b335aaf --- /dev/null +++ b/src/main/java/pro/litvinovg/w2phtml/LogMapAppender.java @@ -0,0 +1,18 @@ +package pro.litvinovg.w2phtml; + +import java.sql.Timestamp; + +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.core.AppenderBase; + +public class LogMapAppender extends AppenderBase{ + + SingleLogArray logArray = SingleLogArray.create(); + + @Override + protected void append(LoggingEvent logEvent) { + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + logArray.addEvent(timestamp + " : " + logEvent.getMessage()); + } + +} diff --git a/src/main/java/pro/litvinovg/w2phtml/SingleLogArray.java b/src/main/java/pro/litvinovg/w2phtml/SingleLogArray.java new file mode 100644 index 0000000..ee2c940 --- /dev/null +++ b/src/main/java/pro/litvinovg/w2phtml/SingleLogArray.java @@ -0,0 +1,47 @@ +package pro.litvinovg.w2phtml; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class SingleLogArray { + private List array = Collections.synchronizedList(new ArrayList()); + private static SingleLogArray INSTANCE = null; + + private SingleLogArray() { + + } + public static SingleLogArray create() { + if (INSTANCE == null) { + INSTANCE = new SingleLogArray(); + } + return INSTANCE; + } + public void addEvent(String event) { + if (array.size() < 1000) { + array.add(event); + } + } + public void clear() { + array.clear(); + } + public boolean isEmpty() { + return array.isEmpty(); + } + public String getLogs() { + if (!array.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (String event : array) { + sb.append(event); + sb.append("\n"); + } + array.clear(); + return sb.toString(); + } else { + return "No errors found."; + } + } + +} diff --git a/src/main/java/pro/litvinovg/w2phtml/gui/ConversionExecutor.java b/src/main/java/pro/litvinovg/w2phtml/gui/ConversionExecutor.java index 4c831d9..978c783 100644 --- a/src/main/java/pro/litvinovg/w2phtml/gui/ConversionExecutor.java +++ b/src/main/java/pro/litvinovg/w2phtml/gui/ConversionExecutor.java @@ -181,12 +181,18 @@ public class ConversionExecutor { if (inputFile.isDirectory()) { convertAllInDir(); } else { - tryConversion(); - JOptionPane.showMessageDialog(frame, "Conversion completed."); + tryConversion(); + showResultsDialog(); + //JOptionPane.showMessageDialog(frame, "Conversion completed."); } } + private void showResultsDialog() { + ResultsDialog results = new ResultsDialog(); + results.setVisible(true); + } + private void tryConversion() { try { Application.main(prepareArgs()); @@ -217,8 +223,7 @@ public class ConversionExecutor { for (File inputFile : inputFiles) { convertFileInDir(inputFile, outputPath, metadataDir); } - JOptionPane.showMessageDialog(frame, "Conversion completed."); - + showResultsDialog(); } private void convertFileInDir(File inputFile, String outputPath, String metadataDir) { diff --git a/src/main/java/pro/litvinovg/w2phtml/gui/LogAppender.java b/src/main/java/pro/litvinovg/w2phtml/gui/LogAppender.java deleted file mode 100644 index 79567ee..0000000 --- a/src/main/java/pro/litvinovg/w2phtml/gui/LogAppender.java +++ /dev/null @@ -1,115 +0,0 @@ -package pro.litvinovg.w2phtml.gui; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import javax.swing.JTextPane; -import javax.swing.SwingUtilities; -import javax.swing.text.AbstractDocument; -import javax.swing.text.BadLocationException; -import javax.swing.text.Document; -import javax.swing.text.Element; -import javax.swing.text.SimpleAttributeSet; - -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.PatternLayout; -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.AppenderBase; - -public class LogAppender extends AppenderBase { - - private static SimpleAttributeSet ERROR_ATT, WARN_ATT, INFO_ATT, DEBUG_ATT, TRACE_ATT, RESTO_ATT; - private PatternLayout patternLayout; - - @Override - protected void append(ch.qos.logback.classic.spi.ILoggingEvent event) { - // Formata mensagem do log - String formattedMsg = patternLayout.doLayout( event); - - // Forma segura de atualizar o JTextpane - SwingUtilities.invokeLater(() -> { - // Alias para o JTextPane no frame da aplicação - JTextPane textPane = null;//App.MAIN_FORM.getTextPane(); - - try { - // Trunca linhas para economizar memória - // Quando atingir 2000 linhas, eu quero que - // apague as 500 primeiras linhas - int limite = 1000; - int apaga = 200; - if (textPane.getDocument().getDefaultRootElement().getElementCount() > limite) { - int end = getLineEndOffset(textPane, apaga); - replaceRange(textPane, null, 0, end); - } - - // Decide qual atributo (estilo) devo usar de acordo com o nível o log - if (event.getLevel() == Level.ERROR) - textPane.getDocument().insertString(textPane.getDocument().getLength(), formattedMsg, ERROR_ATT); - else if (event.getLevel() == Level.WARN) - textPane.getDocument().insertString(textPane.getDocument().getLength(), formattedMsg, WARN_ATT); - else if (event.getLevel() == Level.INFO) - textPane.getDocument().insertString(textPane.getDocument().getLength(), formattedMsg, INFO_ATT); - else if (event.getLevel() == Level.DEBUG) - textPane.getDocument().insertString(textPane.getDocument().getLength(), formattedMsg, DEBUG_ATT); - else if (event.getLevel() == Level.TRACE) - textPane.getDocument().insertString(textPane.getDocument().getLength(), formattedMsg, TRACE_ATT); - else - textPane.getDocument().insertString(textPane.getDocument().getLength(), formattedMsg, RESTO_ATT); - - } catch (BadLocationException e) { - // Faz nada - } - - // Vai para a última linha - textPane.setCaretPosition(textPane.getDocument().getLength()); - }); - } - - public void start() { - patternLayout = new PatternLayout(); - patternLayout.setContext(getContext()); - patternLayout.setPattern("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"); - patternLayout.start(); - - super.start(); - } - - private int getLineCount(JTextPane textPane) { - return textPane.getDocument().getDefaultRootElement().getElementCount(); - } - - - private void replaceRange(JTextPane textPane, String str, int start, int end) throws IllegalArgumentException { - if (end < start) { - throw new IllegalArgumentException("end before start"); - } - Document doc = textPane.getDocument(); - if (doc != null) { - try { - if (doc instanceof AbstractDocument) { - ((AbstractDocument)doc).replace(start, end - start, str, null); - } - else { - doc.remove(start, end - start); - doc.insertString(start, str, null); - } - } catch (BadLocationException e) { - throw new IllegalArgumentException(e.getMessage()); - } - } -} - private int getLineEndOffset(JTextPane textPane, int line) throws BadLocationException { - int lineCount = getLineCount(textPane); - if (line < 0) { - throw new BadLocationException("Negative line", -1); - } else if (line >= lineCount) { - throw new BadLocationException("No such line", textPane.getDocument().getLength()+1); - } else { - Element map = textPane.getDocument().getDefaultRootElement(); - Element lineElem = map.getElement(line); - int endOffset = lineElem.getEndOffset(); - // hide the implicit break at the end of the document - return ((line == lineCount - 1) ? (endOffset - 1) : endOffset); - } -} -} diff --git a/src/main/java/pro/litvinovg/w2phtml/gui/ResultsDialog.java b/src/main/java/pro/litvinovg/w2phtml/gui/ResultsDialog.java new file mode 100644 index 0000000..2d9f2a0 --- /dev/null +++ b/src/main/java/pro/litvinovg/w2phtml/gui/ResultsDialog.java @@ -0,0 +1,110 @@ +package pro.litvinovg.w2phtml.gui; + +import java.awt.BorderLayout; +import java.awt.FlowLayout; +import java.util.Iterator; +import java.util.Map; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.border.EmptyBorder; + +import pro.litvinovg.w2phtml.SingleLogArray; + +import javax.swing.GroupLayout; +import javax.swing.GroupLayout.Alignment; +import javax.swing.JTextArea; +import javax.swing.JLabel; +import javax.swing.JScrollPane; +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; +import java.awt.Color; +import javax.swing.LayoutStyle.ComponentPlacement; +import java.awt.Toolkit; + +public class ResultsDialog extends JDialog { + + private final JPanel contentPanel = new JPanel(); + private JTextArea txt_conversionLogs; + private static ResultsDialog dialog = null; + + /** + * Launch the application. + */ + public static void main(String[] args) { + try { + dialog = new ResultsDialog(); + dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + dialog.setVisible(true); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Create the dialog. + */ + public ResultsDialog() { + setIconImage(Toolkit.getDefaultToolkit().getImage(ResultsDialog.class.getResource("/pro/litvinovg/w2phtml/gui/resources/w2phtml.png"))); + if (dialog != null) { + dialog.dispose(); + } + dialog = this; + setBounds(100, 100, 812, 268); + getContentPane().setLayout(new BorderLayout()); + contentPanel.setBackground(Color.WHITE); + contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); + getContentPane().add(contentPanel, BorderLayout.CENTER); + SingleLogArray singleLogArray = SingleLogArray.create(); + + JScrollPane scrollPane = new JScrollPane(); + + JTextArea txtrConversionCompleted = new JTextArea(); + txtrConversionCompleted.setBackground(Color.WHITE); + txtrConversionCompleted.setText("Conversion completed."); + + GroupLayout gl_contentPanel = new GroupLayout(contentPanel); + gl_contentPanel.setHorizontalGroup( + gl_contentPanel.createParallelGroup(Alignment.LEADING) + .addGroup(Alignment.TRAILING, gl_contentPanel.createSequentialGroup() + .addContainerGap() + .addGroup(gl_contentPanel.createParallelGroup(Alignment.TRAILING) + .addComponent(scrollPane, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 782, Short.MAX_VALUE) + .addComponent(txtrConversionCompleted, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 782, Short.MAX_VALUE)) + .addContainerGap()) + ); + gl_contentPanel.setVerticalGroup( + gl_contentPanel.createParallelGroup(Alignment.LEADING) + .addGroup(gl_contentPanel.createSequentialGroup() + .addContainerGap() + .addComponent(txtrConversionCompleted, GroupLayout.PREFERRED_SIZE, 34, GroupLayout.PREFERRED_SIZE) + .addPreferredGap(ComponentPlacement.RELATED) + .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 142, Short.MAX_VALUE)) + ); + + txt_conversionLogs = new JTextArea(); + txt_conversionLogs.setBackground(Color.WHITE); + scrollPane.setViewportView(txt_conversionLogs); + txt_conversionLogs.setEditable(false); + txt_conversionLogs.setText(singleLogArray.getLogs()); + contentPanel.setLayout(gl_contentPanel); + { + JPanel buttonPane = new JPanel(); + buttonPane.setLayout(new FlowLayout(FlowLayout.CENTER)); + getContentPane().add(buttonPane, BorderLayout.SOUTH); + { + JButton okButton = new JButton("Close"); + okButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + dialog.dispose(); + } + }); + okButton.setActionCommand("OK"); + buttonPane.add(okButton); + getRootPane().setDefaultButton(okButton); + } + } + } +}