View Javadoc

1   /*
2    *  XNap - A P2P framework and client.
3    *
4    *  See the file AUTHORS for copyright information.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation.
9    *
10   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.
14   *
15   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  
20  package org.xnap.gui;
21  
22  import java.awt.Component;
23  import java.awt.GridBagLayout;
24  import java.io.BufferedReader;
25  import java.io.IOException;
26  import java.io.InputStreamReader;
27  import java.io.PrintWriter;
28  import java.net.HttpURLConnection;
29  import java.net.URL;
30  import java.net.URLEncoder;
31  import java.util.Locale;
32  import java.util.Properties;
33  
34  import javax.swing.Action;
35  import javax.swing.Icon;
36  import javax.swing.JLabel;
37  import javax.swing.JOptionPane;
38  import javax.swing.JScrollPane;
39  import javax.swing.JTextArea;
40  import javax.swing.JTextField;
41  import javax.swing.SwingUtilities;
42  import javax.swing.border.EmptyBorder;
43  
44  import org.apache.log4j.Logger;
45  import org.xnap.XNap;
46  import org.xnap.gui.component.DefaultWizardDialog;
47  import org.xnap.gui.util.GUIHelper;
48  import org.xnap.gui.util.GridBagHelper;
49  import org.xnap.gui.util.IconHelper;
50  import org.xnap.loader.XNapClassLoader;
51  import org.xnap.net.NetHelper;
52  import org.xnap.plugin.PluginManager;
53  
54  /***
55   * The feedback dialog.
56   */
57  public class FeedbackWizardDialog extends DefaultWizardDialog
58  {
59  
60      //--- Constant(s) ---
61  
62      //--- Data field(s) ---
63  
64  	protected static Logger logger 
65  		= Logger.getLogger(FeedbackWizardDialog.class);
66      private static FeedbackWizardDialog me = null;
67  
68  	private FeedbackPanel feedbackPanel;
69  
70      //--- Constructor(s) ---
71  
72      private FeedbackWizardDialog() 
73      {
74  		super(BUTTON_CANCEL);
75  
76  		feedbackPanel = new FeedbackPanel();
77  
78  		addPanel(new IntroPanel());
79  		addPanel(feedbackPanel);
80  
81  		getFinishAction().putValue(Action.NAME, XNap.tr("Send"));
82  		getFinishAction().putValue
83  			(Action.SHORT_DESCRIPTION, 
84  			 XNap.tr("Sends your feedback to the XNap team. :-)"));
85  
86          pack();
87      }
88  
89      //--- Method(s) ---
90  
91  	public void close()
92  	{
93  		dispose();
94  		me = null;
95  	}
96  
97  	public void finish()
98  	{
99  		feedbackPanel.send();
100 	}
101 
102     public static String getSystemInfo(boolean includeClasspath)
103     {
104 		Properties p = System.getProperties();
105 		StringBuffer sb = new StringBuffer();
106 		sb.append("XNap ");
107 		sb.append(PluginManager.getCoreVersion());
108 		sb.append(" (");
109 		sb.append(Locale.getDefault());
110 		sb.append(")\nOS : ");
111 		sb.append(p.get("os.name"));
112 		sb.append(" ");
113 		sb.append(p.get("os.version"));
114 		sb.append(" (");
115 		sb.append(p.get("os.arch"));
116 		sb.append(")\nJRE: ");
117 		sb.append(p.get("java.vendor"));
118 		sb.append(" ");
119 		sb.append(p.get("java.version"));
120 		sb.append("\n");
121 		if (includeClasspath) {
122 			sb.append("Class-Path: ");
123 			try {
124 				sb.append(XNapClassLoader.getURLsAsString());
125 			}
126 			catch (Exception e) {
127 				// might occur with older base releases (< 3.0-beta6)
128 				// that do provide getURLsAsString()
129 			}
130 			sb.append("\n");
131 		}
132 		return sb.toString();
133     }
134 
135     public static String getSystemInfo()
136     {
137     	return getSystemInfo(true);
138     }
139     
140     public static void showDialog(Component c)
141     {
142 		if (me == null) {
143 			me = new FeedbackWizardDialog();
144 		}
145 		me.show(c);
146     }
147 
148 	private class IntroPanel extends AbstractSettingsPanel
149 	{
150 
151 		public IntroPanel()
152 		{
153 			setLayout(new GridBagLayout());
154 
155 			GridBagHelper.add(this, new JLabel(GUIHelper.label
156 				(XNap.tr("There are several ways of contacting us:<br><br>First of all check, the <b>Frequently Asked Questions</b> (available from the help menu). For <b>bug reports</b> or <b>feature requests</b> please use the respective <b>trackers</b> on our homepage at http://xnap.org.<br><br>If you just want to praise us for developing XNap or if you want to verbally punish us for releasing such blatant crap to the public or if just want to tell us something else, select Next to advance to the feedback form. Please enter your email address if you think it might be necessary for us to ask further questions or if you would like a reply in general. Please also note that we might not be able to answer in a timely manner or even answer at all due to time constraints.<br><br>Visit <b>http://xnap.org/contact.html</b> for more detailed information."))));
157 		}
158 
159 		public void apply()
160 		{
161 		}
162 			
163 		public String getDescription()
164 		{
165 			return XNap.tr("Feedback is very important to us. Please read the following notes to make sure it is delivered to the right entity.");
166 		}
167 		
168 		public Icon getIcon()
169 		{
170 			return IconHelper.getWizardIcon("message2.png");
171 		}
172 
173 		public String getTitle()
174 		{
175 			return XNap.tr("Send Feedback");
176 		}
177 
178 	}
179 
180 	private class FeedbackPanel extends AbstractSettingsPanel
181 	{
182 
183 		private JTextField jtName;
184 		private JTextField jtEmail;
185 		private JTextField jtSubject;
186 		private JTextArea jtaText;
187 
188 		public FeedbackPanel()
189 		{
190 			// text
191 			setLayout(new GridBagLayout());
192 
193 			GridBagHelper.addLabel(this, XNap.tr("Subject"));
194 			jtSubject = new JTextField(20);
195 			GridBagHelper.add(this, jtSubject);
196 			
197 			GridBagHelper.addLabel(this, XNap.tr("Feedback"));
198 			jtaText = new JTextArea(getSystemInfo(), 12, 40);
199 			//jtaText = new CompletableTextArea(getSystemInfo(), 12, 40);
200 			jtaText.setLineWrap(true);
201 			jtaText.setWrapStyleWord(true);
202 			jtaText.setEditable (true);
203 			jtaText.setBorder(new EmptyBorder(5, 5, 5, 5));
204 			JScrollPane jspText = new JScrollPane(jtaText);
205 			GridBagHelper.addPanel(this, jspText);
206 			
207 			GridBagHelper.addLabel(this, XNap.tr("Your Name"));
208 			jtName = new JTextField(20);
209 			GridBagHelper.add(this, jtName);
210 			
211 			GridBagHelper.addLabel(this, XNap.tr("Your Email"));
212 			jtEmail = new JTextField(20);
213 			GridBagHelper.add(this, jtEmail);
214 			
215 			if (prefs.getRememberFeedback()) {
216 				jtEmail.setText(prefs.getFeedbackEmail());
217 				jtName.setText(prefs.getFeedbackName());
218 			}
219 		}
220 
221 		public void apply()
222 		{
223 			// the sending is done in the FeedbackWizardDialog.close()
224 		}
225 
226 		public boolean send()
227 		{
228 			if (jtaText.getText().trim().length() == 0
229 				|| jtaText.getText().equals(getSystemInfo())) {
230 				JOptionPane.showMessageDialog
231 					(FeedbackWizardDialog.this,
232 					 XNap.tr("Cowardly refusing to send empty or unmodified feedback."),
233 					 XNap.tr("Send Feedback"), JOptionPane.ERROR_MESSAGE);
234 				return false;
235 			}
236 
237 			if (jtEmail.getText().trim().length() == 0) {
238 				Object[] message = new Object[] {
239 					XNap.tr("You did not provide an Email address. "),
240 					XNap.tr("We will not be able to answer. "),
241 					XNap.tr("Really send feedback?")
242 				};
243 				int response = JOptionPane.showConfirmDialog
244 					(FeedbackWizardDialog.this, message, 
245 					 XNap.tr("Send Feedback"), 
246 					 JOptionPane.YES_NO_OPTION);
247 
248 				if (response == JOptionPane.NO_OPTION) {
249 					return false;
250 				}
251 			}
252 
253 			getFinishAction().setEnabled(false);
254 			getCancelAction().setEnabled(false);
255 
256 			setTitle(XNap.tr("Sending feedback") + "...");
257 	
258 			Thread t = new Thread(new SendWorker(), "SendFeedback");
259 			t.start();
260 
261 			return true;
262 		}
263 			
264 		public String getDescription()
265 		{
266 			return XNap.tr("Your feedback will be posted to a mailing list that is public to all XNap developers. As this list is hosted at SourceForge it maybe visible to others. We understand English, German and some French.");
267 		}
268 		
269 		public Icon getIcon()
270 		{
271 			return IconHelper.getWizardIcon("kwrite.png");
272 		}
273 
274 		public String getTitle()
275 		{
276 			return XNap.tr("Enter Feedback");
277 		}
278 
279 		private class SendWorker implements Runnable
280 		{
281 			
282 			private String encode(String s)
283 			{
284 				return (s != null) ? URLEncoder.encode(s.trim()) : "";
285 			}
286 			
287 			public void run()
288 			{
289 				// FIX: all getText() calls need to be Swing synchronized
290 
291 				if (prefs.getRememberFeedback()) {
292 					prefs.setFeedbackEmail(jtEmail.getText());
293 					prefs.setFeedbackName(jtName.getText());
294 				}
295 
296 				StringBuffer sb = new StringBuffer();
297 				sb.append("&noresponse=1");
298 				sb.append("&from=" + encode(jtEmail.getText().trim()));
299 				sb.append("&subject=" + encode(jtSubject.getText()));
300 				sb.append("&name=" + encode(jtName.getText().trim()));
301 				sb.append("&message=" + encode(jtaText.getText().trim()));
302 
303 				try {
304 					logger.info("transmitting feedback");
305 					URL url=new URL(prefs.getFeeedbackURL());
306 					HttpURLConnection conn = (HttpURLConnection)(url.openConnection());
307 					conn.setDoOutput(true);
308 					conn.setDoInput(true);
309 					conn.setRequestMethod("POST");
310 					conn.setUseCaches(false);
311 					conn.setAllowUserInteraction(false);
312 
313 					PrintWriter out=new PrintWriter(conn.getOutputStream());
314 					out.println(sb);
315 					out.flush();
316 					out.close();
317 
318 					BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
319 		
320 					String s;
321 					while ((s = in.readLine())!=null) {
322 						logger.debug(s);
323 					}
324 		
325 					in.close();
326 					conn.disconnect();
327 
328 				}
329 				catch(final IOException e) {
330 					logger.info("transmitting feedback failed");
331 					Runnable runner = new Runnable()
332 						{
333 							public void run()
334 							{
335 								failed(NetHelper.getErrorMessage(e));
336 							}
337 						};
338 					SwingUtilities.invokeLater(runner);
339 					return;
340 				}
341 
342 				Runnable runner = new Runnable()
343 					{
344 						public void run()
345 						{
346 							JOptionPane.showMessageDialog
347 								(FeedbackWizardDialog.this, 
348 								 XNap.tr("Thank you."),
349 								 XNap.tr("Feedback"), 
350 								 JOptionPane.INFORMATION_MESSAGE);
351 							close();
352 						}
353 					};
354 				SwingUtilities.invokeLater(runner);
355 			}
356 
357 			public void failed(String response)
358 			{
359 				JOptionPane.showMessageDialog
360 					(FeedbackWizardDialog.this, 
361 					 XNap.tr("Could not send feedback: {0}.", response),
362 					 XNap.tr("Feedback"), 
363 					 JOptionPane.ERROR_MESSAGE);
364 			
365 				setTitle(XNap.tr("Feedback"));
366 
367 				getFinishAction().setEnabled(true);
368 				getCancelAction().setEnabled(true);
369 			}
370 		}
371 	}
372 
373 }