[SYNCOPE-1220] Support Groovy implementation in the Netbeans plugin, This closes #82 master
authorrohan julka <rohanjulka19@gmail.com>
Tue, 14 Aug 2018 07:20:14 +0000 (09:20 +0200)
committerAndrea Patricelli <andreapatricelli@apache.org>
Tue, 21 Aug 2018 15:20:33 +0000 (17:20 +0200)
18 files changed:
ide/netbeans/pom.xml
ide/netbeans/src/main/java/org/apache/syncope/ide/netbeans/PluginConstants.java
ide/netbeans/src/main/java/org/apache/syncope/ide/netbeans/ResourceConnector.java
ide/netbeans/src/main/java/org/apache/syncope/ide/netbeans/service/ImplementationManagerService.java [new file with mode: 0644]
ide/netbeans/src/main/java/org/apache/syncope/ide/netbeans/view/ResourceExplorerTopComponent.java
ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyAccountRule.groovy [new file with mode: 0644]
ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyItemTransformer.groovy [new file with mode: 0644]
ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyLogicActions.groovy [new file with mode: 0644]
ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyPasswordRule.groovy [new file with mode: 0644]
ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyPropagationActions.groovy [new file with mode: 0644]
ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyPullActions.groovy [new file with mode: 0644]
ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyPullCorrelationRule.groovy [new file with mode: 0644]
ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyPushActions.groovy [new file with mode: 0644]
ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyRecipientsProvider.groovy [new file with mode: 0644]
ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyReconFilterBuilder.groovy [new file with mode: 0644]
ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyReportlet.groovy [new file with mode: 0644]
ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MySchedTaskJobDelegate.groovy [new file with mode: 0644]
ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyValidator.groovy [new file with mode: 0644]

index 719c001..26d2619 100644 (file)
@@ -176,6 +176,7 @@ under the License.
         <filtering>false</filtering>
         <includes>
           <include>org/apache/syncope/**/*.png</include>
+          <include>org/apache/syncope/**/*.groovy</include>
         </includes>
       </resource>
 
