work on a first draft of the AKB UI
authorBruno Sinou <bsinou@argeo.org>
Thu, 7 Nov 2013 16:04:20 +0000 (16:04 +0000)
committerBruno Sinou <bsinou@argeo.org>
Thu, 7 Nov 2013 16:04:20 +0000 (16:04 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@6595 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

18 files changed:
modules/org.argeo.slc.akb.services/META-INF/spring/services.xml
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/META-INF/spring/views.xml
plugins/org.argeo.slc.akb.ui/plugin.xml
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/AkbEnvPerspective.java
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/commands/OpenAkbNodeEditor.java [new file with mode: 0644]
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/editors/AbstractAkbNodeEditor.java [new file with mode: 0644]
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/editors/AkbConnectorAliasEditor.java [new file with mode: 0644]
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/editors/AkbEnvTemplateEditor.java [new file with mode: 0644]
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/editors/AkbNodeEditorInput.java [new file with mode: 0644]
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/providers/AkbTreeLabelProvider.java [new file with mode: 0644]
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/providers/TemplatesTreeContentProvider.java [new file with mode: 0644]
plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/views/AkbTemplatesTreeView.java [new file with mode: 0644]
runtime/org.argeo.slc.akb/src/main/java/org/argeo/slc/akb/AkbNames.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 [new file with mode: 0644]
runtime/org.argeo.slc.akb/src/main/resources/org/argeo/slc/akb/akb.cnd

index 22c33a6e819ad63d30f0698c17390a5f4dd3ffae..fc42e138649822fcc9f7dd17afb9839ed618af0f 100644 (file)
@@ -5,10 +5,10 @@
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
                http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">\r
 \r
-       <!-- <bean id="akbService" class="org.argeo.slc.akb.core.AkbServiceImpl" \r
-               init-method="init" destroy-method="destroy"> <property name="repository" \r
-               ref="peopleRepository" /> <property name="managedRoles" ref="managedRoles" \r
-               /> </bean> -->\r
+       <bean id="akbService" class="org.argeo.slc.akb.core.AkbServiceImpl"\r
+               init-method="init" destroy-method="destroy">\r
+               <property name="repository" ref="akbRepository" />\r
+       </bean>\r
        <bean\r
                class="org.argeo.security.core.AuthenticatedApplicationContextInitialization">\r
                <property name="authenticationManager" ref="authenticationManager" />\r
index 3b2e6ccb0cc58d26d0fb193f2b4b59757384a58a..43e7e4b397d75aa655867c31ae37c48095a128cb 100644 (file)
@@ -4,4 +4,9 @@
        xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd">
 
+       <!-- Opens or show an AKB specific node given some params. -->
+       <bean id="openAkbNodeEditor" class="org.argeo.slc.akb.ui.commands.OpenAkbNodeEditor"
+               scope="prototype">
+               <property name="repository" ref="repository" />
+       </bean>
 </beans>
index 7809cbfad120751730ffa93257b430449971532d..25b421588bf1bee75b7cab81e214932ffc7474cb 100644 (file)
@@ -3,5 +3,12 @@
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd">
-
+       <bean id="akbEnvTemplateEditor" class="org.argeo.slc.akb.ui.editors.AkbEnvTemplateEditor"
+               scope="prototype">
+               <property name="repository" ref="repository" />
+       </bean>
+       <bean id="akbConnectorAliasEditor" class="org.argeo.slc.akb.ui.editors.AkbConnectorAliasEditor"
+               scope="prototype">
+               <property name="repository" ref="repository" />
+       </bean>
 </beans>
\ No newline at end of file
index f592db19bcc6648e55c63cbe9cdf44ce64ac3aef..8b2565f849c3c9701f1386d73515e1842d96bedd 100644 (file)
@@ -10,4 +10,8 @@
                scope="prototype">
                <property name="repository" ref="repository" />
        </bean>
+       <bean id="akbTemplatesTreeView" class="org.argeo.slc.akb.ui.views.AkbTemplatesTreeView"
+               scope="prototype">
+               <property name="repository" ref="repository" />
+       </bean>
 </beans>
index 891619d2173868bc09b767ebc0ff5fe1554cc63e..bdf9dfeee4953535a130ab58aedb11c1ff52d9e2 100644 (file)
                        name="Search"
                        restorable="true">
                </view>
+               <view
+                       class="org.argeo.eclipse.spring.SpringExtensionFactory"
+                       icon="icons/akb.png"
+                       id="org.argeo.slc.akb.ui.akbTemplatesTreeView"
+                       name="Akb Templates"
+                       restorable="true">
+               </view>
        </extension>
        <!-- Editors -->
     <extension
                point="org.eclipse.ui.editors">
+               <editor
+                       class="org.argeo.eclipse.spring.SpringExtensionFactory"
+                       icon="icons/akb.png"
+                       id="org.argeo.slc.akb.ui.akbConnectorAliasEditor"
+                       name="Connector Alias Editor">
+               </editor>
+               <editor
+                       class="org.argeo.eclipse.spring.SpringExtensionFactory"
+                       icon="icons/akb.png"
+                       id="org.argeo.slc.akb.ui.akbEnvTemplateEditor"
+                       name="Environment Template Editor">
+               </editor>
+               
        </extension>
        <!-- Commands -->
        <extension
                point="org.eclipse.ui.commands">
+               <command
+                       defaultHandler="org.argeo.eclipse.spring.SpringExtensionFactory"
+                       id="org.argeo.slc.akb.ui.openAkbNodeEditor"
+                       name="Open Akb Node editor">
+               <commandParameter
+                       id="param.nodeType"
+                       name="Corresponding JCR node type">
+                       </commandParameter>
+               <commandParameter
+                       id="param.nodeJcrId"
+                       name="The Node JCR ID if needed">
+                       </commandParameter>
+               <commandParameter
+                       id="param.parentNodeJcrId"
+                       name="The Parent Node JCR ID if needed">
+                       </commandParameter>
+               </command>
        </extension>            
-       
        <!-- Menus -->
        <extension
                point="org.eclipse.ui.menus">
index abd7f90ca3e6a80ec97188cfc0fd06c499cb0084..cfd6d357153a2919a490a6cf2bbba9c6c5a1eb2f 100644 (file)
@@ -1,6 +1,7 @@
 package org.argeo.slc.akb.ui;
 
 import org.argeo.slc.akb.ui.views.AkbDefaultView;
+import org.argeo.slc.akb.ui.views.AkbTemplatesTreeView;
 import org.eclipse.ui.IFolderLayout;
 import org.eclipse.ui.IPageLayout;
 import org.eclipse.ui.IPerspectiveFactory;
@@ -16,6 +17,7 @@ public class AkbEnvPerspective implements IPerspectiveFactory {
 
                IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT,
                                0.3f, editorArea);
+               left.addView(AkbTemplatesTreeView.ID);
                left.addView(AkbDefaultView.ID);
        }
 }
