You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2013/08/09 23:30:52 UTC

svn commit: r1512502 - in /sling/trunk/tooling/ide: api/src/org/apache/sling/ide/transport/ eclipse-ui/ eclipse-ui/META-INF/ eclipse-ui/OSGI-INF/ eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/ eclipse-ui/src/org/apache/sling/ide/eclipse/ui/in...

Author: rombert
Date: Fri Aug  9 21:30:52 2013
New Revision: 1512502

URL: http://svn.apache.org/r1512502
Log:
SLING-2667 - [Tooling] create text-only console that exposes the
operations performed and their results

Initial verison of a Console which logs all operations performed by the
repository.

Added:
    sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/CommandExecutionProperties.java   (with props)
    sling/trunk/tooling/ide/eclipse-ui/OSGI-INF/
    sling/trunk/tooling/ide/eclipse-ui/OSGI-INF/SlingConsoleEventListener.xml   (with props)
    sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/
    sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsole.java   (with props)
    sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsoleEventListener.java   (with props)
    sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsoleFactory.java   (with props)
    sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AbstractCommand.java   (with props)
    sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AddNodeCommand.java   (with props)
    sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/DeleteNodeCommand.java   (with props)
    sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/GetNodeCommand.java   (with props)
    sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/GetNodeContentCommand.java   (with props)
    sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/ListChildrenCommand.java   (with props)
    sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/TracingCommand.java   (with props)
    sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/UpdateContentCommand.java   (with props)
Modified:
    sling/trunk/tooling/ide/eclipse-ui/META-INF/MANIFEST.MF
    sling/trunk/tooling/ide/eclipse-ui/build.properties
    sling/trunk/tooling/ide/eclipse-ui/plugin.xml
    sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/Activator.java
    sling/trunk/tooling/ide/impl-resource/OSGI-INF/RepositoryImpl.xml
    sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/RepositoryImpl.java

Added: sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/CommandExecutionProperties.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/CommandExecutionProperties.java?rev=1512502&view=auto
==============================================================================
--- sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/CommandExecutionProperties.java (added)
+++ sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/CommandExecutionProperties.java Fri Aug  9 21:30:52 2013
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */package org.apache.sling.ide.transport;
+
+public final class CommandExecutionProperties {
+
+    public static final String TIMESTAMP_START = "timestamp.start";
+    public static final String TIMESTAMP_END = "timestamp.end";
+    public static final String ACTION_TYPE = "action.type";
+    public static final String ACTION_TARGET = "action.target";
+    public static final String RESULT_TEXT = "result.txt";
+    public static final String RESULT_THROWABLE = "result.throwable";
+
+    private CommandExecutionProperties() {
+
+    }
+}

Propchange: sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/CommandExecutionProperties.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/tooling/ide/api/src/org/apache/sling/ide/transport/CommandExecutionProperties.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: sling/trunk/tooling/ide/eclipse-ui/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-ui/META-INF/MANIFEST.MF?rev=1512502&r1=1512501&r2=1512502&view=diff
==============================================================================
--- sling/trunk/tooling/ide/eclipse-ui/META-INF/MANIFEST.MF (original)
+++ sling/trunk/tooling/ide/eclipse-ui/META-INF/MANIFEST.MF Fri Aug  9 21:30:52 2013
@@ -38,6 +38,7 @@ Import-Package: org.apache.sling.ide.ecl
  org.eclipse.swt.layout,
  org.eclipse.swt.widgets,
  org.eclipse.ui,
+ org.eclipse.ui.console,
  org.eclipse.ui.dialogs,
  org.eclipse.ui.forms,
  org.eclipse.ui.forms.widgets,
@@ -48,9 +49,12 @@ Import-Package: org.apache.sling.ide.ecl
  org.eclipse.wst.server.ui,
  org.eclipse.wst.server.ui.editor,
  org.osgi.framework,
- org.osgi.util.tracker;version="1.5.0"
+ org.osgi.service.event;version="1.3.0",
+ org.osgi.util.tracker;version="1.5.0",
+ org.osgi.service.component
 Bundle-ActivationPolicy: lazy
 Require-Bundle: org.eclipse.wst.common.project.facet.ui,
  org.eclipse.ui.navigator;bundle-version="3.5.101",
  org.eclipse.ui.views;bundle-version="3.6.0",
  org.eclipse.ui
