You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2006/06/06 10:09:23 UTC

svn commit: r412034 - in /incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java: ./ org/apache/cayenne/swing/plugin/frame/

Author: aadamchik
Date: Tue Jun  6 01:09:22 2006
New Revision: 412034

URL: http://svn.apache.org/viewvc?rev=412034&view=rev
Log:
support for localizable actions loaded from XML

Added:
    incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/actions.xml
    incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FrameBuilder.java
      - copied, changed from r411842, incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FrameMenuBuilder.java
    incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/QuitAction.java
    incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/plugin.properties
    incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/plugin_ru.properties
Removed:
    incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FrameMenuBuilder.java
Modified:
    incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FrameController.java
    incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FramePlugin.java
    incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/XMLUtil.java

Added: incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/actions.xml
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/actions.xml?rev=412034&view=auto
==============================================================================
--- incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/actions.xml (added)
+++ incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/actions.xml Tue Jun  6 01:09:22 2006
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<actions>
+	
+	<action name="action.quit" class="org.apache.cayenne.swing.plugin.frame.QuitAction">
+		<!--
+			"menu" - boolean specifying whether 
+		           "Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()" should be used as modifier
+		     text is compatible with KeyStroke.getKeyStroke(String)
+		-->
+		<accelerator menu="true">Q</accelerator>
+	</action>
+</actions>
\ No newline at end of file

Copied: incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FrameBuilder.java (from r411842, incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FrameMenuBuilder.java)
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FrameBuilder.java?p2=incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FrameBuilder.java&p1=incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FrameMenuBuilder.java&r1=411842&r2=412034&rev=412034&view=diff
==============================================================================
--- incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FrameMenuBuilder.java (original)
+++ incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FrameBuilder.java Tue Jun  6 01:09:22 2006
@@ -15,34 +15,148 @@
  */
 package org.apache.cayenne.swing.plugin.frame;
 
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
 import java.io.InputStream;
 import java.util.Iterator;
 import java.util.List;
 
+import javax.swing.AbstractAction;
 import javax.swing.Action;
 import javax.swing.JComponent;
 import javax.swing.JFrame;
 import javax.swing.JMenu;
 import javax.swing.JMenuBar;
 import javax.swing.JMenuItem;
+import javax.swing.KeyStroke;
 
 import org.apache.cayenne.swing.CayenneSwingException;
+import org.objectstyle.cayenne.util.Util;
 import org.platonos.pluginengine.Plugin;
