package org.f2o.absurdum.puck.gui.templates; import java.io.IOException; import java.io.InputStream; import java.util.List; import javax.swing.Action; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.MenuElement; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.stream.StreamSource; import org.f2o.absurdum.puck.gui.PuckFrame; import org.f2o.absurdum.puck.gui.codeassist.CodeAssistMenuHandler; import org.f2o.absurdum.puck.gui.config.PuckConfiguration; import org.f2o.absurdum.puck.i18n.UIMessages; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class WorldTemplateMenuBuilder { private Document worldTemplateDoc; private Element worldTemplateRoot; private PuckFrame pf; private boolean useDescriptions = true; //use xml descriptions instead of names in menu items public WorldTemplateMenuBuilder(PuckFrame pf) { this.pf = pf; try { InputStream is = this.getClass().getClassLoader().getResourceAsStream("org/f2o/absurdum/puck/staticconf/worldTemplates.xml"); if ( is == null ) throw new IOException("getResourceAsStream returned null stream for worldTemplates.xml"); Transformer t = TransformerFactory.newInstance().newTransformer(); Source s = new StreamSource(is); DOMResult r = new DOMResult(); t.transform(s,r); worldTemplateDoc = (Document) r.getNode(); worldTemplateRoot = (Element) worldTemplateDoc.getFirstChild(); } catch ( IOException ioe ) { ioe.printStackTrace(); } catch (TransformerConfigurationException e) { e.printStackTrace(); } catch (TransformerFactoryConfigurationError e) { e.printStackTrace(); } catch (TransformerException te) { te.printStackTrace(); } } /** * Returns a menu with the templates for world creation, in the current UI language of, if there are no templates for that language, then in English. * @return */ public JMenu getMenu() { JMenu inOurLanguage = getMenu ( UIMessages.getInstance().getPreferredLanguage() ); if ( inOurLanguage != null ) return inOurLanguage; else return getMenu("en"); } public JMenu getMenu( String preferredLanguage ) { if ( worldTemplateRoot == null ) return null; NodeList nl = worldTemplateRoot.getElementsByTagName("templates"); for ( int i = 0 ; i < nl.getLength(); i++ ) { Element elt = (Element) nl.item(i); if ( preferredLanguage.equals(elt.getAttribute("language")) ) { //this element contains the menus for our language (i.e. the ones we want) return (JMenu) getMenu(elt); } } //no templates found for our language return null; } public JMenuItem getMenu( Element elt ) { if ( "templates".equals(elt.getTagName()) || "menu".equals(elt.getTagName()) ) //top-level or non-top-level menu { //recursively traverse nodes and create a menu with their corresponding submenus JMenu result; if ( useDescriptions ) result = new JMenu ( elt.getAttribute("description") ); else result = new JMenu ( elt.getAttribute("name") ); NodeList nl = elt.getChildNodes(); for ( int i = 0 ; i < nl.getLength() ; i++ ) { if ( nl.item(i) instanceof Element ) { Element child = (Element) nl.item(i); JMenuItem childMenu = getMenu((Element)child); if ( childMenu != null ) result.add(childMenu); } } return result; } if ( "item".equals(elt.getTagName() ) ) { //obtain a leaf menu item JMenuItem result; String label; if ( useDescriptions ) label = ( elt.getAttribute("description") ); else label = ( elt.getAttribute("name") ); result = new JMenuItem(label); Action a = new WorldFromTemplateActionBuilder(pf).getWorldFromTemplateAction(elt.getAttribute("template-ref")); a.putValue(Action.NAME, label); result.setAction(a); return result; } return null; } }