PageRenderTime 104ms CodeModel.GetById 69ms app.highlight 31ms RepoModel.GetById 1ms app.codeStats 0ms

/bundles/plugins-trunk/XML/xml/translate/TrangGUI.java

#
Java | 540 lines | 409 code | 104 blank | 27 comment | 26 complexity | 48aceaa2bcb0b86868fa47114b3a397e MD5 | raw file
  1/*
  2 * TrangGUI.java
  3 * :folding=explicit:collapseFolds=1:
  4 *
  5 * Copyright (C) 2010 Eric Le Lay
  6 *
  7 * The XML plugin is licensed under the GNU General Public License, with
  8 * the following exception:
  9 *
 10 * "Permission is granted to link this code with software released under
 11 * the Apache license version 1.1, for example used by the Xerces XML
 12 * parser package."
 13 *
 14 * This class has been inspired by 
 15 * jing-trang-20090818/mod/trang/src/main/com/thaiopensource/relaxng/translate/Driver.java
 16 */
 17package xml.translate;
 18
 19
 20//{{{ imports
 21
 22//{{{ standard imports
 23import java.util.Collections;
 24import java.util.Arrays;
 25import java.util.List;
 26import java.util.ArrayList;
 27import java.util.Map;
 28import java.util.HashMap;
 29import java.beans.PropertyChangeListener;
 30import java.beans.PropertyChangeEvent;
 31
 32import javax.swing.BorderFactory;
 33import javax.swing.JCheckBox;
 34import javax.swing.JComboBox;
 35import javax.swing.JLabel;
 36import javax.swing.JPanel;
 37import javax.swing.JScrollPane;
 38import javax.swing.JTextArea;
 39import javax.swing.JTextField;
 40import javax.swing.JComponent;
 41import javax.swing.SwingUtilities;
 42
 43import java.awt.Color;
 44import java.awt.BorderLayout;
 45import java.awt.Component;
 46import java.awt.Container;
 47import java.awt.CardLayout;
 48import java.awt.event.ItemListener;
 49import java.awt.event.ItemEvent;
 50import java.awt.event.KeyEvent;
 51import java.awt.event.KeyAdapter;
 52//}}}
 53
 54// jEdit
 55import org.gjt.sp.jedit.gui.EnhancedDialog;
 56import org.gjt.sp.jedit.View;
 57import org.gjt.sp.jedit.Buffer;
 58import org.gjt.sp.jedit.jEdit;
 59import org.gjt.sp.util.Log;
 60
 61// common controls
 62import common.gui.OkCancelButtons;
 63import common.gui.ListPanel;
 64import common.gui.pathbuilder.PathBuilder;
 65import ise.java.awt.KappaLayout;
 66
 67import xml.gui.VFSFileTextField;
 68import xml.gui.VFSFileList;
 69
 70//}}}
 71
 72/**
 73 * graphical front-end to Trang operations.
 74 */
 75public class TrangGUI extends EnhancedDialog {
 76	private static final String OUTPUT_TYPE_PROP = "xml.translate.output-type";
 77	
 78	private View view;
 79	private Buffer buffer;
 80	private VFSFileTextField inputField;
 81	private VFSFileTextField outputField;
 82	private JComboBox inputTypeBox;
 83	private JComboBox outputTypeBox;
 84	private Map<String, Options> inputOptions;
 85	private Map<String, Options> outputOptions;
 86
 87	public TrangGUI(View parent, Buffer buffer){
 88		super(parent, "Trang GUI", false);
 89		
 90		this.view = view;
 91		this.buffer = buffer;
 92		inputOptions = new HashMap<String,Options>();
 93		outputOptions = new HashMap<String,Options>();
 94
 95		Container c = getContentPane();
 96		
 97		c.setLayout(new KappaLayout());
 98		
 99		JLabel l;
100		l = new JLabel("Input:");
101		c.add(l, "0, 0, 2, 1, E, 0, 5");
102		
103		inputField = new VFSFileTextField(view, "xml.translate.input");
104		inputField.setFile(buffer.getPath());
105		inputField.addPropertyChangeListener(new PropertyChangeListener(){
106				public void propertyChange(PropertyChangeEvent pce){
107					if("file".equals(pce.getPropertyName())){
108						String path = (String)pce.getNewValue();
109						final String extension = path.substring(path.length() - 3);
110				
111						if(Arrays.asList(TrangTranslator.inputTypes).contains(extension))
112						{
113							SwingUtilities.invokeLater(new Runnable(){
114									public void run(){
115										inputTypeBox.setSelectedItem(extension);
116									}
117							});
118						}
119					}
120				}
121		});
122		c.add(inputField, "2, 0, 7, 1, W, w, 5");
123		
124		
125		l = new JLabel("Input Type:");
126		c.add(l, "0, 1, 2, 1, E, 0, 5");
127
128		inputTypeBox = new JComboBox(TrangTranslator.inputTypes);
129		inputTypeBox.setName("input-type");
130		c.add(inputTypeBox, "2, 1, 3, 1, W, 0, 5");
131		
132		final CardLayout inputOptionsLayout = new CardLayout();
133		
134		final JPanel inputOptionsPanel = new JPanel(inputOptionsLayout);
135		inputOptionsPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.BLACK),"Options..."));
136
137		inputOptions.put("rng",new Options(""));
138		inputOptions.put("rnc",new Options(""));
139		inputOptions.put("xml",new XMLOptions());
140		inputOptions.put("dtd",new DTDOptions());
141
142		outputOptions.put("rng",new Options(""));
143		outputOptions.put("rnc",new Options(""));
144		outputOptions.put("dtd",new Options(""));
145		outputOptions.put("xsd",new XSDOptions());
146
147		for(Map.Entry<String,Options> options: inputOptions.entrySet()){
148			inputOptionsPanel.add(options.getValue(),options.getKey());
149		}
150		
151		c.add(inputOptionsPanel, "2, 2, 8, 8, 0, hw, 5");
152		
153		inputTypeBox.addItemListener(new ItemListener(){
154			public void itemStateChanged(ItemEvent evt) {
155				String newInputType = (String)inputTypeBox.getSelectedItem();
156
157				inputOptionsLayout.show(inputOptionsPanel, (String)evt.getItem());
158
159				for(Options o:outputOptions.values()){
160					o.inputTypeChanged(newInputType);
161				}
162			}
163		});
164
165		String _guessed = TrangTranslator.guessInputType(buffer);
166		if(_guessed == null){
167			_guessed = "rng";
168		}
169		final String guessed = _guessed;
170		
171		inputTypeBox.setSelectedItem(guessed);
172		
173		l = new JLabel("Output:");
174		c.add(l, "0, 10, 2, 1, E, 0, 5");
175		
176		String outputType = jEdit.getProperty(OUTPUT_TYPE_PROP,"rng");
177		String output;
178		if(buffer.getPath().endsWith(guessed)){
179			output = buffer.getPath().replaceAll(guessed+"$",outputType);
180		}else{
181			output = buffer.getPath() + "." + outputType;
182		}
183
184		outputField = new VFSFileTextField(view,"xml.translate.output");
185		outputField.setFile(buffer.getPath());
186		c.add(outputField, "2, 10, 7, 1, W, w, 5");
187
188		l = new JLabel("Output Type:");
189		c.add(l, "0, 11, 2, 1, E, 0, 5");
190
191		outputTypeBox = new JComboBox(TrangTranslator.outputTypes);
192		outputTypeBox.setName("output-type");
193		c.add(outputTypeBox, "2, 11, 7, 1, W, w, 5");
194		
195		final CardLayout outputOptionsLayout = new CardLayout();
196		
197		final JPanel outputOptionsPanel = new JPanel(outputOptionsLayout);
198
199		for(Map.Entry<String,Options> options: outputOptions.entrySet()){
200			outputOptionsPanel.add(options.getValue(),options.getKey());
201		}
202
203		c.add(outputOptionsPanel, "2, 12, 8, 8, 0, hw, 5");
204
205		outputTypeBox.addItemListener(new ItemListener(){
206			private String oldOutputType = guessed;
207
208			public void itemStateChanged(ItemEvent evt) {
209				String newOutputType = (String)outputTypeBox.getSelectedItem();
210
211				outputOptionsLayout.show(outputOptionsPanel, newOutputType);
212
213				for(Options o:inputOptions.values()){
214					o.outputTypeChanged(newOutputType);
215				}
216				
217				if(outputField.getFile().endsWith(oldOutputType)){
218					String out = outputField.getFile();
219					outputField.setFile(out.substring(0,out.length()-3)+newOutputType);
220					oldOutputType = newOutputType;
221				}
222			}
223		});
224		
225		outputTypeBox.setSelectedItem(guessed);
226
227		c.add(new OkCancelButtons(this),"0, 20, 10, 1, S, 5");
228		pack();
229	}
230	
231	public void ok(){
232		List<String> inputs;
233		List<String> inputParams;
234		List<String> outputParams;
235		Options selectedInputOptions = inputOptions.get((String)inputTypeBox.getSelectedItem());
236		Options selectedOutputOptions = outputOptions.get((String)outputTypeBox.getSelectedItem());
237		
238		if(selectedInputOptions instanceof XMLOptions){
239			XMLOptions xo = (XMLOptions)selectedInputOptions;
240			inputs = new ArrayList<String>();
241			inputs.add(inputField.getFile());
242			inputs.addAll(xo.getOptions());
243			inputParams = Collections.<String>emptyList();
244		}else{
245			inputs = Collections.singletonList(inputField.getFile());
246			inputParams = selectedInputOptions.getOptions();
247		}
248		outputParams = selectedOutputOptions.getOptions();
249		
250		jEdit.setProperty(OUTPUT_TYPE_PROP,(String)outputTypeBox.getSelectedItem());
251		
252		selectedInputOptions.saveOptions();
253		selectedOutputOptions.saveOptions();
254
255		TrangTranslator.translate(view,
256			(String)inputTypeBox.getSelectedItem(),
257			inputs,
258			inputParams,
259			(String)outputTypeBox.getSelectedItem(),
260			outputField.getFile(),
261			outputParams);
262		
263		setVisible(false);
264	}
265	
266	public void cancel(){
267		setVisible(false);
268	}
269	
270	
271	class Options extends JPanel{
272		private int y;
273		private String propertyPrefix;
274		protected Map<String,Option> options;
275		
276		Options(String propertyPrefix){
277			super(new KappaLayout());
278			this.propertyPrefix=propertyPrefix;
279			options = new HashMap<String,Option>();
280		}
281		
282		protected final void addStringOption(String name){
283			JLabel l = new JLabel(jEdit.getProperty(propertyPrefix+name+".label"));
284			add(l,"0, "+y+", 1, 1, E, 0, 5");
285			
286			StringOption option = new StringOption(name);
287			option.setToolTipText(jEdit.getProperty(propertyPrefix+name+".tooltip"));
288			option.setParamValue(jEdit.getProperty(propertyPrefix+name));
289			options.put(name,option);
290			add(option, "1, "+y+", 8, 1, W, w, 5");
291			y++;
292		}
293		
294		protected final void addCustomOption(String name,JComponent comp, int h){
295			JLabel l = new JLabel(jEdit.getProperty(propertyPrefix+name+".label"));
296			add(l,"0, "+y+", 1, 1, E, 0, 5");
297			add(comp, "1, "+y+", 8, "+h+", W, w, 5");
298			y+=h;
299		}
300		
301		protected final void addCheckOption(String name, boolean isNoOption){
302			CheckOption option = new CheckOption(name
303				,jEdit.getProperty(propertyPrefix+name+".label")
304				,isNoOption);
305			option.setToolTipText(jEdit.getProperty(propertyPrefix+name+".tooltip"));
306			option.setParamValue(jEdit.getProperty(propertyPrefix+name));
307			options.put(name,option);
308			add(option, "1, "+y+", 8, 1, W, 0, 5");
309			y++;
310		}
311
312		protected final void addComboOption(String name, String[] values){
313			JLabel l = new JLabel(jEdit.getProperty(name+".label"));
314			add(l,"0, "+y+", 1, 1, E, 0, 5");
315			ComboOption option = new ComboOption(name,values);
316			option.setToolTipText(jEdit.getProperty(propertyPrefix+name+".tooltip"));
317			option.setParamValue(jEdit.getProperty(propertyPrefix+name));
318			options.put(name,option);
319			add(option, "1, "+y+", 8, 1, W, w, 5");
320			y++;
321		}
322
323		public List<String> getOptions(){
324			List<String> res = new ArrayList<String>();
325			for(Option o: options.values()){
326				if(o.hasValue()){
327					res.add(o.getParamValue());
328				}
329			}
330			return res;
331		}
332		
333		public void saveOptions(){
334			for(Option o: options.values()){
335				jEdit.setProperty(propertyPrefix+o.getName(),o.getParamValue());
336			}
337		}
338		
339		public void inputTypeChanged(String newInputType){}
340		public void outputTypeChanged(String newOutputType){}
341	}
342	
343	class XMLOptions extends Options{
344		private VFSFileList list;
345
346		XMLOptions(){
347			super("xml.translate.xml.");
348			setLayout(new BorderLayout());
349			
350			JLabel l = new JLabel(jEdit.getProperty("xml.translate.xml-inputs.label"));
351			l.setAlignmentX(l.LEFT_ALIGNMENT);
352			add(l,BorderLayout.NORTH);
353			
354			list = new VFSFileList(view,"xml.translate.xml-inputs");
355			add(list, BorderLayout.CENTER);
356		}
357		
358		public List<String> getOptions(){
359			Object[] paths = list.getItems();
360			ArrayList<String> al = new ArrayList<String>();
361			for(int i=0;i<paths.length;i++){
362				al.add((String)paths[i]);
363			}
364			return al;
365		}
366		
367	}
368	
369	class DTDOptions extends Options{
370		JTextArea namespaces;
371		
372		DTDOptions(){
373			super("xml.translate.dtd.");
374			
375			addStringOption("xmlns");
376			addCustomOption("namespaces",initNamespaces(),2);
377			addStringOption("colon-replacement");
378			addStringOption("element-define");
379			addCheckOption("inline-attlist",true);
380			addStringOption("attlist-define");
381			addStringOption("any-name");
382			addCheckOption("strict-any",false);
383			addStringOption("annotation-prefix");
384			addCheckOption("generate-start",false);
385			
386		}
387		
388		private JComponent initNamespaces(){
389			namespaces = new JTextArea(3,30);
390			namespaces.setName("namespaces");
391			namespaces.setText(jEdit.getProperty("xml.translate.dtd.namespaces",""));
392			namespaces.setToolTipText(jEdit.getProperty("xml.translate.dtd.namespaces.tooltip"));
393			namespaces.addKeyListener(new KeyAdapter(){
394					public void keyPressed(KeyEvent e){
395						if(KeyEvent.VK_ENTER == e.getKeyCode()){
396							namespaces.setText(namespaces.getText()+"\n");
397							e.consume();
398						}
399					}
400					public void keyReleased(KeyEvent e){
401						if(KeyEvent.VK_ENTER == e.getKeyCode()){
402							e.consume();
403						}
404					}
405			});
406			JScrollPane scr = new JScrollPane(namespaces);
407			//scr.setVerticalScrollBarPolicy(scr.VERTICAL_SCROLLBAR_NEVER);
408			return scr;
409		}
410		
411		public void outputTypeChanged(String newOutputType){
412			options.get("inline-attlist").setParamValue(
413				"xsd".equals(newOutputType)? 
414					"inline-attlist" : "no-inline-attlist");
415		}
416
417		@Override
418		public List<String> getOptions(){
419			List<String> opts = super.getOptions();
420			String[] nsa = namespaces.getText().split("\\s+");
421			for(String ns : nsa){
422				if(!"".equals(ns))opts.add(ns);
423			}
424			return opts;
425		}
426		
427		@Override
428		public void saveOptions(){
429			super.saveOptions();
430			jEdit.setProperty("xml.translate.dtd.namespaces",namespaces.getText());
431		}
432
433		
434	}
435	
436	class XSDOptions extends Options{
437		
438		XSDOptions(){
439			super("xml.translate.xsd.");
440			
441			String[] process = {"strict","lax","skip"};
442			addCheckOption("disable-abstract-elements",false);
443			addComboOption("any-process-contents",process);
444			addComboOption("any-attribute-process-contents",process);
445		}
446
447		public void inputTypeChanged(String newInputType){
448			options.get("any-process-contents")
449				.setParamValue("dtd".equals(newInputType) ? "strict" :"skip");
450		}
451	}
452	
453	interface Option {
454		public String getParamValue();
455		public void setParamValue(String value);
456		public boolean hasValue();
457		public String getName();
458	}
459	
460	class StringOption extends JTextField implements Option{
461		
462		StringOption(String name){
463			super(20);
464			setName(name);
465		}
466		
467		public String getParamValue(){
468			return getName()+"="+getText();
469		}
470		
471		public void setParamValue(String value){
472			if(value.startsWith(getName()+"=")){
473				setText(value.substring(getName().length()+1));
474			}else{
475				setText(value);
476			}
477		}
478		
479		public boolean hasValue(){
480			return getText().length()>0;
481		}
482	}
483	
484	class CheckOption extends JCheckBox implements Option{
485		private boolean noOption;
486		
487		CheckOption(String name, String label, boolean noOption){
488			super(label);
489			setName(name);
490			this.noOption = noOption;
491			
492		}
493		
494		public String getParamValue(){
495			if(isSelected()){
496				return getName();
497			}else{
498				if(noOption){
499					return "no-"+getName();
500				}else{
501					return null;
502				}
503			}
504		}
505		
506		public void setParamValue(String value){
507			setSelected(getName().equals(value));
508		}
509		
510		public boolean hasValue(){
511			// if xxx doesn't have a no-xxx variant, then don't use it if it's not selected
512			return noOption || isSelected();
513		}
514	}
515	
516	class ComboOption extends JComboBox implements Option{
517		
518		ComboOption(String name, String[] values){
519			super(values);
520			setName(name);
521		}
522		
523		public String getParamValue(){
524			return getName()+"="+getSelectedItem();
525		}
526		
527		public void setParamValue(String value){
528			if(value.startsWith(getName()+"=")){
529				setSelectedItem(value.substring(getName().length()+1));
530			}else{
531				setSelectedItem(value);
532			}
533		}
534
535		public boolean hasValue(){
536			return true;
537		}
538	}
539	
540}