+Service-Component: OSGI-INF/*.xml

Added: sling/trunk/tooling/ide/eclipse-ui/OSGI-INF/SlingConsoleEventListener.xml
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-ui/OSGI-INF/SlingConsoleEventListener.xml?rev=1512502&view=auto
==============================================================================
--- sling/trunk/tooling/ide/eclipse-ui/OSGI-INF/SlingConsoleEventListener.xml (added)
+++ sling/trunk/tooling/ide/eclipse-ui/OSGI-INF/SlingConsoleEventListener.xml Fri Aug  9 21:30:52 2013
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
+    <implementation class="org.apache.sling.ide.eclipse.ui.internal.console.SlingConsoleEventListener" />
+    <service>
+        <provide interface="org.osgi.service.event.EventHandler" />
+    </service>
+    <property name="event.topics" value="org/apache/sling/ide/transport" />
+</scr:component>

Propchange: sling/trunk/tooling/ide/eclipse-ui/OSGI-INF/SlingConsoleEventListener.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/tooling/ide/eclipse-ui/OSGI-INF/SlingConsoleEventListener.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Modified: sling/trunk/tooling/ide/eclipse-ui/build.properties
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-ui/build.properties?rev=1512502&r1=1512501&r2=1512502&view=diff
==============================================================================
--- sling/trunk/tooling/ide/eclipse-ui/build.properties (original)
+++ sling/trunk/tooling/ide/eclipse-ui/build.properties Fri Aug  9 21:30:52 2013
@@ -1,5 +1,6 @@
 bin.includes = plugin.xml,\
                META-INF/,\
                .,\
-               icons/
+               icons/,\
+               OSGI-INF/
 source.. = src/

Modified: sling/trunk/tooling/ide/eclipse-ui/plugin.xml
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-ui/plugin.xml?rev=1512502&r1=1512501&r2=1512502&view=diff
==============================================================================
--- sling/trunk/tooling/ide/eclipse-ui/plugin.xml (original)
+++ sling/trunk/tooling/ide/eclipse-ui/plugin.xml Fri Aug  9 21:30:52 2013
@@ -181,5 +181,13 @@
                type="org.eclipse.core.resources.IResource">
          </adapter>
       </factory>
+   </extension>
+   <extension
+         point="org.eclipse.ui.console.consoleFactories">
+      <consoleFactory
+            class="org.apache.sling.ide.eclipse.ui.internal.console.SlingConsoleFactory"
+            label="Sling Console">
+      </consoleFactory>
    </extension> 
+   
 </plugin>    

Modified: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/Activator.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/Activator.java?rev=1512502&r1=1512501&r2=1512502&view=diff
==============================================================================
--- sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/Activator.java (original)
+++ sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/Activator.java Fri Aug  9 21:30:52 2013
@@ -21,6 +21,7 @@ import org.apache.sling.ide.filter.Filte
 import org.apache.sling.ide.serialization.SerializationManager;
 import org.eclipse.core.runtime.Plugin;
 import org.osgi.framework.BundleContext;
+import org.osgi.service.event.EventAdmin;
 import org.osgi.util.tracker.ServiceTracker;
 
 public class Activator extends Plugin {
@@ -30,6 +31,7 @@ public class Activator extends Plugin {
 
     private ServiceTracker<SerializationManager, SerializationManager> serializationManager;
     private ServiceTracker<FilterLocator, FilterLocator> filterLocator;
+    private ServiceTracker<EventAdmin, EventAdmin> eventAdmin;
 
     public static Activator getDefault() {
 
@@ -47,6 +49,9 @@ public class Activator extends Plugin {
         filterLocator = new ServiceTracker<FilterLocator, FilterLocator>(context, FilterLocator.class, null);
         filterLocator.open();
 
+        eventAdmin = new ServiceTracker<EventAdmin, EventAdmin>(context, EventAdmin.class, null);
+        eventAdmin.open();
+
         INSTANCE = this;
     }
 
@@ -55,6 +60,7 @@ public class Activator extends Plugin {
         INSTANCE = null;
         serializationManager.close();
         filterLocator.close();
+        eventAdmin.close();
 
         super.stop(context);
     }
@@ -66,4 +72,8 @@ public class Activator extends Plugin {
     public FilterLocator getFilterLocator() {
         return ServiceUtil.getNotNull(filterLocator);
     }
+
+    public EventAdmin getEventAdmin() {
+        return ServiceUtil.getNotNull(eventAdmin);
+    }
 }

Added: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsole.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsole.java?rev=1512502&view=auto
==============================================================================
--- sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsole.java (added)
+++ sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsole.java Fri Aug  9 21:30:52 2013
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.ide.eclipse.ui.internal.console;
+
+public class SlingConsole {
+
+}

Propchange: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsole.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsole.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsoleEventListener.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsoleEventListener.java?rev=1512502&view=auto
==============================================================================
--- sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsoleEventListener.java (added)
+++ sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsoleEventListener.java Fri Aug  9 21:30:52 2013
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.ide.eclipse.ui.internal.console;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.text.DateFormat;
+import java.util.Date;
+
+import org.apache.sling.ide.transport.CommandExecutionProperties;
+import org.eclipse.ui.console.MessageConsole;
+import org.eclipse.ui.console.MessageConsoleStream;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventHandler;
+
+public class SlingConsoleEventListener implements EventHandler {
+
+    @Override
+    public void handleEvent(Event event) {
+
+        MessageConsole console = SlingConsoleFactory.getConsole();
+        if (console == null) {
+            return;
+        }
+
+        MessageConsoleStream messageStream = console.newMessageStream();
+
+        try {
+            Long start = (Long) event.getProperty(CommandExecutionProperties.TIMESTAMP_START);
+            Long end = (Long) event.getProperty(CommandExecutionProperties.TIMESTAMP_END);
+            String type = (String) event.getProperty(CommandExecutionProperties.ACTION_TYPE);
+            String target = (String) event.getProperty(CommandExecutionProperties.ACTION_TARGET);
+            String result = (String) event.getProperty(CommandExecutionProperties.RESULT_TEXT);
+            Throwable t = (Throwable) event.getProperty(CommandExecutionProperties.RESULT_THROWABLE);
+
+            StringBuilder message = new StringBuilder();
+            DateFormat format = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
+            message.append("[").append(format.format(new Date(start))).append("] ").append(type).append(" -> ")
+                    .append(target);
+            message.append(" : ").append(result).append(" (").append(end - start).append(" ms)").append('\n');
+
+            messageStream.write(message.toString());
+            if (t != null) {
+                t.printStackTrace(new PrintStream(messageStream));
+            }
+
+        } catch (IOException e) {
+            // TODO proper logging
+            e.printStackTrace();
+        } finally {
+            try {
+                messageStream.close();
+            } catch (IOException e) {
+                // TODO proper logging
+                e.printStackTrace();
+            }
+        }
+    }
+
+}

Propchange: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsoleEventListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsoleEventListener.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsoleFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsoleFactory.java?rev=1512502&view=auto
==============================================================================
--- sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsoleFactory.java (added)
+++ sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsoleFactory.java Fri Aug  9 21:30:52 2013
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.ide.eclipse.ui.internal.console;
+
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleFactory;
+import org.eclipse.ui.console.IConsoleManager;
+import org.eclipse.ui.console.MessageConsole;
+
+public class SlingConsoleFactory implements IConsoleFactory {
+
+    public static final String CONSOLE_NAME = "Sling console";
+
+    private MessageConsole console;
+
+    public static MessageConsole getConsole() {
+        // TODO not the right place, should converge with initConsole
+
+        for (IConsole console : ConsolePlugin.getDefault().getConsoleManager().getConsoles()) {
+            if (console.getName().equals(CONSOLE_NAME)) {
+                return (MessageConsole) console;
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public void openConsole() {
+
+        IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager();
+
+        initConsole(consoleManager);
+
+        consoleManager.showConsoleView(console);
+    }
+
+    private void initConsole(IConsoleManager consoleManager) {
+
+        if (console == null) {
+            console = new MessageConsole(CONSOLE_NAME, null);
+            consoleManager.addConsoles(new IConsole[] { console });
+        }
+    }
+
+}

Propchange: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsoleFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/internal/console/SlingConsoleFactory.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: sling/trunk/tooling/ide/impl-resource/OSGI-INF/RepositoryImpl.xml
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-resource/OSGI-INF/RepositoryImpl.xml?rev=1512502&r1=1512501&r2=1512502&view=diff
==============================================================================
--- sling/trunk/tooling/ide/impl-resource/OSGI-INF/RepositoryImpl.xml (original)
+++ sling/trunk/tooling/ide/impl-resource/OSGI-INF/RepositoryImpl.xml Fri Aug  9 21:30:52 2013
@@ -5,4 +5,5 @@
       <provide interface="org.apache.sling.ide.transport.Repository"/>
    </service>
    <reference bind="bindTracer" cardinality="1..1" interface="org.apache.sling.ide.impl.resource.util.Tracer" name="Tracer" policy="static" unbind="unbindTracer"/>
+   <reference bind="bindEventAdmin" cardinality="1..1" interface="org.osgi.service.event.EventAdmin" name="EventAdmin" policy="static" unbind="unbindEventAdmin"/>
 </scr:component>

Added: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AbstractCommand.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AbstractCommand.java?rev=1512502&view=auto
==============================================================================
--- sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AbstractCommand.java (added)
+++ sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AbstractCommand.java Fri Aug  9 21:30:52 2013
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.ide.impl.resource.transport;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.sling.ide.transport.Command;
+import org.apache.sling.ide.transport.RepositoryException;
+import org.apache.sling.ide.transport.RepositoryInfo;
+import org.apache.sling.ide.transport.Result;
+import org.apache.sling.ide.util.PathUtil;
+
+public abstract class AbstractCommand<T> implements Command<T> {
+
+    protected RepositoryInfo repositoryInfo;
+    protected HttpClient httpClient;
+    protected String path;
+
+    public AbstractCommand(RepositoryInfo repositoryInfo, HttpClient httpClient, String relativePath) {
+        this.repositoryInfo = repositoryInfo;
+        this.httpClient = httpClient;
+        this.path = createFullPath(relativePath);
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    private String createFullPath(String relativePath) {
+
+        return PathUtil.join(repositoryInfo.getUrl(), relativePath);
+    }
+
+    protected Result<T> resultForResponseStatus(int responseStatus) {
+        if (isSuccessStatus(responseStatus))
+            return AbstractResult.success(null);
+
+        return failureResultForStatusCode(responseStatus);
+    }
+
+    protected Result<T> failureResultForStatusCode(int responseStatus) {
+        return AbstractResult.failure(new RepositoryException("Repository has returned status code " + responseStatus));
+    }
+
+    protected boolean isSuccessStatus(int responseStatus) {
+
+        // TODO - consider all 2xx and possibly 3xx as success?
+
+        return responseStatus == 200 /* OK */|| responseStatus == 201 /* CREATED */;
+    }
+
+}

