Source code: javax/ide/menu/spi/ActionsVisitor.java
1 package javax.ide.menu.spi;
2
3 import java.util.logging.Level;
4
5 import javax.ide.command.Controller;
6 import javax.ide.extension.BooleanVisitor;
7 import javax.ide.extension.ElementContext;
8 import javax.ide.extension.ElementEndContext;
9 import javax.ide.extension.ElementName;
10 import javax.ide.extension.ElementStartContext;
11 import javax.ide.extension.ElementVisitor;
12 import javax.ide.extension.ExtensionHook;
13 import javax.ide.extension.I18NCharVisitor;
14 import javax.ide.extension.I18NStringVisitor;
15 import javax.ide.extension.IconVisitor;
16 import javax.ide.extension.MetaClassVisitor;
17 import javax.ide.menu.IDEAction;
18 import javax.ide.util.IconDescription;
19 import javax.ide.util.MetaClass;
20
21 final class ActionsVisitor extends ElementVisitor
22 {
23 static final String KEY_ACTION = "action";
24
25 private static final ElementName ACTION = new ElementName(
26 ExtensionHook.MANIFEST_XMLNS, "action" );
27 private static final ElementName LABEL = new ElementName(
28 ExtensionHook.MANIFEST_XMLNS, "label" );
29 private static final ElementName MNEMONIC = new ElementName(
30 ExtensionHook.MANIFEST_XMLNS, "mnemonic" );
31 private static final ElementName TOOLTIP = new ElementName(
32 ExtensionHook.MANIFEST_XMLNS, "tooltip" );
33 private static final ElementName ICONPATH = new ElementName(
34 ExtensionHook.MANIFEST_XMLNS, "iconpath");
35 private static final ElementName ENABLED = new ElementName(
36 ExtensionHook.MANIFEST_XMLNS, "enabled" );
37 private static final ElementName CHECKED = new ElementName(
38 ExtensionHook.MANIFEST_XMLNS, "checked" );
39 private static final ElementName INVOKE_CLASS = new ElementName(
40 ExtensionHook.MANIFEST_XMLNS, "invoke-class" );
41 private static final ElementName UPDATE_CLASS = new ElementName(
42 ExtensionHook.MANIFEST_XMLNS, "update-class" );
43 private static final ElementName ACTION_OVERRIDE = new ElementName(
44 ExtensionHook.MANIFEST_XMLNS, "action-override" );
45
46 private ElementVisitor _actionHandler = new ActionVisitor();
47
48 private ElementVisitor _labelHandler = new LabelHandler();
49 private ElementVisitor _mnemonicHandler = new MnemonicHandler();
50 private ElementVisitor _tooltipHandler = new TooltipHandler();
51 private ElementVisitor _iconpathHandler = new IconpathHandler();
52 private ElementVisitor _enabledHandler = new EnabledHandler();
53 private ElementVisitor _checkedHandler = new CheckedHandler();
54 private ElementVisitor _invokeClassVisitor = new InvokeClassVisitor();
55 private ElementVisitor _updateClassVisitor = new UpdateClassVisitor();
56 private ElementVisitor _actionOverrideVisitor = new ActionOverrideVisitor();
57
58 private static final String KEY_CONTROLLER_HOLDER = "controllerHolder";
59 private static final String KEY_ACTION_REF = "actionRef";
60
61 public void start( ElementStartContext context )
62 {
63 context.registerChildVisitor( ACTION, _actionHandler );
64 context.registerChildVisitor( ACTION_OVERRIDE, _actionOverrideVisitor );
65 }
66
67
68 private class ActionVisitor extends ElementVisitor
69 {
70 public void start( ElementStartContext start )
71 {
72 String id = start.getAttributeValue( "id" ).trim();
73 if ( id == null )
74 {
75 log( start, Level.SEVERE, "Missing attribute 'id'" );
76 }
77 else
78 {
79 MenuModel model =
80 (MenuModel) start.getScopeData().get( MenuHook.KEY_MENU_MODEL );
81 if ( !model.isUniqueActionId( id ) )
82 {
83 log( start, Level.SEVERE, "Duplicate definition of action id '"+id+"'" );
84 return;
85 }
86
87 String toggleText = start.getAttributeValue( "toggle" );
88 boolean isToggle = toggleText == null ? false :
89 Boolean.valueOf( toggleText.trim() ).booleanValue();
90
91 IDEAction action = new IDEAction( id );
92 action.setToggleItem( isToggle );
93
94 start.getScopeData().put( KEY_ACTION, action );
95 start.getScopeData().put( KEY_CONTROLLER_HOLDER, new ControllerHolder() );
96
97 start.registerChildVisitor( LABEL, _labelHandler );
98 start.registerChildVisitor( MNEMONIC, _mnemonicHandler );
99 start.registerChildVisitor( TOOLTIP, _tooltipHandler );
100 start.registerChildVisitor( ICONPATH, _iconpathHandler );
101 start.registerChildVisitor( ENABLED, _enabledHandler );
102 start.registerChildVisitor( CHECKED, _checkedHandler );
103 start.registerChildVisitor( UPDATE_CLASS, _updateClassVisitor );
104 start.registerChildVisitor( INVOKE_CLASS, _invokeClassVisitor );
105 }
106
107 }
108
109 public void end( ElementEndContext context )
110 {
111 IDEAction action = getAction( context );
112 ControllerHolder holder =
113 (ControllerHolder) context.getScopeData().get( KEY_CONTROLLER_HOLDER );
114
115 if ( action.getLabel() == null )
116 {
117 log( context, Level.SEVERE, "Required element 'label' missing." );
118 return; // Return without registering the action.
119 }
120
121
122 MenuModel model =
123 (MenuModel) context.getScopeData().get( MenuHook.KEY_MENU_MODEL );
124
125 if ( holder.invokeClass != null )
126 {
127 Controller controller = new Controller( holder.invokeClass,
128 holder.updateClass );
129 model.addController( action.getID(), controller );
130 }
131
132 model.addAction( getAction( context ) );
133 }
134 }
135
136 private class ActionOverrideVisitor extends ElementVisitor
137 {
138 public void start( ElementStartContext context )
139 {
140 String actionRef = context.getAttributeValue( "action-ref" );
141 if ( actionRef == null || (actionRef = actionRef.trim()).length() == 0)
142 {
143 log( context, Level.SEVERE,
144 "Missing required attribute 'action-ref'." );
145 return;
146 }
147
148 context.getScopeData().put( KEY_ACTION_REF, actionRef );
149 context.getScopeData().put( KEY_CONTROLLER_HOLDER, new ControllerHolder() );
150
151 context.registerChildVisitor( UPDATE_CLASS, _updateClassVisitor );
152 context.registerChildVisitor( INVOKE_CLASS, _invokeClassVisitor );
153 }
154
155 public void end( ElementEndContext context )
156 {
157 ControllerHolder holder =
158 (ControllerHolder) context.getScopeData().get( KEY_CONTROLLER_HOLDER );
159
160 if ( holder.invokeClass == null )
161 {
162 log( context, Level.SEVERE,
163 "Missing required element 'invoke-class'." );
164 return;
165 }
166
167 String actionRef = (String) context.getScopeData().get( KEY_ACTION_REF );
168 MenuModel model =
169 (MenuModel) context.getScopeData().get( MenuHook.KEY_MENU_MODEL );
170
171 model.addController( actionRef, new Controller(
172 holder.invokeClass, holder.updateClass
173 ) );
174
175
176 }
177 }
178
179 private IDEAction getAction( ElementContext context )
180 {
181 return (IDEAction) context.getScopeData().get( KEY_ACTION );
182 }
183
184 private class LabelHandler extends I18NStringVisitor
185 {
186 public void string( ElementContext context, String text )
187 {
188 getAction( context ).setLabel( text );
189 }
190 }
191
192 private class MnemonicHandler extends I18NCharVisitor
193 {
194 public void characterValue( ElementContext context, char theChar )
195 {
196 getAction( context ).setMnemonic( theChar );
197 }
198 }
199
200 private class TooltipHandler extends I18NStringVisitor
201 {
202 public void string( ElementContext context, String text )
203 {
204 getAction( context ).setToolTip( text );
205 }
206 }
207
208 private class IconpathHandler extends IconVisitor
209 {
210 public void icon( ElementContext context, IconDescription icon )
211 {
212 getAction( context ).setIcon( icon );
213 }
214 }
215
216 private class EnabledHandler extends BooleanVisitor
217 {
218 public void booleanValue( ElementContext context, boolean value )
219 {
220 getAction( context ).setEnabled( value );
221 }
222 }
223
224 private class CheckedHandler extends BooleanVisitor
225 {
226 public void booleanValue( ElementContext context, boolean value )
227 {
228 getAction( context ).setChecked( value );
229 }
230 }
231
232 private class UpdateClassVisitor extends MetaClassVisitor
233 {
234 public void metaClass(ElementContext context, MetaClass mc)
235 {
236 ControllerHolder ch = (ControllerHolder) context.getScopeData().get(
237 KEY_CONTROLLER_HOLDER
238 );
239 ch.updateClass = mc;
240 }
241 }
242
243 private class InvokeClassVisitor extends MetaClassVisitor
244 {
245 public void metaClass(ElementContext context, MetaClass mc)
246 {
247 ControllerHolder ch = (ControllerHolder) context.getScopeData().get(
248 KEY_CONTROLLER_HOLDER
249 );
250 ch.invokeClass = mc;
251 }
252 }
253
254 private final class ControllerHolder
255 {
256 private MetaClass invokeClass;
257 private MetaClass updateClass;
258 }
259 }