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}