Propchange: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AbstractCommand.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AbstractCommand.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AddNodeCommand.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AddNodeCommand.java?rev=1512502&view=auto
==============================================================================
--- sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AddNodeCommand.java (added)
+++ sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AddNodeCommand.java Fri Aug  9 21:30:52 2013
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.ide.impl.resource.transport;
+
+import java.io.File;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.multipart.FilePart;
+import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
+import org.apache.commons.httpclient.methods.multipart.Part;
+import org.apache.sling.ide.transport.FileInfo;
+import org.apache.sling.ide.transport.RepositoryException;
+import org.apache.sling.ide.transport.RepositoryInfo;
+import org.apache.sling.ide.transport.Result;
+
+public class AddNodeCommand extends AbstractCommand<Void> {
+    private final FileInfo fileInfo;
+
+    public AddNodeCommand(FileInfo fileInfo, RepositoryInfo repositoryInfo, HttpClient httpClient) {
+        super(repositoryInfo, httpClient, fileInfo.getRelativeLocation());
+        this.fileInfo = fileInfo;
+    }
+
+    @Override
+    public Result<Void> execute() {
+        PostMethod post = new PostMethod(getPath());
+    	try{
+    		File f=new File(fileInfo.getLocation());
+            if (f.isFile()) {
+                Part[] parts = { new FilePart(fileInfo.getName(), f) };
+                post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
+            }
+    		httpClient.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(repositoryInfo.getUsername(),repositoryInfo.getPassword()));
+    		httpClient.getParams().setAuthenticationPreemptive(true);
+            int responseStatus = httpClient.executeMethod(post);
+    		
+    		return resultForResponseStatus(responseStatus);
+    			
+    	} catch(Exception e){
+    		return AbstractResult.failure(new RepositoryException(e));
+    	}finally{
+    		post.releaseConnection();
+    	}
+    }
+
+    @Override
+    public String toString() {
+    	
+    	return String.format("%8s %s", "ADD", fileInfo.getRelativeLocation() + "/" + fileInfo.getName());
+    }
+}
\ No newline at end of file

