Add first draft for Connector Alias and Template environment editors.
authorBruno Sinou <bsinou@argeo.org>
Sat, 9 Nov 2013 14:37:51 +0000 (14:37 +0000)
committerBruno Sinou <bsinou@argeo.org>
Sat, 9 Nov 2013 14:37:51 +0000 (14:37 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@6607 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

18 files changed:
demo/akb_rcp.properties
plugins/org.argeo.slc.akb.ui/META-INF/spring/commands.xml
plugins/org.argeo.slc.akb.ui/META-INF/spring/editors.xml
plugins/org.argeo.slc.akb.ui/plugin.xml
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/AkbUiUtils.java [new file with mode: 0644]
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/commands/DeleteAkbNodes.java [new file with mode: 0644]
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/commands/OpenAkbNodeEditor.java
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/composites/MixTitleComposite.java [new file with mode: 0644]
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/editors/AbstractAkbNodeEditor.java
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/editors/AkbConnectorAliasEditor.java
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/editors/AkbEnvTemplateEditor.java
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/providers/TemplatesTreeContentProvider.java
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/views/AkbDefaultView.java
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/views/AkbTemplatesTreeView.java
runtime/org.argeo.slc.akb/src/main/java/org/argeo/slc/akb/AkbService.java
runtime/org.argeo.slc.akb/src/main/java/org/argeo/slc/akb/AkbTypes.java
runtime/org.argeo.slc.akb/src/main/java/org/argeo/slc/akb/core/AkbServiceImpl.java
runtime/org.argeo.slc.akb/src/main/resources/org/argeo/slc/akb/akb.cnd

index a45f24a4007d0f5b18c9516cec812102bb87cc70..3353c86e364f1790eba7ca9abf2d9d8781703940 100644 (file)
@@ -10,7 +10,7 @@ argeo.osgi.start.2.node=\
 org.argeo.node.repo.jackrabbit,\
 org.argeo.security.dao.os,\
 
-org.argeo.security.ui.initialPerspective=org.argeo.slc.akb.ui.akbEnvPerspective
+org.argeo.security.ui.initialPerspective=org.argeo.slc.akb.ui.akbTemplatesPerspective
 eclipse.application=org.argeo.security.ui.rcp.secureUi
 
 log4j.configuration=file:../../log4j.properties
index 36470a90c878072828ae058ecb02bba910879306..1ed12f648f1a9b77816f83598af63f32dfdd9c0d 100644 (file)
                <property name="repository" ref="repository" />
                <property name="akbService" ref="akbService" />
        </bean>
+
+       <!-- deletes an AKB specific node-->
+       <bean id="deleteAkbNodes" class="org.argeo.slc.akb.ui.commands.DeleteAkbNodes"
+               scope="prototype">
+               <property name="repository" ref="repository" />
+       </bean>
 </beans>
index 25b421588bf1bee75b7cab81e214932ffc7474cb..d9617fe698ff3067fa2c4413075931b2b945201e 100644 (file)
@@ -10,5 +10,6 @@
        <bean id="akbConnectorAliasEditor" class="org.argeo.slc.akb.ui.editors.AkbConnectorAliasEditor"
                scope="prototype">
                <property name="repository" ref="repository" />
+               <property name="akbService" ref="akbService" />
        </bean>
 </beans>
\ No newline at end of file
index bdf9dfeee4953535a130ab58aedb11c1ff52d9e2..be04cd2f5a561c74ae5a385443b9a8d2dd4c6d3a 100644 (file)
                        name="The Parent Node JCR ID if needed">
                        </commandParameter>
                </command>
+               <command
+                       defaultHandler="org.argeo.eclipse.spring.SpringExtensionFactory"
+                       id="org.argeo.slc.akb.ui.deleteAkbNodes"
+                       name="Delete Akb Node(s) and close corresponding editors">
+               <commandParameter
+                       id="param.nodeJcrId"
+                       name="The Node JCR ID if needed">
+                       </commandParameter>
+               </command>
        </extension>            
        <!-- Menus -->
        <extension
diff --git a/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/AkbUiUtils.java b/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/AkbUiUtils.java
new file mode 100644 (file)
index 0000000..c79b937
--- /dev/null
@@ -0,0 +1,257 @@
+package org.argeo.slc.akb.ui;
+
+import java.util.Calendar;
+
+import javax.jcr.Node;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+
+import org.argeo.slc.akb.AkbException;
+import org.argeo.slc.akb.utils.AkbJcrUtils;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.AbstractFormPart;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+/** Some helper methods that factorize widely used snippets in people UI */
+public class AkbUiUtils {
+
+       /**
+        * Shortcut to refresh the value of a <code>Text</code> given a Node and a
+        * property Name
+        */
+       public static String refreshTextWidgetValue(Text text, Node entity,
+                       String propName) {
+               String tmpStr = AkbJcrUtils.get(entity, propName);
+               if (AkbJcrUtils.checkNotEmptyString(tmpStr))
+                       text.setText(tmpStr);
+               return tmpStr;
+       }
+
+       /**
+        * Shortcut to refresh a <code>Text</code> widget given a Node in a form and
+        * a property Name. Also manages its enable state
+        */
+       public static String refreshFormTextWidget(Text text, Node entity,
+                       String propName) {
+               String tmpStr = AkbJcrUtils.get(entity, propName);
+               if (AkbJcrUtils.checkNotEmptyString(tmpStr))
+                       text.setText(tmpStr);
+               text.setEnabled(AkbJcrUtils.isNodeCheckedOutByMe(entity));
+               return tmpStr;
+       }
+
+       /**
+        * Shortcut to refresh a Check box <code>Button</code> widget given a Node
+        * in a form and a property Name.
+        */
+       public static boolean refreshCheckBoxWidget(Button button, Node entity,
+                       String propName) {
+               Boolean tmp = null;
+               try {
+                       if (entity.hasProperty(propName)) {
+                               tmp = entity.getProperty(propName).getBoolean();
+                               button.setSelection(tmp);
+                       }
+               } catch (RepositoryException re) {
+                       throw new AkbException("unable get boolean value for property "
+                                       + propName);
+               }
+               return tmp;
+       }
+
+       /**
+        * Shortcut to add a default modify listeners to a <code>Text</code> widget
+        * that is bound a JCR String Property. Any change in the text is
+        * immediately stored in the active session, but no save is done.
+        */
+       public static void addTextModifyListener(final Text text, final Node node,
+                       final String propName, final AbstractFormPart part) {
+               text.addModifyListener(new ModifyListener() {
+                       @Override
+                       public void modifyText(ModifyEvent event) {
+                               if (setJcrProperty(node, propName, PropertyType.STRING,
+                                               text.getText()))
+                                       part.markDirty();
+                       }
+               });
+       }
+
+       /**
+        * Centralizes management of updating property value. Among other to avoid
+        * infinite loop when the new value is the same as the ones that is already
+        * stored in JCR.
+        * 
+        * @return true if the value as changed
+        */
+       public static boolean setJcrProperty(Node node, String propName,
+                       int propertyType, Object value) {
+               try {
+                       // int propertyType = getPic().getProperty(propName).getType();
+                       switch (propertyType) {
+                       case PropertyType.STRING:
+                               if ("".equals((String) value)
+                                               && (!node.hasProperty(propName) || node
+                                                               .hasProperty(propName)
+                                                               && "".equals(node.getProperty(propName)
+                                                                               .getString())))
+                                       // workaround the fact that the Text widget value cannot be
+                                       // set to null
+                                       return false;
+                               else if (node.hasProperty(propName)
+                                               && node.getProperty(propName).getString()
+                                                               .equals((String) value))
+                                       // nothing changed yet
+                                       return false;
+                               else {
+                                       node.setProperty(propName, (String) value);
+                                       return true;
+                               }
+                       case PropertyType.BOOLEAN:
+                               if (node.hasProperty(propName)
+                                               && node.getProperty(propName).getBoolean() == (Boolean) value)
+                                       // nothing changed yet
+                                       return false;
+                               else {
+                                       node.setProperty(propName, (Boolean) value);
+                                       return true;
+                               }
+                       case PropertyType.DATE:
+                               if (node.hasProperty(propName)
+                                               && node.getProperty(propName).getDate()
+                                                               .equals((Calendar) value))
+                                       // nothing changed yet
+                                       return false;
+                               else {
+                                       node.setProperty(propName, (Calendar) value);
+                                       return true;
+                               }
+                       case PropertyType.LONG:
+                               Long lgValue = (Long) value;
+
+                               if (lgValue == null)
+                                       lgValue = 0L;
+
+                               if (node.hasProperty(propName)
+                                               && node.getProperty(propName).getLong() == lgValue)
+                                       // nothing changed yet
+                                       return false;
+                               else {
+                                       node.setProperty(propName, lgValue);
+                                       return true;
+                               }
+
+                       default:
+                               throw new AkbException("Unimplemented save for property type: "
+                                               + propertyType + " - property: " + propName);
+
+                       }
+               } catch (RepositoryException re) {
+                       throw new AkbException("Error while setting property" + propName
+                                       + " - propertyType: " + propertyType, re);
+               }
+       }
+
+       // ////////////////////////
+       // LAYOUTS AND STYLES
+
+       /** shortcut to set form data while dealing with switching panel */
+       public static void setSwitchingFormData(Composite composite) {
+               FormData fdLabel = new FormData();
+               fdLabel.top = new FormAttachment(0, 0);
+               fdLabel.left = new FormAttachment(0, 0);
+               fdLabel.right = new FormAttachment(100, 0);
+               fdLabel.bottom = new FormAttachment(100, 0);
+               composite.setLayoutData(fdLabel);
+       }
+
+       public static void setTableDefaultStyle(TableViewer viewer,
+                       int customItemHeight) {
+               Table table = viewer.getTable();
+               table.setLinesVisible(true);
+               table.setHeaderVisible(false);
+       }
+
+       /**
+        * Shortcut to provide a gridlayout with no margin and no spacing (dafault
+        * are normally 5 px)
+        */
+       public static GridLayout gridLayoutNoBorder() {
+               return gridLayoutNoBorder(1);
+       }
+
+       /**
+        * Shortcut to provide a gridlayout with no margin and no spacing (default
+        * are normally 5 px) with the given column number (equals width is false).
+        */
+       public static GridLayout gridLayoutNoBorder(int nbOfCol) {
+               GridLayout gl = new GridLayout(nbOfCol, false);
+               gl.marginWidth = gl.marginHeight = gl.horizontalSpacing = gl.verticalSpacing = 0;
+               return gl;
+       }
+
+       /** Creates a text widget with RowData already set */
+       public static Text createRDText(FormToolkit toolkit, Composite parent,
+                       String msg, String toolTip, int width) {
+               Text text = toolkit.createText(parent, "", SWT.BORDER | SWT.SINGLE
+                               | SWT.LEFT);
+               text.setMessage(msg);
+               text.setToolTipText(toolTip);
+               text.setLayoutData(new RowData(width, SWT.DEFAULT));
+               return text;
+       }
+
+       /**
+        * Creates a text widget with GridData already set
+        * 
+        * @param toolkit
+        * @param parent
+        * @param msg
+        * @param toolTip
+        * @param width
+        * @param colSpan
+        * @return
+        */
+       public static Text createGDText(FormToolkit toolkit, Composite parent,
+                       String msg, String toolTip, int width, int colSpan) {
+               Text text = toolkit.createText(parent, "", SWT.BORDER | SWT.SINGLE
+                               | SWT.LEFT);
+               text.setMessage(msg);
+               text.setToolTipText(toolTip);
+               GridData gd = new GridData(SWT.FILL, SWT.FILL, true, false);
+               gd.widthHint = width;
+               gd.horizontalSpan = colSpan;
+               text.setLayoutData(gd);
+               return text;
+       }
+
+       /**
+        * Shortcut to quickly get a FormData object with configured FormAttachment
+        * 
+        * @param left
+        * @param top
+        * @param right
+        * @param bottom
+        * @return
+        */
+       public static FormData createformData(int left, int top, int right,
+                       int bottom) {
+               FormData formData = new FormData();
+               formData.left = new FormAttachment(left, 0);
+               formData.top = new FormAttachment(top, 0);
+               formData.right = new FormAttachment(right, 0);
+               formData.bottom = new FormAttachment(bottom, 0);
+               return formData;
+       }
+}
\ No newline at end of file
diff --git a/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/commands/DeleteAkbNodes.java b/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/commands/DeleteAkbNodes.java
new file mode 100644 (file)
index 0000000..abc4138
--- /dev/null
@@ -0,0 +1,71 @@
+package org.argeo.slc.akb.ui.commands;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.akb.AkbException;
+import org.argeo.slc.akb.ui.AkbUiPlugin;
+import org.argeo.slc.akb.ui.editors.AkbNodeEditorInput;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * Deletes one or more akb nodes also closing the corresponding editors if
+ * needed
+ */
+public class DeleteAkbNodes extends AbstractHandler {
+       public final static String ID = AkbUiPlugin.PLUGIN_ID + ".deleteAkbNodes";
+
+       /* DEPENDENCY INJECTION */
+       private Repository repository;
+
+       public final static String PARAM_NODE_JCR_ID = "param.nodeJcrId";
+
+       // public final static String PARAM_NODE_TYPE = "param.nodeType";
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+
+               // String nodeType = event.getParameter(PARAM_NODE_TYPE);
+               String nodeJcrId = event.getParameter(PARAM_NODE_JCR_ID);
+
+               Session session = null;
+               try {
+                       // caches current Page
+                       IWorkbenchPage currentPage = HandlerUtil.getActiveWorkbenchWindow(
+                                       event).getActivePage();
+
+                       session = repository.login();
+                       Node node = null;
+
+                       if (nodeJcrId != null)
+                               node = session.getNodeByIdentifier(nodeJcrId);
+
+                       // no node has been found or created, return silently
+                       if (node == null)
+                               return null;
+
+                       IEditorPart currPart = currentPage
+                                       .findEditor(new AkbNodeEditorInput(nodeJcrId));
+                       if (currPart != null)
+                               currPart.dispose();
+               } catch (RepositoryException e) {
+                       throw new AkbException("JCR error while deleting node" + nodeJcrId
+                                       + " editor", e);
+               } finally {
+                       JcrUtils.logoutQuietly(session);
+               }
+               return null;
+       }
+
+       /* DEPENDENCY INJECTION */
+       public void setRepository(Repository repository) {
+               this.repository = repository;
+       }
+}
\ No newline at end of file
index 46de0c3d16377fc2fab8478e16f9581e12b18128..c77565d423c9d7f98bbd18ec37ce49cae9b79b14 100644 (file)
@@ -1,6 +1,7 @@
 package org.argeo.slc.akb.ui.commands;
 
 import javax.jcr.Node;
