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}