Propchange: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AddNodeCommand.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AddNodeCommand.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/DeleteNodeCommand.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/DeleteNodeCommand.java?rev=1512502&view=auto
==============================================================================
--- sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/DeleteNodeCommand.java (added)
+++ sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/DeleteNodeCommand.java Fri Aug  9 21:30:52 2013
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.ide.impl.resource.transport;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
+import org.apache.commons.httpclient.methods.multipart.Part;
+import org.apache.commons.httpclient.methods.multipart.StringPart;
+import org.apache.sling.ide.transport.FileInfo;
+import org.apache.sling.ide.transport.RepositoryException;
+import org.apache.sling.ide.transport.RepositoryInfo;
+import org.apache.sling.ide.transport.Result;
+
+class DeleteNodeCommand extends AbstractCommand<Void> {
+
+    private final FileInfo fileInfo;
+
+    DeleteNodeCommand(FileInfo fileInfo, RepositoryInfo repositoryInfo, HttpClient httpClient) {
+        super(repositoryInfo, httpClient, fileInfo.getRelativeLocation() + "/" + fileInfo.getName());
+        this.fileInfo = fileInfo;
+    }
+
+    @Override
+    public Result<Void> execute() {
+        PostMethod post = new PostMethod(getPath());
+    	try{
+    		Part[] parts ={new StringPart(":operation", "delete")};
+    		post.setRequestEntity(new MultipartRequestEntity(parts,post.getParams()));
+    		httpClient.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(repositoryInfo.getUsername(),repositoryInfo.getPassword()));
+    		httpClient.getParams().setAuthenticationPreemptive(true);
+    		int responseStatus=httpClient.executeMethod(post);
+    		
+    		return resultForResponseStatus(responseStatus);
+    	} catch(Exception e){
+    		return AbstractResult.failure(new RepositoryException(e));
+    	}finally{
+    		post.releaseConnection();
+    	}
+    }
+
+    @Override
+    public String toString() {
+    	return String.format("%8s %s", "DELETE", fileInfo.getRelativeLocation() + "/" + fileInfo.getName());
+    }
+}
\ No newline at end of file

Propchange: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/DeleteNodeCommand.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/DeleteNodeCommand.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/GetNodeCommand.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/GetNodeCommand.java?rev=1512502&view=auto
==============================================================================
--- sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/GetNodeCommand.java (added)
+++ sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/GetNodeCommand.java Fri Aug  9 21:30:52 2013
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.ide.impl.resource.transport;
+
+import org.apache.commons.httpclient.Credentials;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.sling.ide.transport.RepositoryException;
+import org.apache.sling.ide.transport.RepositoryInfo;
+import org.apache.sling.ide.transport.Result;
+
+class GetNodeCommand extends AbstractCommand<byte[]> {
+    GetNodeCommand(RepositoryInfo repositoryInfo, HttpClient httpClient, String relativePath) {
+        super(repositoryInfo, httpClient, relativePath);
+    }
+
+    @Override
+    public Result<byte[]> execute() {
+    	
+        GetMethod get = new GetMethod(getPath());
+    	
+    	try{
+    		httpClient.getParams().setAuthenticationPreemptive(true);
+    	    Credentials defaultcreds = new UsernamePasswordCredentials(repositoryInfo.getUsername(), repositoryInfo.getPassword());
+    	    //TODO
+    	    httpClient.getState().setCredentials(new AuthScope(repositoryInfo.getHost(),repositoryInfo.getPort(), AuthScope.ANY_REALM), defaultcreds);
+    		int responseStatus=httpClient.executeMethod(get);
+    		
+    		if ( isSuccessStatus(responseStatus) )
+    			return AbstractResult.success(get.getResponseBody());
+    		
+    		return failureResultForStatusCode(responseStatus);
+    	} catch (Exception e) {
+    		return AbstractResult.failure(new RepositoryException(e));
+    	}finally{
+    		get.releaseConnection();
+    	}
+    }
+
+    @Override
+    public String toString() {
+    	
+    	return String.format("%8s %s", "GETNODE", path);
+    }
+}
\ No newline at end of file

Propchange: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/GetNodeCommand.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/GetNodeCommand.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/GetNodeContentCommand.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/GetNodeContentCommand.java?rev=1512502&view=auto
==============================================================================
--- sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/GetNodeContentCommand.java (added)
+++ sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/GetNodeContentCommand.java Fri Aug  9 21:30:52 2013
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.ide.impl.resource.transport;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.httpclient.Credentials;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.sling.ide.transport.RepositoryException;
+import org.apache.sling.ide.transport.RepositoryInfo;
+import org.apache.sling.ide.transport.Result;
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+class GetNodeContentCommand extends AbstractCommand<Map<String, Object>> {
+
+    GetNodeContentCommand(RepositoryInfo repositoryInfo, HttpClient httpClient, String relativePath) {
+        super(repositoryInfo, httpClient, relativePath);
+    }
+
+    @Override
+    public Result<Map<String, Object>> execute() {
+        GetMethod get = new GetMethod(getPath());
+    	try{
+    		httpClient.getParams().setAuthenticationPreemptive(true);
+    	    Credentials defaultcreds = new UsernamePasswordCredentials(repositoryInfo.getUsername(), repositoryInfo.getPassword());
+    	    httpClient.getState().setCredentials(new AuthScope(repositoryInfo.getHost(),repositoryInfo.getPort(), AuthScope.ANY_REALM), defaultcreds); 
+    		int responseStatus=httpClient.executeMethod(get);
+    		//TODO change responseAsString with something like
+    		// return EncodingUtil.getString(rawdata, m.getResponseCharSet());
+            if (!isSuccessStatus(responseStatus))
+                return failureResultForStatusCode(responseStatus);
+
+            JSONObject result = new JSONObject(get.getResponseBodyAsString());
+
+            Map<String, Object> properties = new HashMap<String, Object>();
+            JSONArray names = result.names();
+            for (int i = 0; i < names.length(); i++) {
+                String name = names.getString(i);
+                Object object = result.get(name);
+                if (object instanceof String) {
+                    properties.put(name, object);
+                } else {
+                    System.out.println("Property '" + name + "' of type '" + object.getClass().getName()
+                            + " is not handled");
+                }
+            }
+
+            return AbstractResult.success(properties);
+    	} catch (Exception e) {
+    		return AbstractResult.failure(new RepositoryException(e));
+    	}finally{
+    		get.releaseConnection();
+    	}
+    }
+
+    @Override
+    public String toString() {
+    	
+        return String.format("%8s %s", "GETCONT", path);
+    }
+}
\ No newline at end of file