diff --git a/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/commands/OpenAkbNodeEditor.java b/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/commands/OpenAkbNodeEditor.java
new file mode 100644 (file)
index 0000000..c02f118
--- /dev/null
@@ -0,0 +1,109 @@
+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.AkbTypes;
+import org.argeo.slc.akb.ui.AkbUiPlugin;
+import org.argeo.slc.akb.ui.editors.AkbConnectorAliasEditor;
+import org.argeo.slc.akb.ui.editors.AkbEnvTemplateEditor;
+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.PartInitException;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * Opens or show an AKB specific node in a single repository / single workspace
+ * environment given some parameters, namely :
+ * <ul>
+ * <li>PARAM_NODE_JCR_ID: the corresponding JCR ID might be null to create a new
+ * one</li>
+ * <li>PARAM_NODE_TYPE: jcr type of the node to create</li>
+ * <li>PARAM_PARENT_NODE_JCR_ID: Only used in the case of the creation of a new
+ * node.</li>
+ * </ul>
+ */
+public class OpenAkbNodeEditor extends AbstractHandler {
+       public final static String ID = AkbUiPlugin.PLUGIN_ID
+                       + ".openAkbNodeEditor";
+
+       /* 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 final static String PARAM_PARENT_NODE_JCR_ID = "param.parentNodeJcrId";
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+
+               String nodeType = event.getParameter(PARAM_NODE_TYPE);
+               String nodeJcrId = event.getParameter(PARAM_NODE_JCR_ID);
+               String parentNodeJcrId = event.getParameter(PARAM_PARENT_NODE_JCR_ID);
+
+               Session session = null;
+               try {
+                       session = repository.login();
+                       Node node = null;
+
+                       if (nodeJcrId == null)
+                               if (parentNodeJcrId == null)
+                                       throw new AkbException(
+                                                       "Define a parent node to create a new node");
+                               else
+                                       node = createNewNode(session, nodeType, parentNodeJcrId);
+                       else
+                               node = session.getNodeByIdentifier(nodeJcrId);
+
+                       String editorId = getEditorForNode(node);
+
+                       AkbNodeEditorInput eei = new AkbNodeEditorInput(
+                                       node.getIdentifier());
+
+                       HandlerUtil.getActiveWorkbenchWindow(event).getActivePage()
+                                       .openEditor(eei, editorId);
+               } catch (PartInitException pie) {
+                       throw new AkbException(
+                                       "Unexpected PartInitException while opening akb node editor",
+                                       pie);
+               } catch (RepositoryException e) {
+                       throw new AkbException("unexpected JCR error while opening "
+                                       + nodeType + " editor", e);
+               } finally {
+                       JcrUtils.logoutQuietly(session);
+               }
+               return null;
+       }
+
+       private Node createNewNode(Session session, String nodeType,
+                       String parentNodeJcrId) throws RepositoryException {
+               Node parentNode = session.getNodeByIdentifier(parentNodeJcrId);
+               Node node = parentNode.addNode("new", nodeType);
+               // corresponding node is saved but not checked in, in order to ease
+               // cancel actions.
+               session.save();
+               return node;
+       }
+
+       private String getEditorForNode(Node node) throws RepositoryException {
+               String editorId = null;
+
+               if (node.isNodeType(AkbTypes.AKB_CONNECTOR_ALIAS))
+                       editorId = AkbConnectorAliasEditor.ID;
+               else if (node.isNodeType(AkbTypes.AKB_ENV_TEMPLATE))
+                       editorId = AkbEnvTemplateEditor.ID;
+               else
+                       throw new AkbException("Editor is undefined for node " + node);
+               return editorId;
+       }
+
+       /* DEPENDENCY INJECTION */
+       public void setRepository(Repository repository) {
+               this.repository = repository;
+       }
+}
\ No newline at end of file
diff --git a/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/editors/AbstractAkbNodeEditor.java b/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/editors/AbstractAkbNodeEditor.java
new file mode 100644 (file)
index 0000000..ba2963e
--- /dev/null
@@ -0,0 +1,122 @@
+package org.argeo.slc.akb.ui.editors;
+
+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.eclipse.core.runtime.IProgressMonitor;
+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;
+
+/**
+ * Parent Abstract Node editor for AKB. Manage life cycle of the JCR session that
+ * is bound to it.
+ */
+public abstract class AbstractAkbNodeEditor extends EditorPart {
+       // private final static Log log = LogFactory
+       // .getLog(AbstractEntityEditor.class);
+
+       // We use a one session per editor pattern to secure various nodes and
+       // changes life cycle
+       private Repository repository;
+       private Session session;
+
+       // Business Objects
+       private Node akbNode;
+
+       // LIFE CYCLE
+       public void init(IEditorSite site, IEditorInput input)
+                       throws PartInitException {
+               setSite(site);
+               setInput(input);
+               try {
+                       session = repository.login();
+                       AkbNodeEditorInput anei = (AkbNodeEditorInput) getEditorInput();
+                       akbNode = session.getNodeByIdentifier(anei.getIdentifier());
+
+                       // try to set a default part name
+                       updatePartName();
+
+                       // update tooltip
+                       // String displayName = CommonsJcrUtils.get(getEntity(),
+                       // Property.JCR_TITLE);
+
+                       // if (CommonsJcrUtils.isEmptyString(displayName))
+                       // displayName = "current item";
+                       // setTitleToolTip("Display and edit information for " +
+                       // displayName);
+               } catch (RepositoryException e) {
+                       throw new AkbException("Unable open editor for akb node", e);
+               }
+       }
+
+       /**
+        * Overwrite to provide a specific part Name
+        */
+       protected void updatePartName() {
+               // String name = CommonsJcrUtils.get(entity, Property.JCR_TITLE);
+               // if (CommonsJcrUtils.checkNotEmptyString(name)) {
+               // if (name.length() > SHORT_NAME_LENGHT)
+               // name = name.substring(0, SHORT_NAME_LENGHT - 1) + "...";
+               // setPartName(name);
+               // }
+       }
+
+       /* EXPOSES TO CHILDREN CLASSES */
+       protected Session getSession() {
+               return session;
+       }
+
+       @Override
+       public void dispose() {
+               try {
+                       // if (cNode != null)
+                       // CommonsJcrUtils.cancelAndCheckin(cNode);
+               }
+
+               finally {
+                       JcrUtils.logoutQuietly(session);
+               }
+               super.dispose();
+       }
+
+       @Override
+       public void doSaveAs() {
+               // unused compulsory method
+       }
+
+       @Override
+       public void doSave(IProgressMonitor monitor) {
+               throw new AkbException("Implement this");
+       }
+
+       @Override
+       public boolean isDirty() {
+               try {
+                       return session.hasPendingChanges();
+               } catch (Exception e) {
+                       throw new AkbException("Error getting session status.", e);
+               }
+       }
+
+       @Override
+       public boolean isSaveAsAllowed() {
+               return false;
+       }
+
+       @Override
+       public void setFocus() {
+       }
+
+       /* DEPENDENCY INJECTION */
+       public void setRepository(Repository repository) {
+               this.repository = repository;
+       }
+}
\ No newline at end of file
diff --git a/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/editors/AkbConnectorAliasEditor.java b/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/editors/AkbConnectorAliasEditor.java
new file mode 100644 (file)
index 0000000..2ff704c
--- /dev/null
@@ -0,0 +1,18 @@
+package org.argeo.slc.akb.ui.editors;
+
+import org.argeo.slc.akb.ui.AkbUiPlugin;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Display and edit a connector Alias
+ */
+public class AkbConnectorAliasEditor extends AbstractAkbNodeEditor {
+
+       public final static String ID = AkbUiPlugin.PLUGIN_ID
+                       + ".akbConnectorAliasEditor";
+
+       /* CONTENT CREATION */
+       @Override
+       public void createPartControl(Composite parent) {
+       }
+}
\ No newline at end of file
diff --git a/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/editors/AkbEnvTemplateEditor.java b/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/editors/AkbEnvTemplateEditor.java
new file mode 100644 (file)
index 0000000..8a16202
--- /dev/null
@@ -0,0 +1,18 @@
+package org.argeo.slc.akb.ui.editors;
+
+import org.argeo.slc.akb.ui.AkbUiPlugin;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Display and edit a connector Alias
+ */
+public class AkbEnvTemplateEditor extends AbstractAkbNodeEditor {
+
+       public final static String ID = AkbUiPlugin.PLUGIN_ID
+                       + ".akbEnvTemplateEditor";
+
+       /* CONTENT CREATION */
+       @Override
+       public void createPartControl(Composite parent) {
+       }
+}
\ No newline at end of file
diff --git a/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/editors/AkbNodeEditorInput.java b/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/editors/AkbNodeEditorInput.java
new file mode 100644 (file)
index 0000000..be77afe
--- /dev/null
@@ -0,0 +1,65 @@
+package org.argeo.slc.akb.ui.editors;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IPersistableElement;
+
+/**
+ * Editor input for all editors that display info on a given AKB JCR Node.
+ * Relies on the Jcr ID
+ */
+public class AkbNodeEditorInput implements IEditorInput {
+
+       private final String jcrId;
+
+       /** the Jcr ID cannot be null */
+       public AkbNodeEditorInput(String jcrId) {
+               this.jcrId = jcrId;
+       }
+
+       public String getIdentifier() {
+               return jcrId;
+       }
+
+       public boolean exists() {
+               return true;
+       }
+
+       public ImageDescriptor getImageDescriptor() {
+               return null;
+       }
+
+       public String getName() {
+               return jcrId;
+       }
+
+       public IPersistableElement getPersistable() {
+               return null;
+       }
+
+       public String getToolTipText() {
+               return "Display and edit information about a given AKB Jcr Node";
+       }
+
+       @SuppressWarnings("rawtypes")
+       public Object getAdapter(Class adapter) {
+               return null;
+       }
+
+       public int hashCode() {
+               return jcrId.hashCode();
+       }
+
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               if (obj == null)
+                       return false;
+               if (getClass() != obj.getClass())
+                       return false;
+               AkbNodeEditorInput other = (AkbNodeEditorInput) obj;
+               if (!jcrId.equals(other.getIdentifier()))
+                       return false;
+               return true;
+       }
+}
\ No newline at end of file
diff --git a/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/providers/AkbTreeLabelProvider.java b/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/providers/AkbTreeLabelProvider.java
new file mode 100644 (file)
index 0000000..8fb639c
--- /dev/null
@@ -0,0 +1,53 @@
+package org.argeo.slc.akb.ui.providers;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
+
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.slc.akb.AkbException;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+/** Basic label provider for an AKB tree */
+public class AkbTreeLabelProvider extends LabelProvider {
+       // private final static Log log = LogFactory
+       // .getLog(ResultTreeLabelProvider.class);
+
+       @Override
+       public String getText(Object element) {
+               try {
+
+                       if (element instanceof Node) {
+                               Node node = (Node) element;
+                               if (node.isNodeType(NodeType.MIX_TITLE))
+                                       return node.getProperty(Property.JCR_TITLE).getString();
+                               else
+                                       return node.getName();
+                       }
+               } catch (RepositoryException e) {
+                       throw new AkbException("Unexpected error while getting "
+                                       + "Custom node label", e);
+               }
+               return ((TreeParent) element).getName();
+       }
+
+       public Image getImage(Object obj) {
+               // if (obj instanceof SingleResultNode) {
+               // // FIXME add realtime modification of process icon (SCHEDULED,
+               // // RUNNING, COMPLETED...)
+               // // Node resultNode = ((SingleResultNode) obj).getNode();
+               // // int status = SlcJcrUtils.aggregateTestStatus(resultNode);
+               // return SlcImages.PROCESS_COMPLETED;
+               // } else if (obj instanceof ResultParent) {
+               // ResultParent rParent = (ResultParent) obj;
+               // if (SlcUiConstants.DEFAULT_MY_RESULTS_FOLDER_LABEL.equals(rParent
+               // .getName()))
+               // return SlcImages.MY_RESULTS_FOLDER;
+               // else
+               // return SlcImages.FOLDER;
+               // } else
+               return null;
+       }
+}
diff --git a/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/providers/TemplatesTreeContentProvider.java b/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/providers/TemplatesTreeContentProvider.java
new file mode 100644 (file)
index 0000000..6d57dce
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.slc.akb.ui.providers;
+
+import org.argeo.eclipse.ui.TreeParent;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/** Basic content provider for a tree of AKB environment templates */
+public class TemplatesTreeContentProvider implements ITreeContentProvider {
+
+       /**
+        * @param parent
+        *            Pass current user home as parameter
+        * 
+        */
+       public Object[] getElements(Object parent) {
+               if (parent instanceof Object[])
+                       return (Object[]) parent;
+               else
+                       return null;
+       }
+
+       public Object getParent(Object child) {
+               return ((TreeParent) child).getParent();
+       }
+
+       public Object[] getChildren(Object parent) {
+               return ((TreeParent) parent).getChildren();
+       }
+
+       public boolean hasChildren(Object parent) {
+               return ((TreeParent) parent).hasChildren();
+       }
+
+       public void dispose() {
+               // FIXME implement if needed
+       }
+
+       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+       }
+}
\ No newline at end of file
diff --git a/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/views/AkbTemplatesTreeView.java b/plugins/org.argeo.slc.akb.ui/src/main/java/org/argeo/slc/akb/ui/views/AkbTemplatesTreeView.java
new file mode 100644 (file)
index 0000000..9e82b4b
--- /dev/null
@@ -0,0 +1,464 @@
+/*\r
+ * Copyright (C) 2007-2012 Argeo GmbH\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.argeo.slc.akb.ui.views;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import javax.jcr.Node;\r
+import javax.jcr.Repository;\r
+import javax.jcr.RepositoryException;\r
+import javax.jcr.Session;\r
+\r
+import org.argeo.eclipse.ui.utils.CommandUtils;\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.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.IMenuListener;\r
+import org.eclipse.jface.action.IMenuManager;\r
+import org.eclipse.jface.action.MenuManager;\r
+import org.eclipse.jface.viewers.DoubleClickEvent;\r
+import org.eclipse.jface.viewers.IDoubleClickListener;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.viewers.TreeViewer;\r
+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.Menu;\r
+import org.eclipse.ui.IWorkbenchWindow;\r
+import org.eclipse.ui.part.ViewPart;\r
+\r
+/** SLC generic JCR Result tree view. */\r
+public class AkbTemplatesTreeView extends ViewPart {\r
+       // private final static Log log =\r
+       // LogFactory.getLog(JcrResultTreeView.class);\r
+\r
+       public final static String ID = AkbUiPlugin.PLUGIN_ID\r
+                       + ".akbTemplatesTreeView";\r
+\r
+       /* DEPENDENCY INJECTION */\r
+       private Session session;\r
+\r
+       // This page widgets\r
+       private TreeViewer resultTreeViewer;\r
+\r
+       // Usefull business objects\r
+       private Node templatesParentNode;\r
+\r
+       // private EventListener myResultsObserver = null;\r
+       // private EventListener allResultsObserver = null;\r
+       //\r
+       // // under My Results\r
+       // private final static String[] observedNodeTypesUnderMyResult = {\r
+       // SlcTypes.SLC_TEST_RESULT, SlcTypes.SLC_RESULT_FOLDER,\r
+       // SlcTypes.SLC_MY_RESULT_ROOT_FOLDER };\r
+       //\r
+       // private final static String[] observedNodeTypesUnderAllResults = {\r
+       // SlcTypes.SLC_TEST_RESULT, NodeType.NT_UNSTRUCTURED };\r
+       //\r
+       // private boolean isResultFolder = false;\r
+\r
+       // /**\r
+       // * To be overridden to adapt size of form and result frames.\r
+       // */\r
+       // protected int[] getWeights() {\r
+       // return new int[] { 70, 30 };\r
+       // }\r
+\r
+       private void initialize() {\r
+               try {\r
+                       templatesParentNode = session\r
+                                       .getNode(AkbNames.AKB_TEMPLATES_BASE_PATH);\r
+               } catch (RepositoryException e) {\r
+                       throw new AkbException("unable to initialize AKB Browser view", e);\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public void createPartControl(Composite parent) {\r
+               initialize();\r
+\r
+               createResultsTreeViewer(parent);\r
+\r
+               // parent.setLayout(new FillLayout());\r
+               // // Main layout\r
+               // SashForm sashForm = new SashForm(parent, SWT.VERTICAL);\r
+               // sashForm.setSashWidth(4);\r
+               // sashForm.setLayout(new FillLayout());\r
+\r
+               // Create the tree on top of the view\r
+               // Composite top = new Composite(sashForm, SWT.NONE);\r
+               // GridLayout gl = new GridLayout(1, false);\r
+               // top.setLayout(gl);\r
+               // resultTreeViewer = createResultsTreeViewer(top);\r
+\r
+               // // Create the property viewer on the bottom\r
+               // Composite bottom = new Composite(sashForm, SWT.NONE);\r
+               // bottom.setLayout(new GridLayout(1, false));\r
+               // propertiesViewer = createPropertiesViewer(bottom);\r
+               //\r
+               // sashForm.setWeights(getWeights());\r
+\r
+               // setOrderedInput(resultTreeViewer);\r
+\r
+               // Initialize observer\r
+               // try {\r
+               // ObservationManager observationManager = session.getWorkspace()\r
+               // .getObservationManager();\r
+               // myResultsObserver = new MyResultsObserver(resultTreeViewer\r
+               // .getTree().getDisplay());\r
+               // allResultsObserver = new AllResultsObserver(resultTreeViewer\r
+               // .getTree().getDisplay());\r
+               //\r
+               // // observe tree changes under MyResults\r
+               // observationManager.addEventListener(myResultsObserver,\r
+               // Event.NODE_ADDED | Event.NODE_REMOVED,\r
+               // SlcJcrResultUtils.getMyResultsBasePath(session), true,\r
+               // null, observedNodeTypesUnderMyResult, false);\r
+               // // observe tree changes under All results\r
+               // observationManager.addEventListener(allResultsObserver,\r
+               // Event.NODE_ADDED | Event.NODE_REMOVED,\r
+               // SlcJcrResultUtils.getSlcResultsBasePath(session), true,\r
+               // null, observedNodeTypesUnderAllResults, false);\r
+               // } catch (RepositoryException e) {\r
+               // throw new SlcException("Cannot register listeners", e);\r
+               // }\r
+       }\r
+\r
+       /**\r
+        * Override default behaviour so that default defined order remains\r
+        * unchanged on first level of the tree\r
+        */\r
+       // private void setOrderedInput(TreeViewer viewer) {\r
+       // // Add specific ordering\r
+       // viewer.setInput(null);\r
+       // viewer.setComparator(null);\r
+       // viewer.setInput(initializeResultTree());\r
+       // viewer.setComparator(new ResultItemsComparator());\r
+       // }\r
+\r
+       // The main tree viewer\r
+       protected TreeViewer createResultsTreeViewer(Composite parent) {\r
+               int style = SWT.BORDER | SWT.MULTI;\r
+\r
+               TreeViewer viewer = new TreeViewer(parent, style);\r
+               viewer.getTree().setLayoutData(\r
+                               new GridData(SWT.FILL, SWT.FILL, true, true));\r
+\r
+               viewer.setContentProvider(new TemplatesTreeContentProvider());\r
+               viewer.setLabelProvider(new AkbTreeLabelProvider());\r
+               viewer.addDoubleClickListener(new ViewDoubleClickListener());\r
+\r
+               // Add label provider with label decorator\r
+               // ResultTreeLabelProvider rtLblProvider = new\r
+               // ResultTreeLabelProvider();\r
+               // ILabelDecorator decorator = AkbUiPlugin.getDefault().getWorkbench()\r
+               // .getDecoratorManager().getLabelDecorator();\r
+               // viewer.setLabelProvider(new DecoratingLabelProvider(rtLblProvider,\r
+               // decorator));\r
+               // viewer.addDoubleClickListener(new ViewDoubleClickListener());\r
+\r
+               // Override default behaviour to insure that 2 distincts results that\r
+               // have the same name will be correctly and distincly returned by\r
+               // corresponding TreeViewer.getSelection() method.\r
+               // viewer.setComparer(new ResultItemsComparer());\r
+\r
+               getSite().setSelectionProvider(viewer);\r
+\r
+               // // add drag & drop support\r
+               // int operations = DND.DROP_COPY | DND.DROP_MOVE;\r
+               // Transfer[] tt = new Transfer[] { TextTransfer.getInstance() };\r
+               // viewer.addDragSupport(operations, tt, new ViewDragListener());\r
+               // viewer.addDropSupport(operations, tt, new ViewDropListener(viewer));\r
+\r
+               // add context menu\r
+               MenuManager menuManager = new MenuManager();\r
+               Menu menu = menuManager.createContextMenu(viewer.getTree());\r
+               menuManager.addMenuListener(new IMenuListener() {\r
+                       public void menuAboutToShow(IMenuManager manager) {\r
+                               contextMenuAboutToShow(manager);\r
+                       }\r
+               });\r
+               viewer.getTree().setMenu(menu);\r
+               menuManager.setRemoveAllWhenShown(true);\r
+\r
+               getSite().registerContextMenu(menuManager, viewer);\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
+       // Detailed property viewer\r
+       // protected TableViewer createPropertiesViewer(Composite parent) {\r
+       // }\r
+\r
+       @Override\r
+       public void setFocus() {\r
+       }\r
+\r
+       // private ResultParent[] initializeResultTree() {\r
+       // try {\r
+       // // Force initialization of the tree structure if needed\r
+       // SlcJcrResultUtils.getSlcResultsParentNode(session);\r
+       // SlcJcrResultUtils.getMyResultParentNode(session);\r
+       // // Remove yesterday and last 7 days virtual folders\r
+       // // ResultParent[] roots = new ResultParent[5];\r
+       // ResultParent[] roots = new ResultParent[3];\r
+       //\r
+       // // My results\r
+       // roots[0] = new ParentNodeFolder(null,\r
+       // SlcJcrResultUtils.getMyResultParentNode(session),\r
+       // SlcUiConstants.DEFAULT_MY_RESULTS_FOLDER_LABEL);\r
+       //\r
+       // // today\r
+       // Calendar cal = Calendar.getInstance();\r
+       // String relPath = JcrUtils.dateAsPath(cal);\r
+       // List<String> datePathes = new ArrayList<String>();\r
+       // datePathes.add(relPath);\r
+       // roots[1] = new VirtualFolder(null,\r
+       // ResultParentUtils.getResultsForDates(session, datePathes),\r
+       // "Today");\r
+       //\r
+       // // // Yesterday\r
+       // // cal = Calendar.getInstance();\r
+       // // cal.add(Calendar.DAY_OF_YEAR, -1);\r
+       // // relPath = JcrUtils.dateAsPath(cal);\r
+       // // datePathes = new ArrayList<String>();\r
+       // // datePathes.add(relPath);\r
+       // // roots[2] = new VirtualFolder(null,\r
+       // // ResultParentUtils.getResultsForDates(session, datePathes),\r
+       // // "Yesterday");\r
+       // // // Last 7 days\r
+       // //\r
+       // // cal = Calendar.getInstance();\r
+       // // datePathes = new ArrayList<String>();\r
+       // //\r
+       // // for (int i = 0; i < 7; i++) {\r
+       // // cal.add(Calendar.DAY_OF_YEAR, -i);\r
+       // // relPath = JcrUtils.dateAsPath(cal);\r
+       // // datePathes.add(relPath);\r
+       // // }\r
+       // // roots[3] = new VirtualFolder(null,\r
+       // // ResultParentUtils.getResultsForDates(session, datePathes),\r
+       // // "Last 7 days");\r
+       //\r
+       // // All results\r
+       // Node otherResultsPar = session.getNode(SlcJcrResultUtils\r
+       // .getSlcResultsBasePath(session));\r
+       // // roots[4] = new ParentNodeFolder(null, otherResultsPar,\r
+       // // "All results");\r
+       // roots[2] = new ParentNodeFolder(null, otherResultsPar,\r
+       // "All results");\r
+       // return roots;\r
+       // } catch (RepositoryException re) {\r
+       // throw new ArgeoException(\r
+       // "Unexpected error while initializing ResultTree.", re);\r
+       // }\r
+       // }\r
+\r
+       // Manage context menu\r
+       /**\r
+        * Defines the commands that will pop up in the context menu.\r
+        **/\r
+       protected void contextMenuAboutToShow(IMenuManager menuManager) {\r
+               IWorkbenchWindow window = AkbUiPlugin.getDefault().getWorkbench()\r
+                               .getActiveWorkbenchWindow();\r
+               try {\r
+                       // IStructuredSelection selection = (IStructuredSelection)\r
+                       // resultTreeViewer\r
+                       // .getSelection();\r
+                       // boolean canAddSubfolder = false;\r
+                       // boolean canRenamefolder = false;\r
+                       // boolean isSingleResultNode = false;\r
+                       // boolean isUnderMyResult = false;\r
+                       // boolean validMultipleDelete = false;\r
+                       //\r
+                       // // Building conditions\r
+                       // if (selection.size() == 1) {\r
+                       // Object obj = selection.getFirstElement();\r
+                       // if (obj instanceof SingleResultNode)\r
+                       // isSingleResultNode = true;\r
+                       // else if (obj instanceof ParentNodeFolder) {\r
+                       // Node cNode = ((ParentNodeFolder) obj).getNode();\r
+                       // if (cNode.isNodeType(SlcTypes.SLC_RESULT_FOLDER)) {\r
+                       // canAddSubfolder = true;\r
+                       // canRenamefolder = true;\r
+                       // isUnderMyResult = true;\r
+                       // } else if (cNode\r
+                       // .isNodeType(SlcTypes.SLC_MY_RESULT_ROOT_FOLDER)) {\r
+                       // canAddSubfolder = true;\r
+                       // }\r
+                       // }\r
+                       // } else {\r
+                       // @SuppressWarnings("rawtypes")\r
+                       // Iterator it = selection.iterator();\r
+                       // multicheck: while (it.hasNext()) {\r
+                       // validMultipleDelete = true;\r
+                       // Object obj = it.next();\r
+                       // if (obj instanceof SingleResultNode)\r
+                       // continue multicheck;\r
+                       // else if (obj instanceof ParentNodeFolder) {\r
+                       // Node cNode = ((ParentNodeFolder) obj).getNode();\r
+                       // if (cNode.isNodeType(SlcTypes.SLC_RESULT_FOLDER))\r
+                       // continue multicheck;\r
+                       // else {\r
+                       // validMultipleDelete = false;\r
+                       // break multicheck;\r
+                       // }\r
+                       // } else {\r
+                       // validMultipleDelete = false;\r
+                       // break multicheck;\r
+                       // }\r
+                       // }\r
+                       // }\r
+\r
+                       Map<String, String> 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
+\r
+                       //\r
+                       // CommandUtils.refreshCommand(menuManager, window, DeleteItems.ID,\r
+                       // DeleteItems.DEFAULT_LABEL, DeleteItems.DEFAULT_IMG_DESCRIPTOR,\r
+                       // isUnderMyResult || isSingleResultNode || validMultipleDelete);\r
+                       //\r
+                       // CommandUtils.refreshCommand(menuManager, window,\r
+                       // AddResultFolder.ID,\r
+                       // AddResultFolder.DEFAULT_LABEL,\r
+                       // ClientUiPlugin.getDefault().getWorkbench().getSharedImages()\r
+                       // .getImageDescriptor(ISharedImages.IMG_OBJ_ADD),\r
+                       // canAddSubfolder);\r
+                       //\r
+                       // CommandUtils.refreshCommand(menuManager, window,\r
+                       // RenameResultFolder.ID,\r
+                       // RenameResultFolder.DEFAULT_LABEL,\r
+                       // RenameResultFolder.DEFAULT_IMG_DESCRIPTOR, canRenamefolder);\r
+                       //\r
+                       // // Command removed for the time being.\r
+                       // CommandUtils.refreshCommand(menuManager, window,\r
+                       // RenameResultNode.ID,\r
+                       // RenameResultNode.DEFAULT_LABEL,\r
+                       // RenameResultNode.DEFAULT_IMG_DESCRIPTOR, false);\r
+                       //\r
+                       // // Test to be removed\r
+                       // // If you use this pattern, do not forget to call\r
+                       // // menuManager.setRemoveAllWhenShown(true);\r
+                       // // when creating the menuManager\r
+                       //\r
+                       // // menuManager.add(new Action("Test") {\r
+                       // // public void run() {\r
+                       // // log.debug("do something");\r
+                       // // }\r
+                       // // });\r
+               } catch (RepositoryException re) {\r
+                       throw new AkbException("Error while refreshing context menu", re);\r
+               }\r
+       }\r
+\r
+       /* INNER CLASSES */\r
+       class ViewDoubleClickListener implements IDoubleClickListener {\r
+               public void doubleClick(DoubleClickEvent evt) {\r
+                       Object obj = ((IStructuredSelection) evt.getSelection())\r
+                                       .getFirstElement();\r
+                       try {\r
+                               if (obj instanceof Node) {\r
+                                       Node node = (Node) obj;\r
+                                       CommandUtils.callCommand(OpenAkbNodeEditor.ID,\r
+                                                       OpenAkbNodeEditor.PARAM_NODE_JCR_ID,\r
+                                                       node.getIdentifier());\r
+                               }\r
+                       } catch (RepositoryException e) {\r
+                               throw new AkbException("Cannot open " + obj, e);\r
+                       }\r
+               }\r
+       }\r
+\r
+       // class MyResultsObserver extends AsyncUiEventListener {\r
+       //\r
+       // public MyResultsObserver(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
+       // List<Node> nodesToRefresh = new ArrayList<Node>();\r
+       //\r
+       // for (Event event : events) {\r
+       // String parPath = JcrUtils.parentPath(event.getPath());\r
+       // if (session.nodeExists(parPath)) {\r
+       // Node node = session.getNode(parPath);\r
+       // if (!nodesToRefresh.contains(node)) {\r
+       // nodesToRefresh.add(node);\r
+       // }\r
+       // }\r
+       // }\r
+       //\r
+       // // Update check nodes\r
+       // for (Node node : nodesToRefresh)\r
+       // jcrRefresh(node);\r
+       // refresh(null);\r
+       // }\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
+       // refresh(null);\r
+       // // if (lastSelectedSourceElementParent != null)\r
+       // // refresh(lastSelectedSourceElementParent);\r
+       // }\r
+       // }\r
+\r
+       /* DEPENDENCY INJECTION */\r
+       public void setRepository(Repository repository) {\r
+               try {\r
+                       session = repository.login();\r
+               } catch (RepositoryException e) {\r
+                       throw new AkbException("unable to log in for " + ID + " view");\r
+               }\r
+       }\r
+}
\ No newline at end of file
index c341f4acc988f1890f7377fc6416c0750e783012..7ba191a421a3fe8849bdd50afc57cfe6067a49e8 100644 (file)
@@ -3,6 +3,21 @@ package org.argeo.slc.akb;
 /** Maps AKB specific JCR Property names with java constants */
 public interface AkbNames {
 
+       public final static String AKB_NAMESPACE = "http://www.argeo.org/ns/akb";
+
+       /* DEFAULT BASE PATHS */
+       public final static String AKB_BASE_PATH = "/akb:system";
+       public final static String AKB_TEMPLATES_BASE_PATH = AKB_BASE_PATH + "/"
+                       + "akb:templates";
+
+       public final static String AKB_ENVIRONMENTS_BASE_PATH = AKB_BASE_PATH + "/"
+                       + "akb:environments";
+
+       /* ENVIRONMENT PROPERTIES */
+
+       /* CONNECTOR PROPERTIES */
        public final static String AKB_CONNECTOR_URL = "akb:connectorUrl";
 
+       /* ITEMS PROPERTIES */
+
 }
\ No newline at end of file
index 79af5b99b818ae74087f6acc9e0d1dcaeb0fadc2..82407f1ce440a4fd6460ce46487a40d9feb9fe0a 100644 (file)
@@ -5,14 +5,18 @@ public interface AkbTypes {
 
        public final static String ARGEO_NOTE = "argeo:note";
 
-       
        // Env and templates 
        public final static String AKB_ENV_TEMPLATE = "akb:envTemplate";
        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";  
 
+       // 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_ITEM_FOLDER = "akb:itemsFolder";
        public final static String AKB_ITEM = "akb:item";
diff --git a/runtime/org.argeo.slc.akb/src/main/java/org/argeo/slc/akb/core/AkbServiceImpl.java b/runtime/org.argeo.slc.akb/src/main/java/org/argeo/slc/akb/core/AkbServiceImpl.java
new file mode 100644 (file)
index 0000000..02ccdc6
--- /dev/null
@@ -0,0 +1,79 @@
+package org.argeo.slc.akb.core;
+
+import java.util.Map;
+
+import javax.annotation.Resource;
+import javax.jcr.Repository;
+import javax.jcr.Session;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.akb.AkbException;
+import org.argeo.slc.akb.AkbNames;
+
+/**
+ * Concrete access to akb services. It provides among other an initialized
+ * environment
+ */
+public class AkbServiceImpl implements AkbNames {
+       private final static Log log = LogFactory.getLog(AkbServiceImpl.class);
+
+       /* DEPENDENCY INJECTION */
+       private Repository repository;
+
+       // Populate the repository in a demo context.
+       private Map<String, Resource> demoData = null;
+
+       /* Life cycle management */
+       /**
+        * Call by each startup in order to make sure the backend is ready to
+        * receive/provide data.
+        */
+       public void init() {
+               Session adminSession = null;
+               try {
+                       adminSession = repository.login();
+
+                       // Initialization of the model
+                       if (!adminSession.nodeExists(AKB_TEMPLATES_BASE_PATH)) {
+                               JcrUtils.mkdirs(adminSession, AKB_TEMPLATES_BASE_PATH);
+                               JcrUtils.mkdirs(adminSession, AKB_ENVIRONMENTS_BASE_PATH);
+                               adminSession.save();
+                               log.info("Repository has been initialized "
+                                               + "with AKB's model");
+                       }
+
+                       // Fill the repository in a demo context
+                       if (demoData != null) {
+                               // Dev only force reload at each start
+                               // if (true) {
+                               // if (!projectsPar.hasNodes()) {
+                       }
+               } catch (Exception e) {
+                       throw new AkbException("Cannot initialize backend", e);
+               } finally {
+                       JcrUtils.logoutQuietly(adminSession);
+               }
+               // log.info("AKB service has been initialized.");
+       }
+
+       /** Clean shutdown of the backend. */
+       public void destroy() {
+               // Do nothing
+       }
+
+       /** Expose injected repository */
+       public Repository getRepository() {
+               return repository;
+       }
+
+       /* DEPENDENCY INJECTION */
+       public void setRepository(Repository repository) {
+               this.repository = repository;
+       }
+
+       public void setDemoData(Map<String, Resource> demoData) {
+               this.demoData = demoData;
+       }
+}
\ No newline at end of file
index a73723a01d032ad2a3ad7d62750c56be0d6c884f..09fed63a8d6fb26428b4a3510f5ff80b04ed2a0f 100644 (file)
@@ -26,7 +26,18 @@ mixin
 [akb:connector] > nt:unstructured, mix:title  
 - akb:connectorUrl (STRING)
 // add argeo keyring
+
+[akb:connectorAlias] > nt:unstructured, mix:title  
     
+
+// Various connector types as mixin
+[akb:sshConnector]  
+mixin
+
+[akb:jdbcConnector]  
+mixin
+
+
     
 //
 // GENERIC ITEM