alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 * ActionSet.java - A set of actions
 * :tabSize=8:indentSize=8:noTabs=false:
 * :folding=explicit:collapseFolds=1:
 *
 * Copyright (C) 2001, 2003 Slava Pestov
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

package org.gjt.sp.jedit;

import com.microstar.xml.*;
import java.io.*;
import java.net.URL;
import java.util.*;
import org.gjt.sp.jedit.gui.InputHandler;
import org.gjt.sp.util.Log;

/**
 * A set of actions, either loaded from an XML file, or constructed at runtime
 * by a plugin.

* *

Action sets loaded from XML files

* * Action sets are read from these files inside the plugin JAR: *
    *
  • actions.xml - actions made available for use in jEdit views, * including the view's Plugins menu, the tool bar, etc.
  • *
  • browser.actions.xml - actions for the file system browser's * Plugins menu.
  • *
* * An action definition file has the following form: * *
<?xml version="1.0"?>
 *<!DOCTYPE ACTIONS SYSTEM "actions.dtd">
 *<ACTIONS>
 *    <ACTION NAME="some-action">
 *        <CODE>
 *            // BeanShell code evaluated when the action is invoked
 *        </CODE>
 *    </ACTION>
 *    <ACTION NAME="some-toggle-action">
 *        <CODE>
 *            // BeanShell code evaluated when the action is invoked
 *        </CODE>
 *        <IS_SELECTED>
 *            // BeanShell code that should evaluate to true or false
 *        </IS_SELECTED>
 *    </ACTION>
 *</ACTIONS>
* * The following elements are valid: * *
    *
  • * ACTIONS is the top-level element and refers * to the set of actions used by the plugin. *
  • *
  • * An ACTION contains the data for a particular action. * It has three attributes: a required NAME; * an optional NO_REPEAT, which is a flag * indicating whether the action should not be repeated with the * C+ENTER command; and an optional * NO_RECORD which is a a flag indicating whether the * action should be recorded if it is invoked while the user is recording a * macro. The two flag attributes * can have two possible values, "TRUE" or * "FALSE". In both cases, "FALSE" is the * default if the attribute is not specified. *
  • *
  • * An ACTION can have two child elements * within it: a required CODE element which * specifies the * BeanShell code that will be executed when the action is invoked, * and an optional IS_SELECTED element, used for * checkbox * menu items. The IS_SELECTED element contains * BeanShell code that returns a boolean flag that will * determine the state of the checkbox. *
  • *
* * Each action must have a property name.label containing * the action's menu item label. * *

View actions

* * Actions defined in actions.xml can be added to the view's * Plugins menu; see {@link EditPlugin}. * The action code may use any standard predefined * BeanShell variable; see {@link BeanShell}. * *

File system browser actions

* * Actions defined in actions.xml can be added to the file * system browser's Plugins menu; see {@link EditPlugin}. * The action code may use any standard predefined * BeanShell variable, in addition to a variable browser which * contains a reference to the current * {@link org.gjt.sp.jedit.browser.VFSBrowser} instance.

* * File system browser actions should not define * <IS_SELECTED> blocks. * *

Custom action sets

* * Call {@link jEdit#addActionSet(ActionSet)} to add a custom action set to * jEdit's action context. You must also call {@link #initKeyBindings()} for new * action sets. Don't forget to call {@link jEdit#removeActionSet(ActionSet)} * before your plugin is unloaded, too. * * @see jEdit#getActionContext() * @see org.gjt.sp.jedit.browser.VFSBrowser#getActionContext() * @see ActionContext#getActionNames() * @see ActionContext#getAction(String) * @see jEdit#addActionSet(ActionSet) * @see jEdit#removeActionSet(ActionSet) * @see PluginJAR#getActionSet() * @see BeanShell * @see View * * @author Slava Pestov * @author John Gellene (API documentation) * @version $Id: ActionSet.java,v 1.31 2004/07/12 19:25:07 spestov Exp $ * @since jEdit 4.0pre1 */ public class ActionSet { //{{{ ActionSet constructor /** * Creates a new action set. * @since jEdit 4.0pre1 */ public ActionSet() { actions = new Hashtable(); loaded = true; label = ""; } //}}} //{{{ ActionSet constructor /** * Creates a new action set. * @param plugin The plugin * @param cachedActionNames The list of cached action names * @param cachedActionToggleFlags The list of cached action toggle flags * @param uri The actions.xml URI * @since jEdit 4.2pre2 */ public ActionSet(PluginJAR plugin, String[] cachedActionNames, boolean[] cachedActionToggleFlags, URL uri) { this(); this.plugin = plugin; this.uri = uri; if(cachedActionNames != null) { for(int i = 0; i < cachedActionNames.length; i++) { actions.put(cachedActionNames[i],placeholder); jEdit.setTemporaryProperty(cachedActionNames[i] + ".toggle",cachedActionToggleFlags[i] ? "true" : "false"); } } loaded = false; } //}}} //{{{ ActionSet constructor /** * Creates a new action set. * @param label The label, shown in the shortcuts option pane * @since jEdit 4.0pre1 */ public ActionSet(String label) { this(); setLabel(label); } //}}} //{{{ getLabel() method /** * Return the action source label. * @since jEdit 4.0pre1 */ public String getLabel() { return label; } //}}} //{{{ setLabel() method /** * Sets the action source label. * @param label The label * @since jEdit 4.0pre1 */ public void setLabel(String label) { if(label == null) throw new NullPointerException(); this.label = label; } //}}} //{{{ getPluginJAR() method /** * Return the plugin this action set was loaded from, or null. * @since jEdit 4.2pre13 */ public PluginJAR getPluginJAR() { return plugin; } //}}} //{{{ addAction() method /** * Adds an action to the action set. * @param action The action * @since jEdit 4.0pre1 */ public void addAction(EditAction action) { actions.put(action.getName(),action); if(context != null) { context.actionNames = null; context.actionHash.put(action.getName(),this); } } //}}} //{{{ removeAction() method /** * Removes an action from the action set. * @param name The action name * @since jEdit 4.0pre1 */ public void removeAction(String name) { actions.remove(name); if(context != null) { context.actionNames = null; context.actionHash.remove(name); } } //}}} //{{{ removeAllActions() method /** * Removes all actions from the action set. * @since jEdit 4.0pre1 */ public void removeAllActions() { if(context != null) { context.actionNames = null; String[] actions = getActionNames(); for(int i = 0; i < actions.length; i++) { context.actionHash.remove(actions[i]); } } this.actions.clear(); } //}}} //{{{ getAction() method /** * Returns an action with the specified name.

* * Deferred loading: this will load the action set if necessary. * * @param name The action name * @since jEdit 4.0pre1 */ public EditAction getAction(String name) { Object obj = actions.get(name); if(obj == placeholder) { load(); obj = actions.get(name); if(obj == placeholder) { Log.log(Log.WARNING,this,"Outdated cache"); obj = null; } } return (EditAction)obj; } //}}} //{{{ getActionCount() method /** * Returns the number of actions in the set. * @since jEdit 4.0pre1 */ public int getActionCount() { return actions.size(); } //}}} //{{{ getActionNames() method /** * Returns an array of all action names in this action set. * @since jEdit 4.2pre1 */ public String[] getActionNames() { String[] retVal = new String[actions.size()]; Enumeration e = actions.keys(); int i = 0; while(e.hasMoreElements()) { retVal[i++] = (String)e.nextElement(); } return retVal; } //}}} //{{{ getCacheableActionNames() method /** * Returns an array of all action names in this action set that should * be cached; namely, BeanShellActions. * @since jEdit 4.2pre1 */ public String[] getCacheableActionNames() { LinkedList retVal = new LinkedList(); Enumeration e = actions.elements(); while(e.hasMoreElements()) { Object obj = e.nextElement(); if(obj == placeholder) { // ??? this should only be called with // fully loaded action set Log.log(Log.WARNING,this,"Action set not up " + "to date"); } else if(obj instanceof BeanShellAction) retVal.add(((BeanShellAction)obj).getName()); } return (String[])retVal.toArray(new String[retVal.size()]); } //}}} //{{{ getActions() method /** * Returns an array of all actions in this action set.

* * Deferred loading: this will load the action set if necessary. * * @since jEdit 4.0pre1 */ public EditAction[] getActions() { load(); EditAction[] retVal = new EditAction[actions.size()]; Enumeration e = actions.elements(); int i = 0; while(e.hasMoreElements()) { retVal[i++] = (EditAction)e.nextElement(); } return retVal; } //}}} //{{{ contains() method /** * Returns if this action set contains the specified action. * @param action The action * @since jEdit 4.2pre1 */ public boolean contains(String action) { return actions.containsKey(action); } //}}} //{{{ size() method /** * Returns the number of actions in this action set. * @since jEdit 4.2pre2 */ public int size() { return actions.size(); } //}}} //{{{ toString() method public String toString() { return label; } //}}} //{{{ initKeyBindings() method /** * Initializes the action set's key bindings. * jEdit calls this method for all registered action sets when the * user changes key bindings in the Global Options dialog box.

* * Note if your plugin adds a custom action set to jEdit's collection, * it must also call this method on the action set after adding it. * * @since jEdit 4.2pre1 */ public void initKeyBindings() { InputHandler inputHandler = jEdit.getInputHandler(); Iterator iter = actions.entrySet().iterator(); while(iter.hasNext()) { Map.Entry entry = (Map.Entry)iter.next(); String name = (String)entry.getKey(); String shortcut1 = jEdit.getProperty(name + ".shortcut"); if(shortcut1 != null) inputHandler.addKeyBinding(shortcut1,name); String shortcut2 = jEdit.getProperty(name + ".shortcut2"); if(shortcut2 != null) inputHandler.addKeyBinding(shortcut2,name); } } //}}} //{{{ load() method /** * Forces the action set to be loaded. Plugins and macros should not * call this method. * @since jEdit 4.2pre1 */ public void load() { if(loaded) return; loaded = true; //actions.clear(); Reader stream = null; try { Log.log(Log.DEBUG,this,"Loading actions from " + uri); ActionListHandler ah = new ActionListHandler(uri.toString(),this); stream = new BufferedReader(new InputStreamReader( uri.openStream())); XmlParser parser = new XmlParser(); parser.setHandler(ah); parser.parse(null, null, stream); } catch(XmlException xe) { int line = xe.getLine(); String message = xe.getMessage(); Log.log(Log.ERROR,this,uri + ":" + line + ": " + message); } catch(Exception e) { Log.log(Log.ERROR,uri,e); } finally { try { if(stream != null) stream.close(); } catch(IOException io) { Log.log(Log.ERROR,this,io); } } } //}}} //{{{ Package-private members ActionContext context; //{{{ getActionNames() method void getActionNames(List vec) { Enumeration e = actions.keys(); while(e.hasMoreElements()) vec.add(e.nextElement()); } //}}} //}}} //{{{ Private members private String label; private Hashtable actions; private PluginJAR plugin; private URL uri; private boolean loaded; private static final Object placeholder = new Object(); //}}} }

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.