index ea2fd80..c1359bf 100644 (file)
@@ -27,6 +27,8 @@ public final class PluginConstants {
 
     public static final String REPORT_XSLTS = "Report XSLTs";
 
+    public static final String GROOVY_SCRIPTS = "Groovy Scripts";
+
     public static final String[] MAIL_TEMPLATE_FORMATS = {
         MailTemplateFormat.HTML.name(), MailTemplateFormat.TEXT.name() };
 
index b7739fa..51df938 100644 (file)
@@ -23,6 +23,7 @@ import java.util.prefs.Preferences;
 import org.apache.commons.lang3.StringUtils;
 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.view.ResourceExplorerTopComponent;
 import org.openide.util.NbPreferences;
 
@@ -32,10 +33,14 @@ public final class ResourceConnector {
 
     private static ReportTemplateManagerService REPORT_TEMPLATE_MANAGER_SERVICE;
 
+     private static ImplementationManagerService IMPLEMENTATION_MANAGER_SERVICE;
+
     private static final Object MAIL_TEMPLATE_MONITOR = new Object();
 
     private static final Object REPORT_TEMPLATE_MONITOR = new Object();
 
+    private static final Object IMPLEMENTATION_MONITOR = new Object();
+
     private ResourceConnector() {
     }
 
@@ -61,6 +66,17 @@ public final class ResourceConnector {
         return REPORT_TEMPLATE_MANAGER_SERVICE;
     }
 
+    public static ImplementationManagerService getImplementationManagerService() throws IOException {
+        synchronized (IMPLEMENTATION_MONITOR) {
+            ConnectionParams connParams = getConnectionParams();
+            IMPLEMENTATION_MANAGER_SERVICE = new ImplementationManagerService(
+                    connParams.getUrl(),
+                    connParams.getUsername(),
+                    connParams.getPassword());
+        }
+        return IMPLEMENTATION_MANAGER_SERVICE;
+    }
+    
     public static ConnectionParams getConnectionParams() {
         Preferences prefs = NbPreferences.forModule(ResourceExplorerTopComponent.class);
         return ConnectionParams.builder()
diff --git a/ide/netbeans/src/main/java/org/apache/syncope/ide/netbeans/service/ImplementationManagerService.java b/ide/netbeans/src/main/java/org/apache/syncope/ide/netbeans/service/ImplementationManagerService.java
new file mode 100644 (file)
index 0000000..b2ccfb8
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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.service;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
+import org.apache.syncope.common.lib.to.ImplementationTO;
+import org.apache.syncope.common.lib.types.ImplementationType;
+import org.apache.syncope.common.rest.api.service.ImplementationService;
+
+public class ImplementationManagerService {
+
+    private final ImplementationService service ;
+
+    public ImplementationManagerService(final String url, final String userName, final String password) {
+        SyncopeClient syncopeClient = new SyncopeClientFactoryBean().setAddress(url).create(userName, password);
+        service = syncopeClient.getService(ImplementationService.class);
+    }
+    public List<ImplementationTO> list(final ImplementationType type) {
+        return service.list(type);
+    } 
+
+    public ImplementationTO read(final ImplementationType type , final String key) {
+        return service.read(type, key);
+    }
+
+    public boolean create(final ImplementationTO implementationTO) {
+        return Response.Status.CREATED.getStatusCode() == service.create(implementationTO).getStatus();
+    }
+
+    public boolean delete(final ImplementationType type , final String key) {
+        return Response.Status.NO_CONTENT.getStatusCode() == service.delete(type, key).getStatus();
+    }
+
+    public boolean update(final ImplementationTO implementationTO) {
+       return Response.Status.NO_CONTENT.getStatusCode() == service.update(implementationTO).getStatus();
+    }
+}
index b2a0198..1edbae0 100644 (file)
@@ -47,13 +47,16 @@ 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.types.ClientExceptionType;
+import org.apache.syncope.common.lib.to.ImplementationTO;
 import org.apache.syncope.common.lib.types.MailTemplateFormat;
 import org.apache.syncope.common.lib.types.ReportTemplateFormat;
+import org.apache.syncope.common.lib.types.ImplementationType;
+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.netbeans.api.editor.EditorRegistry;
 import org.netbeans.api.progress.ProgressHandle;
 import org.netbeans.api.settings.ConvertAsProperties;
@@ -106,10 +109,14 @@ public final class ResourceExplorerTopComponent extends TopComponent {
 
     private final DefaultMutableTreeNode reportXslts;
 
+    private final DefaultMutableTreeNode groovyScripts;
+
     private MailTemplateManagerService mailTemplateManagerService;
 
     private ReportTemplateManagerService reportTemplateManagerService;
 
+    private ImplementationManagerService implementationManagerService;
+
     private Charset encodingPattern;
 
     public ResourceExplorerTopComponent() {
@@ -123,6 +130,7 @@ public final class ResourceExplorerTopComponent extends TopComponent {
         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();
     }
@@ -175,29 +183,43 @@ public final class ResourceExplorerTopComponent extends TopComponent {
             String parentNodeName = parentNode == null ? null : String.valueOf(parentNode.getUserObject());
             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 (IOException e) {
-                    Exceptions.printStackTrace(e);
-                }
+                }  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.info("The Exception is" + ex);
+                getRefreshServerDetails().setVisible(true);
+                }               
             }
         } else if (evt.getButton() == MouseEvent.BUTTON3 && evt.getClickCount() == 1) {
             DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) resourceExplorerTree.
                     getLastSelectedPathComponent();
+            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.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);
             }
@@ -223,6 +245,7 @@ public final class ResourceExplorerTopComponent extends TopComponent {
         try {
             mailTemplateManagerService = ResourceConnector.getMailTemplateManagerService();
             reportTemplateManagerService = ResourceConnector.getReportTemplateManagerService();
+            implementationManagerService = ResourceConnector.getImplementationManagerService();
             // init tree, because on close it is reset
             initTemplatesTree();
             // Load templates
@@ -244,42 +267,24 @@ public final class ResourceExplorerTopComponent extends TopComponent {
                     progr.progress("Loading Templates.");
                     addMailTemplates();
                     addReportXslts();
+                    addGroovyScripts();
                     progr.finish();
                 }
 
-            };
+           }; 
             REQUEST_PROCESSOR.post(tsk);
-        } catch (Exception e) {
+        } catch (IOException e) {
             JOptionPane.showMessageDialog(null, e.getMessage(), "Generic Error", JOptionPane.ERROR_MESSAGE);
             ServerDetailsView serverDetails = getRefreshServerDetails();
+        } catch (Exception ex) {
+            getRefreshServerDetails().setVisible(true);
         }
 