+import javax.jcr.Property;
 import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
@@ -74,7 +75,7 @@ public class OpenAkbNodeEditor extends AbstractHandler {
 
                        String editorId = getEditorForNode(node);
 
-                       // no editor has been found, return
+                       // no editor has been found, return silently
                        if (editorId == null)
                                return null;
 
@@ -98,17 +99,17 @@ public class OpenAkbNodeEditor extends AbstractHandler {
        private Node createNewNode(Session session, String nodeType,
                        String parentNodeJcrId) throws RepositoryException {
                Node node = null;
+               String name = SingleValue.ask("New name", "Create AKB item");
+
+               if (name == null)
+                       return null;
                if (AkbTypes.AKB_ENV_TEMPLATE.equals(nodeType)) {
-                       String name = SingleValue.ask("Template name",
-                                       "Please give a name to the template to create");
-                       if (name != null)
-                               node = akbService.createAkbTemplate(
-                                               session.getNodeByIdentifier(parentNodeJcrId), name);
-                       else
-                               return null;
+                       node = akbService.createAkbTemplate(
+                                       session.getNodeByIdentifier(parentNodeJcrId), name);
                } else {
                        Node parentNode = session.getNodeByIdentifier(parentNodeJcrId);
-                       node = parentNode.addNode("new", nodeType);
+                       node = parentNode.addNode(name, nodeType);
+                       node.setProperty(Property.JCR_TITLE, name);
                }
                // corresponding node is saved but not checked in, in order to ease
                // cancel actions.
@@ -122,8 +123,8 @@ public class OpenAkbNodeEditor extends AbstractHandler {
                        editorId = AkbConnectorAliasEditor.ID;
                else if (node.isNodeType(AkbTypes.AKB_ENV_TEMPLATE))
                        editorId = AkbEnvTemplateEditor.ID;
-               else
-                       throw new AkbException("Editor is undefined for node " + node);
+               // else
+               // throw new AkbException("Editor is undefined for node " + node);
                return editorId;
        }
 
diff --git a/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/composites/MixTitleComposite.java b/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/composites/MixTitleComposite.java
new file mode 100644 (file)
index 0000000..3956483
--- /dev/null
@@ -0,0 +1,96 @@
+package org.argeo.slc.akb.ui.composites;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+
+import org.argeo.slc.akb.ui.AkbUiUtils;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.AbstractFormPart;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+public class MixTitleComposite extends Composite {
+       // private final static Log log =
+       // LogFactory.getLog(MixTitleComposite.class);
+
+       private final Node akbNode;
+       private final FormToolkit toolkit;
+       private final IManagedForm form;
+       // Don't forget to unregister on dispose
+       private AbstractFormPart formPart;
+
+       // To enable set focus
+       private Text titleTxt;
+
+       public MixTitleComposite(Composite parent, int style, FormToolkit toolkit,
+                       IManagedForm form, Node akbNode) {
+               super(parent, style);
+               this.akbNode = akbNode;
+               this.toolkit = toolkit;
+               this.form = form;
+               populate();
+               toolkit.adapt(this);
+       }
+
+       private void populate() {
+               // Initialization
+               Composite parent = this;
+
+               parent.setLayout(new GridLayout(2, false));
+
+               // first line: connector type and name
+               toolkit.createLabel(parent, "Name");
+               titleTxt = toolkit.createText(parent, "", SWT.BORDER);
+               GridData gd = new GridData(SWT.FILL, SWT.TOP, true, false);
+               titleTxt.setLayoutData(gd);
+
+               // 2nd line: description
+               Label lbl = toolkit.createLabel(parent, "Description");
+               lbl.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
+               final Text descTxt = toolkit.createText(parent, "", SWT.BORDER
+                               | SWT.MULTI | SWT.WRAP);
+               gd = new GridData(SWT.FILL, SWT.FILL, true, true);
+               descTxt.setLayoutData(gd);
+
+               // Part Management
+               final AbstractFormPart part = new AbstractFormPart() {
+                       public void refresh() {
+                               super.refresh();
+                               // update display value
+                               AkbUiUtils.refreshFormTextWidget(titleTxt, akbNode,
+                                               Property.JCR_TITLE);
+                               AkbUiUtils.refreshFormTextWidget(descTxt, akbNode,
+                                               Property.JCR_DESCRIPTION);
+                       }
+               };
+               // Listeners
+               AkbUiUtils.addTextModifyListener(titleTxt, akbNode, Property.JCR_TITLE,
+                               part);
+               AkbUiUtils.addTextModifyListener(descTxt, akbNode,
+                               Property.JCR_DESCRIPTION, part);
+               form.addPart(part);
+       }
+
+       @Override
+       public boolean setFocus() {
+               return titleTxt.setFocus();
+       }
+
+       protected void disposePart(AbstractFormPart part) {
+               if (part != null) {
+                       form.removePart(part);
+                       part.dispose();
+               }
+       }
+
+       @Override
+       public void dispose() {
+               disposePart(formPart);
+               super.dispose();
+       }
+}
index cc7c8ddea52eeca8110a661344ffa72042b34908..7eb74bb5ee3a84c998ccf64a43f9e3c248a9c7fa 100644 (file)
@@ -8,18 +8,25 @@ import javax.jcr.Session;
 
 import org.argeo.jcr.JcrUtils;
 import org.argeo.slc.akb.AkbException;
+import org.argeo.slc.akb.AkbService;
 import org.argeo.slc.akb.utils.AkbJcrUtils;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorSite;
 import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.part.EditorPart;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.editor.FormEditor;
+import org.eclipse.ui.forms.editor.FormPage;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
 
 /**
  * Parent Abstract Node editor for AKB. Manage life cycle of the JCR session
  * that is bound to it.
  */
-public abstract class AbstractAkbNodeEditor extends EditorPart {
+public abstract class AbstractAkbNodeEditor extends FormEditor {
        // private final static Log log = LogFactory
        // .getLog(AbstractEntityEditor.class);
 
@@ -27,6 +34,7 @@ public abstract class AbstractAkbNodeEditor extends EditorPart {
        // changes life cycle
        private Repository repository;
        private Session session;
+       private AkbService akbService;
 
        // Business Objects
        private Node akbNode;
@@ -34,7 +42,12 @@ public abstract class AbstractAkbNodeEditor extends EditorPart {
        // Some constants
        private final static int SHORT_NAME_LENGHT = 10;
 
-       // LIFE CYCLE
+       // to implement methods
+       protected abstract String getEditorId();
+
+       protected abstract void populateMainPage(Composite parent,
+                       IManagedForm managedForm);
+
        public void init(IEditorSite site, IEditorInput input)
                        throws PartInitException {
                setSite(site);
@@ -68,11 +81,50 @@ public abstract class AbstractAkbNodeEditor extends EditorPart {
                setTitleToolTip("Display and edit " + name);
        }
 
+       /* Pages management */
+       @Override
+       protected void addPages() {
+               try {
+                       addPage(new ConnectorAliasPage(this, "mainPage", "Main"));
+                       // TODO Add history page
+                       // addPage(new ConnectorAliasPage(this, "mainPage", "Main"));
+               } catch (PartInitException e) {
+                       throw new AkbException("Unable to initialise pages for editor "
+                                       + getEditorId(), e);
+               }
+       }
+
+       /**
+        * Display and edit info
+        */
+       private class ConnectorAliasPage extends FormPage {
+
+               public ConnectorAliasPage(FormEditor editor, String id, String title) {
+                       super(editor, id, title);
+               }
+
+               protected void createFormContent(IManagedForm managedForm) {
+                       super.createFormContent(managedForm);
+                       ScrolledForm form = managedForm.getForm();
+                       form.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+                       populateMainPage(form.getBody(), managedForm);
+               }
+       }
+
        /* EXPOSES TO CHILDREN CLASSES */
        protected Session getSession() {
                return session;
        }
 
+       protected AkbService getAkbService() {
+               return akbService;
+       }
+
+       protected Node getAkbNode() {
+               return akbNode;
+       }
+
+       /* LIFE CYCLE MANAGEMENT */
        @Override
        public void dispose() {
                try {
@@ -93,7 +145,15 @@ public abstract class AbstractAkbNodeEditor extends EditorPart {
 
        @Override
        public void doSave(IProgressMonitor monitor) {
-               throw new AkbException("Implement this");
+               try {
+                       if (getSession().hasPendingChanges())
+                               JcrUtils.updateLastModified(getAkbNode());
+                       getSession().save();
+                       updatePartNameAndToolTip();
+                       this.firePropertyChange(PROP_DIRTY);
+               } catch (Exception e) {
+                       throw new AkbException("Error getting session status.", e);
+               }
        }
 
        @Override
@@ -118,4 +178,8 @@ public abstract class AbstractAkbNodeEditor extends EditorPart {
        public void setRepository(Repository repository) {
                this.repository = repository;
        }
+
+       public void setAkbService(AkbService akbService) {
+               this.akbService = akbService;
+       }
 }
\ No newline at end of file
index 2ff704c4519db99ee088e122c90ad2a2b4894027..a3b776c816b86fbcce79c6046322e3254cc6f93c 100644 (file)
 package org.argeo.slc.akb.ui.editors;
 
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+import org.argeo.slc.akb.AkbException;
+import org.argeo.slc.akb.AkbNames;
+import org.argeo.slc.akb.AkbTypes;
 import org.argeo.slc.akb.ui.AkbUiPlugin;
+import org.argeo.slc.akb.ui.AkbUiUtils;
+import org.argeo.slc.akb.utils.AkbJcrUtils;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.AbstractFormPart;
+import org.eclipse.ui.forms.IManagedForm;
 
 /**
  * Display and edit a connector Alias
  */
 public class AkbConnectorAliasEditor extends AbstractAkbNodeEditor {
+       // private final static Log log = LogFactory
+       // .getLog(AkbConnectorAliasEditor.class);
 
        public final static String ID = AkbUiPlugin.PLUGIN_ID
                        + ".akbConnectorAliasEditor";
 
+       private String[] connectorTypesLbl = new String[] { "JDBC", "SSH", "JCR" };
+       private String[] connectorTypes = new String[] {
+                       AkbTypes.AKB_JDBC_CONNECTOR, AkbTypes.AKB_SSH_CONNECTOR,
+                       AkbTypes.AKB_JCR_CONNECTOR };
+
+       private IManagedForm managedForm;
+
        /* CONTENT CREATION */
        @Override
-       public void createPartControl(Composite parent) {
+       public void populateMainPage(Composite parent, IManagedForm managedForm) {
+               parent.setLayout(AkbUiUtils.gridLayoutNoBorder());
+               this.managedForm = managedForm;
+
+               // First line main info
+               Composite firstLine = getToolkit()
+                               .createComposite(parent, SWT.NO_FOCUS);
+               firstLine.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+               createConnectorAliasInfoCmp(firstLine);
+
+               // Second line define defaut connector and test abilities
+               Composite secondLine = getToolkit().createComposite(parent,
+                               SWT.NO_FOCUS);
+               secondLine.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+               createDefaultTestConnectorCmp(secondLine);
+
+       }
+
+       private void createConnectorAliasInfoCmp(Composite parent) {
+               parent.setLayout(new GridLayout(4, false));
+
+               // first line: connector type and name
+               getToolkit().createLabel(parent, "Connector Type");
+               final Combo typeCmb = new Combo(parent, SWT.READ_ONLY);
+               typeCmb.setItems(connectorTypesLbl);
+
+               getToolkit().createLabel(parent, "Name");
+               final Text titleTxt = getToolkit().createText(parent, "", SWT.BORDER);
+               GridData gd = new GridData(SWT.FILL, SWT.TOP, true, false);
+               titleTxt.setLayoutData(gd);
+
+               // 2nd line: description
+               getToolkit().createLabel(parent, "Short Description");
+               final Text descTxt = getToolkit().createText(parent, "", SWT.BORDER);
+               gd = new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1);
+               descTxt.setLayoutData(gd);
+
+               // Part Management
+               final AbstractFormPart part = new AbstractFormPart() {
+                       public void refresh() {
+                               super.refresh();
+                               // update display value
+                               AkbUiUtils.refreshFormTextWidget(titleTxt, getAkbNode(),
+                                               Property.JCR_TITLE);
+                               AkbUiUtils.refreshFormTextWidget(descTxt, getAkbNode(),
+                                               Property.JCR_DESCRIPTION);
+                       }
+               };
+               // Listeners
+               AkbUiUtils.addTextModifyListener(titleTxt, getAkbNode(),
+                               Property.JCR_TITLE, part);
+               AkbUiUtils.addTextModifyListener(descTxt, getAkbNode(),
+                               Property.JCR_DESCRIPTION, part);
+
+               typeCmb.addModifyListener(new ModifyListener() {
+                       @Override
+                       public void modifyText(ModifyEvent event) {
+
+                               try { // TODO enhance this
+
+                                       // retrieve old and new node type
+                                       int oldIndex = -1;
+                                       for (int i = 0; i < connectorTypes.length; i++) {
+                                               if (getAkbNode().isNodeType(connectorTypes[i])) {
+                                                       oldIndex = i;
+                                                       break;
+                                               }
+                                       }
+                                       int selIndex = typeCmb.getSelectionIndex();
+
+                                       // insure something has really been modified
+                                       if (selIndex < 0 || oldIndex == selIndex)
+                                               return;
+
+                                       // remove old mixin, add new and notify form
+                                       if (oldIndex > -1)
+                                               getAkbNode().removeMixin(connectorTypes[oldIndex]);
+                                       getAkbNode().addMixin(connectorTypes[selIndex]);
+                                       part.markDirty();
+                               } catch (RepositoryException e) {
+                                       throw new AkbException(
+                                                       "Error while updating connector type", e);
+                               }
+                       }
+               });
+
+               managedForm.addPart(part);
+       }
+
+       private void createDefaultTestConnectorCmp(Composite parent) {
+               String groupTitle = "Default test instance";
+               parent.setLayout(new GridLayout());
+               Group group = new Group(parent, SWT.NONE);
+               group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+               getToolkit().adapt(group, false, false);
+
+               group.setText(groupTitle);
+               group.setLayout(AkbUiUtils.gridLayoutNoBorder());
+               // 1st line: the URL
+
+               Composite firstLine = getToolkit().createComposite(group);
+               firstLine.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+               firstLine.setLayout(new GridLayout(3, false));
+
+               getToolkit().createLabel(firstLine, "URL");
+               final Text urlTxt = getToolkit().createText(firstLine, "", SWT.BORDER);
+               urlTxt.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+
+               final Button testBtn = getToolkit().createButton(firstLine,
+                               "Test connection", SWT.PUSH);
+               // testBtn.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false,
+               // false));
+
+               // Part Management
+               final AbstractFormPart part = new AbstractFormPart() {
+                       public void refresh() {
+                               super.refresh();
+                               // update display value
+                               AkbUiUtils.refreshFormTextWidget(urlTxt, getAkbNode(),
+                                               AkbNames.AKB_CONNECTOR_URL);
+                       }
+               };
+               // Listeners
+               AkbUiUtils.addTextModifyListener(urlTxt, getAkbNode(),
+                               AkbNames.AKB_CONNECTOR_URL, part);
+
+               testBtn.addSelectionListener(new SelectionAdapter() {
+                       @Override
+                       public void widgetSelected(SelectionEvent e) {
+                               boolean testSuccesfull = getAkbService().testConnector(
+                                               getAkbNode());
+
+                               String name = AkbJcrUtils.get(getAkbNode(), Property.JCR_TITLE);
+                               String url = AkbJcrUtils.get(getAkbNode(),
+                                               AkbNames.AKB_CONNECTOR_URL);
+
+                               String msg = "to " + name + " (" + url + ")";
+                               if (testSuccesfull)
+                                       MessageDialog.openInformation(getSite().getShell(),
+                                                       "Test successful", "Successfully connected " + msg);
+                               else
+                                       MessageDialog.openError(getSite().getShell(),
+                                                       "Test failure", "Unable to connect" + msg);
+                       }
+               });
+
+               managedForm.addPart(part);
+
+       }
+
+       @Override
+       protected String getEditorId() {
+               return ID;
        }
 }
\ No newline at end of file
index 8a16202fe558e0fe58977d323394eddb1746f8a0..49f443a97d19de267e7e0215a59776eba1138e3f 100644 (file)
@@ -1,7 +1,12 @@
 package org.argeo.slc.akb.ui.editors;
 
 import org.argeo.slc.akb.ui.AkbUiPlugin;
+import org.argeo.slc.akb.ui.AkbUiUtils;
+import org.argeo.slc.akb.ui.composites.MixTitleComposite;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.forms.IManagedForm;
 
 /**
  * Display and edit a connector Alias
@@ -13,6 +18,16 @@ public class AkbEnvTemplateEditor extends AbstractAkbNodeEditor {
 
        /* CONTENT CREATION */
        @Override
-       public void createPartControl(Composite parent) {
+       public void populateMainPage(Composite parent, IManagedForm managedForm) {
+               parent.setLayout(AkbUiUtils.gridLayoutNoBorder());
+               // First line main info
+               MixTitleComposite mixTitleCmp = new MixTitleComposite(parent,
+                               SWT.NO_FOCUS, getToolkit(), managedForm, getAkbNode());
+               mixTitleCmp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+       }
+
+       @Override
+       protected String getEditorId() {
+               return ID;
        }
 }
\ No newline at end of file
index 33571446fe98114077edb06771382b490f6d6ef5..1f39f33d84ff9841a1dfa28b92e58826cf1e3cda 100644 (file)
@@ -42,7 +42,11 @@ public class TemplatesTreeContentProvider implements ITreeContentProvider {
 
        public Object getParent(Object child) {
                try {
-                       return ((Node) child).getParent();
+                       Node node = (Node) child;
+                       if (node.getDepth() == 0)
+                               return null;
+                       else
+                               return node.getParent();
                } catch (RepositoryException e) {
                        throw new AkbException("Error while getting parent node", e);
                }
index 44c419738fef748b441feffad0e3653038596418..ac3e5a49d9aa656fac60395452f180afe0c75372 100644 (file)
@@ -171,4 +171,4 @@ public class AkbDefaultView extends ViewPart {
                // + "session for view " + ID, e);
                // }
        }
- }
\ No newline at end of file
+}
\ No newline at end of file
index 9ab230520c0bc4a4cbf6311e75f16168d9e82fa9..004e151c51485ab95bf241d952368a94b4ec6966 100644 (file)
@@ -25,19 +25,26 @@ import javax.jcr.NodeIterator;
 import javax.jcr.Repository;\r
 import javax.jcr.RepositoryException;\r
 import javax.jcr.Session;\r
+import javax.jcr.observation.Event;\r
+import javax.jcr.observation.EventListener;\r
+import javax.jcr.observation.ObservationManager;\r
 \r
+import org.argeo.eclipse.ui.jcr.AsyncUiEventListener;\r
 import org.argeo.eclipse.ui.utils.CommandUtils;\r
 import org.argeo.jcr.JcrUtils;\r
 import org.argeo.slc.akb.AkbException;\r
 import org.argeo.slc.akb.AkbNames;\r
 import org.argeo.slc.akb.AkbTypes;\r
 import org.argeo.slc.akb.ui.AkbUiPlugin;\r
+import org.argeo.slc.akb.ui.commands.DeleteAkbNodes;\r
 import org.argeo.slc.akb.ui.commands.OpenAkbNodeEditor;\r
 import org.argeo.slc.akb.ui.providers.AkbTreeLabelProvider;\r
 import org.argeo.slc.akb.ui.providers.TemplatesTreeContentProvider;\r
+import org.eclipse.jface.action.IContributionItem;\r
 import org.eclipse.jface.action.IMenuListener;\r
 import org.eclipse.jface.action.IMenuManager;\r
 import org.eclipse.jface.action.MenuManager;\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
 import org.eclipse.jface.viewers.DoubleClickEvent;\r
 import org.eclipse.jface.viewers.IDoubleClickListener;\r
 import org.eclipse.jface.viewers.IStructuredSelection;\r
@@ -45,9 +52,13 @@ import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.swt.SWT;\r
 import org.eclipse.swt.layout.GridData;\r
 import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
 import org.eclipse.swt.widgets.Menu;\r
 import org.eclipse.ui.IWorkbenchWindow;\r
+import org.eclipse.ui.menus.CommandContributionItem;\r
+import org.eclipse.ui.menus.CommandContributionItemParameter;\r
 import org.eclipse.ui.part.ViewPart;\r
+import org.eclipse.ui.services.IServiceLocator;\r
 \r
 /** SLC generic JCR Result tree view. */\r
 public class AkbTemplatesTreeView extends ViewPart {\r
@@ -66,6 +77,12 @@ public class AkbTemplatesTreeView extends ViewPart {
        // Usefull business objects\r
        private Node templatesParentNode;\r
 \r
+       // Observer\r
+       private EventListener allResultsObserver = null;\r
+       private final static String[] observedNodeTypesUnderAllResults = {\r
+                       AkbTypes.AKB_ENV_TEMPLATE, AkbTypes.AKB_CONNECTOR_ALIAS,\r
+                       AkbTypes.AKB_ITEM, AkbTypes.AKB_ITEM_FOLDER };\r
+\r
        // private EventListener myResultsObserver = null;\r
        // private EventListener allResultsObserver = null;\r
        //\r
@@ -200,12 +217,50 @@ public class AkbTemplatesTreeView extends ViewPart {
 \r
                getSite().registerContextMenu(menuManager, viewer);\r
 \r
+               // Initialize observer\r
+               try {\r
+                       ObservationManager observationManager = session.getWorkspace()\r
+                                       .getObservationManager();\r
+\r
+                       allResultsObserver = new AllResultsObserver(viewer.getTree()\r
+                                       .getDisplay());\r
+\r
+                       // observe tree changes under All results\r
+                       observationManager.addEventListener(allResultsObserver,\r
+                                       Event.NODE_ADDED | Event.NODE_REMOVED,\r
+                                       templatesParentNode.getPath(), true, null,\r
+                                       observedNodeTypesUnderAllResults, false);\r
+               } catch (RepositoryException e) {\r
+                       throw new AkbException("Cannot register listeners", e);\r
+               }\r
+\r
                // add change listener to display TestResult information in the property\r
                // viewer\r
                // viewer.addSelectionChangedListener(new MySelectionChangedListener());\r
                return viewer;\r
        }\r
 \r
+       class AllResultsObserver extends AsyncUiEventListener {\r
+\r
+               public AllResultsObserver(Display display) {\r
+                       super(display);\r
+               }\r
+\r
+               @Override\r
+               protected Boolean willProcessInUiThread(List<Event> events)\r
+                               throws RepositoryException {\r
+                       // unfiltered for the time being\r
+                       return true;\r
+               }\r
+\r
+               protected void onEventInUiThread(List<Event> events)\r
+                               throws RepositoryException {\r
+                       resultTreeViewer.setInput(initializeResultTree());\r
+                       // if (lastSelectedSourceElementParent != null)\r
+                       // refresh(lastSelectedSourceElementParent);\r
+               }\r
+       }\r
+\r
        // Detailed property viewer\r
        // protected TableViewer createPropertiesViewer(Composite parent) {\r
        // }\r
@@ -243,22 +298,111 @@ public class AkbTemplatesTreeView extends ViewPart {
                IWorkbenchWindow window = AkbUiPlugin.getDefault().getWorkbench()\r
                                .getActiveWorkbenchWindow();\r
                try {\r
+\r
+                       // Build conditions\r
+                       Node selected = (Node) ((IStructuredSelection) resultTreeViewer\r
+                                       .getSelection()).getFirstElement();\r
+\r
+                       boolean hasSelection = selected != null;\r
+                       boolean isParentItemsFolder = hasSelection ? selected\r
+                                       .isNodeType(AkbTypes.AKB_ITEM_FOLDER) : false;\r
+                       boolean isParentConnectorsFolder = hasSelection ? selected\r
+                                       .isNodeType(AkbTypes.AKB_CONNECTOR_FOLDER) : false;\r
+                       boolean isDeletable = hasSelection ? !(selected.getParent()\r
+                                       .isNodeType(AkbTypes.AKB_ENV_TEMPLATE)) : false;\r
+\r
+                       // Add Connector Alias\r
                        Map<String, String> params = new HashMap<String, String>();\r
+                       if (hasSelection)\r
+                               params.put(OpenAkbNodeEditor.PARAM_PARENT_NODE_JCR_ID,\r
+                                               selected.getIdentifier());\r
+                       params.put(OpenAkbNodeEditor.PARAM_NODE_TYPE,\r
+                                       AkbTypes.AKB_CONNECTOR_ALIAS);\r
+                       refreshParameterizedCommand(menuManager, window,\r
+                                       "cmd.addConnector", OpenAkbNodeEditor.ID,\r
+                                       "Add connector Alias", null, isParentConnectorsFolder,\r
+                                       params);\r
+\r
+                       // Add Item\r
+                       params = new HashMap<String, String>();\r
+                       if (hasSelection)\r
+                               params.put(OpenAkbNodeEditor.PARAM_PARENT_NODE_JCR_ID,\r
+                                               selected.getIdentifier());\r
+                       params.put(OpenAkbNodeEditor.PARAM_NODE_TYPE, AkbTypes.AKB_ITEM);\r
+                       refreshParameterizedCommand(menuManager, window, "cmd.addItem",\r
+                                       OpenAkbNodeEditor.ID, "Add item", null,\r
+                                       isParentItemsFolder, params);\r
+\r
+                       // Add Item Folder\r
+                       params = new HashMap<String, String>();\r
+                       if (hasSelection)\r
+                               params.put(OpenAkbNodeEditor.PARAM_PARENT_NODE_JCR_ID,\r
+                                               selected.getIdentifier());\r
+                       params.put(OpenAkbNodeEditor.PARAM_NODE_TYPE,\r
+                                       AkbTypes.AKB_ITEM_FOLDER);\r
+                       refreshParameterizedCommand(menuManager, window,\r
+                                       "cmd.addItemFolder", OpenAkbNodeEditor.ID,\r
+                                       "Add item folder", null, isParentItemsFolder, params);\r
+\r
+                       // Delete Item\r
+                       params = new HashMap<String, String>();\r
+                       if (hasSelection)\r
+                               params.put(DeleteAkbNodes.PARAM_NODE_JCR_ID,\r
+                                               selected.getIdentifier());\r
+                       refreshParameterizedCommand(menuManager, window, "cmd.deleteItem",\r
+                                       DeleteAkbNodes.ID, "Delete selected item(s)", null,\r
+                                       isDeletable, params);\r
+\r
+                       // create template\r
+                       params = new HashMap<String, String>();\r
                        params.put(OpenAkbNodeEditor.PARAM_PARENT_NODE_JCR_ID,\r
                                        templatesParentNode.getIdentifier());\r
                        params.put(OpenAkbNodeEditor.PARAM_NODE_TYPE,\r
                                        AkbTypes.AKB_ENV_TEMPLATE);\r
-\r
-                       // Effective Refresh\r
-                       CommandUtils.refreshParametrizedCommand(menuManager, window,\r
-                                       OpenAkbNodeEditor.ID, "Create new template...", null, true,\r
-                                       params);\r
+                       refreshParameterizedCommand(menuManager, window,\r
+                                       "cmd.createTemplate", OpenAkbNodeEditor.ID,\r
+                                       "Create new template...", null, true, params);\r
 \r
                } catch (RepositoryException re) {\r
                        throw new AkbException("Error while refreshing context menu", re);\r
                }\r
        }\r
 \r
+       /**\r
+        * Commodities the refresh of a single command with a map of parameters in a\r
+        * Menu.aboutToShow method to simplify further development\r
+        * \r
+        * @param menuManager\r
+        * @param locator\r
+        * @param cmdId\r
+        * @param label\r
+        * @param iconPath\r
+        * @param showCommand\r
+        */\r
+       private void refreshParameterizedCommand(IMenuManager menuManager,\r
+                       IServiceLocator locator, String itemId, String cmdId, String label,\r
+                       ImageDescriptor icon, boolean showCommand,\r
+                       Map<String, String> params) {\r
+               IContributionItem ici = menuManager.find(itemId);\r
+               if (ici != null)\r
+                       menuManager.remove(ici);\r
+               CommandContributionItemParameter contributionItemParameter = new CommandContributionItemParameter(\r
+                               locator, itemId, cmdId, SWT.PUSH);\r
+\r
+               if (showCommand) {\r
+                       // Set Params\r
+                       contributionItemParameter.label = label;\r
+                       contributionItemParameter.icon = icon;\r
+\r
+                       if (params != null)\r
+                               contributionItemParameter.parameters = params;\r
+\r
+                       CommandContributionItem cci = new CommandContributionItem(\r
+                                       contributionItemParameter);\r
+                       menuManager.add(cci);\r
+               }\r
+       }\r
+\r
        /* INNER CLASSES */\r
        class ViewDoubleClickListener implements IDoubleClickListener {\r
                public void doubleClick(DoubleClickEvent evt) {\r
index 7f5348a2aad9ea5bc7e26878b4cf3a73b364839c..1f39ff832bec4c412a7a7a26780ad89d16c4ce5c 100644 (file)
@@ -7,5 +7,13 @@ import javax.jcr.RepositoryException;
 public interface AkbService {
 
        /** Creates a preconfigured AKB Template */
-       public Node createAkbTemplate(Node parent, String name) throws RepositoryException;
+       public Node createAkbTemplate(Node parent, String name)
+                       throws RepositoryException;
+
+       /**
+        * Shortcut to perform whatever test on a given connector only to check if
+        * URL is correctly defined, if the target system is there and if the
+        * current user has the sufficient credentials to connect
+        */
+       public boolean testConnector(Node connector);
 }
index 82407f1ce440a4fd6460ce46487a40d9feb9fe0a..349e419eea8e5c3ce7a962175768b93fa1c4de5d 100644 (file)
@@ -1,31 +1,33 @@
 package org.argeo.slc.akb;
 
-/** Maps AKB specific JCR node types with java constants  */
+/** Maps AKB specific JCR node types with java constants */
 public interface AkbTypes {
 
        public final static String ARGEO_NOTE = "argeo:note";
 
-       // Env and templates 
+       // Env and templates
        public final static String AKB_ENV_TEMPLATE = "akb:envTemplate";
-       public final static String AKB_ENV= "akb:env";
+       public final static String AKB_ENV = "akb:env";
 
        // Connectors
-       public final static String AKB_CONNECTOR = "akb:connector";  
-       public final static String AKB_CONNECTOR_ALIAS = "akb:connectorAlias";  
+
+       public final static String AKB_CONNECTOR_FOLDER = "akb:connectorFolder";
+       public final static String AKB_CONNECTOR = "akb:connector";
+       public final static String AKB_CONNECTOR_ALIAS = "akb:connectorAlias";
 
        // Various connector mixin types
-       public final static String AKB_SSH_CONNECTOR = "akb:sshConnector";  
-       public final static String AKB_JDBC_CONNECTOR = "akb:jdbcConnector";  
-               
-       // Item tree 
+       public final static String AKB_SSH_CONNECTOR = "akb:sshConnector";
+       public final static String AKB_JDBC_CONNECTOR = "akb:jdbcConnector";
+       public final static String AKB_JCR_CONNECTOR = "akb:jcrConnector";
+
+       // Item tree
        public final static String AKB_ITEM_FOLDER = "akb:itemsFolder";
        public final static String AKB_ITEM = "akb:item";
-       
+
        // Various items types
        public final static String AKB_SSH_FILE = "akb:sshFile";
        public final static String AKB_SSH_COMMAND = "akb:sshCommand";
        public final static String AKB_JDBC_QUERY = "akb:jdbcQuery";
        public final static String AKB_NOTE = "akb:note";
 
-
 }
\ No newline at end of file
index b228b0a75a073f6db754c2dd93fe221d66054603..e819bbfa82a858803de4e44e89b7bce31aa4cf36 100644 (file)
@@ -8,7 +8,6 @@ import javax.jcr.Property;
 import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -76,19 +75,25 @@ public class AkbServiceImpl implements AkbService, AkbNames {
                Node newTemplate = parentNode.addNode(name, AkbTypes.AKB_ENV_TEMPLATE);
                newTemplate.setProperty(Property.JCR_TITLE, name);
 
-               Node connectorParent = newTemplate.addNode(connectorParentName,
-                               NodeType.NT_UNSTRUCTURED);
-               connectorParent.addMixin(NodeType.MIX_TITLE);
+               Node connectorParent = newTemplate.addNode(
+                               AkbTypes.AKB_CONNECTOR_FOLDER, AkbTypes.AKB_CONNECTOR_FOLDER);
                connectorParent.setProperty(Property.JCR_TITLE, connectorParentName);
 
-               Node itemsParent = newTemplate.addNode(itemsParentName,
-                               NodeType.NT_UNSTRUCTURED);
-               itemsParent.addMixin(NodeType.MIX_TITLE);
+               Node itemsParent = newTemplate.addNode(AkbTypes.AKB_ITEM_FOLDER,
+                               AkbTypes.AKB_ITEM_FOLDER);
                itemsParent.setProperty(Property.JCR_TITLE, itemsParentName);
 
                return newTemplate;
        }
 
+       // ///////////////////////////////////////
+       // / CONNECTORS
+
+       public boolean testConnector(Node connector) {
+               // TODO Implement this.
+               return false;
+       }
+
        // /** Expose injected repository */
        // public Repository getRepository() {
        // return repository;
index 0e451b3432db01469cd8655aa6107b1f167a3551..ad10673484605de8d8f87f745dd054b19f22dd88 100644 (file)
@@ -27,7 +27,15 @@ mixin
 - akb:connectorUrl (STRING)
 // add argeo keyring
 
-[akb:connectorAlias] > nt:unstructured, mix:title  
+// ease retrieval and enable adding alias specific properties
+[akb:connectorAlias] > akb:connector  
+// Use akb:connectorUrl property to define default test connector
+
+
+// HELPER
+[akb:connectorFolder] > nt:unstructured, mix:title  
++ * (akb:connector, akb:connectorAlias) * 
+
     
 
 // Various connector types as mixin
@@ -37,6 +45,9 @@ mixin
 [akb:jdbcConnector]  
 mixin
 
+[akb:jcrConnector]  
+mixin
+
 
     
 //
@@ -47,8 +58,9 @@ mixin
 //
 // GENERIC ITEM FOLDER
 //
-[akb:itemsFolder] > nt:unstructured
+[akb:itemsFolder] > nt:unstructured, mix:title  
 + * (akb:item) * 
++ * (akb:itemsFolder) * 
 
 //
 // SSH FILE