Propchange: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/GetNodeContentCommand.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/GetNodeContentCommand.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/ListChildrenCommand.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/ListChildrenCommand.java?rev=1512502&view=auto
==============================================================================
--- sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/ListChildrenCommand.java (added)
+++ sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/ListChildrenCommand.java Fri Aug  9 21:30:52 2013
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.ide.impl.resource.transport;
+
+import java.util.Iterator;
+
+import org.apache.commons.httpclient.Credentials;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.sling.ide.transport.Repository;
+import org.apache.sling.ide.transport.RepositoryException;
+import org.apache.sling.ide.transport.RepositoryInfo;
+import org.apache.sling.ide.transport.ResourceProxy;
+import org.apache.sling.ide.transport.Result;
+import org.apache.sling.ide.util.PathUtil;
+import org.json.JSONObject;
+
+class ListChildrenCommand extends AbstractCommand<ResourceProxy> {
+
+    ListChildrenCommand(RepositoryInfo repositoryInfo, HttpClient httpClient, String relativePath) {
+        super(repositoryInfo, httpClient, relativePath);
+    }
+
+    @Override
+    public Result<ResourceProxy> execute() {
+        GetMethod get = new GetMethod(getPath());
+    	try{
+    		httpClient.getParams().setAuthenticationPreemptive(true);
+    	    Credentials defaultcreds = new UsernamePasswordCredentials(repositoryInfo.getUsername(), repositoryInfo.getPassword());
+    	    httpClient.getState().setCredentials(new AuthScope(repositoryInfo.getHost(),repositoryInfo.getPort(), AuthScope.ANY_REALM), defaultcreds);
+    		int responseStatus=httpClient.executeMethod(get);
+
+    		//TODO change responseAsString with something like
+    		//return EncodingUtil.getString(rawdata, m.getResponseCharSet());
+            if (!isSuccessStatus(responseStatus))
+                return failureResultForStatusCode(responseStatus);
+
+            ResourceProxy resource = new ResourceProxy(path);
+
+            JSONObject json = new JSONObject(get.getResponseBodyAsString());
+            String primaryType = json.optString(Repository.JCR_PRIMARY_TYPE);
+            if (primaryType != null) { // TODO - needed?
+                resource.addProperty(Repository.JCR_PRIMARY_TYPE, primaryType);
+            }
+
+            // TODO - populate all properties
+
+            for (Iterator<?> keyIterator = json.keys(); keyIterator.hasNext();) {
+
+                String key = (String) keyIterator.next();
+                JSONObject value = json.optJSONObject(key);
+                if (value != null) {
+                    ResourceProxy child = new ResourceProxy(PathUtil.join(path, key));
+                    child.addProperty(Repository.JCR_PRIMARY_TYPE, value.optString(Repository.JCR_PRIMARY_TYPE));
+                    resource.addChild(child);
+                }
+            }
+    		
+            return AbstractResult.success(resource);
+    	} catch (Exception e) {
+    		return AbstractResult.failure(new RepositoryException(e));
+    	}finally{
+    		get.releaseConnection();
+    	}
+    }
+
+    @Override
+    public String toString() {
+    	
+        return String.format("%8s %s", "LISTCH", path);
+    }
+}
\ No newline at end of file

Propchange: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/ListChildrenCommand.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/ListChildrenCommand.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/RepositoryImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/RepositoryImpl.java?rev=1512502&r1=1512501&r2=1512502&view=diff
==============================================================================
--- sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/RepositoryImpl.java (original)
+++ sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/RepositoryImpl.java Fri Aug  9 21:30:52 2013
@@ -16,314 +16,56 @@
  */
 package org.apache.sling.ide.impl.resource.transport;
 
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.httpclient.Credentials;
 import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.UsernamePasswordCredentials;
-import org.apache.commons.httpclient.auth.AuthScope;
-import org.apache.commons.httpclient.methods.GetMethod;
-import org.apache.commons.httpclient.methods.PostMethod;
-import org.apache.commons.httpclient.methods.multipart.FilePart;
-import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
-import org.apache.commons.httpclient.methods.multipart.Part;
-import org.apache.commons.httpclient.methods.multipart.StringPart;
 import org.apache.sling.ide.impl.resource.util.Tracer;
 import org.apache.sling.ide.transport.Command;
 import org.apache.sling.ide.transport.FileInfo;
-import org.apache.sling.ide.transport.ProtectedNodes;
-import org.apache.sling.ide.transport.Repository;
-import org.apache.sling.ide.transport.RepositoryException;
 import org.apache.sling.ide.transport.ResourceProxy;
