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 final static 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 Document doc = new Document(panel); 089 XMLOutputter out = new XMLOutputter(); 090 out.setFormat(Format.getPrettyFormat() 091 .setLineSeparator(System.getProperty("line.separator")) 092 .setTextMode(Format.TextMode.TRIM)); 093 094 return out.outputString(doc); 095 } catch (NullPointerException ex) { 096 log.warn("Requested Panel [{}] does not exist.", name); 097 return "ERROR Requested panel [" + name + "] does not exist."; 098 } 099 } 100 101 @Override 102 protected String getJsonPanel(String name) { 103 log.debug("Getting {} for {}", getPanelType(), name); 104 try { 105 PanelEditor editor = (PanelEditor) getEditor(name); 106 if (editor == null) { 107 log.warn("Requested Panel [{}] does not exist.", name); 108 return "ERROR Requested panel [" + name + "] does not exist."; 109 } 110 111 ObjectNode root = this.mapper.createObjectNode(); 112 ObjectNode panel = root.putObject("panel"); 113 114 JFrame frame = editor.getTargetFrame(); 115 116 panel.put("name", name); 117 panel.put("height", frame.getContentPane().getHeight()); 118 panel.put("width", frame.getContentPane().getWidth()); 119 panel.put("panelheight", frame.getContentPane().getHeight()); 120 panel.put("panelwidth", frame.getContentPane().getWidth()); 121 122 panel.put("showtooltips", editor.showToolTip()); 123 panel.put("controlling", editor.allControlling()); 124 if (editor.getBackgroundColor() != null) { 125 ObjectNode color = panel.putObject("backgroundColor"); 126 color.put("red", editor.getBackgroundColor().getRed()); 127 color.put("green", editor.getBackgroundColor().getGreen()); 128 color.put("blue", editor.getBackgroundColor().getBlue()); 129 } 130 131 // include contents 132 log.debug("N elements: {}", editor.getContents().size()); 133 for (Positionable sub : editor.getContents()) { 134 try { 135 // TODO: get all panel contents as JSON 136 // I tried using JavaBean Introspection to simply build the contents using Jackson Databindings, 137 // but when a panel element has a reference to the panel or to itself as a property, this leads 138 // to infinite recursion 139 log.debug("missing code, so not processing Positionable {}", sub); 140 } catch (Exception ex) { 141 log.error("Error storing panel element: {}", sub, ex); 142 } 143 } 144 145 return this.mapper.writeValueAsString(root); 146 } catch (NullPointerException ex) { 147 log.warn("Requested Panel [{}] does not exist.", name); 148 return "ERROR Requested panel [" + name + "] does not exist."; 149 } catch (JsonGenerationException e) { 150 log.error("Error generating JSON", e); 151 return "ERROR " + e.getLocalizedMessage(); 152 } catch (JsonMappingException e) { 153 log.error("Error mapping JSON", e); 154 return "ERROR " + e.getLocalizedMessage(); 155 } catch (IOException e) { 156 log.error("IOException", e); 157 return "ERROR " + e.getLocalizedMessage(); 158 } 159 } 160}