+import org.platonos.pluginengine.logging.LoggerLevel;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
-public class FrameMenuBuilder {
+public class FrameBuilder {
 
     protected FramePlugin framePlugin;
 
-    public FrameMenuBuilder(FramePlugin framePlugin) {
+    public FrameBuilder(FramePlugin framePlugin) {
         this.framePlugin = framePlugin;
     }
 
+    public void addActions(Plugin plugin, String xmlPath) {
+        InputStream actionXML = plugin
+                .getPluginClassLoader()
+                .getResourceAsStream(xmlPath);
+        if (actionXML == null) {
+            throw new CayenneSwingException("No action XML file found at " + xmlPath);
+        }
+
+        Document doc;
+        try {
+            doc = XMLUtil.newBuilder().parse(actionXML);
+        }
+        catch (Exception e) {
+            throw new CayenneSwingException(
+                    "Error parsing action XML '" + xmlPath + "'",
+                    e);
+        }
+
+        List children = XMLUtil.getChildren(doc.getDocumentElement(), "action");
+        Iterator it = children.iterator();
+        while (it.hasNext()) {
+            addAction(plugin, (Element) it.next());
+        }
+    }
+
+    /**
+     * Adds an action configuring it from plugin properties.
+     */
+    protected void addAction(Plugin plugin, Element actionXML) {
+
+        String key = actionXML.getAttribute("name");
+        if (key == null) {
+            throw new CayenneSwingException("No 'name' attribute in action XML");
+        }
+
+        String actionClassName = actionXML.getAttribute("class");
+        if (actionClassName == null) {
+            throw new CayenneSwingException("No 'class' attribute in action XML");
+        }
+
+        Action action;
+        try {
+            action = (Action) Class.forName(
+                    actionClassName,
+                    true,
+                    plugin.getPluginClassLoader()).newInstance();
+        }
+        catch (Exception e) {
+            framePlugin.getPluginEngine().getLogger().log(
+                    LoggerLevel.WARNING,
+                    "Error instantiating action '" + actionClassName + "'",
+                    e);
+
+            // create noop disabled action
+            action = new AbstractAction() {
+
+                public void actionPerformed(ActionEvent e) {
+                }
+            };
+            action.setEnabled(false);
+        }
+
+        List accelerators = XMLUtil.getChildren(actionXML, "accelerator");
+        if (!accelerators.isEmpty()) {
+            KeyStroke accelerator = processAcceleratorKey((Element) accelerators.get(0));
+            action.putValue(Action.ACCELERATOR_KEY, accelerator);
+        }
+
+        action.putValue(Action.NAME, plugin.replaceToken("$$"
+                + key
+                + '.'
+                + Action.NAME
+                + "$$"));
+        action.putValue(Action.SHORT_DESCRIPTION, plugin.replaceToken("$$"
+                + key
+                + '.'
+                + Action.SHORT_DESCRIPTION
+                + "$$"));
+
+        action.putValue(Action.LONG_DESCRIPTION, plugin.replaceToken("$$"
+                + key
+                + '.'
+                + Action.LONG_DESCRIPTION
+                + "$$"));
+
+        framePlugin.getActionMap().put(key, action);
+    }
+
+    protected KeyStroke processAcceleratorKey(Element acceleratorXML) {
+
+        // extract key code...
+        String key = XMLUtil.getText(acceleratorXML);
+        if (Util.isEmptyString(key)) {
+            throw new CayenneSwingException("No key stroke text in accelerator XML");
+        }
+
+        KeyStroke ks = KeyStroke.getKeyStroke(key);
+        boolean menu = "true".equalsIgnoreCase(acceleratorXML.getAttribute("menu"));
+
+        if (menu) {
+            ks = KeyStroke.getKeyStroke(ks.getKeyCode(), ks.getModifiers()
+                    | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), ks
+                    .isOnKeyRelease());
+        }
+
+        return ks;
+    }
+
     /**
      * Adds a menu contributed by plugin.
      */
-    public void addMenu(Plugin plugin, String xmlPath) {
+    public void addMenus(Plugin plugin, String xmlPath) {
         JFrame frame = framePlugin.getFrameController().getFrame();
 
         JMenuBar menu = frame.getJMenuBar();
@@ -67,7 +181,10 @@
         List children = XMLUtil.getChildren(doc.getDocumentElement(), "menu");
         Iterator it = children.iterator();
         while (it.hasNext()) {
-            menu.add(processMenu(plugin, (Element) it.next(), 1));
+            JComponent child = processMenu(plugin, (Element) it.next(), 1);
+            if (child != null) {
+                menu.add(child);
+            }
         }
     }
 
@@ -76,6 +193,10 @@
      */
     protected JComponent processMenu(Plugin plugin, Element menuXML, int depth) {
 
+        if ("true".equalsIgnoreCase(menuXML.getAttribute("separator"))) {
+            return null;
+        }
+
         List children = XMLUtil.getChildren(menuXML, "menu");
 
         Action action = framePlugin.getActionMap().get(menuXML.getAttribute("action"));
@@ -89,14 +210,20 @@
             menu.setAction(action);
         }
         else if (key != null) {
-            menu.setText(plugin.replaceToken(key));
+            menu.setText(plugin.replaceToken("$$" + key + "$$"));
         }
 
         depth++;
         Iterator it = children.iterator();
         while (it.hasNext()) {
             JComponent component = processMenu(plugin, (Element) it.next(), depth);
-            menu.add(component);
+
+            if (component != null) {
+                menu.add(component);
+            }
+            else if (menu instanceof JMenu) {
+                ((JMenu) menu).addSeparator();
+            }
         }
 
         // disable empty menus

Modified: incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FrameController.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FrameController.java?rev=412034&r1=412033&r2=412034&view=diff
==============================================================================
--- incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FrameController.java (original)
+++ incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FrameController.java Tue Jun  6 01:09:22 2006
@@ -22,8 +22,6 @@
 import java.awt.event.WindowEvent;
 import java.util.prefs.Preferences;
 
-import javax.swing.AbstractAction;
-import javax.swing.Action;
 import javax.swing.JFrame;
 
 import org.apache.cayenne.swing.BoundsBinding;
@@ -58,23 +56,6 @@
     }
 
     /**
-     * Returns an action that calls 'shutdownAction' on this controller.
-     */
-    public Action getDefaultShutdownAction() {
-        return new AbstractAction() {
-
-            public void actionPerformed(ActionEvent e) {
-                shutdown();
-            }
-        };
-    }
-
-    public Action getShutdownAction() {
-        Action action = framePlugin.getActionMap().get(FramePlugin.QUIT_ACTION);
-        return action != null ? action : getDefaultShutdownAction();
-    }
-
-    /**
      * Starts the application frame.
      */
     public void startup() {
@@ -87,7 +68,8 @@
         frame.addWindowListener(new WindowAdapter() {
 
             public void windowClosing(WindowEvent e) {
-                getShutdownAction().actionPerformed(new ActionEvent(this, 1, null));
+                framePlugin.getActionMap().get(FramePlugin.QUIT_ACTION).actionPerformed(
+                        new ActionEvent(this, 1, null));
             }
         });
 

Modified: incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FramePlugin.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FramePlugin.java?rev=412034&r1=412033&r2=412034&view=diff
==============================================================================
--- incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FramePlugin.java (original)
+++ incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/FramePlugin.java Tue Jun  6 01:09:22 2006
@@ -34,13 +34,13 @@
 
     public static final String FRAME_BUILDERS_EXT = "frameBuilders";
 
-    protected FrameMenuBuilder menuBuilder;
+    protected FrameBuilder frameBuilder;
     protected FrameController frameController;
     protected ActionMap actionMap;
 
     protected void start() {
 
-        menuBuilder = new FrameMenuBuilder(this);
+        frameBuilder = new FrameBuilder(this);
         frameController = new FrameController(this);
         actionMap = new ActionMap();
 
@@ -55,6 +55,9 @@
 
     protected void initActions(List extensions) {
 
+        // init default actions that can be later overriden by plugins
+        frameBuilder.addActions(this.getPlugin(), "actions.xml");
+
         Iterator it = extensions.iterator();
         while (it.hasNext()) {
             Extension extension = (Extension) it.next();
@@ -63,11 +66,6 @@
 
             ext.initActions(this);
         }
-
-        // add default close action
-        if (actionMap.get(QUIT_ACTION) == null) {
-            actionMap.put(QUIT_ACTION, frameController.getDefaultShutdownAction());
-        }
     }
 
     protected void initMenus(List extensions) {
@@ -110,7 +108,7 @@
         this.frameController = frameController;
     }
 
-    public FrameMenuBuilder getMenuBuilder() {
-        return menuBuilder;
+    public FrameBuilder getFrameBuilder() {
+        return frameBuilder;
     }
 }

Added: incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/QuitAction.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/QuitAction.java?rev=412034&view=auto
==============================================================================
--- incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/QuitAction.java (added)
+++ incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/QuitAction.java Tue Jun  6 01:09:22 2006
@@ -0,0 +1,37 @@
+/*
+ *  Copyright 2006 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.cayenne.swing.plugin.frame;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+
+import org.platonos.pluginengine.PluginEngine;
+
+/**
+ * A default Quit action.
+ * 
+ * @author Andrus Adamchik
+ */
+public class QuitAction extends AbstractAction {
+
+    public void actionPerformed(ActionEvent e) {
+        FramePlugin plugin = (FramePlugin) PluginEngine
+                .getPlugin(FramePlugin.class)
+                .getLifecycleInstance();
+        plugin.getFrameController().shutdown();
+    }
+}

Modified: incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/XMLUtil.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/XMLUtil.java?rev=412034&r1=412033&r2=412034&view=diff
==============================================================================
--- incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/XMLUtil.java (original)
+++ incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/org/apache/cayenne/swing/plugin/frame/XMLUtil.java Tue Jun  6 01:09:22 2006
@@ -24,6 +24,7 @@
 
 import org.apache.commons.collections.Predicate;
 import org.objectstyle.cayenne.CayenneRuntimeException;
+import org.w3c.dom.CharacterData;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
@@ -67,6 +68,30 @@
         };
 
         return allMatches(node.getChildNodes(), p);
+    }
+    
+    /**
+     * Returns text content of a given Node.
+     */
+    static String getText(Node node) {
+
+        NodeList nodes = node.getChildNodes();
+        int len = nodes.getLength();
+
+        if (len == 0) {
+            return null;
+        }
+
+        StringBuffer text = new StringBuffer();
+        for (int i = 0; i < len; i++) {
+            Node child = nodes.item(i);
+
+            if (child instanceof CharacterData) {
+                text.append(((CharacterData) child).getData());
+            }
+        }
+
+        return text.length() == 0 ? null : text.toString();
     }
     
     private static List allMatches(NodeList list, Predicate predicate) {

Added: incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/plugin.properties
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/plugin.properties?rev=412034&view=auto
==============================================================================
--- incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/plugin.properties (added)
+++ incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/plugin.properties Tue Jun  6 01:09:22 2006
@@ -0,0 +1,2 @@
+
+action.quit.name = Quit

Added: incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/plugin_ru.properties
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/plugin_ru.properties?rev=412034&view=auto
==============================================================================
--- incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/plugin_ru.properties (added)
+++ incubator/cayenne/main/branches/PROTO-3.0/swing-plugin/src/main/java/plugin_ru.properties Tue Jun  6 01:09:22 2006
@@ -0,0 +1,2 @@
+
+action.quit.name = \u0412\u044B\u0445\u043E\u0434