-import org.apache.sling.ide.transport.Result;
-import org.apache.sling.ide.util.PathUtil;
-import org.json.JSONArray;
-import org.json.JSONObject;
+import org.osgi.service.event.EventAdmin;
 
 public class RepositoryImpl extends AbstractRepository{
 	
     private final HttpClient httpClient = new HttpClient();
     private Tracer tracer;
+    private EventAdmin eventAdmin;
 
-	/* (non-Javadoc)
-	 * @see org.apache.sling.slingclipse.api.Repository#newAddNodeCommand(org.apache.sling.slingclipse.api.FileInfo)
-	 */
 	@Override
 	public Command<Void> newAddNodeCommand(final FileInfo fileInfo) {
-        return wrap(new Command<Void>() {
-			@Override
-			public Result<Void> execute() {
-                PostMethod post = new PostMethod(createFullPath(fileInfo.getRelativeLocation()));
-				try{
-					File f=new File(fileInfo.getLocation());
-                    if (f.isFile()) {
-                        Part[] parts = { new FilePart(fileInfo.getName(), f) };
-                        post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
-                    }
-					httpClient.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(repositoryInfo.getUsername(),repositoryInfo.getPassword()));
-					httpClient.getParams().setAuthenticationPreemptive(true);
-                    int responseStatus = httpClient.executeMethod(post);
-					
-					return resultForResponseStatus(responseStatus);
-						
-				} catch(Exception e){
-					return AbstractResult.failure(new RepositoryException(e));
-				}finally{
-					post.releaseConnection();
-				}
-			}
-
-			@Override
-			public String toString() {
-				
-				return String.format("%8s %s", "ADD", fileInfo.getRelativeLocation() + "/" + fileInfo.getName());
-			}
-        });
+        return wrap(new AddNodeCommand(fileInfo, repositoryInfo, httpClient));
 	}
 
-    private <T> Command<T> wrap(Command<T> command) {
+    private <T> Command<T> wrap(AbstractCommand<T> command) {
 
-        return new TracingCommand<T>(command, tracer);
+        return new TracingCommand<T>(command, tracer, eventAdmin);
     }
 
-	private Result<Void> resultForResponseStatus(int responseStatus) {
-		if ( isSuccessStatus(responseStatus) )
-			return AbstractResult.success(null);
-		
-		return failureResultForStatusCode(responseStatus);
-	}
-
-	private <T> Result<T> failureResultForStatusCode(int responseStatus) {
-		return AbstractResult.failure(new RepositoryException("Repository has returned status code " + responseStatus));
-	}
-
-	private boolean isSuccessStatus(int responseStatus) {
-		
-		// TODO - consider all 2xx and possibly 3xx as success?
-		
-		return responseStatus == 200 /* OK */ || responseStatus == 201 /* CREATED */;
-	}
-
 	@Override
 	public Command<Void> newDeleteNodeCommand(final FileInfo fileInfo) {
-        return wrap(new Command<Void>() {
-			@Override
-			public Result<Void> execute() {
-                PostMethod post = new PostMethod(createFullPath(fileInfo.getRelativeLocation() + "/"
-                        + fileInfo.getName()));
-				try{
-					Part[] parts ={new StringPart(":operation", "delete")};
-					post.setRequestEntity(new MultipartRequestEntity(parts,post.getParams()));
-					httpClient.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(repositoryInfo.getUsername(),repositoryInfo.getPassword()));
-					httpClient.getParams().setAuthenticationPreemptive(true);
-					int responseStatus=httpClient.executeMethod(post);
-					
-					return resultForResponseStatus(responseStatus);
-				} catch(Exception e){
-					return AbstractResult.failure(new RepositoryException(e));
-				}finally{
-					post.releaseConnection();
-				}
-			}
-			
-			@Override
-			public String toString() {
-				return String.format("%8s %s", "DELETE", fileInfo.getRelativeLocation() + "/" + fileInfo.getName());
-			}
-        });
+        return wrap(new DeleteNodeCommand(fileInfo, repositoryInfo, httpClient));
 	}
 	
 	@Override
     public Command<ResourceProxy> newListChildrenNodeCommand(final String path) {
-        return wrap(new Command<ResourceProxy>() {
-			@Override
-            public Result<ResourceProxy> execute() {
-                GetMethod get = new GetMethod(createFullPath(path + ".1.json"));
-				try{
-					httpClient.getParams().setAuthenticationPreemptive(true);
-				    Credentials defaultcreds = new UsernamePasswordCredentials(repositoryInfo.getUsername(), repositoryInfo.getPassword());
-				    httpClient.getState().setCredentials(new AuthScope(repositoryInfo.getHost(),repositoryInfo.getPort(), AuthScope.ANY_REALM), defaultcreds);
-					int responseStatus=httpClient.executeMethod(get);
-
-					//TODO change responseAsString with something like
-					//return EncodingUtil.getString(rawdata, m.getResponseCharSet());
-                    if (!isSuccessStatus(responseStatus))
-                        return failureResultForStatusCode(responseStatus);
-
-                    ResourceProxy resource = new ResourceProxy(path);
-
-                    JSONObject json = new JSONObject(get.getResponseBodyAsString());
-                    String primaryType = json.optString(Repository.JCR_PRIMARY_TYPE);
-                    if (primaryType != null) { // TODO - needed?
-                        resource.addProperty(Repository.JCR_PRIMARY_TYPE, primaryType);
-                    }
-
-                    // TODO - populate all properties
-
-                    for (Iterator<?> keyIterator = json.keys(); keyIterator.hasNext();) {
-
-                        String key = (String) keyIterator.next();
-                        JSONObject value = json.optJSONObject(key);
-                        if (value != null) {
-                            ResourceProxy child = new ResourceProxy(PathUtil.join(path, key));
-                            child.addProperty(Repository.JCR_PRIMARY_TYPE, value.optString(Repository.JCR_PRIMARY_TYPE));
-                            resource.addChild(child);
-                        }
-                    }
-					
-                    return AbstractResult.success(resource);
-				} catch (Exception e) {
-					return AbstractResult.failure(new RepositoryException(e));
-				}finally{
-					get.releaseConnection();
-				}
-			}
-			
-			@Override
-			public String toString() {
-				
-                return String.format("%8s %s", "LISTCH", path);
-			}
-        });
+        return wrap(new ListChildrenCommand(repositoryInfo, httpClient, path + ".1.json"));
 	}
 
 	@Override
 	public Command<byte[]> newGetNodeCommand(final String path) {
 		
-        return wrap(new Command<byte[]>() {
-			@Override
-			public Result<byte[]> execute() {
-				
-                GetMethod get = new GetMethod(createFullPath(path));
-				
-				try{
-					httpClient.getParams().setAuthenticationPreemptive(true);
-				    Credentials defaultcreds = new UsernamePasswordCredentials(repositoryInfo.getUsername(), repositoryInfo.getPassword());
-				    //TODO
-				    httpClient.getState().setCredentials(new AuthScope(repositoryInfo.getHost(),repositoryInfo.getPort(), AuthScope.ANY_REALM), defaultcreds);
-					int responseStatus=httpClient.executeMethod(get);
-					
-					if ( isSuccessStatus(responseStatus) )
-						return AbstractResult.success(get.getResponseBody());
-					
-					return failureResultForStatusCode(responseStatus);
-				} catch (Exception e) {
-					return AbstractResult.failure(new RepositoryException(e));
-				}finally{
-					get.releaseConnection();
-				}
-			}
-			
-			@Override
-			public String toString() {
-				
-				return String.format("%8s %s", "GETNODE", path);
-			}
-        });
+        return wrap(new GetNodeCommand(repositoryInfo, httpClient, path));
 	}
 	