-        Runnable tsk = new Runnable() {
-
-            @Override
-            public void run() {
-                final ProgressHandle progr = ProgressHandle.createHandle("Loading Templates", new Cancellable() {
-
-                    @Override
-                    public boolean cancel() {
-                        return true;
-                    }
-                });
-
-                progr.start();
-                progr.progress("Loading Templates.");
-                addMailTemplates();
-                addReportXslts();
-                progr.finish();
-            }
-
-        };
-        RequestProcessor.getDefault().post(tsk);
     }
-
     @Override
     public void componentClosed() {
-        // TODO add custom code on component closing
+        // TODO add custom code on component
+        resetTree();
     }
 
     void writeProperties(final java.util.Properties p) {
@@ -312,6 +317,26 @@ public final class ResourceExplorerTopComponent extends TopComponent {
         treeModel.reload();
     }
 
+    private void addGroovyScripts() {
+        for (ImplementationType type : ImplementationType.values()) {
+            String implType = type.toString();
+            DefaultMutableTreeNode tempNode = new DefaultMutableTreeNode(implType.toString());
+           if (implType.equals("JWT_SSO_PROVIDER") || implType.equals("AUDIT_APPENDER")) {
+                continue ;
+           }
+            List<ImplementationTO> scripts = implementationManagerService.list(type);
+            for (ImplementationTO script : scripts) {
+                 if (script.getEngine() == ImplementationEngine.GROOVY) {
+                    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");
@@ -363,11 +388,17 @@ public final class ResourceExplorerTopComponent extends TopComponent {
 
             @Override
             public void actionPerformed(final ActionEvent e) {
-                String name = JOptionPane.showInputDialog("Enter Name");
+            try {
+                String name = null ;
+                while (StringUtils.isBlank(name)) {
+                     name = JOptionPane.showInputDialog("Enter Name");
+                }
+                DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent();
                 boolean added = false;
                 if (!"exit".equals(e.getActionCommand())) {
 
-                    if (node.getUserObject().equals(PluginConstants.MAIL_TEMPLATES)) {
+                    if (PluginConstants.MAIL_TEMPLATES.equals(node.getUserObject())) {
+
                         MailTemplateTO mailTemplate = new MailTemplateTO();
                         mailTemplate.setKey(name);
                         added = mailTemplateManagerService.create(mailTemplate);
@@ -377,11 +408,78 @@ public final class ResourceExplorerTopComponent extends TopComponent {
                         mailTemplateManagerService.setFormat(name,
                                 MailTemplateFormat.TEXT,
                                 IOUtils.toInputStream("//Enter Content here", encodingPattern));
-                        try {
                             openMailEditor(name);
-                        } catch (IOException ex) {
-                            Exceptions.printStackTrace(ex);
-                        }
+                    } else if (PluginConstants.GROOVY_SCRIPTS.equals(parent.getUserObject())) {
+                            ImplementationTO newNode = new ImplementationTO();
+                            ImplementationType type = getType((String) node.getUserObject());
+                            newNode.setKey(name);
+                            newNode.setEngine(ImplementationEngine.GROOVY);
+                            newNode.setType(type);
+                            String templateClassName = null;
+                            switch (type) {
+                                case REPORTLET:
+                                    templateClassName = "MyReportlet";
+                                    break;
+
+                                case ACCOUNT_RULE:
+                                    templateClassName = "MyAccountRule";
+                                    break;
+
+                                case PASSWORD_RULE:
+                                    templateClassName = "MyPasswordRule";
+                                    break;
+
+                                case ITEM_TRANSFORMER:
+                                    templateClassName = "MyItemTransformer";
+                                    break;
+
+                                case TASKJOB_DELEGATE:
+                                    templateClassName = "MySchedTaskJobDelegate";
+                                    break;
+
+                                case RECON_FILTER_BUILDER:
+                                    templateClassName = "MyReconFilterBuilder";
+                                    break;
+
+                                case LOGIC_ACTIONS:
+                                    templateClassName = "MyLogicActions";
+                                    break;
+
+                                case PROPAGATION_ACTIONS:
+                                    templateClassName = "MyPropagationActions";
+                                    break;
+
+                                case PULL_ACTIONS:
+                                    templateClassName = "MyPullActions";
+                                    break;
+
+                                case PUSH_ACTIONS:
+                                    templateClassName = "MyPushActions";
+                                    break;
+
+                                case PULL_CORRELATION_RULE:
+                                    templateClassName = "MyPullCorrelationRule";
+                                    break;
+
+                                case PUSH_CORRELATION_RULE:
+                                    templateClassName = "MyPushCorrelationRule";
+                                    break;
+
+                                case VALIDATOR:
+                                    templateClassName = "MyValidator";
+                                    break;
+
+                                case RECIPIENTS_PROVIDER:
+                                    templateClassName = "MyRecipientsProvider";
+                                    break;
+
+                                default:
+                            }
+                                    newNode.setBody(IOUtils.toString(
+                                    getClass().getResourceAsStream("/org/apache/syncope/ide/netbeans/implementations/"
+                                    + templateClassName + ".groovy")));
+                                    added = implementationManagerService.create(newNode);
+                                    openScriptEditor(name, (String) node.getUserObject());
                     } else {
                         ReportTemplateTO reportTemplate = new ReportTemplateTO();
                         reportTemplate.setKey(name);
@@ -395,11 +493,7 @@ public final class ResourceExplorerTopComponent extends TopComponent {
                         reportTemplateManagerService.setFormat(name,
                                 ReportTemplateFormat.HTML,
                                 IOUtils.toInputStream("//Enter content here", encodingPattern));
-                        try {
                             openReportEditor(name);
-                        } catch (IOException ex) {
-                            Exceptions.printStackTrace(ex);
-                        }
                     }
 
                     if (added) {
@@ -410,7 +504,14 @@ public final class ResourceExplorerTopComponent extends TopComponent {
                                 null, "Error while creating new element", "Error", JOptionPane.ERROR_MESSAGE);
                     }
                 }
+            } catch (SyncopeClientException excp) {
+                JOptionPane.showMessageDialog(null, excp.getMessage(), "Syncope Error", JOptionPane.ERROR_MESSAGE);
+            } catch (IOException ex) {
+                JOptionPane.showMessageDialog(null , ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
+            } catch (Exception exc) {
+                 getRefreshServerDetails().setVisible(true);
             }
+        }
         });
 
         menu.show(evt.getComponent(), evt.getX(), evt.getY());
@@ -429,11 +530,16 @@ public final class ResourceExplorerTopComponent extends TopComponent {
                 int result = JOptionPane.showConfirmDialog(null, "Are you sure to delete the item?");
                 if (result == JOptionPane.OK_OPTION) {
                     DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent();
-                    boolean deleted;
-                    if (parent.getUserObject().equals(PluginConstants.MAIL_TEMPLATES)) {
-                        deleted = mailTemplateManagerService.delete((String) node.getUserObject());
+                    String nodeName = (String) node.getUserObject() ;
+                    boolean deleted = false;
+                try {
+                    if (PluginConstants.MAIL_TEMPLATES.equals(parent.getUserObject())) {
+                        deleted = mailTemplateManagerService.delete(nodeName);
+                    } else if (PluginConstants.REPORT_XSLTS.equals(parent.getUserObject())) {
+                        deleted = reportTemplateManagerService.delete(nodeName);
                     } else {
-                        deleted = reportTemplateManagerService.delete((String) node.getUserObject());
+                        ImplementationType type = getType((String) parent.getUserObject());
+                        deleted = implementationManagerService.delete(type, nodeName);
                     }
                     if (deleted) {
                         node.removeFromParent();
@@ -442,6 +548,12 @@ public final class ResourceExplorerTopComponent extends TopComponent {
                         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);
+                    }
                 }
             }
         });
@@ -460,7 +572,6 @@ public final class ResourceExplorerTopComponent extends TopComponent {
             String type = null;
             InputStream is = null;
 
-            try {
                 switch (format) {
                     case HTML:
                         type = "html";
@@ -474,24 +585,6 @@ public final class ResourceExplorerTopComponent extends TopComponent {
                         LOG.log(Level.SEVERE, String.format("Format [%s] not supported", format));
                         break;
                 }
-            } catch (SyncopeClientException e) {
-                LOG.log(Level.SEVERE,
-                        String.format("Unable to get [%s] mail template in [%s] format", name, format), e);
-                if (ClientExceptionType.NotFound.equals(e.getType())) {
-                    LOG.log(Level.SEVERE, String.format(
-                            "Report template in [%s] format not found, create an empty one", format));
-                } else {
-                    JOptionPane.showMessageDialog(
-                            null, String.format("Unable to get [%s] report template in [%s] format", name, format),
-                            "Connection Error", JOptionPane.ERROR_MESSAGE);
-                }
-            } catch (Exception e) {
-                LOG.log(Level.SEVERE,
-                        String.format("Unable to get [%s] mail template in [%s] format", name, format), e);
-                JOptionPane.showMessageDialog(
-                        null, String.format("Unable to get [%s] mail template in [%s] format", name, format), "Error",
-                        JOptionPane.ERROR_MESSAGE);
-            }
             String content = is == null ? StringUtils.EMPTY : IOUtils.toString(is, encodingPattern);
 
             String mailTemplatesDirName = System.getProperty("java.io.tmpdir") + "/Templates/Mail/";
@@ -521,15 +614,42 @@ public final class ResourceExplorerTopComponent extends TopComponent {
         }
     }
 
+    private void openScriptEditor(final String name , final String type) throws IOException {
+            ImplementationTO node = implementationManagerService.read(getType(type), name);
+            String groovyScriptsDirName = System.getProperty("java.io.tmpdir") + "/Groovy/"
+            + node.getType().toString() + "/";
+            File groovyScriptsDir = new File(groovyScriptsDirName);
+            if (!groovyScriptsDir.exists()) {
+                groovyScriptsDir.mkdirs();
+            }
+            File file = new File(groovyScriptsDirName + name + ".groovy");
+            FileWriter fw = new FileWriter(file);
+            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(new PropertyChangeListener() {
+
+                @Override
+                public void propertyChange(final PropertyChangeEvent evt) {
+                    if (DataObject.PROP_MODIFIED.equals(evt.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;
-            try {
                 switch (format) {
                     case HTML:
                         is = (InputStream) reportTemplateManagerService.getFormat(name, ReportTemplateFormat.HTML);
@@ -544,24 +664,6 @@ public final class ResourceExplorerTopComponent extends TopComponent {
                         LOG.log(Level.SEVERE, String.format("Format [%s] not supported", format));
                         break;
                 }
-            } catch (SyncopeClientException e) {
-                LOG.log(Level.SEVERE, String.format("Unable to get [%s] report template in [%s] format", name, format),
-                        e);
-                if (ClientExceptionType.NotFound.equals(e.getType())) {
-                    LOG.log(Level.SEVERE, String.format(
-                            "Report template [%s] not found, create an empty one", name));
-                } else {
-                    JOptionPane.showMessageDialog(
-                            null, String.format("Unable to get [%s] report template in [%s] format", name, format),
-                            "Connection Error", JOptionPane.ERROR_MESSAGE);
-                }
-            } catch (Exception e) {
-                LOG.log(Level.SEVERE, String.format("Unable to get [%s] report template in [%s] format", name, format),
-                        e);
-                JOptionPane.showMessageDialog(
-                        null, String.format("Unable to get [%s] report template in [%s] format", name, format),
-                        "Generic Error", JOptionPane.ERROR_MESSAGE);
-            }
             String content = is == null ? StringUtils.EMPTY : IOUtils.toString(is, encodingPattern);
 
             String reportTemplatesDirName = System.getProperty("java.io.tmpdir") + "/Templates/Report/";
@@ -597,15 +699,16 @@ public final class ResourceExplorerTopComponent extends TopComponent {
             Document document = ed.getDocument();
             String content = document.getText(0, document.getLength());
             String path = (String) document.getProperty(Document.TitleProperty);
-            String[] temp = path.split(File.separator);
+            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 (templateType.equals("Mail")) {
-                if (format.equals("txt")) {
+            if ("Mail".equals(templateType)) {
+                if ("txt".equals(format)) {
                     mailTemplateManagerService.setFormat(key,
                             MailTemplateFormat.TEXT,
                             IOUtils.toInputStream(content, encodingPattern));
@@ -614,22 +717,39 @@ public final class ResourceExplorerTopComponent extends TopComponent {
                             MailTemplateFormat.HTML,
                             IOUtils.toInputStream(content, encodingPattern));
                 }
-            } else if (format.equals("html")) {
+            } else if ("html".equals(format)) {
                 reportTemplateManagerService.setFormat(key,
                         ReportTemplateFormat.HTML,
                         IOUtils.toInputStream(content, encodingPattern));
-            } else if (format.equals("fo")) {
+            } else if ("fo".equals(format)) {
                 reportTemplateManagerService.setFormat(key,
                         ReportTemplateFormat.FO,
                         IOUtils.toInputStream(content, encodingPattern));
-            } else {
+            } else if ("csv".equals(format)) {
                 reportTemplateManagerService.setFormat(key,
                         ReportTemplateFormat.CSV,
                         IOUtils.toInputStream(content, encodingPattern));
+            } else if ("Groovy".equals(fileName)) {
+                    ImplementationTO node = implementationManagerService.read(getType(templateType), key);
+                    node.setBody(content);
+                    implementationManagerService.update(node);
             }
         } catch (BadLocationException e) {
             Exceptions.printStackTrace(e);
+        } catch (Exception e) {
+            getRefreshServerDetails().setVisible(true);
+        }
+    }
+
+    private ImplementationType getType(final String typeName) {
+        ImplementationType type = null ;
+        for (ImplementationType implType : ImplementationType.values()) {
+            if (implType.toString().equals(typeName)) {
+                type = implType ;
+            }
+
         }
+        return (type);
     }
 
     private void closeComponent() {
@@ -642,6 +762,7 @@ public final class ResourceExplorerTopComponent extends TopComponent {
     private void initTemplatesTree() {
         visibleRoot.add(mailTemplates);
         visibleRoot.add(reportXslts);
+        visibleRoot.add(groovyScripts);
         treeModel.reload();
     }
 
@@ -649,6 +770,7 @@ public final class ResourceExplorerTopComponent extends TopComponent {
         visibleRoot.removeAllChildren();
         mailTemplates.removeAllChildren();
         reportXslts.removeAllChildren();
+        groovyScripts.removeAllChildren();
         treeModel.reload();
     }
 
diff --git a/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyAccountRule.groovy b/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyAccountRule.groovy
new file mode 100644 (file)
index 0000000..978e76d
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+import groovy.transform.CompileStatic
+import org.apache.syncope.core.persistence.api.dao.AccountRule
+import org.apache.syncope.core.persistence.api.entity.user.User
+
+@CompileStatic
+class MyAccountRule implements AccountRule {
+  
+  void enforce(User user) {
+  }
+
+}
diff --git a/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyItemTransformer.groovy b/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyItemTransformer.groovy
new file mode 100644 (file)
index 0000000..fd4b5d4
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+import groovy.transform.CompileStatic
+import org.apache.syncope.common.lib.to.EntityTO
+import org.apache.syncope.core.persistence.api.entity.Entity
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue
+import org.apache.syncope.core.persistence.api.entity.resource.Item
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer
+
+@CompileStatic
+class MyItemTransformer implements ItemTransformer {
+       
+  @Override
+  List<PlainAttrValue> beforePropagation(
+    Item item,
+    Entity entity,
+    List<PlainAttrValue> values) {
+
+    return values;
+  }
+    
+  @Override
+  List<Object> beforePull(
+    Item item,
+    EntityTO entityTO,
+    List<Object> values) {
+
+    return values;
+  }
+}
diff --git a/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyLogicActions.groovy b/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyLogicActions.groovy
new file mode 100644 (file)
index 0000000..df22aa2
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+import groovy.transform.CompileStatic
+import org.apache.syncope.common.lib.patch.AnyPatch
+import org.apache.syncope.common.lib.patch.AttrPatch
+import org.apache.syncope.common.lib.to.AnyTO
+import org.apache.syncope.common.lib.to.AttrTO
+import org.apache.syncope.core.provisioning.api.LogicActions
+
+@CompileStatic
+class MyLogicActions implements LogicActions {
+  
+  @Override
+  <A extends AnyTO> A beforeCreate(final A input) {
+    return input;
+  }
+
+  @Override
+  <M extends AnyPatch> M beforeUpdate(final M input) {
+    return input;
+  }
+}
diff --git a/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyPasswordRule.groovy b/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyPasswordRule.groovy
new file mode 100644 (file)
index 0000000..dab38ba
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+import groovy.transform.CompileStatic
+import org.apache.syncope.core.persistence.api.dao.PasswordRule
+import org.apache.syncope.core.persistence.api.entity.user.User
+
+@CompileStatic
+class MyPasswordRule implements PasswordRule {
+  
+  void enforce(User user) {
+  }
+}
diff --git a/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyPropagationActions.groovy b/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyPropagationActions.groovy
new file mode 100644 (file)
index 0000000..6a24777
--- /dev/null
@@ -0,0 +1,43 @@
+
+/*
+ * 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.
+ */
+import groovy.transform.CompileStatic
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec
+import org.apache.syncope.core.provisioning.api.propagation.PropagationActions
+import org.identityconnectors.framework.common.objects.ConnectorObject
+
+@CompileStatic
+class MyPropagationActions implements PropagationActions {
+  
+  @Override
+  void before(PropagationTask task, ConnectorObject beforeObj) {
+    // do nothing
+  }
+
+  @Override
+  void onError(PropagationTask task, TaskExec execution, Exception error) {
+    // do nothing
+  }
+
+  @Override
+  void after(PropagationTask task, TaskExec execution, ConnectorObject afterObj) {
+    // do nothing
+  }
+}
diff --git a/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyPullActions.groovy b/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyPullActions.groovy
new file mode 100644 (file)
index 0000000..893e7a9
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+import groovy.transform.CompileStatic
+import org.apache.syncope.common.lib.patch.AnyPatch
+import org.apache.syncope.common.lib.to.EntityTO
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask
+import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningActions
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport
+import org.apache.syncope.core.provisioning.api.pushpull.PullActions
+import org.identityconnectors.framework.common.objects.SyncDelta
+import org.quartz.JobExecutionException
+
+@CompileStatic
+class MyPullActions implements PullActions {
+  
+  @Override
+  SyncDelta preprocess(SyncDelta delta) {
+    return delta;
+  }
+  
+  @Override
+  void beforeProvision(
+    ProvisioningProfile profile,
+    SyncDelta delta,
+    EntityTO entity) throws JobExecutionException {
+
+  }
+
+  @Override
+  void beforeAssign(
+    ProvisioningProfile profile,
+    SyncDelta delta,
+    EntityTO entity) throws JobExecutionException {
+
+  }
+
+  @Override
+  void beforeUnassign(
+    ProvisioningProfile profile,
+    SyncDelta delta,
+    EntityTO entity) throws JobExecutionException {
+
+  }
+
+  @Override
+  void beforeDeprovision(
+    ProvisioningProfile profile,
+    SyncDelta delta,
+    EntityTO entity) throws JobExecutionException {
+
+  }
+
+  @Override
+  void beforeUnlink(
+    ProvisioningProfile profile,
+    SyncDelta delta,
+    EntityTO entity) throws JobExecutionException {
+
+  }
+
+  @Override
+  void beforeLink(
+    ProvisioningProfile profile,
+    SyncDelta delta,
+    EntityTO entity) throws JobExecutionException {
+
+  }
+
+  @Override
+  <P extends AnyPatch> void beforeUpdate(
+    ProvisioningProfile profile,
+    SyncDelta delta,
+    EntityTO entity,
+    P anyPatch) throws JobExecutionException {
+
+  }
+
+  @Override
+  void beforeDelete(
+    ProvisioningProfile profile,
+    SyncDelta delta,
+    EntityTO entity) throws JobExecutionException {
+
+  }
+
+  @Override
+  void after(
+    ProvisioningProfile profile,
+    SyncDelta delta,
+    EntityTO entity,
+    ProvisioningReport result) throws JobExecutionException {
+
+    // do nothing
+  }
+
+  @Override
+  IgnoreProvisionException onError(
+    ProvisioningProfile profile,
+    SyncDelta delta,
+    Exception e) throws JobExecutionException {
+
+    return null;
+  }
+}
diff --git a/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyPullCorrelationRule.groovy b/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyPullCorrelationRule.groovy
new file mode 100644 (file)
index 0000000..bb56ebe
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+import groovy.transform.CompileStatic
+import org.apache.syncope.core.persistence.api.dao.PullCorrelationRule
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond
+import org.apache.syncope.core.persistence.api.entity.resource.Provision
+import org.identityconnectors.framework.common.objects.ConnectorObject
+
+@CompileStatic
+class MyPullCorrelationRule implements PullCorrelationRule {
+
+  @Override
+  SearchCond getSearchCond(ConnectorObject connObj, Provision provision) {
+    
+  }
+}
diff --git a/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyPushActions.groovy b/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyPushActions.groovy
new file mode 100644 (file)
index 0000000..dad4206
--- /dev/null
@@ -0,0 +1,112 @@
+
+/*
+ * 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.
+ */
+import groovy.transform.CompileStatic
+import org.apache.syncope.core.persistence.api.entity.Entity
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport
+import org.apache.syncope.core.provisioning.api.pushpull.PushActions
+import org.quartz.JobExecutionException
+
+@CompileStatic
+class MyPushActions implements PushActions {
+  
+  @Override 
+  Entity beforeAssign(
+    ProvisioningProfile profile,
+    Entity entity) throws JobExecutionException {
+
+    return entity;
+  }
+
+  @Override 
+  Entity beforeProvision(
+    ProvisioningProfile profile,
+    Entity entity) throws JobExecutionException {
+
+    return entity;
+  }
+
+  @Override 
+  Entity beforeUpdate(
+    ProvisioningProfile profile,
+    Entity entity) throws JobExecutionException {
+
+    return entity;
+  }
+
+  @Override 
+  Entity beforeLink(
+    ProvisioningProfile profile,
+    Entity entity) throws JobExecutionException {
+
+    return entity;
+  }
+
+  @Override 
+  Entity beforeUnlink(
+    ProvisioningProfile profile,
+    Entity entity) throws JobExecutionException {
+
+    return entity;
+  }
+
+  @Override 
+  Entity beforeUnassign(
+    ProvisioningProfile profile,
+    Entity entity) throws JobExecutionException {
+
+    return entity;
+  }
+
+  @Override 
+  Entity beforeDeprovision(
+    ProvisioningProfile profile,
+    Entity entity) throws JobExecutionException {
+
+    return entity;
+  }
+
+  @Override 
+  Entity beforeDelete(
+    ProvisioningProfile profile,
+    Entity entity) throws JobExecutionException {
+
+    return entity;
+  }
+
+  @Override 
+  void onError(
+    ProvisioningProfile profile,
+    Entity entity,
+    ProvisioningReport result,
+    Exception error) throws JobExecutionException {
+
+    // do nothing
+  }
+
+  @Override 
+  void after(
+    ProvisioningProfile profile,
+    Entity entity,
+    ProvisioningReport result) throws JobExecutionException {
+
+    // do nothing
+  }
+}
diff --git a/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyRecipientsProvider.groovy b/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyRecipientsProvider.groovy
new file mode 100644 (file)
index 0000000..d118861
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+import groovy.transform.CompileStatic
+import org.apache.syncope.core.persistence.api.attrvalue.validation.Validator
+import org.apache.syncope.core.persistence.api.entity.Notification
+import org.apache.syncope.core.provisioning.api.notification.RecipientsProvider
+
+@CompileStatic
+class MyRecipientsProvider implements RecipientsProvider {
+  
+  @Override
+  Set<String> provideRecipients(Notification notification) {
+    return Collections.emptyList();
+  }
+}
diff --git a/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyReconFilterBuilder.groovy b/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyReconFilterBuilder.groovy
new file mode 100644 (file)
index 0000000..b19b88e
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+import groovy.transform.CompileStatic
+import org.apache.syncope.core.provisioning.api.pushpull.ReconFilterBuilder
+import org.identityconnectors.framework.common.objects.filter.Filter
+
+@CompileStatic
+class MyReconFilterBuilder implements ReconFilterBuilder {
+  
+  @Override
+  Filter build() {
+    return PASS_THROUGH;
+  }
+}
diff --git a/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyReportlet.groovy b/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyReportlet.groovy
new file mode 100644 (file)
index 0000000..07447c2
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+import groovy.transform.CompileStatic
+import org.apache.syncope.core.persistence.api.attrvalue.validation.Validator
+import org.apache.syncope.core.persistence.api.dao.Reportlet
+import org.xml.sax.SAXException
+
+@CompileStatic
+class MyReportlet implements Reportlet {
+  
+  @Override
+  void extract(ContentHandler handler) throws SAXException {
+  }
+}
diff --git a/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MySchedTaskJobDelegate.groovy b/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MySchedTaskJobDelegate.groovy
new file mode 100644 (file)
index 0000000..3356319
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+import groovy.transform.CompileStatic
+import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate
+import org.quartz.JobExecutionContext
+import org.quartz.JobExecutionException
+
+@CompileStatic
+class MySchedTaskJobDelegate implements SchedTaskJobDelegate {
+       
+  @Override
+  void execute(String taskKey, boolean dryRun, JobExecutionContext context) throws JobExecutionException {
+   
+  }
+}
diff --git a/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyValidator.groovy b/ide/netbeans/src/main/resources/org/apache/syncope/ide/netbeans/implementations/MyValidator.groovy
new file mode 100644 (file)
index 0000000..b0c3e37
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+import groovy.transform.CompileStatic
+import org.apache.syncope.core.persistence.api.attrvalue.validation.Validator
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue
+import org.apache.syncope.core.persistence.api.entity.PlainSchema
+
+@CompileStatic
+class MyValidator implements Validator {
+  
+  @Override
+  void setSchema(PlainSchema schema) {
+  }
+
+  @Override
+  void validate(String value, PlainAttrValue attrValue) {      
+  }
+}