001package jmri.web.servlet.panel; 002 003import com.fasterxml.jackson.core.JsonGenerationException; 004import com.fasterxml.jackson.databind.JsonMappingException; 005import com.fasterxml.jackson.databind.node.ObjectNode; 006import java.io.IOException; 007import java.util.List; 008import javax.servlet.annotation.WebServlet; 009import javax.servlet.http.HttpServlet; 010import javax.swing.JFrame; 011import jmri.jmrit.display.Positionable; 012import jmri.jmrit.display.panelEditor.PanelEditor; 013import org.jdom2.Document; 014import org.jdom2.Element; 015import org.jdom2.output.Format; 016import org.jdom2.output.XMLOutputter; 017import org.openide.util.lookup.ServiceProvider; 018import org.slf4j.Logger; 019import org.slf4j.LoggerFactory; 020 021/** 022 * Return xml (for specified Panel) suitable for use by external clients. 023 * <p> 024 * See JMRI Web Server - Panel Servlet Help in help/en/html/web/PanelServlet.shtml for an example description of 025 * the interaction between the Web Servlets, the Web Browser and the JMRI application. 026 * 027 * @author Randall Wood (C) 2016 028 */ 029@WebServlet(name = "PanelServlet", 030 urlPatterns = { 031 "/panel", 032 "/panel/Panel", 033 "/web/showPanel.html" // redirect to /panel/ since ~ 19 Jan 2014 034 }) 035@ServiceProvider(service = HttpServlet.class) 036public class PanelServlet extends AbstractPanelServlet { 037 038 private static final Logger log = LoggerFactory.getLogger(PanelServlet.class); 039 040 @Override 041 protected String getPanelType() { 042 return "Panel"; // NOI18N 043 } 044 045 @Override 046 protected String getXmlPanel(String name) { 047 log.debug("Getting {} for {}", getPanelType(), name); 048 try { 049 PanelEditor editor = (PanelEditor) getEditor(name); 050 if (editor == null) { 051 log.warn("Requested Panel [{}] does not exist.", name); 052 return "ERROR Requested panel [" + name + "] does not exist."; 053 } 054 055 Element panel = new Element("panel"); 056 057 JFrame frame = editor.getTargetFrame(); 058 059 panel.setAttribute("name", name); 060 panel.setAttribute("height", Integer.toString(frame.getContentPane().getHeight())); 061 panel.setAttribute("width", Integer.toString(frame.getContentPane().getWidth())); 062 panel.setAttribute("panelheight", Integer.toString(editor.getTargetPanel().getHeight())); 063 panel.setAttribute("panelwidth", Integer.toString(editor.getTargetPanel().getWidth())); 064 065 panel.setAttribute("showtooltips", (editor.showToolTip()) ? "yes" : "no"); 066 panel.setAttribute("controlling", (editor.allControlling()) ? "yes" : "no"); 067 if (editor.getBackgroundColor() != null) { 068 Element color = new Element("backgroundColor"); 069 color.setAttribute("red", Integer.toString(editor.getBackgroundColor().getRed())); 070 color.setAttribute("green", Integer.toString(editor.getBackgroundColor().getGreen())); 071 color.setAttribute("blue", Integer.toString(editor.getBackgroundColor().getBlue())); 072 panel.addContent(color); 073 } 074 075 // include contents 076 List<Positionable> contents = editor.getContents(); 077 log.debug("Panel has {} elements", contents.size()); 078 for (Positionable sub : contents) { 079 if (sub != null) { 080 try { 081 panel.addContent(positionableElement(sub)); 082 } catch (Exception ex) { 083 log.error("Error storing panel element", ex); 084 } 085 } 086 } 087 088 convertNamedColors(panel); 089 Document doc = new Document(panel); 090 XMLOutputter out = new XMLOutputter(); 091 out.setFormat(Format.getPrettyFormat() 092 .setLineSeparator(System.getProperty("line.separator")) 093 .setTextMode(Format.TextMode.TRIM)); 094 095 return out.outputString(doc); 096 } catch (NullPointerException ex) { 097 log.warn("Requested Panel [{}] does not exist.", name); 098 return "ERROR Requested panel [" + name + "] does not exist."; 099 } 100 } 101 102 @Override 103 protected String getJsonPanel(String name) { 104 log.debug("Getting {} for {}", getPanelType(), name); 105 try { 106 PanelEditor editor = (PanelEditor) getEditor(name); 107 if (editor == null) { 108 log.warn("Requested Panel [{}] does not exist.", name); 109 return "ERROR Requested panel [" + name + "] does not exist."; 110 } 111 112 ObjectNode root = this.mapper.createObjectNode(); 113 ObjectNode panel = root.putObject("panel"); 114 115 JFrame frame = editor.getTargetFrame(); 116 117 panel.put("name", name); 118 panel.put("height", frame.getContentPane().getHeight()); 119 panel.put("width", frame.getContentPane().getWidth()); 120 panel.put("panelheight", frame.getContentPane().getHeight()); 121 panel.put("panelwidth", frame.getContentPane().getWidth()); 122 123 panel.put("showtooltips", editor.showToolTip()); 124 panel.put("controlling", editor.allControlling()); 125 if (editor.getBackgroundColor() != null) { 126 ObjectNode color = panel.putObject("backgroundColor"); 127 color.put("red", editor.getBackgroundColor().getRed()); 128 color.put("green", editor.getBackgroundColor().getGreen()); 129 color.put("blue", editor.getBackgroundColor().getBlue()); 130 } 131 132 // include contents 133 log.debug("N elements: {}", editor.getContents().size()); 134 for (Positionable sub : editor.getContents()) { 135 try { 136 // TODO: get all panel contents as JSON 137 // I tried using JavaBean Introspection to simply build the contents using Jackson Databindings, 138 // but when a panel element has a reference to the panel or to itself as a property, this leads 139 // to infinite recursion 140 log.debug("missing code, so not processing Positionable {}", sub); 141 } catch (Exception ex) { 142 log.error("Error storing panel element: {}", sub, ex); 143 } 144 } 145 146 return this.mapper.writeValueAsString(root); 147 } catch (NullPointerException ex) { 148 log.warn("Requested Panel [{}] does not exist.", name); 149 return "ERROR Requested panel [" + name + "] does not exist."; 150 } catch (JsonGenerationException e) { 151 log.error("Error generating JSON", e); 152 return "ERROR " + e.getLocalizedMessage(); 153 } catch (JsonMappingException e) { 154 log.error("Error mapping JSON", e); 155 return "ERROR " + e.getLocalizedMessage(); 156 } catch (IOException e) { 157 log.error("IOException", e); 158 return "ERROR " + e.getLocalizedMessage(); 159 } 160 } 161}