/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.syncope.ide.netbeans.view; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Optional; import java.util.logging.Level; import java.util.logging.Logger; import java.util.prefs.Preferences; import javax.swing.ImageIcon; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.JTextComponent; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.to.MailTemplateTO; import org.apache.syncope.common.lib.to.ReportTemplateTO; import org.apache.syncope.common.lib.to.ImplementationTO; import org.apache.syncope.common.lib.types.IdMImplementationType; import org.apache.syncope.common.lib.types.IdRepoImplementationType; import org.apache.syncope.common.lib.types.MailTemplateFormat; import org.apache.syncope.common.lib.types.ReportTemplateFormat; import org.apache.syncope.common.lib.types.ImplementationEngine; import org.apache.syncope.ide.netbeans.PluginConstants; import org.apache.syncope.ide.netbeans.ResourceConnector; import org.apache.syncope.ide.netbeans.service.MailTemplateManagerService; import org.apache.syncope.ide.netbeans.service.ReportTemplateManagerService; import org.apache.syncope.ide.netbeans.service.ImplementationManagerService; import org.apache.syncope.ide.netbeans.service.SyncopeManagerService; import org.netbeans.api.editor.EditorRegistry; import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.settings.ConvertAsProperties; import org.openide.awt.ActionID; import org.openide.awt.ActionReference; import org.openide.cookies.OpenCookie; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.openide.loaders.DataObject; import org.openide.util.Exceptions; import org.openide.util.NbPreferences; import org.openide.util.RequestProcessor; import org.openide.windows.TopComponent; /** * Top component which displays something. */ @ConvertAsProperties( dtd = "-//org.apache.syncope.ide.netbeans//ResourceExplorer//EN", autostore = false ) @TopComponent.Description( preferredID = "ResourceExplorerTopComponent", iconBase = "images/syncope.png", persistenceType = TopComponent.PERSISTENCE_ALWAYS ) @TopComponent.Registration(mode = "explorer", openAtStartup = false) @ActionID(category = "Window", id = "org.apache.syncope.ide.netbeans.ResourceExplorerTopComponent") @ActionReference(path = "Menu/Window") @TopComponent.OpenActionRegistration( displayName = "Apache Syncope", preferredID = "ResourceExplorerTopComponent" ) public final class ResourceExplorerTopComponent extends TopComponent { private static final long serialVersionUID = -1643737786852621861L; public static final Logger LOG = Logger.getLogger("ResourceExplorerTopComponent"); private static final RequestProcessor REQUEST_PROCESSOR = new RequestProcessor(ResourceExplorerTopComponent.class); private final DefaultTreeModel treeModel; private final DefaultMutableTreeNode visibleRoot; private final DefaultMutableTreeNode root; private final DefaultMutableTreeNode mailTemplates; private final DefaultMutableTreeNode reportXslts; private final DefaultMutableTreeNode groovyScripts; private SyncopeManagerService syncopeManagerService; private MailTemplateManagerService mailTemplateManagerService; private ReportTemplateManagerService reportTemplateManagerService; private ImplementationManagerService implementationManagerService; private Charset encodingPattern; public ResourceExplorerTopComponent() { initComponents(); setName(PluginConstants.ROOT_NAME); setToolTipText(PluginConstants.TOOL_TIP_TEXT); treeModel = (DefaultTreeModel) resourceExplorerTree.getModel(); root = (DefaultMutableTreeNode) treeModel.getRoot(); visibleRoot = new DefaultMutableTreeNode(PluginConstants.ROOT_NAME); mailTemplates = new DefaultMutableTreeNode(PluginConstants.MAIL_TEMPLATES); reportXslts = new DefaultMutableTreeNode(PluginConstants.REPORT_XSLTS); groovyScripts = new DefaultMutableTreeNode(PluginConstants.GROOVY_SCRIPTS); root.add(visibleRoot); initTemplatesTree(); } /** * This method is called from within the constructor to initialize the form. WARNING: Do NOT modify this code. The * content of this method is always regenerated by the Form Editor. */ //CHECKSTYLE:OFF // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { jScrollPane1 = new javax.swing.JScrollPane(); resourceExplorerTree = new javax.swing.JTree(); javax.swing.tree.DefaultMutableTreeNode treeNode1 = new javax.swing.tree.DefaultMutableTreeNode("root"); resourceExplorerTree.setModel(new javax.swing.tree.DefaultTreeModel(treeNode1)); resourceExplorerTree.setRootVisible(false); resourceExplorerTree.setScrollsOnExpand(true); resourceExplorerTree.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { resourceExplorerTreeMouseClicked(evt); } }); jScrollPane1.setViewportView(resourceExplorerTree); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 258, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 445, Short.MAX_VALUE) ); }// </editor-fold>//GEN-END:initComponents //CHECKSTYLE:ON @Override public Image getIcon() { return new ImageIcon(getClass().getResource("/org/apache/syncope/ide/netbeans/view/favicon.png")).getImage(); } private void resourceExplorerTreeMouseClicked(final java.awt.event.MouseEvent evt) { if (evt.getButton() == MouseEvent.BUTTON1 && evt.getClickCount() == 2) { DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) resourceExplorerTree. getLastSelectedPathComponent(); DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) selectedNode.getParent(); String parentNodeName = Optional.ofNullable(parentNode) .map(node -> String.valueOf(node.getUserObject())).orElse(null); if (selectedNode.isLeaf() && StringUtils.isNotBlank(parentNodeName)) { String leafNodeName = (String) selectedNode.getUserObject(); DefaultMutableTreeNode grandParentNode = (DefaultMutableTreeNode) parentNode.getParent(); String grandParentNodeName = (String) grandParentNode.getUserObject(); try { if (PluginConstants.MAIL_TEMPLATES.equals(parentNodeName)) { openMailEditor(leafNodeName); } else if (PluginConstants.REPORT_XSLTS.equals(parentNodeName)) { openReportEditor(leafNodeName); } else if (PluginConstants.GROOVY_SCRIPTS.equals(grandParentNodeName)) { openScriptEditor(leafNodeName, parentNodeName); } } catch (SyncopeClientException ex) { JOptionPane.showMessageDialog(null, ex.getMessage(), "Syncope Error", JOptionPane.ERROR_MESSAGE); } catch (IOException ex) { JOptionPane.showMessageDialog(null, ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } catch (Exception ex) { LOG.log(Level.WARNING, "While navigating explorer tree {0}", ex); getRefreshServerDetails().setVisible(true); } } } else if (evt.getButton() == MouseEvent.BUTTON3 && evt.getClickCount() == 1) { DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) resourceExplorerTree. getLastSelectedPathComponent(); if (selectedNode != null) { DefaultMutableTreeNode parent = (DefaultMutableTreeNode) selectedNode.getParent(); String parentNodeName = (String) parent.getUserObject(); String selectedNodeName = (String) selectedNode.getUserObject(); if (selectedNode.isLeaf() && !PluginConstants.ROOT_NAME.equals(selectedNodeName) && !PluginConstants.MAIL_TEMPLATES.equals(selectedNodeName) && !PluginConstants.REPORT_XSLTS.equals(selectedNodeName) && !PluginConstants.GROOVY_SCRIPTS.equals(parentNodeName)) { leafRightClickAction(evt, selectedNode); } else if (PluginConstants.MAIL_TEMPLATES.equals(selectedNodeName)) { folderRightClickAction(evt, mailTemplates); } else if (PluginConstants.REPORT_XSLTS.equals(selectedNodeName)) { folderRightClickAction(evt, reportXslts); } else if (PluginConstants.GROOVY_SCRIPTS.equals(parentNodeName)) { folderRightClickAction(evt, selectedNode); } else if (PluginConstants.ROOT_NAME.equals(selectedNodeName)) { rootRightClickAction(evt); } } } } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTree resourceExplorerTree; // End of variables declaration//GEN-END:variables @Override public void componentOpened() { // look for connection preferences Preferences prefs = NbPreferences.forModule(ResourceExplorerTopComponent.class); if (StringUtils.isBlank(prefs.get("scheme", null)) || StringUtils.isBlank(prefs.get("host", null)) || StringUtils.isBlank(prefs.get("port", null)) || StringUtils.isBlank(prefs.get("username", null)) || StringUtils.isBlank(prefs.get("password", null))) { new ServerDetailsView(null, true).setVisible(true); } try { syncopeManagerService = ResourceConnector.getSyncopeManagerService(); mailTemplateManagerService = ResourceConnector.getMailTemplateManagerService(); reportTemplateManagerService = ResourceConnector.getReportTemplateManagerService(); implementationManagerService = ResourceConnector.getImplementationManagerService(); // init tree, because on close it is reset initTemplatesTree(); // Load templates LOG.info("Loading Apache Syncope templates..."); Runnable tsk = () -> { final ProgressHandle progr = ProgressHandle.createHandle("Loading Templates", () -> true); progr.start(); progr.progress("Loading Templates."); addMailTemplates(); addReportXslts(); addGroovyScripts(); progr.finish(); }; REQUEST_PROCESSOR.post(tsk); } catch (IOException e) { JOptionPane.showMessageDialog(null, e.getMessage(), "Generic Error", JOptionPane.ERROR_MESSAGE); getRefreshServerDetails(); } catch (Exception ex) { getRefreshServerDetails().setVisible(true); } } @Override public void componentClosed() { // TODO add custom code on component resetTree(); } static void writeProperties(final java.util.Properties p) { // better to version settings since initial version as advocated at // http://wiki.apidesign.org/wiki/PropertyFiles p.setProperty("version", "1.0"); // TODO store your settings } static void readProperties(final java.util.Properties p) { String version = p.getProperty("version"); // TODO read your settings according to their version } private void addMailTemplates() { List<MailTemplateTO> mailTemplateList = mailTemplateManagerService.list(); mailTemplateList .forEach(mailTemplate -> this.mailTemplates.add(new DefaultMutableTreeNode(mailTemplate.getKey()))); treeModel.reload(); } private void addReportXslts() { List<ReportTemplateTO> reportTemplates = reportTemplateManagerService.list(); reportTemplates.forEach(reportTemplate -> reportXslts.add(new DefaultMutableTreeNode(reportTemplate.getKey()))); treeModel.reload(); } private void addGroovyScripts() { syncopeManagerService.getImplementationTypes().stream(). filter(type -> !IdRepoImplementationType.JWT_SSO_PROVIDER.equals(type) && !IdRepoImplementationType.AUDIT_APPENDER.equals(type)). forEach(type -> { DefaultMutableTreeNode tempNode = new DefaultMutableTreeNode(type); List<ImplementationTO> scripts = implementationManagerService.list(type); scripts.stream(). filter((script) -> (script.getEngine() == ImplementationEngine.GROOVY)). forEach(script -> tempNode.add(new DefaultMutableTreeNode(script.getKey()))); groovyScripts.add(tempNode); }); treeModel.reload(); } private void rootRightClickAction(final MouseEvent evt) { JPopupMenu menu = new JPopupMenu(); JMenuItem refreshItem = new JMenuItem("Refresh Templates"); JMenuItem resetConnectionItem = new JMenuItem("Reset Connection"); menu.add(refreshItem); menu.add(resetConnectionItem); refreshItem.addActionListener(event -> { // simulate close and open to refresh the tree componentClosed(); componentOpened(); }); resetConnectionItem.addActionListener(event -> { ServerDetailsView serverDetails = getRefreshServerDetails(); // set previous preferences Preferences prefs = NbPreferences.forModule(ResourceExplorerTopComponent.class); serverDetails.setDetails(prefs.get("scheme", "http"), prefs.get("host", "localhost"), prefs.get("port", "8080"), prefs.get("username", StringUtils.EMPTY), prefs.get("password", StringUtils.EMPTY)); // reset connection preferences prefs.remove("scheme"); prefs.remove("host"); prefs.remove("port"); prefs.remove("username"); prefs.remove("password"); serverDetails.setVisible(true); }); menu.show(evt.getComponent(), evt.getX(), evt.getY()); } private void folderRightClickAction(final MouseEvent evt, final DefaultMutableTreeNode node) { JPopupMenu menu = new JPopupMenu(); JMenuItem addItem = new JMenuItem("New"); menu.add(addItem); addItem.addActionListener(event -> { try { String name1 = JOptionPane.showInputDialog("Enter Name"); if (StringUtils.isBlank(name1)) { return; } DefaultMutableTreeNode parent1 = (DefaultMutableTreeNode) node.getParent(); if (!"exit".equals(event.getActionCommand())) { boolean added; if (PluginConstants.MAIL_TEMPLATES.equals(node.getUserObject())) { MailTemplateTO mailTemplate = new MailTemplateTO(); mailTemplate.setKey(name1); added = mailTemplateManagerService.create(mailTemplate); mailTemplateManagerService.setFormat(name1, MailTemplateFormat.HTML, IOUtils.toInputStream("//Enter Content here", encodingPattern)); mailTemplateManagerService.setFormat(name1, MailTemplateFormat.TEXT, IOUtils.toInputStream("//Enter Content here", encodingPattern)); openMailEditor(name1); } else if (PluginConstants.GROOVY_SCRIPTS.equals(parent1.getUserObject())) { ImplementationTO newNode = new ImplementationTO(); String type = (String) node.getUserObject(); newNode.setKey(name1); newNode.setEngine(ImplementationEngine.GROOVY); newNode.setType(type); String templateClassName = null; switch (type) { case IdRepoImplementationType.REPORTLET: templateClassName = "MyReportlet"; break; case IdRepoImplementationType.ACCOUNT_RULE: templateClassName = "MyAccountRule"; break; case IdRepoImplementationType.PASSWORD_RULE: templateClassName = "MyPasswordRule"; break; case IdRepoImplementationType.ITEM_TRANSFORMER: templateClassName = "MyItemTransformer"; break; case IdRepoImplementationType.TASKJOB_DELEGATE: templateClassName = "MySchedTaskJobDelegate"; break; case IdMImplementationType.RECON_FILTER_BUILDER: templateClassName = "MyReconFilterBuilder"; break; case IdRepoImplementationType.LOGIC_ACTIONS: templateClassName = "MyLogicActions"; break; case IdMImplementationType.PROPAGATION_ACTIONS: templateClassName = "MyPropagationActions"; break; case IdMImplementationType.PULL_ACTIONS: templateClassName = "MyPullActions"; break; case IdMImplementationType.PUSH_ACTIONS: templateClassName = "MyPushActions"; break; case IdMImplementationType.PULL_CORRELATION_RULE: templateClassName = "MyPullCorrelationRule"; break; case IdMImplementationType.PUSH_CORRELATION_RULE: templateClassName = "MyPushCorrelationRule"; break; case IdRepoImplementationType.VALIDATOR: templateClassName = "MyValidator"; break; case IdRepoImplementationType.RECIPIENTS_PROVIDER: templateClassName = "MyRecipientsProvider"; break; case IdMImplementationType.PROVISION_SORTER: templateClassName = "MyProvisionSorter"; break; default: } newNode.setBody(IOUtils.toString(getClass().getResourceAsStream( "/org/apache/syncope/ide/netbeans/implementations/" + templateClassName + ".groovy"), StandardCharsets.UTF_8)); added = implementationManagerService.create(newNode); openScriptEditor(name1, (String) node.getUserObject()); } else { ReportTemplateTO reportTemplate = new ReportTemplateTO(); reportTemplate.setKey(name1); added = reportTemplateManagerService.create(reportTemplate); reportTemplateManagerService.setFormat(name1, ReportTemplateFormat.FO, IOUtils.toInputStream("//Enter content here", encodingPattern)); reportTemplateManagerService.setFormat(name1, ReportTemplateFormat.CSV, IOUtils.toInputStream("//Enter content here", encodingPattern)); reportTemplateManagerService.setFormat(name1, ReportTemplateFormat.HTML, IOUtils.toInputStream("//Enter content here", encodingPattern)); openReportEditor(name1); } if (added) { node.add(new DefaultMutableTreeNode(name1)); treeModel.reload(node); } else { JOptionPane.showMessageDialog( null, "Error while creating new element", "Error", JOptionPane.ERROR_MESSAGE); } } } catch (SyncopeClientException sce) { JOptionPane.showMessageDialog(null, sce.getMessage(), "Syncope Error", JOptionPane.ERROR_MESSAGE); } catch (IOException ioe) { JOptionPane.showMessageDialog(null, ioe.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); } catch (Exception e) { LOG.log(Level.WARNING, "Refreshing after exception", e); getRefreshServerDetails().setVisible(true); } }); menu.show(evt.getComponent(), evt.getX(), evt.getY()); } private void leafRightClickAction(final MouseEvent evt, final DefaultMutableTreeNode node) { JPopupMenu menu = new JPopupMenu(); JMenuItem deleteItem = new JMenuItem("Delete"); menu.add(deleteItem); deleteItem.addActionListener(event -> { int result = JOptionPane.showConfirmDialog(null, "Are you sure to delete the item?"); if (result == JOptionPane.OK_OPTION) { DefaultMutableTreeNode parent1 = (DefaultMutableTreeNode) node.getParent(); String nodeName1 = (String) node.getUserObject(); try { boolean deleted; if (PluginConstants.MAIL_TEMPLATES.equals(parent1.getUserObject())) { deleted = mailTemplateManagerService.delete(nodeName1); } else if (PluginConstants.REPORT_XSLTS.equals(parent1.getUserObject())) { deleted = reportTemplateManagerService.delete(nodeName1); } else { String type = (String) parent1.getUserObject(); deleted = implementationManagerService.delete(type, nodeName1); } if (deleted) { node.removeFromParent(); treeModel.reload(parent1); } else { JOptionPane.showMessageDialog( null, "Error while deleting new element", "Error", JOptionPane.ERROR_MESSAGE); } } catch (SyncopeClientException exc) { JOptionPane.showMessageDialog( null, exc.getMessage(), "Syncope Error", JOptionPane.ERROR_MESSAGE); } catch (Exception ex) { getRefreshServerDetails().setVisible(true); } } }); menu.show(evt.getComponent(), evt.getX(), evt.getY()); } private void openMailEditor(final String name) throws IOException { String formatStr = (String) JOptionPane.showInputDialog(null, "Select File Format", "File format", JOptionPane.QUESTION_MESSAGE, null, PluginConstants.MAIL_TEMPLATE_FORMATS, MailTemplateFormat.TEXT.name()); if (StringUtils.isNotBlank(formatStr)) { MailTemplateFormat format = MailTemplateFormat.valueOf(formatStr); String type = null; InputStream is = null; switch (format) { case HTML: type = "html"; is = (InputStream) mailTemplateManagerService.getFormat(name, MailTemplateFormat.HTML); break; case TEXT: type = "txt"; is = (InputStream) mailTemplateManagerService.getFormat(name, MailTemplateFormat.TEXT); break; default: LOG.log(Level.SEVERE, String.format("Format [%s] not supported", format)); break; } String content = is == null ? StringUtils.EMPTY : IOUtils.toString(is, encodingPattern); String mailTemplatesDirName = System.getProperty("java.io.tmpdir") + "/Templates/Mail/"; File mailTemplatesDir = new File(mailTemplatesDirName); if (!mailTemplatesDir.exists()) { mailTemplatesDir.mkdirs(); } File file = new File(mailTemplatesDirName + name + '.' + type); FileWriter fw = new FileWriter(file, StandardCharsets.UTF_8); fw.write(content); fw.flush(); FileObject fob = FileUtil.toFileObject(file.getAbsoluteFile()); fob.setAttribute("description", "TEXT"); DataObject data = DataObject.find(fob); data.getLookup().lookup(OpenCookie.class).open(); data.addPropertyChangeListener(event -> { if (DataObject.PROP_MODIFIED.equals(event.getPropertyName())) { //save item remotely LOG.info(String.format("Saving Mail template [%s]", name)); saveContent(); } }); } } private void openScriptEditor(final String name, final String type) throws IOException { ImplementationTO node = implementationManagerService.read(type, name); String groovyScriptsDirName = System.getProperty("java.io.tmpdir") + "/Groovy/" + node.getType() + '/'; File groovyScriptsDir = new File(groovyScriptsDirName); if (!groovyScriptsDir.exists()) { groovyScriptsDir.mkdirs(); } File file = new File(groovyScriptsDirName + name + ".groovy"); FileWriter fw = new FileWriter(file, StandardCharsets.UTF_8); fw.write(node.getBody()); fw.flush(); FileObject fob = FileUtil.toFileObject(file.getAbsoluteFile()); DataObject data = DataObject.find(fob); data.getLookup().lookup(OpenCookie.class).open(); data.addPropertyChangeListener(event -> { if (DataObject.PROP_MODIFIED.equals(event.getPropertyName())) { //save item remotely LOG.info(String.format("Saving Groovy template [%s]", name)); saveContent(); } }); } private void openReportEditor(final String name) throws IOException { String formatStr = (String) JOptionPane.showInputDialog(null, "Select File Format", "File format", JOptionPane.QUESTION_MESSAGE, null, PluginConstants.REPORT_TEMPLATE_FORMATS, ReportTemplateFormat.FO.name()); if (StringUtils.isNotBlank(formatStr)) { ReportTemplateFormat format = ReportTemplateFormat.valueOf(formatStr); InputStream is = null; switch (format) { case HTML: is = (InputStream) reportTemplateManagerService.getFormat(name, ReportTemplateFormat.HTML); break; case CSV: is = (InputStream) reportTemplateManagerService.getFormat(name, ReportTemplateFormat.CSV); break; case FO: is = (InputStream) reportTemplateManagerService.getFormat(name, ReportTemplateFormat.FO); break; default: LOG.log(Level.SEVERE, String.format("Format [%s] not supported", format)); break; } String content = is == null ? StringUtils.EMPTY : IOUtils.toString(is, encodingPattern); String reportTemplatesDirName = System.getProperty("java.io.tmpdir") + "/Templates/Report/"; File reportTemplatesDir = new File(reportTemplatesDirName); if (!reportTemplatesDir.exists()) { reportTemplatesDir.mkdirs(); } File file = new File(reportTemplatesDirName + name + '.' + format. name().toLowerCase()); FileWriter fw = new FileWriter(file, StandardCharsets.UTF_8); fw.write(content); fw.flush(); FileObject fob = FileUtil.toFileObject(file.getAbsoluteFile()); DataObject data = DataObject.find(fob); data.getLookup().lookup(OpenCookie.class).open(); data.addPropertyChangeListener(event -> { if (DataObject.PROP_MODIFIED.equals(event.getPropertyName())) { //save item remotely LOG.info(String.format("Saving Report template [%s]", name)); saveContent(); } }); } } private void saveContent() { try { JTextComponent ed = EditorRegistry.lastFocusedComponent(); Document document = ed.getDocument(); String content = document.getText(0, document.getLength()); String path = (String) document.getProperty(Document.TitleProperty); String[] temp = path.split(File.separator.replace("\\", "\\\\")); String name = temp[temp.length - 1]; String fileName = temp[temp.length - 3]; String templateType = temp[temp.length - 2]; temp = name.split("\\."); String format = temp[1]; String key = temp[0]; if ("Mail".equals(templateType)) { if ("txt".equals(format)) { mailTemplateManagerService.setFormat(key, MailTemplateFormat.TEXT, IOUtils.toInputStream(content, encodingPattern)); } else { mailTemplateManagerService.setFormat(key, MailTemplateFormat.HTML, IOUtils.toInputStream(content, encodingPattern)); } } else if ("html".equals(format)) { reportTemplateManagerService.setFormat(key, ReportTemplateFormat.HTML, IOUtils.toInputStream(content, encodingPattern)); } else if ("fo".equals(format)) { reportTemplateManagerService.setFormat(key, ReportTemplateFormat.FO, IOUtils.toInputStream(content, encodingPattern)); } else if ("csv".equals(format)) { reportTemplateManagerService.setFormat(key, ReportTemplateFormat.CSV, IOUtils.toInputStream(content, encodingPattern)); } else if ("Groovy".equals(fileName)) { ImplementationTO node = implementationManagerService.read(templateType, key); node.setBody(content); implementationManagerService.update(node); } } catch (BadLocationException e) { Exceptions.printStackTrace(e); } catch (Exception e) { getRefreshServerDetails().setVisible(true); } } private void initTemplatesTree() { visibleRoot.add(mailTemplates); visibleRoot.add(reportXslts); visibleRoot.add(groovyScripts); treeModel.reload(); } private void resetTree() { visibleRoot.removeAllChildren(); mailTemplates.removeAllChildren(); reportXslts.removeAllChildren(); groovyScripts.removeAllChildren(); treeModel.reload(); } private ServerDetailsView getRefreshServerDetails() { return new ServerDetailsView(null, true) { private static final long serialVersionUID = 3926689175745815987L; @Override protected void okButtonActionPerformed(final ActionEvent evt) { super.okButtonActionPerformed(evt); // simulate close and open to refresh the tree componentClosed(); componentOpened(); } }; } }