-    private String createFullPath(String relativePath) {
-
-        return PathUtil.join(repositoryInfo.getUrl(), relativePath);
-    }
-
 	@Override
     public Command<Map<String, Object>> newGetNodeContentCommand(final String path) {
-        return wrap(new Command<Map<String, Object>>() {
-			@Override
-            public Result<Map<String, Object>> execute() {
-				//TODO handle the response type
-                GetMethod get = new GetMethod(createFullPath(path + ".json"));
-				try{
-					httpClient.getParams().setAuthenticationPreemptive(true);
-				    Credentials defaultcreds = new UsernamePasswordCredentials(repositoryInfo.getUsername(), repositoryInfo.getPassword());
-				    httpClient.getState().setCredentials(new AuthScope(repositoryInfo.getHost(),repositoryInfo.getPort(), AuthScope.ANY_REALM), defaultcreds); 
-					int responseStatus=httpClient.executeMethod(get);
-					//TODO change responseAsString with something like
-					// return EncodingUtil.getString(rawdata, m.getResponseCharSet());
-                    if (!isSuccessStatus(responseStatus))
-                        return failureResultForStatusCode(responseStatus);
-
-                    JSONObject result = new JSONObject(get.getResponseBodyAsString());
-
-                    Map<String, Object> properties = new HashMap<String, Object>();
-                    JSONArray names = result.names();
-                    for (int i = 0; i < names.length(); i++) {
-                        String name = names.getString(i);
-                        Object object = result.get(name);
-                        if (object instanceof String) {
-                            properties.put(name, object);
-                        } else {
-                            System.out.println("Property '" + name + "' of type '" + object.getClass().getName()
-                                    + " is not handled");
-                        }
-                    }
-
-                    return AbstractResult.success(properties);
-				} catch (Exception e) {
-					return AbstractResult.failure(new RepositoryException(e));
-				}finally{
-					get.releaseConnection();
-				}
-			}
-			
-			@Override
-			public String toString() {
-				
-                return String.format("%8s %s", "GETCONT", path);
-			}
-        });
+        return wrap(new GetNodeContentCommand(repositoryInfo, httpClient, path + ".json"));
 	}
 	
 	@Override
     public Command<Void> newUpdateContentNodeCommand(final FileInfo fileInfo, final Map<String, Object> properties) {
 		
-        return wrap(new Command<Void>() {
-			@Override
-			public Result<Void> execute() {
-                PostMethod post = new PostMethod(createFullPath(fileInfo.getRelativeLocation()));
-				try{
-                    List<Part> parts = new ArrayList<Part>();
-                    for (Map.Entry<String, Object> property : properties.entrySet()) {
-                        if (ProtectedNodes.exists(property.getKey())) {
-                            continue;
-                        }
-
-                        Object propValue = property.getValue();
-
-                        if (propValue instanceof String) {
-                            parts.add(new StringPart(property.getKey(), (String) propValue));
-                        } else if (property != null) {
-                            // TODO handle multi-valued properties
-                            System.err.println("Unable to handle property " + property.getKey() + " of type "
-                                    + property.getValue().getClass());
-                        }
-					}
-                    post.setRequestEntity(new MultipartRequestEntity(parts.toArray(new Part[parts.size()]), post
-                            .getParams()));
-					httpClient.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(repositoryInfo.getUsername(),repositoryInfo.getPassword()));
-					httpClient.getParams().setAuthenticationPreemptive(true);
-					int responseStatus=httpClient.executeMethod(post);
-					
-					return resultForResponseStatus(responseStatus);
-				} catch(Exception e){
-					return AbstractResult.failure(new RepositoryException(e));
-				}finally{
-					post.releaseConnection();
-				}
-			}
-			
-			@Override
-			public String toString() {
-				
-				return String.format("%8s %s", "UPDATE", fileInfo.getRelativeLocation() + "/" + fileInfo.getName());
-			}
-        });
+        return wrap(new UpdateContentCommand(repositoryInfo, httpClient, fileInfo.getRelativeLocation(), properties, fileInfo));
 	}
 
     public void bindTracer(Tracer tracer) {
@@ -336,26 +78,13 @@ public class RepositoryImpl extends Abst
         this.tracer = null;
     }
 
