From 3434dc1a97f48f0b9388de394486e0e024c18e6d Mon Sep 17 00:00:00 2001 From: magenoxx Date: Thu, 26 Jan 2012 22:13:44 +0400 Subject: [PATCH] Added User Feedback support. --- .../src/main/java/mage/client/MageFrame.form | 19 +- .../src/main/java/mage/client/MageFrame.java | 310 +++++++++-------- .../mage/client/dialog/FeedbackDialog.form | 258 ++++++++++++++ .../mage/client/dialog/FeedbackDialog.java | 328 ++++++++++++++++++ Mage.Common/src/mage/db/EntityManager.java | 108 +++++- .../src/mage/db/EntityManagerTest.java | 10 + Mage.Common/src/mage/db/Storage.java | 6 +- Mage.Common/src/mage/db/model/Feedback.java | 102 ++++++ .../src/mage/interfaces/MageServer.java | 3 + Mage.Common/src/mage/remote/Session.java | 12 + .../main/java/mage/server/MageServerImpl.java | 16 +- .../mage/server/services/FeedbackService.java | 14 + .../java/mage/server/services/LogKeys.java | 2 + .../services/impl/FeedbackServiceImpl.java | 26 ++ 14 files changed, 1065 insertions(+), 149 deletions(-) create mode 100644 Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.form create mode 100644 Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.java create mode 100644 Mage.Common/src/mage/db/model/Feedback.java create mode 100644 Mage.Server/src/main/java/mage/server/services/FeedbackService.java create mode 100644 Mage.Server/src/main/java/mage/server/services/impl/FeedbackServiceImpl.java diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.form b/Mage.Client/src/main/java/mage/client/MageFrame.form index 1b50b9288c..808b56ba8a 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.form +++ b/Mage.Client/src/main/java/mage/client/MageFrame.form @@ -61,6 +61,19 @@ + + + + + + + + + + + + + @@ -77,7 +90,7 @@ - + @@ -95,7 +108,7 @@ - + @@ -157,7 +170,7 @@ - + diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index a15029bccb..a79c5ef888 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -35,7 +35,6 @@ package mage.client; import mage.Constants; -import mage.interfaces.Action; import mage.cards.Card; import mage.cards.decks.Deck; import mage.client.cards.CardsStorage; @@ -62,7 +61,8 @@ import mage.client.util.SettingsManager; import mage.client.util.gui.ArrowBuilder; import mage.components.ImagePanel; import mage.game.match.MatchOptions; -import mage.interfaces.*; +import mage.interfaces.Action; +import mage.interfaces.MageClient; import mage.interfaces.callback.CallbackClient; import mage.interfaces.callback.ClientCallback; import mage.remote.Connection; @@ -611,143 +611,157 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") - // //GEN-BEGIN:initComponents - private void initComponents() { + // //GEN-BEGIN:initComponents + private void initComponents() { - desktopPane = new MageJDesktop(); - mageToolbar = new javax.swing.JToolBar(); - btnConnect = new javax.swing.JButton(); - jSeparator4 = new javax.swing.JToolBar.Separator(); - btnGames = new javax.swing.JButton(); - jSeparator3 = new javax.swing.JToolBar.Separator(); - btnDeckEditor = new javax.swing.JButton(); - jSeparator2 = new javax.swing.JToolBar.Separator(); - btnCollectionViewer = new javax.swing.JButton(); - jSeparator5 = new javax.swing.JToolBar.Separator(); - btnPreferences = new javax.swing.JButton(); - jSeparator6 = new javax.swing.JToolBar.Separator(); - btnAbout = new javax.swing.JButton(); - jSeparator1 = new javax.swing.JToolBar.Separator(); - btnExit = new javax.swing.JButton(); - lblStatus = new javax.swing.JLabel(); + desktopPane = new MageJDesktop(); + mageToolbar = new javax.swing.JToolBar(); + btnSendFeedback = new javax.swing.JButton(); + jSeparator4 = new javax.swing.JToolBar.Separator(); + btnConnect = new javax.swing.JButton(); + jSeparator3 = new javax.swing.JToolBar.Separator(); + btnGames = new javax.swing.JButton(); + jSeparator1 = new javax.swing.JToolBar.Separator(); + btnDeckEditor = new javax.swing.JButton(); + jSeparator2 = new javax.swing.JToolBar.Separator(); + btnCollectionViewer = new javax.swing.JButton(); + jSeparator5 = new javax.swing.JToolBar.Separator(); + btnPreferences = new javax.swing.JButton(); + jSeparator6 = new javax.swing.JToolBar.Separator(); + btnAbout = new javax.swing.JButton(); + jSeparator7 = new javax.swing.JToolBar.Separator(); + btnExit = new javax.swing.JButton(); + lblStatus = new javax.swing.JLabel(); - setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); - setMinimumSize(new Dimension(600, 400)); + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + setMinimumSize(new java.awt.Dimension(1024, 768)); - desktopPane.setBackground(new java.awt.Color(204, 204, 204)); + desktopPane.setBackground(new java.awt.Color(204, 204, 204)); - mageToolbar.setFloatable(false); - mageToolbar.setRollover(true); + mageToolbar.setFloatable(false); + mageToolbar.setRollover(true); - btnConnect.setText("Connect"); - btnConnect.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); - btnConnect.setFocusable(false); - btnConnect.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnConnect.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnConnect.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnConnectActionPerformed(evt); - } - }); - mageToolbar.add(btnConnect); - mageToolbar.add(jSeparator4); + btnSendFeedback.setText("Feedback"); + btnSendFeedback.setFocusable(false); + btnSendFeedback.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnSendFeedback.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnSendFeedback.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnSendFeedbackActionPerformed(evt); + } + }); + mageToolbar.add(btnSendFeedback); + mageToolbar.add(jSeparator4); - btnGames.setText("Games"); - btnGames.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); - btnGames.setFocusable(false); - btnGames.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnGames.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnGames.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnGamesActionPerformed(evt); - } - }); - mageToolbar.add(btnGames); - mageToolbar.add(jSeparator3); + btnConnect.setText("Connect"); + btnConnect.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); + btnConnect.setFocusable(false); + btnConnect.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnConnect.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnConnect.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnConnectActionPerformed(evt); + } + }); + mageToolbar.add(btnConnect); + mageToolbar.add(jSeparator3); - btnDeckEditor.setText("Deck Editor"); - btnDeckEditor.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); - btnDeckEditor.setFocusable(false); - btnDeckEditor.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnDeckEditor.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnDeckEditor.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnDeckEditorActionPerformed(evt); - } - }); - mageToolbar.add(btnDeckEditor); - mageToolbar.add(jSeparator2); + btnGames.setText("Games"); + btnGames.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); + btnGames.setFocusable(false); + btnGames.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnGames.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnGames.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnGamesActionPerformed(evt); + } + }); + mageToolbar.add(btnGames); + mageToolbar.add(jSeparator1); - btnCollectionViewer.setText("Collection Viewer"); - btnCollectionViewer.setFocusable(false); - btnCollectionViewer.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnCollectionViewer.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnCollectionViewer.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnCollectionViewerActionPerformed(evt); - } - }); - mageToolbar.add(btnCollectionViewer); - mageToolbar.add(jSeparator5); + btnDeckEditor.setText("Deck Editor"); + btnDeckEditor.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); + btnDeckEditor.setFocusable(false); + btnDeckEditor.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnDeckEditor.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnDeckEditor.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnDeckEditorActionPerformed(evt); + } + }); + mageToolbar.add(btnDeckEditor); + mageToolbar.add(jSeparator2); - btnPreferences.setText("Preferences"); - btnPreferences.setFocusable(false); - btnPreferences.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnPreferences.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnPreferences.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnPreferencesActionPerformed(evt); - } - }); - mageToolbar.add(btnPreferences); - mageToolbar.add(jSeparator6); + btnCollectionViewer.setText("Collection Viewer"); + btnCollectionViewer.setFocusable(false); + btnCollectionViewer.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnCollectionViewer.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnCollectionViewer.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnCollectionViewerActionPerformed(evt); + } + }); + mageToolbar.add(btnCollectionViewer); + mageToolbar.add(jSeparator5); - btnAbout.setText("About"); - btnAbout.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); - btnAbout.setFocusable(false); - btnAbout.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnAbout.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnAbout.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnAboutActionPerformed(evt); - } - }); - mageToolbar.add(btnAbout); - mageToolbar.add(jSeparator1); + btnPreferences.setText("Preferences"); + btnPreferences.setFocusable(false); + btnPreferences.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnPreferences.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnPreferences.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnPreferencesActionPerformed(evt); + } + }); + mageToolbar.add(btnPreferences); + mageToolbar.add(jSeparator6); - btnExit.setText("Exit"); - btnExit.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); - btnExit.setFocusable(false); - btnExit.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - btnExit.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); - btnExit.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - btnExitActionPerformed(evt); - } - }); - mageToolbar.add(btnExit); + btnAbout.setText("About"); + btnAbout.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); + btnAbout.setFocusable(false); + btnAbout.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnAbout.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnAbout.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnAboutActionPerformed(evt); + } + }); + mageToolbar.add(btnAbout); + mageToolbar.add(jSeparator7); - lblStatus.setText("Not connected "); - mageToolbar.add(Box.createHorizontalGlue()); - mageToolbar.add(lblStatus); + btnExit.setText("Exit"); + btnExit.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); + btnExit.setFocusable(false); + btnExit.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + btnExit.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + btnExit.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + btnExitActionPerformed(evt); + } + }); + mageToolbar.add(btnExit); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); - getContentPane().setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(desktopPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1144, Short.MAX_VALUE) - .addComponent(mageToolbar, javax.swing.GroupLayout.DEFAULT_SIZE, 1144, Short.MAX_VALUE) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(mageToolbar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0) - .addComponent(desktopPane, javax.swing.GroupLayout.DEFAULT_SIZE, 880, Short.MAX_VALUE)) - ); + lblStatus.setText("Not connected "); + mageToolbar.add(Box.createHorizontalGlue()); + mageToolbar.add(lblStatus); - pack(); - }// //GEN-END:initComponents + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(desktopPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1144, Short.MAX_VALUE) + .addComponent(mageToolbar, javax.swing.GroupLayout.DEFAULT_SIZE, 1144, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(mageToolbar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0) + .addComponent(desktopPane, javax.swing.GroupLayout.DEFAULT_SIZE, 880, Short.MAX_VALUE)) + ); + + pack(); + }// //GEN-END:initComponents private void btnDeckEditorActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDeckEditorActionPerformed showDeckEditor(DeckEditorMode.Constructed, null, null, 0); @@ -813,6 +827,14 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { PreferencesDialog.main(new String[]{}); }//GEN-LAST:event_btnPreferencesActionPerformed + private void btnSendFeedbackActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSendFeedbackActionPerformed + if (!session.isConnected()) { + JOptionPane.showMessageDialog(null, "You may send us feedback only when connected to server.", "Information", JOptionPane.INFORMATION_MESSAGE); + return; + } + FeedbackDialog.main(new String[]{}); + }//GEN-LAST:event_btnSendFeedbackActionPerformed + public void exitApp() { if (session.isConnected()) { if (JOptionPane.showConfirmDialog(this, "You are currently connected. Are you sure you want to disconnect?", "Confirm disconnect", JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) { @@ -954,24 +976,26 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { }); } - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JButton btnAbout; - private javax.swing.JButton btnCollectionViewer; - private javax.swing.JButton btnConnect; - private javax.swing.JButton btnDeckEditor; - private javax.swing.JButton btnExit; - private javax.swing.JButton btnGames; - private javax.swing.JButton btnPreferences; - private static javax.swing.JDesktopPane desktopPane; - private javax.swing.JToolBar.Separator jSeparator1; - private javax.swing.JToolBar.Separator jSeparator2; - private javax.swing.JToolBar.Separator jSeparator3; - private javax.swing.JToolBar.Separator jSeparator4; - private javax.swing.JToolBar.Separator jSeparator5; - private javax.swing.JToolBar.Separator jSeparator6; - private javax.swing.JLabel lblStatus; - private javax.swing.JToolBar mageToolbar; - // End of variables declaration//GEN-END:variables + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton btnAbout; + private javax.swing.JButton btnCollectionViewer; + private javax.swing.JButton btnConnect; + private javax.swing.JButton btnDeckEditor; + private javax.swing.JButton btnExit; + private javax.swing.JButton btnGames; + private javax.swing.JButton btnPreferences; + private javax.swing.JButton btnSendFeedback; + private static javax.swing.JDesktopPane desktopPane; + private javax.swing.JToolBar.Separator jSeparator1; + private javax.swing.JToolBar.Separator jSeparator2; + private javax.swing.JToolBar.Separator jSeparator3; + private javax.swing.JToolBar.Separator jSeparator4; + private javax.swing.JToolBar.Separator jSeparator5; + private javax.swing.JToolBar.Separator jSeparator6; + private javax.swing.JToolBar.Separator jSeparator7; + private javax.swing.JLabel lblStatus; + private javax.swing.JToolBar mageToolbar; + // End of variables declaration//GEN-END:variables private static final long serialVersionUID = -9104885239063142218L; private ImagePanel backgroundPane; diff --git a/Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.form b/Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.form new file mode 100644 index 0000000000..43875f57d7 --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.form @@ -0,0 +1,258 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.java b/Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.java new file mode 100644 index 0000000000..4ea1a6d53b --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.java @@ -0,0 +1,328 @@ +/* +* Copyright 2012 BetaSteward_at_googlemail.com. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are +* permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this list of +* conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, this list +* of conditions and the following disclaimer in the documentation and/or other materials +* provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* The views and conclusions contained in the software and documentation are those of the +* authors and should not be interpreted as representing official policies, either expressed +* or implied, of BetaSteward_at_googlemail.com. +*/ + +package mage.client.dialog; + +import mage.client.MageFrame; +import org.apache.log4j.Logger; + +import javax.swing.*; + +/** + * Feedback dialog. + * + * @author noxx + */ +public class FeedbackDialog extends javax.swing.JDialog { + + private static final transient Logger log = Logger.getLogger(PreferencesDialog.class); + + private String[] feedbackTypes = {"", "Bug or \"something doesn't work\"", + "Feature or \"I need that function\"", + "Thank you or \"Devs, you are so cool!\"", + "Question or \"I'm so curious about\""}; + + /** Creates new form PreferencesDialog */ + public FeedbackDialog(java.awt.Frame parent, boolean modal) { + super(parent, modal); + initComponents(); + cbFeedbackType.setModel(new DefaultComboBoxModel(feedbackTypes)); + } + + /** This method is called from within the constructor to + * initialize the form. + * WARNING: Do NOT modify this code. The content of this method is + * always regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jTabbedPane1 = new javax.swing.JTabbedPane(); + jPanel6 = new javax.swing.JPanel(); + pnlProxy = new javax.swing.JPanel(); + lblProxyServer = new javax.swing.JLabel(); + txtIdeaTitle = new javax.swing.JTextField(); + lblProxyPort = new javax.swing.JLabel(); + txtEmail = new javax.swing.JTextField(); + lblProxyUserName = new javax.swing.JLabel(); + cbFeedbackType = new javax.swing.JComboBox(); + lblProxyType = new javax.swing.JLabel(); + jScrollPane1 = new javax.swing.JScrollPane(); + txtFeedbackMessage = new javax.swing.JTextArea(); + jLabel2 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + jLabel1 = new javax.swing.JLabel(); + sendButton = new javax.swing.JButton(); + cancelButton = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle("Feedback"); + + lblProxyServer.setText("Enter your idea*"); + + lblProxyPort.setText("Your email:"); + + lblProxyUserName.setText("Describe your idea*"); + + lblProxyType.setText("Category"); + + txtFeedbackMessage.setColumns(20); + txtFeedbackMessage.setFont(new java.awt.Font("Tahoma", 0, 11)); + txtFeedbackMessage.setRows(5); + txtFeedbackMessage.setText("(300 characters max)"); + jScrollPane1.setViewportView(txtFeedbackMessage); + + jLabel2.setFont(new java.awt.Font("Tahoma", 2, 11)); + jLabel2.setText("(optional)"); + + jLabel3.setFont(new java.awt.Font("Tahoma", 2, 11)); + jLabel3.setText("(optional)"); + + javax.swing.GroupLayout pnlProxyLayout = new javax.swing.GroupLayout(pnlProxy); + pnlProxy.setLayout(pnlProxyLayout); + pnlProxyLayout.setHorizontalGroup( + pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnlProxyLayout.createSequentialGroup() + .addContainerGap() + .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(lblProxyUserName, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(lblProxyType, javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(lblProxyServer, javax.swing.GroupLayout.Alignment.LEADING)) + .addComponent(lblProxyPort)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlProxyLayout.createSequentialGroup() + .addComponent(cbFeedbackType, 0, 243, Short.MAX_VALUE) + .addGap(26, 26, 26) + .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(20, 20, 20)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlProxyLayout.createSequentialGroup() + .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(pnlProxyLayout.createSequentialGroup() + .addComponent(txtEmail, javax.swing.GroupLayout.DEFAULT_SIZE, 238, Short.MAX_VALUE) + .addGap(32, 32, 32) + .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(9, 9, 9)) + .addComponent(txtIdeaTitle, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 325, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 325, Short.MAX_VALUE)) + .addContainerGap()))) + ); + pnlProxyLayout.setVerticalGroup( + pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(pnlProxyLayout.createSequentialGroup() + .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(lblProxyServer) + .addComponent(txtIdeaTitle, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(cbFeedbackType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblProxyType) + .addComponent(jLabel2)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(lblProxyUserName) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 85, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(pnlProxyLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3) + .addComponent(txtEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lblProxyPort)) + .addContainerGap(21, Short.MAX_VALUE)) + ); + + jLabel1.setFont(new java.awt.Font("Arial", 1, 14)); + jLabel1.setForeground(new java.awt.Color(255, 153, 51)); + jLabel1.setText("I suggest you..."); + + javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6); + jPanel6.setLayout(jPanel6Layout); + jPanel6Layout.setHorizontalGroup( + jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel6Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(pnlProxy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel6Layout.setVerticalGroup( + jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel6Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(pnlProxy, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(41, Short.MAX_VALUE)) + ); + + jTabbedPane1.addTab("Give feedback", jPanel6); + + sendButton.setText("Send"); + sendButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + sendButtonActionPerformed(evt); + } + }); + + cancelButton.setText("Cancel"); + cancelButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + cancelButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 469, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap(324, Short.MAX_VALUE) + .addComponent(sendButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cancelButton) + .addGap(17, 17, 17)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 292, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(cancelButton) + .addComponent(sendButton)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + jTabbedPane1.getAccessibleContext().setAccessibleName("Feedback"); + + pack(); + }// //GEN-END:initComponents + + private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed + dialog.setVisible(false); + }//GEN-LAST:event_cancelButtonActionPerformed + + private void sendButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sendButtonActionPerformed + String title = txtIdeaTitle.getText().trim(); + if (title.isEmpty()) { + JOptionPane.showMessageDialog(null, "\"Enter your idea\" is a mandatory field", "Warning", JOptionPane.INFORMATION_MESSAGE); + return; + } + if (title.length() > 100) { + JOptionPane.showMessageDialog(null, "\"Enter your idea\" value is too long (100 characters max)", "Warning", JOptionPane.INFORMATION_MESSAGE); + return; + } + String type = cleanUpType(cbFeedbackType.getSelectedItem().toString()); + String message = txtFeedbackMessage.getText().trim(); + if (message.isEmpty()) { + JOptionPane.showMessageDialog(null, "\"Describe your idea\" is a mandatory field.", "Warning", JOptionPane.INFORMATION_MESSAGE); + return; + } + if (message.length() > 300) { + JOptionPane.showMessageDialog(null, "\"Describe your idea\" value is too long (300 characters max)", "Warning", JOptionPane.INFORMATION_MESSAGE); + } + String email = cleanUpType(cbFeedbackType.getSelectedItem().toString()); + if (MageFrame.getSession().sendFeedback(title, type, message, email)) { + JOptionPane.showMessageDialog(null, "Feedback was sent. Thank you!", "Success", JOptionPane.INFORMATION_MESSAGE); + reset(); + } else { + JOptionPane.showMessageDialog(null, "Couldn't sent feedback.", "Error", JOptionPane.ERROR_MESSAGE); + } + }//GEN-LAST:event_sendButtonActionPerformed + + private String cleanUpType(String type) { + if (type == null || type.isEmpty()) { + return ""; + } + if (type.toLowerCase().startsWith("bug")) { + return "bug"; + } + if (type.toLowerCase().startsWith("feature")) { + return "feature"; + } + if (type.toLowerCase().startsWith("thank")) { + return "thank"; + } + if (type.toLowerCase().startsWith("question")) { + return "question"; + } + return ""; + } + + private void reset() { + jTabbedPane1.setSelectedIndex(0); + txtIdeaTitle.setText(""); + txtFeedbackMessage.setText(""); + txtEmail.setText(""); + } + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + if (!dialog.isVisible()) { + dialog.setLocation(300, 200); + dialog.setVisible(true); + } else { + dialog.requestFocus(); + } + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton cancelButton; + private javax.swing.JComboBox cbFeedbackType; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JPanel jPanel6; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTabbedPane jTabbedPane1; + private javax.swing.JLabel lblProxyPort; + private javax.swing.JLabel lblProxyServer; + private javax.swing.JLabel lblProxyType; + private javax.swing.JLabel lblProxyUserName; + private javax.swing.JPanel pnlProxy; + private javax.swing.JButton sendButton; + private javax.swing.JTextField txtEmail; + private javax.swing.JTextArea txtFeedbackMessage; + private javax.swing.JTextField txtIdeaTitle; + // End of variables declaration//GEN-END:variables + + private static final FeedbackDialog dialog = new FeedbackDialog(new javax.swing.JFrame(), true); + + static { + dialog.setResizable(false); + } +} diff --git a/Mage.Common/src/mage/db/EntityManager.java b/Mage.Common/src/mage/db/EntityManager.java index 131daa217e..c04fa485e0 100644 --- a/Mage.Common/src/mage/db/EntityManager.java +++ b/Mage.Common/src/mage/db/EntityManager.java @@ -1,5 +1,6 @@ package mage.db; +import mage.db.model.Feedback; import mage.db.model.Log; import org.apache.log4j.Logger; @@ -19,12 +20,18 @@ public enum EntityManager implements Storage { private static final String MAGE_JDBC_URL = "jdbc:sqlite:db/mage.db"; + private static final String MAGE_JDBC_URL_FEEDBACK_DB = "jdbc:sqlite:db/feedback.db"; + private static String QUERY_SAVE_LOG = "insert into logs values (?, ?, ?, ?, ?, ?, ?, ?)"; private static String QUERY_GET_ALL_LOGS = "select * from logs"; + private static String QUERY_SAVE_FEEDBACK = "insert into feedbacks values (?, ?, ?, ?, ?, ?, ?, ?)"; + private static String QUERY_GET_ALL_FEEDBACKS = "select * from feedbacks"; + static { try { init(); + initFeedbackDB(); } catch (Exception e) { log.fatal(e); e.printStackTrace(); @@ -69,6 +76,10 @@ public enum EntityManager implements Storage { } } + /** + * Get all logs + * @return + */ @Override public List getAllLogs() { List logs = new ArrayList(); @@ -88,7 +99,6 @@ public enum EntityManager implements Storage { } args.add(arg); } - log.setArguments(args); logs.add(log); } rs.close(); @@ -106,6 +116,86 @@ public enum EntityManager implements Storage { return logs; } + /** + * Inserts feedback entry to DB. + * + * + * @param username + * @param title + * @param type + * @param message + * @param email + * @param host + * @param created + * @throws SQLException + */ + public void insertFeedback(String username, String title, String type, String message, String email, String host, java.util.Date created) throws SQLException { + Connection conn = DriverManager.getConnection(MAGE_JDBC_URL_FEEDBACK_DB); + + try { + PreparedStatement prep = conn.prepareStatement(QUERY_SAVE_FEEDBACK); + + prep.setString(1, username); + prep.setString(2, title); + prep.setString(3, type); + prep.setString(4, message); + prep.setString(5, email); + prep.setString(6, host); + prep.setDate(7, new java.sql.Date(created.getTime())); + prep.setString(8, "new"); + + prep.execute(); + } finally { + try { + if (conn != null) conn.close(); + } catch (Exception e) { + // swallow + } + } + } + + /** + * Get all feedbacks + * @return + */ + @Override + public List getAllFeedbacks() { + List feedbacks = new ArrayList(); + + try { + Connection conn = DriverManager.getConnection(MAGE_JDBC_URL_FEEDBACK_DB); + try { + Statement stat = conn.createStatement(); + ResultSet rs = stat.executeQuery(QUERY_GET_ALL_FEEDBACKS); + while (rs.next()) { + Feedback feedback = new Feedback(); + + feedback.setUsername(rs.getString(1)); + feedback.setTitle(rs.getString(2)); + feedback.setType(rs.getString(3)); + feedback.setMessage(rs.getString(4)); + feedback.setEmail(rs.getString(5)); + feedback.setHost(rs.getString(6)); + feedback.setCreatedDate(rs.getDate(7)); + feedback.setStatus(rs.getString(8)); + + feedbacks.add(feedback); + } + rs.close(); + } finally { + try { + if (conn != null) conn.close(); + } catch (Exception e) { + // swallow + } + } + } catch (SQLException e) { + log.fatal("SQL Exception: ", e); + } + + return feedbacks; + } + /** * Inits database. Creates tables if they don't exist. * @@ -128,6 +218,22 @@ public enum EntityManager implements Storage { } } + protected static void initFeedbackDB() throws Exception { + Class.forName("org.sqlite.JDBC"); + checkDBFolderExistance(); + Connection conn = DriverManager.getConnection(MAGE_JDBC_URL_FEEDBACK_DB); + try { + Statement stat = conn.createStatement(); + stat.executeUpdate("create table if not exists feedbacks (username, title, type, message, email, host, created_dt, status);"); + } finally { + try { + conn.close(); + } catch (Exception e) { + // swallow + } + } + } + /** * Reinits database. Drops all tables and then creates them from scratch. * BE CAREFUL! THIS METHOD WILL DESTROY ALL DATA. diff --git a/Mage.Common/src/mage/db/EntityManagerTest.java b/Mage.Common/src/mage/db/EntityManagerTest.java index 613ac98a09..5b74b09ff2 100644 --- a/Mage.Common/src/mage/db/EntityManagerTest.java +++ b/Mage.Common/src/mage/db/EntityManagerTest.java @@ -1,5 +1,6 @@ package mage.db; +import mage.db.model.Feedback; import mage.db.model.Log; import java.text.DateFormat; @@ -29,5 +30,14 @@ public class EntityManagerTest { System.out.println("]"); System.out.println(" --------------"); } + + System.out.println("********************************"); + + List feedbackList = EntityManager.instance.getAllFeedbacks(); + System.out.println("feedbacks found: " + feedbackList.size()); + for (Feedback feedback : feedbackList) { + System.out.println(feedback.toString()); + System.out.println("--------------"); + } } } diff --git a/Mage.Common/src/mage/db/Storage.java b/Mage.Common/src/mage/db/Storage.java index a309587046..f4c4dc8255 100644 --- a/Mage.Common/src/mage/db/Storage.java +++ b/Mage.Common/src/mage/db/Storage.java @@ -1,14 +1,18 @@ package mage.db; +import mage.db.model.Feedback; import mage.db.model.Log; import java.util.Date; import java.util.List; /** - * + * Storage interface for saving and fetching entities. + * @author noxx */ public interface Storage { void insertLog(String key, Date date, String... args) throws Exception; List getAllLogs(); + void insertFeedback(String username, String title, String type, String message, String email, String host, java.util.Date created) throws Exception; + List getAllFeedbacks(); } diff --git a/Mage.Common/src/mage/db/model/Feedback.java b/Mage.Common/src/mage/db/model/Feedback.java new file mode 100644 index 0000000000..3f84353c49 --- /dev/null +++ b/Mage.Common/src/mage/db/model/Feedback.java @@ -0,0 +1,102 @@ +package mage.db.model; + +import java.util.Date; + +/** + * Feedback entity. + * + * @author noxx + */ +public class Feedback { + + private String username; + private String title; + private String type; + private String message; + private String email; + private String host; + + private Date createdDate; + + private String status; + + public Feedback() { + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public Date getCreatedDate() { + return createdDate; + } + + public void setCreatedDate(Date createdDate) { + this.createdDate = createdDate; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + String msg = message != null && message.length() > 5 ? message.substring(0, 5) : message; + sb.append("Feedback [username=").append(username) + .append(", host=").append(host) + .append(", title=").append(title) + .append(", type=").append(type) + .append(", message=").append(msg) + .append("...]"); + return sb.toString(); + } +} diff --git a/Mage.Common/src/mage/interfaces/MageServer.java b/Mage.Common/src/mage/interfaces/MageServer.java index 3dd9c192e6..dcdc922888 100644 --- a/Mage.Common/src/mage/interfaces/MageServer.java +++ b/Mage.Common/src/mage/interfaces/MageServer.java @@ -125,4 +125,7 @@ public interface MageServer { // messages of the day public Object getServerMessagesCompressed(String sessionId) throws MageException; + + // feedback + public void sendFeedbackMessage(String sessionId, String username, String title, String type, String message, String email) throws MageException; } diff --git a/Mage.Common/src/mage/remote/Session.java b/Mage.Common/src/mage/remote/Session.java index 82c8edaf1d..3b1657484b 100644 --- a/Mage.Common/src/mage/remote/Session.java +++ b/Mage.Common/src/mage/remote/Session.java @@ -252,6 +252,18 @@ public class Session { client.showError("Network error. You have been disconnected"); } + public synchronized boolean sendFeedback(String title, String type, String message, String email) { + if (isConnected()) { + try { + server.sendFeedbackMessage(sessionId, connection.getUsername(), title, type, message, email); + return true; + } catch (MageException e) { + logger.error(e); + } + } + return false; + } + class CallbackHandler implements InvokerCallbackHandler { @Override public void handleCallback(Callback callback) throws HandleCallbackException { diff --git a/Mage.Server/src/main/java/mage/server/MageServerImpl.java b/Mage.Server/src/main/java/mage/server/MageServerImpl.java index f08665dd8a..f5acdcacc7 100644 --- a/Mage.Server/src/main/java/mage/server/MageServerImpl.java +++ b/Mage.Server/src/main/java/mage/server/MageServerImpl.java @@ -42,6 +42,7 @@ import mage.remote.MageVersionException; import mage.server.draft.DraftManager; import mage.server.game.*; import mage.server.services.LogKeys; +import mage.server.services.impl.FeedbackServiceImpl; import mage.server.services.impl.LogServiceImpl; import mage.server.tournament.TournamentFactory; import mage.server.tournament.TournamentManager; @@ -61,7 +62,7 @@ import java.util.concurrent.ExecutorService; /** * - * @author BetaSteward_at_googlemail.com + * @author BetaSteward_at_googlemail.com, noxx */ public class MageServerImpl implements MageServer { @@ -707,6 +708,19 @@ public class MageServerImpl implements MageServer { }); } + @Override + public void sendFeedbackMessage(final String sessionId, final String username, final String title, final String type, final String message, final String email) throws MageException { + if (title != null && message != null) { + execute("sendFeedbackMessage", sessionId, new Action() { + public void execute() { + String host = SessionManager.getInstance().getSession(sessionId).getHost(); + FeedbackServiceImpl.instance.feedback(username, title, type, message, email, host); + LogServiceImpl.instance.log(LogKeys.KEY_FEEDBACK_ADDED, sessionId, username, host); + } + }); + } + } + public void sendBroadcastMessage(final String sessionId, final String message) throws MageException { if (message != null) { execute("sendBroadcastMessage", sessionId, new Action() { diff --git a/Mage.Server/src/main/java/mage/server/services/FeedbackService.java b/Mage.Server/src/main/java/mage/server/services/FeedbackService.java new file mode 100644 index 0000000000..c3fe97a0ad --- /dev/null +++ b/Mage.Server/src/main/java/mage/server/services/FeedbackService.java @@ -0,0 +1,14 @@ +package mage.server.services; + +/** + * Responsible for gathering feedback from users and storing them in DB. + * + * @author noxx + */ +public interface FeedbackService { + + /** + * Saves feedback. + */ + void feedback(String username, String title, String type, String message, String email, String host); +} diff --git a/Mage.Server/src/main/java/mage/server/services/LogKeys.java b/Mage.Server/src/main/java/mage/server/services/LogKeys.java index 6626f48ed4..a45b5703c4 100644 --- a/Mage.Server/src/main/java/mage/server/services/LogKeys.java +++ b/Mage.Server/src/main/java/mage/server/services/LogKeys.java @@ -28,4 +28,6 @@ public interface LogKeys { public static final String KEY_WRONG_VERSION = "wrongVersion"; public static final String KEY_NOT_ADMIN = "notAdminRestrictedOperation"; + + public static final String KEY_FEEDBACK_ADDED = "feedbackAdded"; } diff --git a/Mage.Server/src/main/java/mage/server/services/impl/FeedbackServiceImpl.java b/Mage.Server/src/main/java/mage/server/services/impl/FeedbackServiceImpl.java new file mode 100644 index 0000000000..1f26af508f --- /dev/null +++ b/Mage.Server/src/main/java/mage/server/services/impl/FeedbackServiceImpl.java @@ -0,0 +1,26 @@ +package mage.server.services.impl; + +import mage.db.EntityManager; +import mage.server.services.FeedbackService; +import org.apache.log4j.Logger; + +import java.util.Calendar; + +/** + * @author noxx + */ +public enum FeedbackServiceImpl implements FeedbackService { + instance; + + private static Logger log = Logger.getLogger(FeedbackServiceImpl.class); + + @Override + public void feedback(String username, String title, String type, String message, String email, String host) { + Calendar cal = Calendar.getInstance(); + try { + EntityManager.instance.insertFeedback(username, title, type, message, email, host, cal.getTime()); + } catch (Exception e) { + log.fatal(e); + } + } +}