// BlogBridge -- RSS feed reader, manager, and web based service
// Copyright (C) 2002-2006 by R. Pito Salas
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software Foundation;
// either version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with this program;
// if not, write to the Free Software Foundation, Inc., 59 Temple Place,
// Suite 330, Boston, MA 02111-1307 USA
//
// Contact: R. Pito Salas
// mailto:pitosalas@users.sourceforge.net
// More information: about BlogBridge
// http://www.blogbridge.com
// http://sourceforge.net/projects/blogbridge
//
// $Id: OpenAboutDialogAction.java,v 1.23 2007/03/29 10:21:02 spyromus Exp $
//
package com.salas.bb.core.actions;
import com.jgoodies.uif.application.Application;
import com.jgoodies.uif.util.ResourceUtils;
import com.jgoodies.uifextras.convenience.DefaultAboutDialog;
import com.salas.bb.core.ApplicationLauncher;
import com.salas.bb.core.FeatureManager;
import com.salas.bb.core.GlobalController;
import com.salas.bb.core.GlobalModel;
import com.salas.bb.domain.prefs.UserPreferences;
import com.salas.bb.service.ServicePreferences;
import com.salas.bb.utils.BrowserLauncher;
import com.salas.bb.utils.Constants;
import com.salas.bb.utils.ResourceID;
import com.salas.bb.utils.i18n.Strings;
import javax.swing.*;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Pattern;
/**
* Action which opens About dialog.
*/
public final class OpenAboutDialogAction extends AbstractAction
{
private static final Pattern PATTERN_VERSION =
Pattern.compile("<version/?>", Pattern.CASE_INSENSITIVE);
private static final Pattern PATTERN_REG_STATUS =
Pattern.compile("<regstatus/?>", Pattern.CASE_INSENSITIVE);
private static final Pattern PATTERN_REG_NAME =
Pattern.compile("<regname/?>", Pattern.CASE_INSENSITIVE);
private static final Pattern PATTERN_REG_EMAIL =
Pattern.compile("<regemail/?>", Pattern.CASE_INSENSITIVE);
private static final Pattern PATTERN_PLAN_INFO =
Pattern.compile("<plan_info/?>", Pattern.CASE_INSENSITIVE);
private static final Pattern PATTERN_WORKING_FOLDER =
Pattern.compile("<working_folder/?>", Pattern.CASE_INSENSITIVE);
private static OpenAboutDialogAction instance;
private boolean initialized;
private JPanel panel;
private JEditorPane text;
private String html;
/**
* Hidden singleton constructor.
*/
private OpenAboutDialogAction()
{
initialized = false;
}
private void init()
{
panel = new JPanel();
panel.setLayout(new BorderLayout());
text = new JEditorPane();
text.setEditorKit(new HTMLEditorKit());
text.setEditable(false);
Dimension size = new Dimension(400, 300);
text.setMinimumSize(size);
text.setMaximumSize(size);
text.setPreferredSize(size);
final UserPreferences preferences = GlobalModel.SINGLETON.getUserPreferences();
text.addHyperlinkListener(new BrowserLauncher.LinkListener(preferences));
panel.add(new JScrollPane(text), BorderLayout.CENTER);
String tutS = ResourceUtils.getString(ResourceID.URL_ABOUT);
URL aboutTextURL = ResourceUtils.getURL(tutS);
// Prepare HTML. Substitute version number here because it cannot change during run.
html = readHtml(aboutTextURL);
String releaseType = ApplicationLauncher.getReleaseType();
String version = Application.getDescription().getVersion() +
(releaseType == null ? "" : " " + releaseType);
html = PATTERN_VERSION.matcher(html).replaceAll(version);
HTMLDocument doc = (HTMLDocument)text.getDocument();
doc.setBase(aboutTextURL);
}
private String readHtml(URL url)
{
String result;
try
{
Reader reader = new BufferedReader(new InputStreamReader(url.openStream()));
int ch;
StringBuffer buf = new StringBuffer();
while ((ch = reader.read()) != -1)
{
buf.append((char)ch);
}
result = buf.toString();
reader.close();
} catch (IOException e)
{
result = Strings.message("aboutdialog.data.is.unavailable");
}
return result;
}
/**
* Returns initialized instance.
*
* @return instance of action.
*/
public static synchronized OpenAboutDialogAction getInstance()
{
if (instance == null) instance = new OpenAboutDialogAction();
return instance;
}
/**
* Invoked when action occurs.
*
* @param e action event details object.
*/
public void actionPerformed(ActionEvent e)
{
// Once only initialization
if (!initialized) init();
// Fill in the current registration state info, since that can change from About command
// to About command.
String message = prepareText();
text.setText(message);
text.setCaretPosition(0);
new DefaultAboutDialog(GlobalController.SINGLETON.getMainFrame(), panel).open();
}
/**
* Substitutes registration status, name and email.
*
* @return resulting HTML.
*/
private String prepareText()
{
String result;
ServicePreferences servicePreferences = GlobalModel.SINGLETON.getServicePreferences();
String regStatus;
String regName = Constants.EMPTY_STRING;
String regEmail = Constants.EMPTY_STRING;
boolean registered = servicePreferences.isAccountInformationEntered();
if (registered)
{
regStatus = Strings.message("aboutdialog.registered");
regName = servicePreferences.getFullName();
regEmail = servicePreferences.getEmail();
} else
{
regStatus = Strings.message("aboutdialog.unregistered");
}
result = PATTERN_REG_STATUS.matcher(html).replaceAll(regStatus);
result = PATTERN_REG_NAME.matcher(result).replaceAll(regName);
result = PATTERN_REG_EMAIL.matcher(result).replaceAll(regEmail);
result = PATTERN_PLAN_INFO.matcher(result).replaceAll(getPlanInfo());
result = PATTERN_WORKING_FOLDER.matcher(result).replaceAll(getWorkingFolder());
return result;
}
/**
* Returns the working folder.
*
* @return folder.
*/
private String getWorkingFolder()
{
String p = ApplicationLauncher.getContextPath();
p = p.replaceAll("\\\\", "\\\\\\\\");
p = p.replaceAll("\\$", "\\\\$");
return p;
}
/**
* Prepares plan information for insertion.
* @return detailed plan info.
*/
private String getPlanInfo()
{
FeatureManager fm = GlobalController.SINGLETON.getFeatureManager();
String name = fm.getPlanName();
Date date = fm.getPlanExpirationDate();
float price = fm.getPlanPrice();
int period = fm.getPlanPeriodMonths();
boolean trial = fm.isPlanTrial();
String info = name;
if (date != null)
{
String dates = SimpleDateFormat.getDateInstance(SimpleDateFormat.SHORT).format(date);
if (trial)
{
info += " Trial (Expires: " + dates + ")";
} else if (price == 0)
{
info += " (Expires: " + dates + ")";
} else if (period != 0)
{
info += MessageFormat.format(" (Next Installment: {0}, \\${1} for the next {2} months)", dates,
new DecimalFormat("#.00", new DecimalFormatSymbols(Locale.US)).format(price), period);
}
}
return info;
}
}