-    static class TracingCommand<T> implements Command<T> {
-
-        private final Command<T> command;
-        private final Tracer tracer;
+    public void bindEventAdmin(EventAdmin eventAdmin) {
 
-        public TracingCommand(Command<T> command, Tracer tracer) {
-            this.command = command;
-            this.tracer = tracer;
-        }
-
-        @Override
-        public Result<T> execute() {
-
-            Result<T> result = command.execute();
-
-            if (tracer != null)
-                tracer.trace("{0} -> {1}", command, result.toString());
+        this.eventAdmin = eventAdmin;
+    }
 
-            return result;
-        }
+    public void unbindEventAdmin(EventAdmin eventAdmin) {
 
+        this.eventAdmin = null;
     }
 }

Added: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/TracingCommand.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/TracingCommand.java?rev=1512502&view=auto
==============================================================================
--- sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/TracingCommand.java (added)
+++ sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/TracingCommand.java Fri Aug  9 21:30:52 2013
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.ide.impl.resource.transport;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.sling.ide.impl.resource.util.Tracer;
+import org.apache.sling.ide.transport.Command;
+import org.apache.sling.ide.transport.CommandExecutionProperties;
+import org.apache.sling.ide.transport.RepositoryException;
+import org.apache.sling.ide.transport.Result;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+
+class TracingCommand<T> implements Command<T> {
+
+    private final AbstractCommand<T> command;
+    private final Tracer tracer;
+    private final EventAdmin eventAdmin;
+
+    public TracingCommand(AbstractCommand<T> command, Tracer tracer, EventAdmin eventAdmin) {
+        this.command = command;
+        this.tracer = tracer;
+        this.eventAdmin = eventAdmin;
+    }
+
+    @Override
+    public Result<T> execute() {
+
+        long start = System.currentTimeMillis();
+        Result<T> result = command.execute();
+        long end = System.currentTimeMillis();
+
+        if (tracer != null)
+            tracer.trace("{0} -> {1}", command, result.toString());
+
+        if (eventAdmin != null) {
+            Map<String, Object> props = new HashMap<String, Object>();
+            props.put(CommandExecutionProperties.RESULT_TEXT, result.toString());
+            try {
+                result.get();
+            } catch (RepositoryException e) {
+                props.put(CommandExecutionProperties.RESULT_THROWABLE, e);
+            }
+            props.put(CommandExecutionProperties.ACTION_TYPE, command.getClass().getSimpleName());
+            props.put(CommandExecutionProperties.ACTION_TARGET, command.getPath());
+            props.put(CommandExecutionProperties.TIMESTAMP_START, start);
+            props.put(CommandExecutionProperties.TIMESTAMP_END, end);
+            Event event = new Event("org/apache/sling/ide/transport", props);
+            eventAdmin.postEvent(event);
+        }
+
+        return result;
+    }
+
+}
\ No newline at end of file

Propchange: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/TracingCommand.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/TracingCommand.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/UpdateContentCommand.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/UpdateContentCommand.java?rev=1512502&view=auto
==============================================================================
--- sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/UpdateContentCommand.java (added)
+++ sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/UpdateContentCommand.java Fri Aug  9 21:30:52 2013
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.ide.impl.resource.transport;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
+import org.apache.commons.httpclient.methods.multipart.Part;
+import org.apache.commons.httpclient.methods.multipart.StringPart;
+import org.apache.sling.ide.transport.FileInfo;
+import org.apache.sling.ide.transport.ProtectedNodes;
+import org.apache.sling.ide.transport.RepositoryException;
+import org.apache.sling.ide.transport.RepositoryInfo;
+import org.apache.sling.ide.transport.Result;
+
+class UpdateContentCommand extends AbstractCommand<Void> {
+
+    private final Map<String, Object> properties;
+    private final FileInfo fileInfo;
+
+    UpdateContentCommand(RepositoryInfo repositoryInfo, HttpClient httpClient, String relativePath,
+            Map<String, Object> properties, FileInfo fileInfo) {
+        super(repositoryInfo, httpClient, relativePath);
+        this.properties = properties;
+        this.fileInfo = fileInfo;
+    }
+
+    @Override
+    public Result<Void> execute() {
+        PostMethod post = new PostMethod(getPath());
+    	try{
+            List<Part> parts = new ArrayList<Part>();
+            for (Map.Entry<String, Object> property : properties.entrySet()) {
+                if (ProtectedNodes.exists(property.getKey())) {
+                    continue;
+                }
+
+                Object propValue = property.getValue();
+
+                if (propValue instanceof String) {
+                    parts.add(new StringPart(property.getKey(), (String) propValue));
+                } else if (property != null) {
+                    // TODO handle multi-valued properties
+                    System.err.println("Unable to handle property " + property.getKey() + " of type "
+                            + property.getValue().getClass());
+                }
+    		}
+            post.setRequestEntity(new MultipartRequestEntity(parts.toArray(new Part[parts.size()]), post
+                    .getParams()));
+    		httpClient.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(repositoryInfo.getUsername(),repositoryInfo.getPassword()));
+    		httpClient.getParams().setAuthenticationPreemptive(true);
+    		int responseStatus=httpClient.executeMethod(post);
+    		
+    		return resultForResponseStatus(responseStatus);
+    	} catch(Exception e){
+    		return AbstractResult.failure(new RepositoryException(e));
+    	}finally{
+    		post.releaseConnection();
+    	}
+    }
+
+    @Override
+    public String toString() {
+    	
+    	return String.format("%8s %s", "UPDATE", fileInfo.getRelativeLocation() + "/" + fileInfo.getName());
+    }
+}
\ No newline at end of file

Propchange: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/UpdateContentCommand.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/UpdateContentCommand.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL