|
From: <ls...@us...> - 2009-02-14 13:03:15
|
Revision: 5023
http://jnode.svn.sourceforge.net/jnode/?rev=5023&view=rev
Author: lsantha
Date: 2009-02-14 11:43:39 +0000 (Sat, 14 Feb 2009)
Log Message:
-----------
Plugin list editor. (initial commit)
Added Paths:
-----------
trunk/builder/src/builder/org/jnode/pluginlist/
trunk/builder/src/builder/org/jnode/pluginlist/Main.java
trunk/builder/src/builder/org/jnode/pluginlist/Plugin.java
trunk/builder/src/builder/org/jnode/pluginlist/PluginList.java
trunk/builder/src/builder/org/jnode/pluginlist/PluginListEditor.java
trunk/builder/src/builder/org/jnode/pluginlist/PluginListModel.java
trunk/builder/src/builder/org/jnode/pluginlist/PluginNode.java
trunk/builder/src/builder/org/jnode/pluginlist/PluginRepository.java
trunk/builder/src/builder/org/jnode/pluginlist/PluginTreePane.java
trunk/builder/src/builder/org/jnode/pluginlist/Project.java
trunk/builder/src/builder/org/jnode/pluginlist/ProjectNode.java
trunk/builder/src/builder/org/jnode/pluginlist/RootNode.java
trunk/builder/src/builder/org/jnode/pluginlist/Syncable.java
Added: trunk/builder/src/builder/org/jnode/pluginlist/Main.java
===================================================================
--- trunk/builder/src/builder/org/jnode/pluginlist/Main.java (rev 0)
+++ trunk/builder/src/builder/org/jnode/pluginlist/Main.java 2009-02-14 11:43:39 UTC (rev 5023)
@@ -0,0 +1,211 @@
+package org.jnode.pluginlist;
+
+import java.io.File;
+import java.io.Reader;
+import java.io.FileReader;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.util.Hashtable;
+import java.util.prefs.Preferences;
+import java.awt.Component;
+import org.jnode.nanoxml.XMLElement;
+import javax.swing.JFileChooser;
+
+public class Main {
+ private static Preferences prefs = Preferences.userNodeForPackage(Main.class);
+ private static File baseDir;
+ private static File pluginListFile;
+ private static PluginList pluginList;
+ private static PluginRepository pluginRepository;
+ private static PluginListEditor pluginListEditor;
+ private static boolean unsaved;
+
+ static File openDirectory(Component parent) throws Exception {
+ JFileChooser fc = new JFileChooser();
+ fc.setDialogType(JFileChooser.OPEN_DIALOG);
+ fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ fc.setDialogTitle("Select JNode project root directory");
+ if (JFileChooser.APPROVE_OPTION == fc.showOpenDialog(parent)) {
+ File ret = fc.getSelectedFile();
+ if (ret != null) {
+ prefs.put("jnode.base.dir", ret.getCanonicalPath());
+ return ret;
+ }
+ }
+ return null;
+ }
+
+ static File openFile(Component parent) throws Exception {
+ JFileChooser fc = new JFileChooser();
+ fc.setDialogType(JFileChooser.OPEN_DIALOG);
+ fc.setDialogTitle("Select JNode plugin list");
+ fc.setCurrentDirectory(baseDir);
+ if (JFileChooser.APPROVE_OPTION == fc.showOpenDialog(parent)) {
+ File ret = fc.getSelectedFile();
+ if (ret != null) {
+ prefs.put("jnode.pluginlist.file", ret.getCanonicalPath());
+ return ret;
+ }
+ }
+ return null;
+ }
+
+ static void save() throws Exception {
+ pluginList.setPlugins(pluginRepository.getSelectedPluginIds());
+ BufferedWriter bw = new BufferedWriter(new FileWriter(pluginListFile));
+ pluginList.write(bw);
+ bw.flush();
+ bw.close();
+ unsaved = false;
+ pluginListEditor.updateTitle(pluginListFile.getName());
+ }
+
+ static void saveAs(Component parent) throws Exception {
+ JFileChooser fc = new JFileChooser();
+ fc.setDialogType(JFileChooser.SAVE_DIALOG);
+ fc.setDialogTitle("Save JNode plugin list as");
+ fc.setCurrentDirectory(baseDir);
+ if (JFileChooser.APPROVE_OPTION == fc.showOpenDialog(parent)) {
+ File ret = fc.getSelectedFile();
+ if (ret != null) {
+ pluginListFile = ret;
+ prefs.put("jnode.pluginlist.file", pluginListFile.getCanonicalPath());
+ save();
+ pluginListEditor.updateTitle(pluginListFile.getName());
+ }
+ }
+ }
+
+ public static void main(String[] argv) throws Exception {
+ String str = prefs.get("jnode.base.dir", null);
+ if (str == null || !(baseDir = new File(str)).exists()) {
+ baseDir = openDirectory(null);
+ if (baseDir == null) {
+ System.exit(0);
+ }
+ }
+
+ str = prefs.get("jnode.pluginlist.file", null);
+ if (str == null || !(pluginListFile = new File(str)).exists()) {
+ pluginListFile = openFile(null);
+ if (pluginListFile == null) {
+ System.exit(0);
+ }
+ }
+
+ pluginList = new PluginList();
+ pluginList.read(new FileReader(pluginListFile));
+
+ pluginRepository = new PluginRepository();
+ pluginRepository.reload(pluginList);
+
+ pluginListEditor = new PluginListEditor(pluginRepository, pluginListFile.getName());
+ pluginListEditor.start();
+ }
+
+ static void reloadPluginList(File plf) throws Exception {
+ PluginList pl = new PluginList();
+ pl.read(new FileReader(plf));
+ pluginRepository.reselect(pl);
+ pluginListFile = plf;
+ pluginList = pl;
+ pluginListEditor.reload(pluginRepository);
+ pluginListEditor.updateTitle(plf.getName());
+ }
+
+ static void reloadRepository(File dir) throws Exception {
+ baseDir = dir;
+ PluginRepository pr = new PluginRepository();
+ pr.reload(pluginList);
+ pluginRepository = pr;
+ pluginListEditor.reload(pr);
+ }
+
+ public static Project readProject(String name, PluginRepository repo) throws Exception {
+ Project proj = new Project(name);
+
+ File pdir = new File(baseDir, name);
+ File ddir = new File(pdir, "descriptors");
+ for (File f : ddir.listFiles()) {
+ if (!f.getName().endsWith(".xml"))
+ continue;
+
+ Plugin pl = readPlugin(new BufferedReader(new FileReader(f)));
+ if (pl != null) {
+ if (pl.isSystem()) {
+ repo.addSystemPlugin(pl);
+ } else {
+ proj.addPlugin(pl);
+ }
+ } else {
+ //warning
+ }
+ }
+
+ return proj;
+ }
+
+
+ public static Plugin readPlugin(Reader in) throws Exception {
+
+ final XMLElement root = new XMLElement(new Hashtable(), true, false);
+ root.parseFromReader(in);
+ String rname = root.getName();
+ if (rname.equals("plugin") || rname.equals("fragment")) {
+ String id = (String) root.getAttribute("id");
+ if (id == null) {
+ throw new RuntimeException("Invalid plugin");
+ }
+ Plugin plug = new Plugin(id);
+ String system = (String) root.getAttribute("system");
+ if (system != null && "true".equals(system)) {
+ plug.setSystem();
+ }
+ for (XMLElement obj : root.getChildren()) {
+ String name = obj.getName();
+ if (name.equals("requires")) {
+ for (XMLElement ch : obj.getChildren()) {
+ String xname = ch.getName();
+ if (xname.equals("import")) {
+ String pid = (String) ch.getAttribute("plugin");
+ if (pid != null) {
+ plug.addRecuiredId(pid);
+ }
+ }
+ }
+ }
+ }
+ if (rname.equals("fragment")) {
+ String pid = (String) root.getAttribute("plugin-id");
+ if (pid == null) {
+ throw new RuntimeException("Invalid fragment");
+ }
+ plug.addRecuiredId(pid);
+ }
+ return plug;
+ }
+
+ return null;
+ }
+
+ static boolean isUnsaved() {
+ return unsaved;
+ }
+
+ static void setSaved() {
+ unsaved = false;
+ }
+
+ static void setUnsaved() {
+ if (!Main.unsaved) {
+ if (pluginListEditor != null) {
+ pluginListEditor.updateTitle(pluginListFile.getName() + " (modified)");
+ } else {
+ return;
+ }
+ }
+ Main.unsaved = true;
+ }
+}
+
Added: trunk/builder/src/builder/org/jnode/pluginlist/Plugin.java
===================================================================
--- trunk/builder/src/builder/org/jnode/pluginlist/Plugin.java (rev 0)
+++ trunk/builder/src/builder/org/jnode/pluginlist/Plugin.java 2009-02-14 11:43:39 UTC (rev 5023)
@@ -0,0 +1,101 @@
+package org.jnode.pluginlist;
+
+import java.util.Set;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ *
+ */
+class Plugin implements Comparable {
+ private String id;
+ private boolean system;
+ private Set<Plugin> required = new HashSet<Plugin>();
+ private Set<Plugin> used = new HashSet<Plugin>();
+ private Set<String> requiredId = new HashSet<String>();
+
+
+ public Plugin(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setRequired(Set<Plugin> required) {
+ this.required = required;
+ }
+
+ public Set<Plugin> getRequired() {
+ return required;
+ }
+
+ void addRecuiredId(String pid) {
+ requiredId.add(pid);
+ }
+
+ void resolve(PluginRepository m) {
+ List<String> sys = new ArrayList<String>();
+ for (String r : requiredId) {
+ Plugin plugin = m.getPlugin(r);
+ if (plugin == null)
+ throw new RuntimeException("Unknown plugin: " + r);
+
+ if (plugin.isSystem()) {
+ sys.add(r);
+ continue;
+ }
+
+ required.add(plugin);
+ plugin.used.add(this);
+ }
+
+ requiredId.removeAll(sys);
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ return this.id.compareTo(((Plugin) o).id);
+ }
+
+ @Override
+ public String toString() {
+ return id;
+ }
+
+ Set<Plugin> allRequired() {
+ Set<Plugin> req = new HashSet<Plugin>();
+ allRequired0(req);
+ return req;
+ }
+
+ private void allRequired0(Set<Plugin> req) {
+ for (Plugin p : required) {
+ req.add(p);
+ p.allRequired0(req);
+ }
+ }
+
+ Set<Plugin> allUsed() {
+ Set<Plugin> req = new HashSet<Plugin>();
+ allUsed0(req);
+ return req;
+ }
+
+ private void allUsed0(Set<Plugin> req) {
+ for (Plugin p : used) {
+ req.add(p);
+ p.allUsed0(req);
+ }
+ }
+
+ public boolean isSystem() {
+ return system;
+ }
+
+ public void setSystem() {
+ this.system = true;
+ }
+}
Added: trunk/builder/src/builder/org/jnode/pluginlist/PluginList.java
===================================================================
--- trunk/builder/src/builder/org/jnode/pluginlist/PluginList.java (rev 0)
+++ trunk/builder/src/builder/org/jnode/pluginlist/PluginList.java 2009-02-14 11:43:39 UTC (rev 5023)
@@ -0,0 +1,94 @@
+package org.jnode.pluginlist;
+
+import java.util.Properties;
+import java.util.Hashtable;
+import java.util.Set;
+import java.util.HashSet;
+import java.io.Reader;
+import java.io.Writer;
+import java.io.PrintWriter;
+import org.jnode.nanoxml.XMLElement;
+
+/**
+ *
+ */
+class PluginList {
+ private String name;
+ private Set<String> plugins = new HashSet<String>();
+ private Properties attributes = new Properties();
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Set<String> getPlugins() {
+ return plugins;
+ }
+
+ public void setPlugins(Set<String> plugins) {
+ this.plugins = plugins;
+ }
+
+ void read(Reader in) throws Exception {
+
+ final XMLElement root = new XMLElement(new Hashtable(), true, false);
+ root.parseFromReader(in);
+ String rname = root.getName();
+ if (rname.equals("plugin-list")) {
+ name = (String) root.getAttribute("name");
+ if (name == null) {
+ throw new RuntimeException("Invalid plugin list");
+ }
+
+ for (XMLElement obj : root.getChildren()) {
+ String name = obj.getName();
+ if (name.equals("manifest")) {
+ for (XMLElement ch : obj.getChildren()) {
+ String xname = ch.getName();
+ if (xname.equals("attribute")) {
+ String key = (String) ch.getAttribute("key");
+ String value = (String) ch.getAttribute("value");
+ if (key == null || value == null)
+ throw new RuntimeException("Invalid attribute in plugin list");
+ attributes.setProperty(key, value);
+ }
+ }
+ } else if (name.equals("plugin")) {
+ String plugin = (String) obj.getAttribute("id");
+ if (plugin == null)
+ throw new RuntimeException("Invalid plugin in plugin list");
+
+ plugins.add(plugin);
+ }
+ }
+ }
+ }
+
+ void write(Writer w) throws Exception {
+ PrintWriter pw = new PrintWriter(w);
+ pw.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ pw.println();
+ pw.println("<plugin-list name=\"" + name + "\">");
+ pw.print(" ");
+ pw.println("<manifest>");
+ for (Object key : attributes.keySet()) {
+ pw.print(" ");
+ pw.print(" ");
+ pw.println("<attribute key=\"" + key + "\" value=\"" + attributes.get(key) + "\"/>");
+ }
+ pw.print(" ");
+ pw.println("</manifest>");
+ pw.print(" ");
+ pw.println();
+ for (String p : plugins) {
+ pw.print(" ");
+ pw.println("<plugin id=\"" + p + "\"/>");
+ }
+ pw.println("</plugin-list>");
+ pw.flush();
+ }
+}
Added: trunk/builder/src/builder/org/jnode/pluginlist/PluginListEditor.java
===================================================================
--- trunk/builder/src/builder/org/jnode/pluginlist/PluginListEditor.java (rev 0)
+++ trunk/builder/src/builder/org/jnode/pluginlist/PluginListEditor.java 2009-02-14 11:43:39 UTC (rev 5023)
@@ -0,0 +1,274 @@
+package org.jnode.pluginlist;
+
+import javax.swing.JFrame;
+import javax.swing.JSplitPane;
+import javax.swing.JTree;
+import javax.swing.JOptionPane;
+import javax.swing.JMenuBar;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.tree.TreePath;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.TreeNode;
+import java.awt.BorderLayout;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.Set;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.io.File;
+
+/**
+ *
+ */
+class PluginListEditor {
+ private JFrame frame;
+ private PluginTreePane leftPane;
+ private PluginTreePane rightPane;
+ private JSplitPane splitPane;
+ private PluginRepository repository;
+
+ Set<Plugin> getSelectedPlugins(JTree tree) {
+ Set<Plugin> set = new HashSet<Plugin>();
+ final TreePath[] patha = tree.getSelectionPaths();
+ if (patha != null && patha.length > 0) {
+ for (TreePath path : patha) {
+ DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
+ Object object = node.getUserObject();
+ if ((object instanceof Plugin))
+ set.add((Plugin) object);
+ }
+ }
+
+ return set;
+ }
+
+ public PluginListEditor(PluginRepository pluginRepository, String fileName) {
+ repository = pluginRepository;
+ frame = new JFrame();
+ updateTitle(fileName);
+ splitPane = new JSplitPane();
+ splitPane.setResizeWeight(0.5);
+ frame.add(splitPane, BorderLayout.CENTER);
+ frame.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ saveOnExit();
+ }
+ });
+ leftPane = new PluginTreePane(repository.getAvailableModel());
+ leftPane.tree.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if (e.getClickCount() == 2) {
+ selectPlugin(getSelectedPlugins(leftPane.tree));
+ }
+ }
+ });
+ rightPane = new PluginTreePane(repository.getSelectedModel());
+ rightPane.tree.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if (e.getClickCount() == 2) {
+ deselectPlugin(getSelectedPlugins(rightPane.tree));
+ }
+ }
+ });
+ splitPane.setLeftComponent(leftPane);
+ splitPane.setRightComponent(rightPane);
+ JMenuBar mb = new JMenuBar();
+ frame.setJMenuBar(mb);
+ JMenu file = new JMenu("File");
+ mb.add(file);
+ JMenuItem save = new JMenuItem("Save");
+ file.add(save);
+ save.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ try {
+ Main.save();
+ } catch (Exception x) {
+ JOptionPane.showMessageDialog(frame, x.getMessage(), "Error saving file",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ });
+ JMenuItem saveAs = new JMenuItem("Save as...");
+ file.add(saveAs);
+ saveAs.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ try {
+ Main.saveAs(frame);
+ } catch (Exception x) {
+ JOptionPane.showMessageDialog(frame, x.getMessage(), "Error saving file",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ });
+ JMenuItem openFile = new JMenuItem("Open plugin list...");
+ file.add(openFile);
+ openFile.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ try {
+ File plf = Main.openFile(frame);
+ if (plf != null)
+ Main.reloadPluginList(plf);
+ } catch (Exception x) {
+ JOptionPane.showMessageDialog(frame, x.getMessage(), "Error opening plugin list",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ });
+ JMenuItem openDir = new JMenuItem("Set project directory...");
+ file.add(openDir);
+ openDir.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ try {
+ File dir = Main.openDirectory(frame);
+ if (dir != null)
+ Main.reloadRepository(dir);
+ } catch (Exception x) {
+ JOptionPane.showMessageDialog(frame, x.getMessage(), "Error selecting project directory",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ });
+ file.addSeparator();
+ JMenuItem exit = new JMenuItem("Exit");
+ file.add(exit);
+ exit.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ saveOnExit();
+ frame.setVisible(false);
+ frame.dispose();
+ }
+ });
+ }
+
+ void reload(PluginRepository repo) {
+ repository = repo;
+ leftPane.tree.setModel(new DefaultTreeModel(new RootNode(repository.getAvailableModel())));
+ rightPane.tree.setModel(new DefaultTreeModel(new RootNode(repository.getSelectedModel())));
+ }
+
+ private void saveOnExit() {
+ if (Main.isUnsaved()) {
+ if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(frame,
+ "The plugin list was modified. Save changes?", "Save changes?", JOptionPane.YES_NO_OPTION)) {
+ try {
+ Main.save();
+ } catch (Exception x) {
+ JOptionPane.showMessageDialog(frame, x.getMessage(), "Error saving file",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }
+ }
+
+ private void deselectPlugin(Set<Plugin> plugins) {
+ Set<Plugin> usedby = new HashSet<Plugin>();
+ for (Plugin p : plugins) {
+ for (Plugin u : p.allUsed())
+ if (repository.isSelected(u.getId()))
+ usedby.add(u);
+ }
+
+ if (!usedby.isEmpty()) {
+ StringBuilder sb = new StringBuilder("<html><b>The following plugins will be removed:</b><br/>");
+ for (Plugin p : usedby) {
+ sb.append(p.getId()).append("<br/>");
+ }
+ sb.append("</html>");
+ if (JOptionPane.YES_OPTION != JOptionPane.showConfirmDialog(splitPane, sb.toString()))
+ return;
+ }
+ Set<Plugin> moved = repository.deselect(plugins);
+
+ DefaultMutableTreeNode root = (DefaultMutableTreeNode) rightPane.tree.getModel().getRoot();
+ Enumeration en = root.breadthFirstEnumeration();
+ while (en.hasMoreElements()) {
+ DefaultMutableTreeNode nod = (DefaultMutableTreeNode) en.nextElement();
+ if (moved.contains(nod.getUserObject())) {
+ TreeNode node1 = nod.getParent();
+ if (node1 != null) {
+ ((Syncable) nod.getParent()).sync();
+ ((DefaultTreeModel) rightPane.tree.getModel()).reload(node1);
+ }
+ }
+ }
+
+ ((Syncable) ((DefaultTreeModel) leftPane.tree.getModel()).getRoot()).sync();
+ root = (DefaultMutableTreeNode) leftPane.tree.getModel().getRoot();
+ en = root.breadthFirstEnumeration();
+ while (en.hasMoreElements()) {
+ DefaultMutableTreeNode nod = (DefaultMutableTreeNode) en.nextElement();
+ if (moved.contains(nod.getUserObject())) {
+ ((DefaultTreeModel) leftPane.tree.getModel()).reload(nod.getParent());
+ }
+ }
+ }
+
+ private void selectPlugin(Set<Plugin> plugins) {
+ Set<Plugin> requires = new HashSet<Plugin>();
+ for (Plugin p : plugins) {
+ for (Plugin u : p.allRequired())
+ if (!repository.isSelected(u.getId()))
+ requires.add(u);
+ }
+
+ if (!requires.isEmpty()) {
+ StringBuilder sb = new StringBuilder("<html><b>The following plugins will be selected:</b><br/>");
+ for (Plugin p : requires) {
+ sb.append(p.getId()).append("<br/>");
+ }
+ sb.append("</html>");
+ if (JOptionPane.YES_OPTION != JOptionPane.showConfirmDialog(splitPane, sb.toString()))
+ return;
+ }
+ Set<Plugin> moved = repository.select(plugins);
+
+ DefaultMutableTreeNode root = (DefaultMutableTreeNode) leftPane.tree.getModel().getRoot();
+ Enumeration en = root.breadthFirstEnumeration();
+ while (en.hasMoreElements()) {
+ DefaultMutableTreeNode nod = (DefaultMutableTreeNode) en.nextElement();
+ if (moved.contains(nod.getUserObject())) {
+ TreeNode node1 = nod.getParent();
+ if (node1 != null) {
+ ((Syncable) nod.getParent()).sync();
+ ((DefaultTreeModel) leftPane.tree.getModel()).reload(node1);
+ }
+ }
+ }
+
+ ((Syncable) ((DefaultTreeModel) rightPane.tree.getModel()).getRoot()).sync();
+ root = (DefaultMutableTreeNode) rightPane.tree.getModel().getRoot();
+ en = root.breadthFirstEnumeration();
+ while (en.hasMoreElements()) {
+ DefaultMutableTreeNode nod = (DefaultMutableTreeNode) en.nextElement();
+ if (moved.contains(nod.getUserObject())) {
+ ((DefaultTreeModel) rightPane.tree.getModel()).reload(nod.getParent());
+ }
+ }
+ }
+
+ void start() {
+ frame.setSize(500, 500);
+ frame.setLocationRelativeTo(null);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.setVisible(true);
+ splitPane.setDividerLocation(0.5);
+ }
+
+ void updateTitle(String fileName) {
+ frame.setTitle("Plugin list editor: " + fileName);
+ }
+}
Added: trunk/builder/src/builder/org/jnode/pluginlist/PluginListModel.java
===================================================================
--- trunk/builder/src/builder/org/jnode/pluginlist/PluginListModel.java (rev 0)
+++ trunk/builder/src/builder/org/jnode/pluginlist/PluginListModel.java 2009-02-14 11:43:39 UTC (rev 5023)
@@ -0,0 +1,14 @@
+package org.jnode.pluginlist;
+
+/**
+ *
+ */
+interface PluginListModel {
+ PluginRepository getRepository();
+
+ Project getProject(int index);
+
+ int size();
+
+ String getTooltipText(Plugin o);
+}
Added: trunk/builder/src/builder/org/jnode/pluginlist/PluginNode.java
===================================================================
--- trunk/builder/src/builder/org/jnode/pluginlist/PluginNode.java (rev 0)
+++ trunk/builder/src/builder/org/jnode/pluginlist/PluginNode.java 2009-02-14 11:43:39 UTC (rev 5023)
@@ -0,0 +1,21 @@
+package org.jnode.pluginlist;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+
+/**
+ *
+ */
+class PluginNode extends DefaultMutableTreeNode implements Syncable {
+ public PluginNode(Plugin p) {
+ super(p);
+ }
+
+ @Override
+ public boolean isLeaf() {
+ return true;
+ }
+
+ public void sync() {
+ //nothing to do
+ }
+}
Added: trunk/builder/src/builder/org/jnode/pluginlist/PluginRepository.java
===================================================================
--- trunk/builder/src/builder/org/jnode/pluginlist/PluginRepository.java (rev 0)
+++ trunk/builder/src/builder/org/jnode/pluginlist/PluginRepository.java 2009-02-14 11:43:39 UTC (rev 5023)
@@ -0,0 +1,284 @@
+package org.jnode.pluginlist;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.TreeSet;
+
+/**
+ *
+ */
+class PluginRepository {
+ private List<Project> available = new ArrayList<Project>();
+ private List<Project> selected = new ArrayList<Project>();
+ private HashMap<String, PluginInfo> pluginMap = new HashMap<String, PluginInfo>();
+
+ void addSystemPlugin(Plugin plu) {
+ if (plu.isSystem()) {
+ pluginMap.put(plu.getId(), new PluginInfo(plu, null));
+ }
+ }
+
+ void reselect(PluginList pluginList) {
+ Set<Plugin> ps = new HashSet<Plugin>();
+ for (Map.Entry<String, PluginInfo> e : pluginMap.entrySet()) {
+ if (e.getValue().selected)
+ ps.add(e.getValue().plugin);
+ }
+ deselect(ps);
+
+ ps.clear();
+ for (String p : pluginList.getPlugins()) {
+ Plugin plug = getPlugin(p);
+ if (plug == null)
+ throw new RuntimeException("Invalid plugin in plugin list: " + p);
+
+ ps.add(plug);
+ }
+
+ select(ps);
+ Main.setSaved();
+ }
+
+ Set<Plugin> select(Set<Plugin> plugins) {
+ Set<Plugin> ret = new HashSet<Plugin>();
+ for (Plugin plugin : plugins)
+ select0(plugin, ret);
+ sortSeleted();
+ if (!ret.isEmpty())
+ Main.setUnsaved();
+ return ret;
+ }
+
+ private void select0(Plugin plugin, Set<Plugin> set) {
+ PluginInfo pi = pluginMap.get(plugin.getId());
+ if (pi.selected)
+ return;
+
+ Plugin plu = pi.plugin;
+ if (plu.isSystem())
+ return;
+
+ Project a_pro = getProject(pi.project, available);
+ Project s_pro = getProject(pi.project, selected);
+
+ a_pro.remove(plu);
+ s_pro.addPlugin(plu);
+ s_pro.sort();
+ pi.selected = true;
+
+ set.add(plu);
+
+ for (Plugin r : plu.allRequired())
+ select0(r, set);
+ }
+
+ public Set<Plugin> deselect(Set<Plugin> plugins) {
+ Set<Plugin> ret = new HashSet<Plugin>();
+ for (Plugin plugin : plugins)
+ deselect0(plugin, ret);
+ sortAvailable();
+ if (!ret.isEmpty())
+ Main.setUnsaved();
+ return ret;
+ }
+
+ private void deselect0(Plugin plugin, Set<Plugin> set) {
+ PluginInfo pi = pluginMap.get(plugin.getId());
+ if (!pi.selected)
+ return;
+
+ Plugin plu = pi.plugin;
+ if (plu.isSystem())
+ return;
+
+ Project a_pro = getProject(pi.project, available);
+ Project s_pro = getProject(pi.project, selected);
+
+ s_pro.remove(plu);
+ a_pro.addPlugin(plu);
+ a_pro.sort();
+ pi.selected = false;
+
+ set.add(plu);
+
+ for (Plugin r : plu.allUsed())
+ deselect0(r, set);
+ }
+
+ Project getProject(String name, List<Project> list) {
+ for (Project pro : list)
+ if (name.equals(pro.getName()))
+ return pro;
+ return null;
+ }
+
+ void reload(PluginList pluginList) throws Exception {
+ available.clear();
+ selected.clear();
+ pluginMap.clear();
+
+ addProject(Main.readProject("core", this));
+ addProject(Main.readProject("gui", this));
+ addProject(Main.readProject("fs", this));
+ addProject(Main.readProject("net", this));
+ addProject(Main.readProject("shell", this));
+ addProject(Main.readProject("distr", this));
+ addProject(Main.readProject("textui", this));
+
+ validate();
+ reselect(pluginList);
+ sortAvailable();
+ sortSeleted();
+ }
+
+ static class PluginInfo {
+ Plugin plugin;
+ String project;
+ boolean selected;
+
+ PluginInfo(Plugin plugin, String project) {
+ this.plugin = plugin;
+ this.project = project;
+ }
+ }
+
+ void addProject(Project proj) {
+ available.add(proj);
+ Project p = new Project(proj.getName());
+ selected.add(p);
+ }
+
+ public Project getProject(int index) {
+ return available.get(index);
+ }
+
+ @Override
+ public String toString() {
+ return "";
+ }
+
+ public int size() {
+ return available.size();
+ }
+
+ Plugin getPlugin(String id) {
+ return pluginMap.get(id).plugin;
+ }
+
+ String getProject(String id) {
+ return pluginMap.get(id).project;
+ }
+
+ boolean isSelected(String id) {
+ return pluginMap.get(id).selected;
+ }
+
+ void validate() {
+ for (Project j : available) {
+ for (Plugin p : j.plugins()) {
+ pluginMap.put(p.getId(), new PluginInfo(p, j.getName()));
+ }
+ }
+
+ for (Map.Entry<String, PluginInfo> e : pluginMap.entrySet()) {
+ e.getValue().plugin.resolve(this);
+ }
+ }
+
+ void sortAvailable() {
+ Collections.sort(available);
+ for (Project p : available)
+ p.sort();
+ }
+
+ void sortSeleted() {
+ Collections.sort(selected);
+ for (Project p : selected)
+ p.sort();
+ }
+
+ PluginListModel getAvailableModel() {
+ return new PluginListModelImpl(available) {
+ public String getTooltipText(Plugin plugin) {
+ Set<Plugin> plugins = plugin.allRequired();
+ Set<Plugin> plugins2 = new HashSet<Plugin>();
+ for (Plugin p : plugins) {
+ if (!getRepository().isSelected(p.getId()))
+ plugins2.add(p);
+ }
+
+ if (plugins2.size() > 0) {
+ StringBuilder sb = new StringBuilder("<html> <b>Requires:</b><br/>");
+ for (Plugin p : plugins2) {
+ sb.append(p.getId());
+ sb.append("<br/>");
+ }
+ sb.append("</html>");
+ return sb.length() == 0 ? null : sb.toString();
+ }
+ return null;
+ }
+ };
+ }
+
+ PluginListModel getSelectedModel() {
+ return new PluginListModelImpl(selected) {
+ public String getTooltipText(Plugin plugin) {
+ Set<Plugin> plugins = plugin.allUsed();
+ Set<Plugin> plugins2 = new HashSet<Plugin>();
+ for (Plugin p : plugins) {
+ if (getRepository().isSelected(p.getId()))
+ plugins2.add(p);
+ }
+
+ if (plugins2.size() > 0) {
+ StringBuilder sb = new StringBuilder("<html> <b>Used by:</b><br/>");
+ for (Plugin p : plugins2) {
+ sb.append(p.getId());
+ sb.append("<br/>");
+ }
+ sb.append("</html>");
+ return sb.length() == 0 ? null : sb.toString();
+ }
+ return null;
+ }
+ };
+ }
+
+ Set<String> getSelectedPluginIds() {
+ Set<String> ret = new TreeSet<String>();
+ for (Map.Entry<String, PluginInfo> e : pluginMap.entrySet()) {
+ if (e.getValue().selected)
+ ret.add(e.getKey());
+ }
+ return ret;
+ }
+
+ private abstract class PluginListModelImpl implements PluginListModel {
+ private List<Project> projectList;
+
+ private PluginListModelImpl(List<Project> projectList) {
+ this.projectList = projectList;
+ }
+
+ @Override
+ public PluginRepository getRepository() {
+ return PluginRepository.this;
+ }
+
+ @Override
+ public Project getProject(int index) {
+ return projectList.get(index);
+ }
+
+ @Override
+ public int size() {
+ return projectList.size();
+ }
+ }
+}
Added: trunk/builder/src/builder/org/jnode/pluginlist/PluginTreePane.java
===================================================================
--- trunk/builder/src/builder/org/jnode/pluginlist/PluginTreePane.java (rev 0)
+++ trunk/builder/src/builder/org/jnode/pluginlist/PluginTreePane.java 2009-02-14 11:43:39 UTC (rev 5023)
@@ -0,0 +1,35 @@
+package org.jnode.pluginlist;
+
+import javax.swing.JPanel;
+import javax.swing.JTree;
+import javax.swing.JScrollPane;
+import javax.swing.tree.TreePath;
+import javax.swing.tree.DefaultMutableTreeNode;
+import java.awt.BorderLayout;
+import java.awt.event.MouseEvent;
+
+/**
+ *
+ */
+class PluginTreePane extends JPanel {
+ JTree tree;
+
+ PluginTreePane(final PluginListModel model) {
+ tree = new JTree(new RootNode(model)) {
+ @Override
+ public String getToolTipText(MouseEvent event) {
+ TreePath path = tree.getClosestPathForLocation(event.getX(), event.getY());
+ Object o = ((DefaultMutableTreeNode) path.getLastPathComponent()).getUserObject();
+ if (o instanceof Plugin) {
+ return model.getTooltipText((Plugin) o);
+ }
+ return null;
+ }
+ };
+ tree.setToolTipText("");
+ tree.setRootVisible(false);
+ setLayout(new BorderLayout());
+ add(new JScrollPane(tree), BorderLayout.CENTER);
+ }
+
+}
Added: trunk/builder/src/builder/org/jnode/pluginlist/Project.java
===================================================================
--- trunk/builder/src/builder/org/jnode/pluginlist/Project.java (rev 0)
+++ trunk/builder/src/builder/org/jnode/pluginlist/Project.java 2009-02-14 11:43:39 UTC (rev 5023)
@@ -0,0 +1,55 @@
+package org.jnode.pluginlist;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ *
+ */
+class Project implements Comparable {
+ private String name;
+ private List<Plugin> pluginList = new ArrayList<Plugin>();
+
+ public Project(String name) {
+ this.name = name;
+ }
+
+ void addPlugin(Plugin plugin) {
+ pluginList.add(plugin);
+ }
+
+ List<Plugin> plugins() {
+ return Collections.unmodifiableList(pluginList);
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ public Plugin getPlugin(int index) {
+ return pluginList.get(index);
+ }
+
+ public int size() {
+ return pluginList.size();
+ }
+
+ void sort() {
+ Collections.sort(pluginList);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ return name.compareTo(((Project) o).name);
+ }
+
+ public void remove(Plugin plu) {
+ pluginList.remove(plu);
+ }
+}
Added: trunk/builder/src/builder/org/jnode/pluginlist/ProjectNode.java
===================================================================
--- trunk/builder/src/builder/org/jnode/pluginlist/ProjectNode.java (rev 0)
+++ trunk/builder/src/builder/org/jnode/pluginlist/ProjectNode.java 2009-02-14 11:43:39 UTC (rev 5023)
@@ -0,0 +1,26 @@
+package org.jnode.pluginlist;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+
+/**
+ *
+ */
+class ProjectNode extends DefaultMutableTreeNode implements Syncable {
+ public ProjectNode(Project project) {
+ super(project);
+ for (Plugin p : project.plugins())
+ add(new PluginNode(p));
+ }
+
+ public void sync() {
+ Project project = (Project) getUserObject();
+ if (project.size() != getChildCount()) {
+ removeAllChildren();
+ for (Plugin p : project.plugins())
+ add(new PluginNode(p));
+ }
+
+ for (int i = 0; i < getChildCount(); i++)
+ ((PluginNode) getChildAt(i)).sync();
+ }
+}
Added: trunk/builder/src/builder/org/jnode/pluginlist/RootNode.java
===================================================================
--- trunk/builder/src/builder/org/jnode/pluginlist/RootNode.java (rev 0)
+++ trunk/builder/src/builder/org/jnode/pluginlist/RootNode.java 2009-02-14 11:43:39 UTC (rev 5023)
@@ -0,0 +1,35 @@
+package org.jnode.pluginlist;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+
+/**
+ *
+ */
+class RootNode extends DefaultMutableTreeNode implements Syncable {
+ public RootNode(PluginListModel model) {
+ super(model);
+ for (int i = 0; i < model.size(); i++)
+ add(new ProjectNode(model.getProject(i)));
+ }
+
+ @Override
+ public boolean isLeaf() {
+ return false;
+ }
+
+ @Override
+ public boolean isRoot() {
+ return true;
+ }
+
+ public void sync() {
+ PluginListModel model = (PluginListModel) getUserObject();
+ if (model.size() != getChildCount()) {
+ removeAllChildren();
+ for (int i = 0; i < model.size(); i++)
+ add(new ProjectNode(model.getProject(i)));
+ }
+ for (int i = 0; i < getChildCount(); i++)
+ ((ProjectNode) getChildAt(i)).sync();
+ }
+}
Added: trunk/builder/src/builder/org/jnode/pluginlist/Syncable.java
===================================================================
--- trunk/builder/src/builder/org/jnode/pluginlist/Syncable.java (rev 0)
+++ trunk/builder/src/builder/org/jnode/pluginlist/Syncable.java 2009-02-14 11:43:39 UTC (rev 5023)
@@ -0,0 +1,8 @@
+package org.jnode.pluginlist;
+
+/**
+ *
+ */
+interface Syncable {
+ void sync();
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|