2 * jSite - a tool for uploading websites into Freenet
3 * Copyright (C) 2006 David Roden
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
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.
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.
20 package de.todesbaum.jsite.main;
22 import java.awt.event.ActionEvent;
23 import java.awt.event.ActionListener;
24 import java.io.IOException;
25 import java.text.MessageFormat;
26 import java.util.HashMap;
27 import java.util.Locale;
30 import java.util.Map.Entry;
32 import javax.swing.AbstractAction;
33 import javax.swing.Action;
34 import javax.swing.ButtonGroup;
35 import javax.swing.Icon;
36 import javax.swing.JList;
37 import javax.swing.JMenu;
38 import javax.swing.JMenuBar;
39 import javax.swing.JOptionPane;
40 import javax.swing.JPanel;
41 import javax.swing.JRadioButtonMenuItem;
42 import javax.swing.event.ListSelectionEvent;
43 import javax.swing.event.ListSelectionListener;
45 import de.todesbaum.jsite.application.FileOption;
46 import de.todesbaum.jsite.application.Freenet7Interface;
47 import de.todesbaum.jsite.application.Node;
48 import de.todesbaum.jsite.application.Project;
49 import de.todesbaum.jsite.gui.NodeManagerListener;
50 import de.todesbaum.jsite.gui.NodeManagerPage;
51 import de.todesbaum.jsite.gui.ProjectFilesPage;
52 import de.todesbaum.jsite.gui.ProjectInsertPage;
53 import de.todesbaum.jsite.gui.ProjectPage;
54 import de.todesbaum.jsite.i18n.I18n;
55 import de.todesbaum.util.image.IconLoader;
56 import de.todesbaum.util.swing.TWizard;
57 import de.todesbaum.util.swing.TWizardPage;
58 import de.todesbaum.util.swing.WizardListener;
61 * @author <a href="mailto:droden@gmail.com">David Roden </a>
64 public class Main implements ActionListener, ListSelectionListener, WizardListener, NodeManagerListener {
66 private static boolean debug = false;
67 private Configuration configuration;
68 private Freenet7Interface freenetInterface = new Freenet7Interface();
69 protected Icon jSiteIcon;
71 private static enum PageType {
72 PAGE_NODE_MANAGER, PAGE_PROJECTS, PAGE_PROJECT_FILES, PAGE_INSERT_PROJECT
75 private static final Locale[] SUPPORTED_LOCALES = new Locale[] { Locale.ENGLISH, Locale.GERMAN, Locale.FRENCH };
76 private Map<Locale, Action> languageActions = new HashMap<Locale, Action>();
77 private Action manageNodeAction;
78 private Action aboutAction;
79 protected TWizard wizard;
80 protected JMenu nodeMenu;
81 private Node selectedNode;
82 private final Map<PageType, TWizardPage> pages = new HashMap<PageType, TWizardPage>();
88 private Main(String configFilename) {
89 if (configFilename != null) {
90 configuration = new Configuration(configFilename);
92 configuration = new Configuration();
94 Locale.setDefault(configuration.getLocale());
95 I18n.setLocale(configuration.getLocale());
96 if (!configuration.createLockFile()) {
97 JOptionPane.showMessageDialog(null, I18n.getMessage("jsite.main.already-running"), null, JOptionPane.ERROR_MESSAGE);
100 wizard = new TWizard();
102 wizard.setJMenuBar(createMenuBar());
103 wizard.setPreviousName(I18n.getMessage("jsite.wizard.previous"));
104 wizard.setNextName(I18n.getMessage("jsite.wizard.next"));
105 wizard.setQuitName(I18n.getMessage("jsite.wizard.quit"));
106 wizard.setPreviousEnabled(false);
107 wizard.setNextEnabled(true);
108 wizard.addWizardListener(this);
109 jSiteIcon = IconLoader.loadIcon("/jsite-icon.png");
110 wizard.setIcon(jSiteIcon);
113 showPage(PageType.PAGE_PROJECTS);
114 wizard.setPreviousName((String) manageNodeAction.getValue(Action.NAME));
117 private void createActions() {
118 for (final Locale locale: SUPPORTED_LOCALES) {
119 languageActions.put(locale, new AbstractAction(I18n.getMessage("jsite.menu.language." + locale.getLanguage())) {
121 public void actionPerformed(ActionEvent actionEvent) {
122 switchLanguage(locale);
126 manageNodeAction = new AbstractAction(I18n.getMessage("jsite.menu.nodes.manage-nodes")) {
127 public void actionPerformed(ActionEvent actionEvent) {
128 showPage(PageType.PAGE_NODE_MANAGER);
129 wizard.setPreviousName(I18n.getMessage("jsite.wizard.previous"));
130 wizard.setNextName(I18n.getMessage("jsite.wizard.next"));
133 aboutAction = new AbstractAction(I18n.getMessage("jsite.menu.help.about")) {
135 public void actionPerformed(ActionEvent e) {
136 JOptionPane.showMessageDialog(wizard, MessageFormat.format(I18n.getMessage("jsite.about.message"), Version.getVersion()), null, JOptionPane.INFORMATION_MESSAGE, jSiteIcon);
141 private JMenuBar createMenuBar() {
142 JMenuBar menuBar = new JMenuBar();
143 JMenu languageMenu = new JMenu(I18n.getMessage("jsite.menu.languages"));
144 menuBar.add(languageMenu);
145 ButtonGroup languageButtonGroup = new ButtonGroup();
146 for (Locale locale: SUPPORTED_LOCALES) {
147 Action languageAction = languageActions.get(locale);
148 JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem(languageActions.get(locale));
149 if (locale.equals(Locale.getDefault())) {
150 menuItem.setSelected(true);
152 languageAction.putValue("menuItem", menuItem);
153 languageButtonGroup.add(menuItem);
154 languageMenu.add(menuItem);
156 nodeMenu = new JMenu(I18n.getMessage("jsite.menu.nodes"));
157 menuBar.add(nodeMenu);
158 selectedNode = configuration.getSelectedNode();
159 nodesUpdated(configuration.getNodes());
161 /* evil hack to right-align the help menu */
162 JPanel panel = new JPanel();
163 panel.setOpaque(false);
166 JMenu helpMenu = new JMenu(I18n.getMessage("jsite.menu.help"));
167 menuBar.add(helpMenu);
168 helpMenu.add(aboutAction);
172 private void initPages() {
173 NodeManagerPage nodeManagerPage = new NodeManagerPage();
174 nodeManagerPage.setName("page.node-manager");
175 nodeManagerPage.addNodeManagerListener(this);
176 nodeManagerPage.setNodes(configuration.getNodes());
177 pages.put(PageType.PAGE_NODE_MANAGER, nodeManagerPage);
179 ProjectPage projectPage = new ProjectPage();
180 projectPage.setName("page.project");
181 projectPage.setProjects(configuration.getProjects());
182 projectPage.setFreenetInterface(freenetInterface);
183 projectPage.addListSelectionListener(this);
184 pages.put(PageType.PAGE_PROJECTS, projectPage);
186 ProjectFilesPage projectFilesPage = new ProjectFilesPage();
187 projectFilesPage.setName("page.project.files");
188 pages.put(PageType.PAGE_PROJECT_FILES, projectFilesPage);
190 ProjectInsertPage projectInsertPage = new ProjectInsertPage();
191 projectInsertPage.setDebug(debug);
192 projectInsertPage.setName("page.project.insert");
193 projectInsertPage.setFreenetInterface(freenetInterface);
194 pages.put(PageType.PAGE_INSERT_PROJECT, projectInsertPage);
197 protected void showPage(PageType pageType) {
198 wizard.setPreviousEnabled(pageType.ordinal() > 0);
199 wizard.setNextEnabled(pageType.ordinal() < (pages.size() - 1));
200 wizard.setPage(pages.get(pageType));
201 wizard.setTitle(pages.get(pageType).getHeading() + " - jSite");
204 private boolean saveConfiguration() {
205 NodeManagerPage nodeManagerPage = (NodeManagerPage) pages.get(PageType.PAGE_NODE_MANAGER);
206 configuration.setNodes(nodeManagerPage.getNodes());
207 if (selectedNode != null) {
208 configuration.setSelectedNode(selectedNode);
211 ProjectPage projectPage = (ProjectPage) pages.get(PageType.PAGE_PROJECTS);
212 configuration.setProjects(projectPage.getProjects());
214 return configuration.save();
217 private Locale findSupportedLocale(Locale forLocale) {
218 for (Locale locale: SUPPORTED_LOCALES) {
219 if (locale.equals(forLocale)) {
223 for (Locale locale: SUPPORTED_LOCALES) {
224 if (locale.getCountry().equals(forLocale.getCountry()) && locale.getLanguage().equals(forLocale.getLanguage())) {
228 for (Locale locale: SUPPORTED_LOCALES) {
229 if (locale.getLanguage().equals(forLocale.getLanguage())) {
233 return SUPPORTED_LOCALES[0];
240 protected void switchLanguage(Locale locale) {
241 Locale supportedLocale = findSupportedLocale(locale);
242 Action languageAction = languageActions.get(supportedLocale);
243 JRadioButtonMenuItem menuItem = (JRadioButtonMenuItem) languageAction.getValue("menuItem");
244 menuItem.setSelected(true);
245 /* show the restart message in the other language! */
246 Locale currentLocale = I18n.getLocale();
247 I18n.setLocale(supportedLocale);
248 JOptionPane.showMessageDialog(wizard, I18n.getMessage("jsite.menu.language.change.restart-message"), null, JOptionPane.INFORMATION_MESSAGE);
249 I18n.setLocale(currentLocale);
250 configuration.setLocale(supportedLocale);
254 // INTERFACE ListSelectionListener
260 public void valueChanged(ListSelectionEvent e) {
261 JList list = (JList) e.getSource();
262 int selectedRow = list.getSelectedIndex();
263 wizard.setNextEnabled(selectedRow > -1);
267 // INTERFACE WizardListener
273 public void wizardNextPressed(TWizard wizard) {
274 String pageName = wizard.getPage().getName();
275 if ("page.node-manager".equals(pageName)) {
276 showPage(PageType.PAGE_PROJECTS);
277 wizard.setPreviousName((String) manageNodeAction.getValue(Action.NAME));
278 } else if ("page.project".equals(pageName)) {
279 ProjectPage projectPage = (ProjectPage) wizard.getPage();
280 Project project = projectPage.getSelectedProject();
281 if ((project.getLocalPath() == null) || (project.getLocalPath().trim().length() == 0)) {
282 JOptionPane.showMessageDialog(wizard, I18n.getMessage("jsite.project.warning.no-local-path"), null, JOptionPane.ERROR_MESSAGE);
285 if ((project.getPath() == null) || (project.getPath().trim().length() == 0)) {
286 JOptionPane.showMessageDialog(wizard, I18n.getMessage("jsite.project.warning.no-path"), null, JOptionPane.ERROR_MESSAGE);
289 ((ProjectFilesPage) pages.get(PageType.PAGE_PROJECT_FILES)).setProject(project);
290 ((ProjectInsertPage) pages.get(PageType.PAGE_INSERT_PROJECT)).setProject(project);
291 showPage(PageType.PAGE_PROJECT_FILES);
292 wizard.setNextName(I18n.getMessage("jsite.project-files.insert-now"));
293 wizard.setPreviousName(I18n.getMessage("jsite.wizard.previous"));
294 } else if ("page.project.files".equals(pageName)) {
295 ProjectPage projectPage = (ProjectPage) pages.get(PageType.PAGE_PROJECTS);
296 Project project = projectPage.getSelectedProject();
297 if (selectedNode == null) {
298 JOptionPane.showMessageDialog(wizard, I18n.getMessage("jsite.project-files.no-node-selected"), null, JOptionPane.ERROR_MESSAGE);
301 if (project.getIndexFile() == null) {
302 if (JOptionPane.showConfirmDialog(wizard, I18n.getMessage("jsite.project-files.empty-index"), null, JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE) != JOptionPane.OK_OPTION) {
306 if (!project.getFileOption(project.getIndexFile()).getContainer().equals("")) {
307 if (JOptionPane.showConfirmDialog(wizard, I18n.getMessage("jsite.project-files.container-index"), null, JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE) != JOptionPane.OK_OPTION) {
311 if (!project.getFileOption(project.getIndexFile()).getMimeType().equals("text/html")) {
312 if (JOptionPane.showConfirmDialog(wizard, I18n.getMessage("jsite.project-files.index-not-html"), null, JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE) != JOptionPane.OK_OPTION) {
316 Map<String, FileOption> fileOptions = project.getFileOptions();
317 Set<Entry<String, FileOption>> fileOptionEntries = fileOptions.entrySet();
318 for (Entry<String, FileOption> fileOptionEntry: fileOptionEntries) {
319 FileOption fileOption = fileOptionEntry.getValue();
320 if (!fileOption.isInsert() && ((fileOption.getCustomKey().length() == 0) || "CHK@".equals(fileOption.getCustomKey()))) {
321 JOptionPane.showMessageDialog(wizard, MessageFormat.format(I18n.getMessage("jsite.project-files.no-custom-key"), fileOptionEntry.getKey()), null, JOptionPane.ERROR_MESSAGE);
325 boolean nodeRunning = false;
327 nodeRunning = freenetInterface.isNodePresent();
328 } catch (IOException e) {
331 JOptionPane.showMessageDialog(wizard, I18n.getMessage("jsite.project-files.no-node-running"), null, JOptionPane.ERROR_MESSAGE);
334 configuration.save();
335 wizard.setNextName(I18n.getMessage("jsite.wizard.next"));
336 showPage(PageType.PAGE_INSERT_PROJECT);
337 nodeMenu.setEnabled(false);
338 } else if ("page.project.insert".equals(pageName)) {
339 showPage(PageType.PAGE_PROJECTS);
340 nodeMenu.setEnabled(true);
347 public void wizardPreviousPressed(TWizard wizard) {
348 String pageName = wizard.getPage().getName();
349 if ("page.project".equals(pageName)) {
350 showPage(PageType.PAGE_NODE_MANAGER);
351 wizard.setPreviousName(I18n.getMessage("jsite.wizard.previous"));
352 } else if ("page.project.files".equals(pageName)) {
353 showPage(PageType.PAGE_PROJECTS);
354 wizard.setNextName(I18n.getMessage("jsite.wizard.next"));
355 wizard.setPreviousName((String) manageNodeAction.getValue(Action.NAME));
356 } else if ("page.project.insert".equals(pageName)) {
357 showPage(PageType.PAGE_PROJECT_FILES);
364 public void wizardQuitPressed(TWizard wizard) {
365 if (JOptionPane.showConfirmDialog(wizard, I18n.getMessage("jsite.quit.question"), null, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) {
366 if (saveConfiguration()) {
369 if (JOptionPane.showConfirmDialog(wizard, I18n.getMessage("jsite.quit.config-not-saved"), null, JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.OK_OPTION) {
376 // INTERFACE NodeManagerListener
382 public void nodesUpdated(Node[] nodes) {
383 nodeMenu.removeAll();
384 ButtonGroup nodeButtonGroup = new ButtonGroup();
385 Node newSelectedNode = null;
386 for (Node node: nodes) {
387 JRadioButtonMenuItem nodeMenuItem = new JRadioButtonMenuItem(node.getName());
388 nodeMenuItem.putClientProperty("Node", node);
389 nodeMenuItem.addActionListener(this);
390 nodeButtonGroup.add(nodeMenuItem);
391 if (node.equals(selectedNode)) {
392 newSelectedNode = node;
393 nodeMenuItem.setSelected(true);
395 nodeMenu.add(nodeMenuItem);
397 nodeMenu.addSeparator();
398 nodeMenu.add(manageNodeAction);
399 selectedNode = newSelectedNode;
400 freenetInterface.setNode(selectedNode);
406 public void actionPerformed(ActionEvent e) {
407 Object source = e.getSource();
408 if (source instanceof JRadioButtonMenuItem) {
409 JRadioButtonMenuItem menuItem = (JRadioButtonMenuItem) source;
410 Node node = (Node) menuItem.getClientProperty("Node");
412 freenetInterface.setNode(selectedNode);
419 public static void main(String[] args) {
420 String configFilename = null;
421 boolean nextIsConfigFilename = false;
422 for (String argument: args) {
423 if (nextIsConfigFilename) {
424 configFilename = argument;
425 nextIsConfigFilename = false;
427 if ("--help".equals(argument)) {
430 } else if ("--debug".equals(argument)) {
432 } else if ("--config-file".equals(argument)) {
433 nextIsConfigFilename = true;
436 if (nextIsConfigFilename) {
437 System.out.println("--config-file needs parameter!");
440 new Main(configFilename);
443 private static void printHelp() {
444 System.out.println("--help\tshows this cruft");
445 System.out.println("--debug\tenables some debug output");
446 System.out.println("--config-file <file>\tuse specified configuration file");