PageRenderTime 72ms CodeModel.GetById 53ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 0ms

/bundles/plugins-trunk/Console/console/commando/CommandoHandler.java

#
Java | 366 lines | 267 code | 47 blank | 52 comment | 65 complexity | 6bfc74ffc10f62d429e8812f78492c01 MD5 | raw file
  1/*
  2 * CommandoHandler.java - Reads commando XML file
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright (C) 2001, 2005 Slava Pestov
  7 * Copyright (C) 2010 Eric Le Lay
  8 *
  9 * This program is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU General Public License
 11 * as published by the Free Software Foundation; either version 2
 12 * of the License, or any later version.
 13 *
 14 * This program is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17 * GNU General Public License for more details.
 18 *
 19 * You should have received a copy of the GNU General Public License
 20 * along with this program; if not, write to the Free Software
 21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 22 */
 23
 24package console.commando;
 25
 26//{{{ Imports
 27import java.io.StringReader;
 28import java.util.List;
 29import java.util.Stack;
 30import java.util.Vector;
 31
 32import javax.swing.border.TitledBorder;
 33
 34import org.gjt.sp.jedit.BeanShell;
 35import org.gjt.sp.jedit.View;
 36import org.gjt.sp.jedit.jEdit;
 37import org.gjt.sp.util.Log;
 38
 39import org.gjt.sp.jedit.bsh.NameSpace;
 40import org.gjt.sp.jedit.bsh.This;
 41
 42import org.xml.sax.helpers.DefaultHandler;
 43import org.xml.sax.InputSource;
 44import org.xml.sax.Attributes;
 45
 46//}}}
 47
 48public class CommandoHandler extends DefaultHandler
 49{
 50	//{{{ CommandoHandler constructor
 51	CommandoHandler(View view, CommandoCommand command,
 52		CommandoDialog.SettingsPane settings,
 53		NameSpace nameSpace,
 54		List<This> components,
 55		List<Script> scripts)
 56	{
 57		this.view = view;
 58		this.command = command;
 59		this.settings = pane = settings;
 60		this.nameSpace = nameSpace;
 61		this.components = components;
 62		this.scripts = scripts;
 63
 64		stateStack = new Stack<String>();
 65		options = new Vector<Option>();
 66	} //}}}
 67
 68	//{{{ resolveEntity() method
 69	@Override
 70	public InputSource resolveEntity(String publicId, String systemId) 
 71	{
 72		// could have used EntityResolver2.resolveEntity(4),
 73		// but it's not always available 
 74		if(systemId.endsWith("commando.dtd"))
 75		{
 76			return new InputSource(new StringReader("<!-- -->"));
 77		}
 78
 79		return null;
 80	}
 81	//}}}
 82
 83	//{{{ attribute() method
 84	public void attribute(String aname, String value)
 85	{
 86		aname = (aname == null) ? null : aname.intern();
 87		value = (value == null) ? null : value.intern();
 88
 89		if(aname == "LABEL")
 90			label = value;
 91		else if(aname == "VARNAME")
 92			varName = value;
 93		else if(aname == "DEFAULT")
 94			defaultValue = value;
 95		else if(aname == "EVAL")
 96			eval = value;
 97		else if(aname == "VALUE")
 98			optionValue = value;
 99		else if(aname == "CONFIRM")
100			confirm = "TRUE".equals(value);
101		else if(aname == "TO_BUFFER")
102			toBuffer = "TRUE".equals(value);
103		else if(aname == "BUFFER_MODE")
104			mode = value;
105		else if(aname == "SHELL")
106			shell = value;
107	} //}}}
108
109	//{{{ charData() method
110	@Override
111	public void characters(char[] c, int off, int len)
112	{
113		String tag = peekElement();
114		String text = new String(c, off, len);
115		
116		//code might be passed line by line, so concatenate
117		if(tag == "COMMAND")
118			code = code == null ? text : code+text;
119	} //}}}
120
121	//{{{ startElement() method
122	@Override
123	public void startElement(String ns, String localName, String qName, Attributes attributes)
124	{
125		// handle the attributes before pushing the element
126		// (this is what the old com.microstar.xml XmlParser implementation did)
127		for(int i=0;i<attributes.getLength();i++)
128		{
129			String aname = attributes.getLocalName(i);
130			String value = attributes.getValue(i);
131			attribute(aname, value);
132		}
133		
134		pushElement(localName);
135
136		String tag = peekElement();
137		if(tag == "CAPTION")
138		{
139			pane = new CommandoDialog.SettingsPane();
140			pane.setBorder(new TitledBorder(label));
141			settings.addComponent(pane);
142			label = null;
143		}
144		else if(tag == "CHOICE")
145		{
146			choiceLabel = label;
147			options = new Vector<Option>();
148		}
149		
150	} //}}}
151
152	@Override
153	public void endElement(String ns, String localName, String qName)
154	{
155		if(localName == null)
156			return;
157
158		String tag = peekElement();
159
160		if(localName.equals(tag))
161		{
162			if(tag == "OPTION")
163			{
164				options.addElement(new Option(label,optionValue));
165				label = optionValue = null;
166			}
167			else if(tag == "CAPTION")
168			{
169				pane = settings;
170			}
171			else if(tag == "COMMANDS" || tag == "UI"
172				|| tag == "COMMANDO")
173			{
174				// ignore these, they're syntax sugar
175			}
176			else if(tag == "COMMAND")
177			{
178				scripts.add(new Script(
179					confirm,toBuffer,mode,
180					shell,code));
181				confirm = false;
182				toBuffer = false;
183				shell = code = null;
184			}
185			else
186			{
187				try
188				{
189					NameSpace tmp = new NameSpace(
190						BeanShell.getNameSpace(),
191						"commando");
192					tmp.setVariable("pane",pane);
193					tmp.setVariable("ns",nameSpace);
194					if(tag == "CHOICE")
195						tmp.setVariable("label",choiceLabel);
196					else
197						tmp.setVariable("label",label);
198					tmp.setVariable("var",varName);
199					tmp.setVariable("options",options);
200
201					defaultValue = jEdit.getProperty(
202						command.getPropertyPrefix()
203						+ varName,defaultValue);
204
205					if(eval != null)
206					{
207						defaultValue =
208							String.valueOf(
209							BeanShell.eval(
210							view,tmp,eval));
211					}
212					if(defaultValue == null)
213						nameSpace.setVariable(varName,"");
214					else
215						nameSpace.setVariable(varName,defaultValue);
216
217					// this stores This instances
218					// we call valueChanged() on
219					// them to update namespace
220					
221					String script = "commando" + tag + "(view,pane,ns,label,var,options)";
222					Object value = BeanShell.eval(view, tmp, script);
223					components.add((This)value);
224				}
225				catch(Exception e)
226				{
227					Log.log(Log.ERROR,this,e);
228				}
229
230				label = varName = defaultValue = eval = null;
231			}
232
233			popElement();
234		}
235		else
236		{
237			// can't happen
238			throw new InternalError();
239		}
240	} //}}}
241
242	//{{{ startDocument() method
243	@Override
244	public void startDocument()
245	{
246		pushElement(null);
247	} //}}}
248
249	//{{{ Private members
250
251	//{{{ Instance variables
252	private View view;
253	private CommandoCommand command;
254	private CommandoDialog.SettingsPane settings;
255	private CommandoDialog.SettingsPane pane;
256	private NameSpace nameSpace;
257	private List<This> components;
258	private List<Script> scripts;
259
260	private String varName;
261	private String defaultValue;
262	private String eval;
263	private String optionValue;
264	private String choiceLabel;
265	private String label;
266	private boolean confirm;
267	private boolean toBuffer;
268	private String mode;
269	private String shell;
270	private String code;
271
272	private Vector<Option> options;
273
274	private Stack<String> stateStack;
275	//}}}
276
277	//{{{ pushElement() method
278	private void pushElement(String name)
279	{
280		name = (name == null) ? null : name.intern();
281
282		stateStack.push(name);
283	} //}}}
284
285	//{{{ peekElement() method
286	private String peekElement()
287	{
288		return stateStack.peek();
289	} //}}}
290
291	//{{{ popElement() method
292	private String popElement()
293	{
294		return stateStack.pop();
295	} //}}}
296
297	//}}}
298
299	//{{{ Script class
300	class Script
301	{
302		boolean confirm;
303		boolean toBuffer;
304		String mode;
305		String shell;
306		String code;
307
308		Script(boolean confirm, boolean toBuffer, String mode,
309			String shell, String code)
310		{
311			this.confirm = confirm;
312			this.toBuffer = toBuffer;
313			this.mode = mode;
314			this.shell = shell;
315			this.code = code;
316		}
317
318		Command getCommand()
319		{
320			Object command = BeanShell.eval(view,nameSpace,code);
321			if(command == null)
322				return null;
323			return new Command(confirm,toBuffer,mode,
324				shell,String.valueOf(command));
325		}
326	} //}}}
327
328	//{{{ Command class
329	// static for use by CommandoThread
330	static class Command
331	{
332		boolean confirm;
333		boolean toBuffer;
334		String mode;
335		String shell;
336		String command;
337
338		Command(boolean confirm, boolean toBuffer, String mode,
339			String shell, String command)
340		{
341			this.confirm = confirm;
342			this.toBuffer = toBuffer;
343			this.mode = mode;
344			this.shell = shell;
345			this.command = command;
346		}
347	} //}}}
348
349	//{{{ Option class
350	public static class Option
351	{
352		public String label;
353		public String value;
354
355		Option(String label, String value)
356		{
357			this.label = label;
358			this.value = value;
359		}
360
361		public String toString()
362		{
363			return label;
364		}
365	} //}}}
366}