From ec7238716569602420f80f8eafc1c5238cf19d7c Mon Sep 17 00:00:00 2001 From: orbiter Date: Thu, 5 Aug 2010 10:43:03 +0000 Subject: [PATCH] added a very early test version of a YaCy gui component. The gui currently does nothing else than providing a search window that sends the search string to the browser The gui is started when YaCy is started with the option -g or --gui, like ./startYACY.sh -g The gui will primary be used to provide a 'real' macintosh version that can be started and operated like any other macintosh application. A special mac application wrapper will follow. git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@7021 6c8d7289-2bf4-0310-a012-ef5d649a1542 --- source/de/anomic/search/Switchboard.java | 1 + source/net/yacy/gui/InfoPage.java | 135 ++++++++++ source/net/yacy/gui/YaCyApp.java | 150 +++++++++++ .../net/yacy/gui/framework/Application.java | 88 +++++++ source/net/yacy/gui/framework/Browser.java | 156 ++++++++++++ source/net/yacy/gui/framework/Layout.java | 36 +++ source/net/yacy/gui/framework/Operation.java | 30 +++ .../net/yacy/gui/framework/Switchboard.java | 239 ++++++++++++++++++ source/net/yacy/yacy.java | 25 +- startYACY.command | 2 +- startYACY.sh | 11 +- 11 files changed, 864 insertions(+), 9 deletions(-) create mode 100644 source/net/yacy/gui/InfoPage.java create mode 100644 source/net/yacy/gui/YaCyApp.java create mode 100644 source/net/yacy/gui/framework/Application.java create mode 100644 source/net/yacy/gui/framework/Browser.java create mode 100644 source/net/yacy/gui/framework/Layout.java create mode 100644 source/net/yacy/gui/framework/Operation.java create mode 100644 source/net/yacy/gui/framework/Switchboard.java diff --git a/source/de/anomic/search/Switchboard.java b/source/de/anomic/search/Switchboard.java index 93c419de1..f64b46331 100644 --- a/source/de/anomic/search/Switchboard.java +++ b/source/de/anomic/search/Switchboard.java @@ -1148,6 +1148,7 @@ public final class Switchboard extends serverSwitch { log.logConfig("SWITCHBOARD SHUTDOWN STEP 1: sending termination signal to managed threads:"); MemoryTracker.stopSystemProfiling(); terminateAllThreads(true); + net.yacy.gui.framework.Switchboard.shutdown(); log.logConfig("SWITCHBOARD SHUTDOWN STEP 2: sending termination signal to threaded indexing"); // closing all still running db importer jobs indexingDocumentProcessor.announceShutdown(); diff --git a/source/net/yacy/gui/InfoPage.java b/source/net/yacy/gui/InfoPage.java new file mode 100644 index 000000000..5299ff561 --- /dev/null +++ b/source/net/yacy/gui/InfoPage.java @@ -0,0 +1,135 @@ +/** + * InfoPage + * Copyright 2010 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany + * First released 05.08.2010 at http://yacy.net + * + * $LastChangedDate: 2010-06-16 17:11:21 +0200 (Mi, 16 Jun 2010) $ + * $LastChangedRevision: 6922 $ + * $LastChangedBy: orbiter $ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program in the file lgpl21.txt + * If not, see . + */ + +package net.yacy.gui; + +import java.awt.Color; +import java.awt.Font; +import java.awt.LayoutManager; +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.ActionMap; +import javax.swing.BorderFactory; +import javax.swing.GroupLayout; +import javax.swing.InputMap; +import javax.swing.JComponent; +import javax.swing.JEditorPane; +import javax.swing.JScrollPane; +import javax.swing.JTextField; +import javax.swing.KeyStroke; +import javax.swing.event.DocumentListener; +import javax.swing.text.JTextComponent; + +import net.yacy.gui.framework.Browser; +import net.yacy.gui.framework.Layout; +import net.yacy.gui.framework.Switchboard; + +public class InfoPage implements Layout { + + private static final String COMMIT_ACTION = "commit"; + + private static final int width = 500; + private static final int height = 600; + private static final int textHeight = 18; + + final String host; + final int port; + JTextComponent SearchBox; + + public InfoPage(String host, int port) { + this.host = host; this.port = port; + } + + + private class CommitAction extends AbstractAction { + private static final long serialVersionUID = 3630229455629476865L; + public void actionPerformed(ActionEvent ev) { + //int pos = SearchBox.getSelectionEnd(); + Browser.openBrowser("http://" + host + ":" + port + "/yacysearch.html?display=0&verify=true&contentdom=text&nav=all&maximumRecords=10&startRecord=0&resource=global&urlmaskfilter=.*&prefermaskfilter=&indexof=off&meanCount=5&query=" + SearchBox.getText().replace(' ', '+')); + SearchBox.setText(""); + //SearchBox..insert(" ", pos); + //SearchBox.setCaretPosition(pos + 1); + } + } + + public LayoutManager getPage(JComponent context, DocumentListener listener) { + GroupLayout page = new GroupLayout(context); + + //String[] fnames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); + //for (String fname: fnames) System.out.println("font: " + fname); + + Font font = Font.decode("SansSerif"); + if (font != null) font = font.deriveFont((float) 14.0); + //if (font != null) font = font.deriveFont(Font.BOLD); + + SearchBox = new JTextField(); + SearchBox.setText("search..."); + SearchBox.setCaretPosition(0); + SearchBox.moveCaretPosition(9); + SearchBox.setFont(font.deriveFont((float) 14.0).deriveFont(Font.BOLD)); + SearchBox.setSize(width + 4, textHeight); + SearchBox.setBorder(BorderFactory.createEmptyBorder()); + SearchBox.setBackground(Color.decode("#EEEEDD")); + SearchBox.getDocument().addDocumentListener(listener); + InputMap im = SearchBox.getInputMap(); + ActionMap am = SearchBox.getActionMap(); + im.put(KeyStroke.getKeyStroke("ENTER"), COMMIT_ACTION); + am.put(COMMIT_ACTION, new CommitAction()); + + Switchboard.InfoBox = new JTextField(); + Switchboard.InfoBox.setBorder(BorderFactory.createTitledBorder("")); + Switchboard.InfoBox.setSize(width, textHeight); + Switchboard.InfoBox.setBorder(BorderFactory.createEmptyBorder()); + Switchboard.InfoBox.setBackground(Color.decode("#EEEEDD")); + Switchboard.InfoBox.setText("search window initialized"); + Switchboard.InfoBox.setFont(font.deriveFont((float) 11.0)); + + // make the scroll pane that contains the search result + JComponent mainText = new JEditorPane(); + mainText.setPreferredSize(new java.awt.Dimension(480, 590)); + ((JEditorPane) mainText).setText("This is a very early test for a YaCy search gui.\nYou may enter a search term and press enter."); + //page.add(new splashCanvas()); + + //SplashScreen splash = SplashScreen.getSplashScreen(); + //Graphics2D g2 = splash.createGraphics(); + //splash.update(); + + JScrollPane pane = new JScrollPane(); + pane.setViewportView(mainText); + + // combine search box and scroll pane + page.setVerticalGroup(page.createSequentialGroup() + .addComponent(SearchBox, GroupLayout.PREFERRED_SIZE, textHeight + 4, GroupLayout.PREFERRED_SIZE) + .addComponent(pane, 0, height, Short.MAX_VALUE) // height + .addComponent(Switchboard.InfoBox, GroupLayout.PREFERRED_SIZE, textHeight, GroupLayout.PREFERRED_SIZE) + ); + page.setHorizontalGroup(page.createSequentialGroup() + .addGroup(page.createParallelGroup() + .addComponent(SearchBox, GroupLayout.Alignment.LEADING, 0, width, Short.MAX_VALUE) // width + .addComponent(pane, GroupLayout.Alignment.LEADING, 0, width, Short.MAX_VALUE) + .addComponent(Switchboard.InfoBox, GroupLayout.Alignment.TRAILING, 0, width, Short.MAX_VALUE))); + return page; + } +} diff --git a/source/net/yacy/gui/YaCyApp.java b/source/net/yacy/gui/YaCyApp.java new file mode 100644 index 000000000..0f0e23e05 --- /dev/null +++ b/source/net/yacy/gui/YaCyApp.java @@ -0,0 +1,150 @@ +/** + * YaCyApp + * Copyright 2010 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany + * First released 05.08.2010 at http://yacy.net + * + * $LastChangedDate: 2010-06-16 17:11:21 +0200 (Mi, 16 Jun 2010) $ + * $LastChangedRevision: 6922 $ + * $LastChangedBy: orbiter $ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program in the file lgpl21.txt + * If not, see . + */ + +package net.yacy.gui; + +import java.awt.Canvas; +import java.awt.Graphics; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.image.BufferedImage; +import java.awt.image.ImageObserver; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import javax.imageio.ImageIO; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +import net.yacy.gui.framework.Application; +import net.yacy.gui.framework.Operation; +import net.yacy.gui.framework.Switchboard; + +import org.apache.log4j.Logger; + +public class YaCyApp { + + public static Logger log = Logger.getLogger(YaCyApp.class); + private static JFrame app; + private static Operation operation; + private static BufferedImage splashImg = null; + private static File splashFile = null; + static { + try { + javax.swing.UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + if (splashFile != null) splashImg = ImageIO.read(splashFile); + } catch(Exception e) { + e.printStackTrace(); + } + } + + public class splashCanvas extends Canvas { + private static final long serialVersionUID = -8823028472678019008L; + ImageObserver obs; + public splashCanvas(ImageObserver obs) { this.obs = obs; } + public void paint(Graphics g) { + if (splashImg != null) g.drawImage(splashImg, 0, 0, obs); + } + } + + public static class Op implements Operation { + + JFrame app; + final String host; + final int port; + + public Op(JFrame app, String host, int port) { + this.app = app; + this.host = host; + this.port = port; + } + + public void closeAndExit() { + if (app != null) app.setVisible(false); // fake closing + //Browser.openBrowser("http://" + host + ":" + port + "/Steering.html?shutdown="); + de.anomic.search.Switchboard.getSwitchboard().terminate(100, "shutdown request from gui"); + Switchboard.shutdown(); + //System.exit(0); + } + } + + public static void start(String host, int port) { + + Switchboard.startInfoUpdater(); + operation = new Op(app, host, port); + + final List menues = new ArrayList(); + + // the file menu + JMenu FileMenu = new JMenu("File"); + JMenuItem OpenItem = new JMenuItem("Open"); + OpenItem.setEnabled(false); + JMenuItem QuitItem = new JMenuItem("Quit"); + QuitItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + operation.closeAndExit(); + } + }); + FileMenu.add(OpenItem); + FileMenu.add(QuitItem); + menues.add(FileMenu); + + // the edit menu + JMenu EditMenu = new JMenu("Edit"); + JMenuItem CutItem = new JMenuItem("Cut"); + CutItem.setEnabled(false); + JMenuItem CopyItem = new JMenuItem("Copy"); + CopyItem.setEnabled(false); + JMenuItem PasteItem = new JMenuItem("Paste"); + PasteItem.setEnabled(false); + EditMenu.add(CutItem); + EditMenu.add(CopyItem); + EditMenu.add(PasteItem); + menues.add(EditMenu); + + // registering shutdown hook + log.info("Registering Shutdown Hook"); + Switchboard.addShutdownHook(Thread.currentThread()); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + app = new Application("YaCy GUI", operation, menues, new InfoPage("localhost", 8080)); + app.setLocationRelativeTo(null); + app.setVisible(true); + } + }); + } + + public static void main(String[] args) { + + if (args.length > 0) Switchboard.load(new File(args[0])); + start("localhost", 8080); + + } + +} \ No newline at end of file diff --git a/source/net/yacy/gui/framework/Application.java b/source/net/yacy/gui/framework/Application.java new file mode 100644 index 000000000..e2ed2f29e --- /dev/null +++ b/source/net/yacy/gui/framework/Application.java @@ -0,0 +1,88 @@ +/** + * Application + * Copyright 2010 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany + * First released 05.08.2010 at http://yacy.net + * + * $LastChangedDate: 2010-06-16 17:11:21 +0200 (Mi, 16 Jun 2010) $ + * $LastChangedRevision: 6922 $ + * $LastChangedBy: orbiter $ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program in the file lgpl21.txt + * If not, see . + */ + +package net.yacy.gui.framework; + +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.List; + +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; + +import javax.swing.WindowConstants; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + + +public class Application extends JFrame implements DocumentListener { + + private static final long serialVersionUID = 1753502658600073141L; + + public Application(String windowName, final Operation operation, List menues, Layout pageprovider) { + super(windowName); + + try { + getContentPane().setLayout(pageprovider.getPage((JComponent) getContentPane(), this)); + + this.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + operation.closeAndExit(); + } + }); + this.addWindowStateListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + operation.closeAndExit(); + } + }); + + setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + + // make menus + JMenuBar mainMenu = new JMenuBar(); + setJMenuBar(mainMenu); + for (JMenu menu: menues) mainMenu.add(menu); + + pack(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void insertUpdate(DocumentEvent e) { + + } + + public void removeUpdate(DocumentEvent e) { + + } + + public void changedUpdate(DocumentEvent e) { + + } + + +} \ No newline at end of file diff --git a/source/net/yacy/gui/framework/Browser.java b/source/net/yacy/gui/framework/Browser.java new file mode 100644 index 000000000..7302efac8 --- /dev/null +++ b/source/net/yacy/gui/framework/Browser.java @@ -0,0 +1,156 @@ +/** + * Browser + * Copyright 2010 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany + * First released 05.08.2010 at http://yacy.net + * + * $LastChangedDate: 2010-06-16 17:11:21 +0200 (Mi, 16 Jun 2010) $ + * $LastChangedRevision: 6922 $ + * $LastChangedBy: orbiter $ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program in the file lgpl21.txt + * If not, see . + */ + +package net.yacy.gui.framework; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.reflect.Method; +import java.util.Properties; + +import net.yacy.kelondro.logging.Log; + +public class Browser { + + // constants for system identification + public static final int systemMacOSC = 0; // 'classic' Mac OS 7.6.1/8.*/9.* + public static final int systemMacOSX = 1; // all Mac OS X + public static final int systemUnix = 2; // all Unix/Linux type systems + public static final int systemWindows = 3; // all Windows 95/98/NT/2K/XP + public static final int systemUnknown = -1; // any other system + + // constants for file type identification (Mac only) + public static final String blankTypeString = "____"; + + // system-identification statics + public static final int systemOS; + public static final boolean isMacArchitecture; + public static final boolean isUnixFS; + public static final boolean canExecUnix; + public static final boolean isWindows; + public static final boolean isWin32; + + // calculated system constants + public static int maxPathLength = 65535; + + // Macintosh-specific statics + private static Class macMRJFileUtils = null; + private static Method macOpenURL = null; + + // static initialization + static { + // check operation system type + final Properties sysprop = System.getProperties(); + final String sysname = sysprop.getProperty("os.name","").toLowerCase(); + if (sysname.startsWith("mac os x")) systemOS = systemMacOSX; + else if (sysname.startsWith("mac os")) systemOS = systemMacOSC; + else if (sysname.startsWith("windows")) systemOS = systemWindows; + else if ((sysname.startsWith("linux")) || (sysname.startsWith("unix"))) systemOS = systemUnix; + else systemOS = systemUnknown; + + isMacArchitecture = ((systemOS == systemMacOSC) || (systemOS == systemMacOSX)); + isUnixFS = ((systemOS == systemMacOSX) || (systemOS == systemUnix)); + canExecUnix = ((isUnixFS) || (!((systemOS == systemMacOSC) || (systemOS == systemWindows)))); + isWindows = (systemOS == systemWindows); + isWin32 = (isWindows && System.getProperty("os.arch", "").contains("x86")); + + // set up the MRJ Methods through reflection + if (isMacArchitecture) try { + macMRJFileUtils = Class.forName("com.apple.mrj.MRJFileUtils"); + macOpenURL = macMRJFileUtils.getMethod("openURL", new Class[] {Class.forName("java.lang.String")}); + final byte[] nullb = new byte[4]; + for (int i = 0; i < 4; i++) nullb[i] = 0; + } catch (final Exception e) { + //Log.logException(e); + macMRJFileUtils = null; + } + + // set up maximum path length according to system + if (isWindows) maxPathLength = 255; else maxPathLength = 65535; + } + + + public static void openBrowser(final String url) { + openBrowser(url, "firefox"); + } + + public static void openBrowser(final String url, final String app) { + try { + String cmd; + Process p; + if (systemOS != systemUnknown) { + if (systemOS == systemMacOSC) { + if ((isMacArchitecture) && (macMRJFileUtils != null)) { + macOpenURL.invoke(null, new Object[] {url}); + } + } else if (systemOS == systemMacOSX) { + p = Runtime.getRuntime().exec(new String[] {"/usr/bin/osascript", "-e", "open location \"" + url + "\""}); + p.waitFor(); + if (p.exitValue() != 0) throw new RuntimeException("EXEC ERROR: " + errorResponse(p)); + } else if (systemOS == systemUnix) { + cmd = app + " -remote openURL(" + url + ")"; + p = Runtime.getRuntime().exec(cmd); + p.waitFor(); + if (p.exitValue() != 0) { + cmd = app + " " + url; + p = Runtime.getRuntime().exec(cmd); + // no error checking, because it blocks until firefox is closed + } + } else if (systemOS == systemWindows) { + // see forum at http://forum.java.sun.com/thread.jsp?forum=57&thread=233364&message=838441 + if (System.getProperty("os.name").contains("2000")) cmd = "rundll32 url.dll,FileProtocolHandler " + url; + else cmd = "rundll32 url.dll,FileProtocolHandler \"" + url + "\""; + //cmd = "cmd.exe /c start javascript:document.location='" + url + "'"; + p = Runtime.getRuntime().exec(cmd); + p.waitFor(); + if (p.exitValue() != 0) throw new RuntimeException("EXEC ERROR: " + errorResponse(p)); + } + } + } catch (final Exception e) { + System.err.println("ERROR "+ e.getClass() +" in openBrowser(): "+ e.getMessage()); + // browser could not be started automatically, tell user to do it + System.out.println("please start your browser and open the following location: " + url); + } + } + + private static String errorResponse(final Process p) { + final BufferedReader err = new BufferedReader(new InputStreamReader(p.getErrorStream())); + String line, error = ""; + try { + while ((line = err.readLine()) != null) { + error = line + "\n"; + } + return error; + } catch (final IOException e) { + return null; + } finally { + try { + err.close(); + } catch (IOException e) { + Log.logException(e); + } + } + } +} diff --git a/source/net/yacy/gui/framework/Layout.java b/source/net/yacy/gui/framework/Layout.java new file mode 100644 index 000000000..4e77c4268 --- /dev/null +++ b/source/net/yacy/gui/framework/Layout.java @@ -0,0 +1,36 @@ +/** + * Layout + * Copyright 2010 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany + * First released 05.08.2010 at http://yacy.net + * + * $LastChangedDate: 2010-06-16 17:11:21 +0200 (Mi, 16 Jun 2010) $ + * $LastChangedRevision: 6922 $ + * $LastChangedBy: orbiter $ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program in the file lgpl21.txt + * If not, see . + */ + +package net.yacy.gui.framework; + +import java.awt.LayoutManager; + +import javax.swing.JComponent; +import javax.swing.event.DocumentListener; + +public interface Layout { + + public LayoutManager getPage(JComponent context, DocumentListener listener); + +} diff --git a/source/net/yacy/gui/framework/Operation.java b/source/net/yacy/gui/framework/Operation.java new file mode 100644 index 000000000..b54fc9be0 --- /dev/null +++ b/source/net/yacy/gui/framework/Operation.java @@ -0,0 +1,30 @@ +/** + * Operation + * Copyright 2010 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany + * First released 05.08.2010 at http://yacy.net + * + * $LastChangedDate: 2010-06-16 17:11:21 +0200 (Mi, 16 Jun 2010) $ + * $LastChangedRevision: 6922 $ + * $LastChangedBy: orbiter $ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program in the file lgpl21.txt + * If not, see . + */ + +package net.yacy.gui.framework; + +public interface Operation { + + public void closeAndExit(); +} diff --git a/source/net/yacy/gui/framework/Switchboard.java b/source/net/yacy/gui/framework/Switchboard.java new file mode 100644 index 000000000..8842c2d42 --- /dev/null +++ b/source/net/yacy/gui/framework/Switchboard.java @@ -0,0 +1,239 @@ +/** + * Switchboard + * Copyright 2010 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany + * First released 05.08.2010 at http://yacy.net + * + * $LastChangedDate: 2010-06-16 17:11:21 +0200 (Mi, 16 Jun 2010) $ + * $LastChangedRevision: 6922 $ + * $LastChangedBy: orbiter $ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program in the file lgpl21.txt + * If not, see . + */ + +package net.yacy.gui.framework; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Properties; + +import javax.swing.text.JTextComponent; + +import org.apache.log4j.Logger; + + + +/** + * a static class that holds application-wide parameters + * very useful because global settings need not be passed + * to all classes and methods + * + * @author m.christen + * + */ +public class Switchboard { + + /** + * the shallrun variable is used + * by all application parts to see if they must terminate + */ + private static boolean shallrun = true; + + /** + * a global properties object + */ + private static Properties properties = new Properties(); + + public static Logger log = Logger.getLogger(Switchboard.class); + + + public static void startInfoUpdater() { + new InfoUpdater(2000).start(); + } + + public static void addShutdownHook(Thread mainThread) { + // registering shutdown hook + final Runtime run = Runtime.getRuntime(); + run.addShutdownHook(new shutdownHookThread(mainThread)); + } + + public static JTextComponent InfoBox = null; + private static String InfoBoxMessage = ""; + private static long InfoBoxMessageUntil = 0; + + public static void info(String infoString, long infoTime) { + InfoBoxMessage = infoString; + InfoBoxMessageUntil = System.currentTimeMillis() + infoTime; + } + + public static class InfoUpdater extends Thread { + long steptime; + public InfoUpdater(long steptime) { + this.steptime = steptime; + } + public void run() { + while (shallrun) { + if (InfoBox != null) { + if (System.currentTimeMillis() < InfoBoxMessageUntil) { + InfoBox.setText(InfoBoxMessage); + } + } + try {Thread.sleep(steptime);} catch (InterruptedException e) {} + } + } + } + + /** + * This class is a helper class whose instance is started, when the java virtual + * machine shuts down. Signals the plasmaSwitchboard to shut down. + */ + public static class shutdownHookThread extends Thread { + private final Thread mainThread; + + public shutdownHookThread(final Thread mainThread) { + super(); + this.mainThread = mainThread; + } + + public void run() { + try { + if (shallrun()) { + log.info("Shutdown via shutdown hook."); + + // send a shutdown signal to the switchboard + log.info("Signaling shutdown to the switchboard."); + shutdown(); + + // waiting for the main thread to finish execution + log.info("Waiting for main thread to finish."); + if (this.mainThread != null && this.mainThread.isAlive()) { + this.mainThread.join(); + } + } + } catch (final Exception e) { + log.info("Unexpected error. " + e.getClass().getName(),e); + } + } + } + + /** + * test if the application shall run + * @return true if the application shall run + */ + public static boolean shallrun() { + return shallrun; + } + + /** + * set a termination signal. + * this is not reversible. + */ + public static void shutdown() { + shallrun = false; + } + + /** + * initialize the properties with the content of a file + * @param propFile + */ + public static void load(File propFile) { + try { + properties.load(new FileInputStream(propFile)); + } catch (FileNotFoundException e1) { + log.info("error: file dispatcher.properties does not exist. Exit"); + System.exit(-1); + } catch (IOException e1) { + log.info("error: file dispatcher.properties cannot be readed. Exit"); + System.exit(-1); + } + } + + /** + * access to the properties object + * @param key + * @return the property value or null if the property does not exist + */ + public static String get(String key) { + return properties.getProperty(key); + } + + /** + * access to the properties object + * @param key + * @param dflt + * @return + */ + public static String get(String key, String dflt) { + return properties.getProperty(key, dflt); + } + + /** + * convenience access to integer values in properties + * @param key + * @param dflt + * @return + */ + public static int getInt(String key, int dflt) { + if (!properties.containsKey(key)) return dflt; + return Integer.parseInt(properties.getProperty(key)); + } + + /** + * convenience access to boolean values in properties + * @param key + * @param dflt + * @return + */ + public static boolean getBool(String key, boolean dflt) { + if (!properties.containsKey(key)) return dflt; + String s = properties.getProperty(key); + return s.equals("true") || s.equals("1"); + } + + public static File getFile(String key) { + String s = properties.getProperty(key); + if (s == null) return null; + s.replace("/", File.separator); + return new File(s); + } + + /** + * set a property + * @param key + * @param value + */ + public static void set(String key, String value) { + properties.setProperty(key, value); + } + + /** + * convenience method to set a integer property + * @param key + * @param value + */ + public static void set(String key, int value) { + properties.setProperty(key, Integer.toString(value)); + } + + /** + * convenience method to set a boolean property + * @param key + * @param value + */ + public static void set(String key, boolean value) { + properties.setProperty(key, (value) ? "true" : "false"); + } +} \ No newline at end of file diff --git a/source/net/yacy/yacy.java b/source/net/yacy/yacy.java index 79005080f..b29d1a0e9 100644 --- a/source/net/yacy/yacy.java +++ b/source/net/yacy/yacy.java @@ -46,6 +46,7 @@ import java.util.concurrent.Semaphore; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import net.yacy.gui.YaCyApp; import net.yacy.kelondro.blob.MapDataMining; import net.yacy.kelondro.data.meta.DigestURI; import net.yacy.kelondro.data.meta.URIMetadataRow; @@ -154,7 +155,7 @@ public final class yacy { * @param homePath Root-path where all information is to be found. * @param startupFree free memory at startup time, to be used later for statistics */ - private static void startup(final File homePath, final long startupMemFree, final long startupMemTotal) { + private static void startup(final File homePath, final long startupMemFree, final long startupMemTotal, boolean gui) { try { // start up System.out.println(copyright); @@ -225,19 +226,22 @@ public final class yacy { sb.setConfig("memoryFreeAfterStartup", startupMemFree); sb.setConfig("memoryTotalAfterStartup", startupMemTotal); + // start gui if wanted + if (gui) YaCyApp.start("localhost", (int) sb.getConfigLong("port", 8080)); + // hardcoded, forced, temporary value-migration sb.setConfig("htTemplatePath", "htroot/env/templates"); int oldRev; - try { + try { oldRev = Integer.parseInt(sb.getConfig("svnRevision", "0")); } catch (NumberFormatException e) { oldRev = 0; - } + } int newRev = Integer.parseInt(yacyBuildProperties.getSVNRevision()); sb.setConfig("svnRevision", yacyBuildProperties.getSVNRevision()); - // TODO: remove! + // TODO: remove! //sb.setConfig("version", Double.toString(version)); //sb.setConfig("vString", yacyVersion.combined2prettyVersion(Double.toString(version))); //sb.setConfig("vdate", (vDATE.startsWith("@")) ? DateFormatter.formatShortDay() : vDATE); @@ -959,7 +963,11 @@ public final class yacy { final long startupMemTotal = MemoryControl.total(); // go into headless awt mode - System.setProperty("java.awt.headless", "true"); + if (args.length >= 1 && args[0].toLowerCase().equals("-gui")) { + System.setProperty("java.awt.headless", "false"); + } else { + System.setProperty("java.awt.headless", "true"); + } File applicationRoot = new File(System.getProperty("user.dir").replace('\\', '/')); //System.out.println("args.length=" + args.length); @@ -967,7 +975,10 @@ public final class yacy { if ((args.length >= 1) && ((args[0].toLowerCase().equals("-startup")) || (args[0].equals("-start")))) { // normal start-up of yacy if (args.length == 2) applicationRoot= new File(args[1]); - startup(applicationRoot, startupMemFree, startupMemTotal); + startup(applicationRoot, startupMemFree, startupMemTotal, false); + } else if (args.length >= 1 && args[0].toLowerCase().equals("-gui")) { + // start-up of yacy with gui + startup(applicationRoot, startupMemFree, startupMemTotal, true); } else if ((args.length >= 1) && ((args[0].toLowerCase().equals("-shutdown")) || (args[0].equals("-stop")))) { // normal shutdown of yacy if (args.length == 2) applicationRoot= new File(args[1]); @@ -1023,7 +1034,7 @@ public final class yacy { RWIHashList(applicationRoot, outfile, domain, format); } else { if (args.length == 1) applicationRoot= new File(args[0]); - startup(applicationRoot, startupMemFree, startupMemTotal); + startup(applicationRoot, startupMemFree, startupMemTotal, false); } } } diff --git a/startYACY.command b/startYACY.command index 26725d5be..81ef3d690 100755 --- a/startYACY.command +++ b/startYACY.command @@ -1,5 +1,5 @@ cd `dirname $0` -./startYACY.sh & +./startYACY.sh --gui & echo "****************** YaCy Web Crawler/Indexer & Search Engine *******************" echo "**** (C) by Michael Peter Christen, usage granted under the GPL Version 2 ****" echo "**** USE AT YOUR OWN RISK! Project home and releases: http://yacy.net/ ****" diff --git a/startYACY.sh b/startYACY.sh index 4cf678967..54f351537 100755 --- a/startYACY.sh +++ b/startYACY.sh @@ -44,13 +44,14 @@ Options -l, --logging save the output of YaCy to yacy.log -d, --debug show the output of YaCy on the console -p, --print-out only print the command, which would be executed to start YaCy + -g, --gui start a gui for YaCy USAGE } #startup YaCy cd "`dirname $0`" -options="`getopt -n YaCy -o h,d,l,p,t -l help,debug,logging,print-out,tail-log -- $@`" +options="`getopt -n YaCy -o h,d,l,p,t,g -l help,debug,logging,print-out,tail-log,gui -- $@`" if [ $? -ne 0 ];then exit 1; fi @@ -62,6 +63,7 @@ LOGGING=0 DEBUG=0 PRINTONLY=0 TAILLOG=0 +GUI=0 for option in $options;do if [ $isparameter -ne 1 ];then #option case $option in @@ -93,6 +95,9 @@ for option in $options;do -t|--tail-log) TAILLOG=1 ;; + -g|--gui) + GUI=1 + ;; esac #case option else #parameter if [ x$option = "--" ];then #option / parameter separator @@ -172,6 +177,10 @@ for N in lib/*.jar; do CLASSPATH="$CLASSPATH$N:"; done CLASSPATH=".:htroot:$CLASSPATH" cmdline="$JAVA $JAVA_ARGS -Djava.awt.headless=true -classpath $CLASSPATH net.yacy.yacy"; +if [ $GUI -eq 1 ] #gui +then + cmdline="$cmdline -gui" +fi if [ $DEBUG -eq 1 ] #debug then cmdline=$cmdline