Author: rombert
Date: Fri Sep 20 13:30:56 2013
New Revision: 1524999

URL: http://svn.apache.org/r1524999
Log:
SLING-3072 -  Repository: API needs a single method to create a node and
set its non-binary properties

The Repository interface now has a single newAddOrUpdateNodeCommand . As
a side effect, extra properties for nt:file nodes serialized in a
${NODENAME}.dir/.content.xml file are now propertly saved.

Added:
    
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommand.java
   (contents, props changed)
      - copied, changed from r1524739, 
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/UpdateNodePropertiesCommand.java
Removed:
    
sling/branches/tooling-ide-vlt/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/AddNodeCommand.java
    
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/AddNodeCommand.java
    
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/UpdateNodePropertiesCommand.java
Modified:
    
sling/branches/tooling-ide-vlt/tooling/ide/api-test/src/test/java/org/apache/sling/ide/serialization/StubRepository.java
    
sling/branches/tooling-ide-vlt/tooling/ide/api/src/org/apache/sling/ide/serialization/SerializationManager.java
    
sling/branches/tooling-ide-vlt/tooling/ide/api/src/org/apache/sling/ide/transport/Repository.java
    
sling/branches/tooling-ide-vlt/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/SlingLaunchpadBehaviour.java
    
sling/branches/tooling-ide-vlt/tooling/ide/impl-resource-test/src/test/java/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManagerTest.java
    
sling/branches/tooling-ide-vlt/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManager.java
    
sling/branches/tooling-ide-vlt/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/RepositoryImpl.java
    
sling/branches/tooling-ide-vlt/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/UpdateContentCommand.java
    
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/VltRepository.java
    
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/serialization/VltSerializationManager.java

Modified: 
sling/branches/tooling-ide-vlt/tooling/ide/api-test/src/test/java/org/apache/sling/ide/serialization/StubRepository.java
URL: 
http://svn.apache.org/viewvc/sling/branches/tooling-ide-vlt/tooling/ide/api-test/src/test/java/org/apache/sling/ide/serialization/StubRepository.java?rev=1524999&r1=1524998&r2=1524999&view=diff
==============================================================================
--- 
sling/branches/tooling-ide-vlt/tooling/ide/api-test/src/test/java/org/apache/sling/ide/serialization/StubRepository.java
 (original)
+++ 
sling/branches/tooling-ide-vlt/tooling/ide/api-test/src/test/java/org/apache/sling/ide/serialization/StubRepository.java
 Fri Sep 20 13:30:56 2013
@@ -30,11 +30,6 @@ public class StubRepository implements R
     }
 
     @Override
-    public Command<Void> newUpdateContentNodeCommand(FileInfo fileInfo, 
ResourceProxy resourceProxy) {
-        return null;
-    }
-
-    @Override
     public Command<ResourceProxy> newListChildrenNodeCommand(final String 
path) {
 
         if ("/jcr:system/jcr:nodeTypes".equals(path)) {
@@ -125,7 +120,7 @@ public class StubRepository implements R
     }
 
     @Override
-    public Command<Void> newAddNodeCommand(FileInfo fileInfo) {
+    public Command<Void> newAddOrUpdateNodeCommand(FileInfo fileInfo, 
ResourceProxy resourceInfo) {
         return null;
     }
 

Modified: 
sling/branches/tooling-ide-vlt/tooling/ide/api/src/org/apache/sling/ide/serialization/SerializationManager.java
URL: 
http://svn.apache.org/viewvc/sling/branches/tooling-ide-vlt/tooling/ide/api/src/org/apache/sling/ide/serialization/SerializationManager.java?rev=1524999&r1=1524998&r2=1524999&view=diff
==============================================================================
--- 
sling/branches/tooling-ide-vlt/tooling/ide/api/src/org/apache/sling/ide/serialization/SerializationManager.java
 (original)
+++ 
sling/branches/tooling-ide-vlt/tooling/ide/api/src/org/apache/sling/ide/serialization/SerializationManager.java
 Fri Sep 20 13:30:56 2013
@@ -31,9 +31,15 @@ public interface SerializationManager {
 
     String getBaseResourcePath(String serializationFilePath);
 
-    String getSerializationFilePath(String baseFilePath);
+    String getSerializationFilePath(String baseFilePath, SerializationKind 
serializationKind);
 
     SerializationDataBuilder newBuilder(Repository repository, File 
contentSyncRoot) throws SerializationException;
 
+    /**
+     * @param filePath The filePath, in OS format, relative to the local 
content sync root
+     * @param source
+     * @return
+     * @throws IOException
+     */
     ResourceProxy readSerializationData(String filePath, InputStream source) 
throws IOException;
 }

Modified: 
sling/branches/tooling-ide-vlt/tooling/ide/api/src/org/apache/sling/ide/transport/Repository.java
URL: 
http://svn.apache.org/viewvc/sling/branches/tooling-ide-vlt/tooling/ide/api/src/org/apache/sling/ide/transport/Repository.java?rev=1524999&r1=1524998&r2=1524999&view=diff
==============================================================================
--- 
sling/branches/tooling-ide-vlt/tooling/ide/api/src/org/apache/sling/ide/transport/Repository.java
 (original)
+++ 
sling/branches/tooling-ide-vlt/tooling/ide/api/src/org/apache/sling/ide/transport/Repository.java
 Fri Sep 20 13:30:56 2013
@@ -81,9 +81,7 @@ public interface Repository {
 
     RepositoryInfo getRepositoryInfo();
 
-       Command<Void> newAddNodeCommand(FileInfo fileInfo);
-       
-    Command<Void> newUpdateContentNodeCommand(FileInfo fileInfo, ResourceProxy 
resourceProxy);
+    Command<Void> newAddOrUpdateNodeCommand(FileInfo fileInfo, ResourceProxy 
resourceProxy);
        
        Command<Void> newDeleteNodeCommand(FileInfo fileInfo);
  

Modified: 
sling/branches/tooling-ide-vlt/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/SlingLaunchpadBehaviour.java
URL: 
http://svn.apache.org/viewvc/sling/branches/tooling-ide-vlt/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/SlingLaunchpadBehaviour.java?rev=1524999&r1=1524998&r2=1524999&view=diff
==============================================================================
--- 
sling/branches/tooling-ide-vlt/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/SlingLaunchpadBehaviour.java
 (original)
+++ 
sling/branches/tooling-ide-vlt/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/internal/SlingLaunchpadBehaviour.java
 Fri Sep 20 13:30:56 2013
@@ -21,6 +21,7 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -42,6 +43,7 @@ import org.apache.sling.ide.filter.Filte
 import org.apache.sling.ide.filter.FilterLocator;
 import org.apache.sling.ide.filter.FilterResult;
 import org.apache.sling.ide.serialization.SerializationException;
+import org.apache.sling.ide.serialization.SerializationKind;
 import org.apache.sling.ide.serialization.SerializationManager;
 import org.apache.sling.ide.transport.Command;
 import org.apache.sling.ide.transport.FileInfo;
@@ -195,6 +197,9 @@ public class SlingLaunchpadBehaviour ext
                 } catch (SerializationException e) {
                     throw new CoreException(new Status(IStatus.ERROR, 
Activator.PLUGIN_ID, "Serialization error for "
                             + trace.toString(), e));
+                } catch (IOException e) {
+                    throw new CoreException(new Status(IStatus.ERROR, 
Activator.PLUGIN_ID, "IO error for "
+                            + trace.toString(), e));
                 }
             }
         } finally {
@@ -271,8 +276,8 @@ public class SlingLaunchpadBehaviour ext
                }
        }
 
-       private void publishContentModule(int kind, int deltaKind,
-                       IModule[] module, IProgressMonitor monitor) throws 
CoreException, SerializationException {
+    private void publishContentModule(int kind, int deltaKind, IModule[] 
module, IProgressMonitor monitor)
+            throws CoreException, SerializationException, IOException {
 
                if (runLaunchesIfExist(kind, deltaKind, module, monitor)) {
                        return;
@@ -355,8 +360,10 @@ public class SlingLaunchpadBehaviour ext
 //        setServerPublishState(IServer.PUBLISH_STATE_NONE);
        }
 
-       private List<IModuleResourceDelta> filterContentXmlParents(
-                       List<IModuleResourceDelta> publishedResourceDelta) {
+    // TODO - this needs to be revisited, as it potentially prevents empty 
folders ( nt:folder node type) from being
+    // created
+    // TODO - we shouldn't hardcode knowledge of .content.xml here
+    private List<IModuleResourceDelta> 
filterContentXmlParents(List<IModuleResourceDelta> publishedResourceDelta) {
                List<IModuleResourceDelta> adjustedPublishedResourceDelta = new 
LinkedList<IModuleResourceDelta>();
                Map<String,IModuleResourceDelta> map = new HashMap<String, 
IModuleResourceDelta>();
                for (IModuleResourceDelta resourceDelta : 
publishedResourceDelta) {
@@ -366,10 +373,6 @@ public class SlingLaunchpadBehaviour ext
                                .hasNext();) {
                        IModuleResourceDelta iModuleResourceDelta = it.next();
                        String resPath = 
iModuleResourceDelta.getModuleRelativePath().toString();
-                       if (resPath.contains(".dir")) {
-                               // filter those for the moment
-                               continue;
-                       }
                        IModuleResourceDelta originalEntry = map.get(resPath);
                        IModuleResourceDelta detailedEntry = map.remove(
                                        resPath+"/.content.xml");
@@ -382,8 +385,10 @@ public class SlingLaunchpadBehaviour ext
                return adjustedPublishedResourceDelta;
        }
 
-       private List<IModuleResource> filterContentXmlParents(
-                       IModuleResource[] moduleResources) {
+    // TODO - this needs to be revisited, as it potentially prevents empty 
folders ( nt:folder node type) from being
+    // created
+    // TODO - we shouldn't hardcode knowledge of .content.xml here
+    private List<IModuleResource> filterContentXmlParents(IModuleResource[] 
moduleResources) {
                List<IModuleResource> moduleResourcesList = 
Arrays.asList(moduleResources);
         List<IModuleResource> adjustedModuleResourcesList = new 
LinkedList<IModuleResource>();
         Map<String,IModuleResource> map1 = new HashMap<String, 
IModuleResource>();
@@ -396,9 +401,6 @@ public class SlingLaunchpadBehaviour ext
                                .hasNext();) {
                        IModuleResource iModuleResource = it.next();
                        String resPath = 
iModuleResource.getModuleRelativePath().toString();
-                       if (resPath.contains(".dir")) {
-                               continue;
-                       }
                        IModuleResource originalEntry = map1.get(resPath);
                        IModuleResource detailedEntry = 
map1.remove(resPath+"/.content.xml");
                if (detailedEntry!=null) {
@@ -471,12 +473,16 @@ public class SlingLaunchpadBehaviour ext
         }
         Result<?> result = command.execute();
 
-        if (!result.isSuccess()) // TODO proper logging
-            throw new CoreException(new Status(Status.ERROR, "some.plugin", 
result.toString()));
+        if (!result.isSuccess()) {
+            // TODO - proper error logging
+            throw new CoreException(new Status(Status.ERROR, 
Activator.PLUGIN_ID, "Failed publishing "
+                    + result.toString()));
+        }
+
     }
 
     private Command<?> addFileCommand(Repository repository, IModuleResource 
resource) throws CoreException,
-            SerializationException {
+            SerializationException, IOException {
 
         FileInfo info = createFileInfo(resource, repository);
 
@@ -491,27 +497,96 @@ public class SlingLaunchpadBehaviour ext
         }
 
         File syncDirectoryAsFile = 
ProjectUtil.getSyncDirectoryFullPath(res.getProject()).toFile();
+        IFolder syncDirectory = ProjectUtil.getSyncDirectory(res.getProject());
 
         if (serializationManager(repository, 
syncDirectoryAsFile).isSerializationFile(info.getLocation())) {
-
+            InputStream contents = null;
             try {
                 IFile file = (IFile) resource.getAdapter(IFile.class);
-                InputStream contents = file.getContents();
-                IFolder syncDirectory = 
ProjectUtil.getSyncDirectory(res.getProject());
+                contents = file.getContents();
                 String resourceLocation = 
file.getFullPath().makeRelativeTo(syncDirectory.getFullPath()).toOSString();
                 ResourceProxy resourceProxy = serializationManager(repository, 
syncDirectoryAsFile)
                         .readSerializationData(resourceLocation, contents);
-                return repository.newUpdateContentNodeCommand(info, 
resourceProxy);
+                // TODO - not sure if this 100% correct, but we definitely 
should not refer to the FileInfo as the
+                // .serialization file, since for nt:file/nt:resource nodes 
this will overwrite the file contents
+                String primaryType = (String) 
resourceProxy.getProperties().get(Repository.JCR_PRIMARY_TYPE);
+                if (Repository.NT_FILE.equals(primaryType) || 
Repository.NT_RESOURCE.equals(primaryType)) {
+                    // TODO move logic to serializationManager
+                    File locationFile = new File(info.getLocation());
+                    String locationFileParent = locationFile.getParent();
+                    int endIndex = locationFileParent.length() - 
".dir".length();
+                    File actualFile = new File(locationFileParent.substring(0, 
endIndex));
+                    String newLocation = actualFile.getAbsolutePath();
+                    String newName = actualFile.getName();
+                    String newRelativeLocation = 
actualFile.getAbsolutePath().substring(
+                            syncDirectoryAsFile.getAbsolutePath().length());
+                    info = new FileInfo(newLocation, newRelativeLocation, 
newName);
+                }
+
+                return repository.newAddOrUpdateNodeCommand(info, 
resourceProxy);
             } catch (IOException e) {
                 // TODO logging
                 e.printStackTrace();
                 return null;
+            } finally {
+                if (contents != null) {
+                    contents.close();
+                }
             }
         } else {
-            return repository.newAddNodeCommand(info);
+
+            IFile file = (IFile) resource.getAdapter(IFile.class);
+            IFolder folder = (IFolder) resource.getAdapter(IFolder.class);
+            ResourceProxy resourceProxy = null;
+
+            IResource changedResource = file != null ? file : folder;
+            if (changedResource == null) {
+                System.err.println("Could not find a file or a folder for " + 
info);
+                return null;
+            }
+
+            SerializationKind serializationKind;
+            String fallbackNodeType;
+            if (changedResource.getType() == IResource.FILE) {
+                serializationKind = SerializationKind.FILE;
+                fallbackNodeType = Repository.NT_FILE;
+            } else { // i.e. IResource.FOLDER
+                serializationKind = SerializationKind.FOLDER;
+                fallbackNodeType = Repository.NT_FOLDER;
+            }
+
+            String resourceLocation = '/' + 
changedResource.getFullPath().makeRelativeTo(syncDirectory.getFullPath())
+                    .toPortableString();
+            String serializationFilePath = 
serializationManager.getSerializationFilePath(resourceLocation,
+                    serializationKind);
+            IResource serializationResource = 
syncDirectory.findMember(serializationFilePath);
+            resourceProxy = buildResourceProxy(resourceLocation, 
serializationResource, syncDirectory, fallbackNodeType);
+
+            return repository.newAddOrUpdateNodeCommand(info, resourceProxy);
         }
     }
 
+    private ResourceProxy buildResourceProxy(String resourceLocation, 
IResource serializationResource,
+            IFolder syncDirectory, String fallbackPrimaryType) throws 
IOException, CoreException {
+        if (serializationResource instanceof IFile) {
+            IFile serializationFile = (IFile) serializationResource;
+            InputStream contents = null;
+            try {
+                contents = serializationFile.getContents();
+                String serializationFilePath = 
serializationResource.getFullPath()
+                        
.makeRelativeTo(syncDirectory.getFullPath()).toOSString();
+                return 
serializationManager.readSerializationData(serializationFilePath, contents);
+            } finally {
+                if (contents != null) {
+                    contents.close();
+                }
+            }
+        }
+
+        return new ResourceProxy(resourceLocation, 
Collections.singletonMap(Repository.JCR_PRIMARY_TYPE,
+                    (Object) fallbackPrimaryType));
+    }
+
     private FileInfo createFileInfo(IModuleResource resource, Repository 
repository) throws SerializationException {
 
         IResource file = getResource(resource);

Modified: 
sling/branches/tooling-ide-vlt/tooling/ide/impl-resource-test/src/test/java/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManagerTest.java
URL: 
http://svn.apache.org/viewvc/sling/branches/tooling-ide-vlt/tooling/ide/impl-resource-test/src/test/java/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManagerTest.java?rev=1524999&r1=1524998&r2=1524999&view=diff
==============================================================================
--- 
sling/branches/tooling-ide-vlt/tooling/ide/impl-resource-test/src/test/java/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManagerTest.java
 (original)
+++ 
sling/branches/tooling-ide-vlt/tooling/ide/impl-resource-test/src/test/java/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManagerTest.java
 Fri Sep 20 13:30:56 2013
@@ -30,6 +30,7 @@ import java.util.Map;
 
 import org.apache.sling.ide.serialization.SerializationData;
 import org.apache.sling.ide.serialization.SerializationException;
+import org.apache.sling.ide.serialization.SerializationKind;
 import org.apache.sling.ide.transport.ResourceProxy;
 import org.custommonkey.xmlunit.XMLUnit;
 import org.junit.Before;
@@ -150,7 +151,7 @@ public class SimpleXmlSerializationManag
     @Test
     public void serializationFileLocation() {
         
-        String serializationFilePath = sm.getSerializationFilePath("jcr_root");
+        String serializationFilePath = sm.getSerializationFilePath("jcr_root", 
SerializationKind.FOLDER);
         
         assertThat(serializationFilePath, is("jcr_root" + File.separatorChar + 
".content.xml"));
     }

Modified: 
sling/branches/tooling-ide-vlt/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManager.java
URL: 
http://svn.apache.org/viewvc/sling/branches/tooling-ide-vlt/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManager.java?rev=1524999&r1=1524998&r2=1524999&view=diff
==============================================================================
--- 
sling/branches/tooling-ide-vlt/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManager.java
 (original)
+++ 
sling/branches/tooling-ide-vlt/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/serialization/SimpleXmlSerializationManager.java
 Fri Sep 20 13:30:56 2013
@@ -37,6 +37,7 @@ import javax.xml.transform.stream.Stream
 import org.apache.sling.ide.serialization.SerializationData;
 import org.apache.sling.ide.serialization.SerializationDataBuilder;
 import org.apache.sling.ide.serialization.SerializationException;
+import org.apache.sling.ide.serialization.SerializationKind;
 import org.apache.sling.ide.serialization.SerializationManager;
 import org.apache.sling.ide.transport.Repository;
 import org.apache.sling.ide.transport.ResourceProxy;
@@ -60,7 +61,7 @@ public class SimpleXmlSerializationManag
     }
 
     @Override
-    public String getSerializationFilePath(String baseFilePath) {
+    public String getSerializationFilePath(String baseFilePath, 
SerializationKind serializationKind) {
         return baseFilePath + File.separatorChar + CONTENT_XML;
     }
 

Modified: 
sling/branches/tooling-ide-vlt/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/RepositoryImpl.java
URL: 
http://svn.apache.org/viewvc/sling/branches/tooling-ide-vlt/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/RepositoryImpl.java?rev=1524999&r1=1524998&r2=1524999&view=diff
==============================================================================
--- 
sling/branches/tooling-ide-vlt/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/RepositoryImpl.java
 (original)
+++ 
sling/branches/tooling-ide-vlt/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/RepositoryImpl.java
 Fri Sep 20 13:30:56 2013
@@ -28,12 +28,6 @@ public class RepositoryImpl extends Abst
     private final HttpClient httpClient = new HttpClient();
     private EventAdmin eventAdmin;
 
-       @Override
-       public Command<Void> newAddNodeCommand(final FileInfo fileInfo) {
-        return wrap(new AddNodeCommand(fileInfo, repositoryInfo, httpClient));
-       }
-
-
     private <T> Command<T> wrap(AbstractCommand<T> command) {
         return new TracingCommand<T>(command, eventAdmin);
     }
@@ -60,7 +54,7 @@ public class RepositoryImpl extends Abst
        }
        
        @Override
-    public Command<Void> newUpdateContentNodeCommand(final FileInfo fileInfo, 
ResourceProxy resource) {
+    public Command<Void> newAddOrUpdateNodeCommand(final FileInfo fileInfo, 
ResourceProxy resource) {
                
         return wrap(new UpdateContentCommand(repositoryInfo, httpClient, 
fileInfo.getRelativeLocation(),
                 resource.getProperties(), fileInfo));

Modified: 
sling/branches/tooling-ide-vlt/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/UpdateContentCommand.java
URL: 
http://svn.apache.org/viewvc/sling/branches/tooling-ide-vlt/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/UpdateContentCommand.java?rev=1524999&r1=1524998&r2=1524999&view=diff
==============================================================================
--- 
sling/branches/tooling-ide-vlt/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/UpdateContentCommand.java
 (original)
+++ 
sling/branches/tooling-ide-vlt/tooling/ide/impl-resource/src/org/apache/sling/ide/impl/resource/transport/UpdateContentCommand.java
 Fri Sep 20 13:30:56 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.sling.ide.impl.resource.transport;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -24,6 +25,7 @@ import org.apache.commons.httpclient.Htt
 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.commons.httpclient.methods.multipart.StringPart;
@@ -65,6 +67,10 @@ class UpdateContentCommand extends Abstr
                             + property.getValue().getClass());
                 }
                }
+            File f = new File(fileInfo.getLocation());
+            if (f.isFile()) {
+                parts.add(new FilePart(fileInfo.getName(), f));
+            }
             post.setRequestEntity(new MultipartRequestEntity(parts.toArray(new 
Part[parts.size()]), post
                     .getParams()));
                httpClient.getState().setCredentials(AuthScope.ANY, new 
UsernamePasswordCredentials(repositoryInfo.getUsername(),repositoryInfo.getPassword()));

Copied: 
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommand.java
 (from r1524739, 
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/UpdateNodePropertiesCommand.java)
URL: 
http://svn.apache.org/viewvc/sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommand.java?p2=sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommand.java&p1=sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/UpdateNodePropertiesCommand.java&r1=1524739&r2=1524999&rev=1524999&view=diff
==============================================================================
--- 
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/UpdateNodePropertiesCommand.java
 (original)
+++ 
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommand.java
 Fri Sep 20 13:30:56 2013
@@ -16,86 +16,136 @@
  */
 package org.apache.sling.ide.impl.vlt;
 
+import static org.apache.jackrabbit.vault.util.JcrConstants.JCR_CONTENT;
+import static org.apache.jackrabbit.vault.util.JcrConstants.JCR_DATA;
+import static org.apache.jackrabbit.vault.util.JcrConstants.JCR_LASTMODIFIED;
+import static org.apache.jackrabbit.vault.util.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.vault.util.JcrConstants.NT_RESOURCE;
+import static org.apache.sling.ide.transport.Repository.NT_FILE;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.Calendar;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 
+import javax.jcr.Binary;
 import javax.jcr.Credentials;
 import javax.jcr.Node;
 import javax.jcr.Property;
 import javax.jcr.PropertyIterator;
+import javax.jcr.PropertyType;
 import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.Value;
 import javax.jcr.ValueFactory;
+import javax.jcr.nodetype.NodeType;
 
+import org.apache.jackrabbit.vault.util.Text;
 import org.apache.sling.ide.transport.FileInfo;
 import org.apache.sling.ide.transport.ResourceProxy;
+import org.apache.sling.ide.util.PathUtil;
 
-public class UpdateNodePropertiesCommand extends JcrCommand<Void> {
+public class AddOrUpdateNodeCommand extends JcrCommand<Void> {
 
     private ResourceProxy resource;
+    private FileInfo fileInfo;
 
-       public UpdateNodePropertiesCommand(Repository jcrRepo, Credentials 
credentials, FileInfo fileInfo,
+       public AddOrUpdateNodeCommand(Repository jcrRepo, Credentials 
credentials, FileInfo fileInfo,
             ResourceProxy resource) {
 
         super(jcrRepo, credentials, resource.getPath());
         
+        this.fileInfo = fileInfo;
         this.resource = resource;
     }
 
     @Override
     protected Void execute0(Session session) throws RepositoryException, 
IOException {
 
-       update(resource, session);
+        update(resource, session);
         return null;
     }
     
-    private void update(ResourceProxy resource, Session session) throws 
RepositoryException, IOException {
-        String resPath = resource.getPath();
+    private void update(ResourceProxy resource, Session session) throws 
RepositoryException,
+            IOException {
 
-        // TODO - this is a workaround for partial coverage nodes being sent 
here
-        // when a .content.xml file with partial coverage is added here, the 
children are listed with no properties
-        // and get all their properties deleted
-        if (resource.getProperties().isEmpty()) {
-            return;
-        }
-               updatePath(resPath, resource.getProperties(), session);
-        Iterator<ResourceProxy> it = resource.getChildren().iterator();
-        while(it.hasNext()) {
-               update(it.next(), session);
+        String path = resource.getPath();
+        boolean nodeExists = session.nodeExists(path);
+
+        Node node;
+        if (nodeExists) {
+            node = session.getNode(path);
+        } else {
+            node = createNode(resource, session);
+        }
+
+        updateNode(node, resource);
+        for (ResourceProxy child : resource.getChildren()) {
+            // TODO - this is a workaround for partial coverage nodes being 
sent here
+            // when a .content.xml file with partial coverage is added here, 
the children are listed with no properties
+            // and get all their properties deleted
+            if (child.getProperties().isEmpty()) {
+                continue;
+            }
+            update(child, session);
         }
+
+        // TODO - does not handle deletion of nodes which no longer have a 
matching resource
        }
 
-       private void updatePath(final String path, final Map<String, Object> 
serializationData, final Session session) throws RepositoryException, 
IOException {
-               if (!session.nodeExists(path)) {
-                       // then create the node
-                       Object primaryType = 
serializationData.get("jcr:primaryType");
-                       String relPath = path.startsWith("/") ? 
path.substring(1) : path;
-                       if (primaryType!=null) {
-                               session.getRootNode().addNode(relPath, 
String.valueOf(primaryType));
-                       } else {
-                               session.getRootNode().addNode(relPath);
-                       }
-               }
-        Node node = session.getNode(path);
-        
+    private Node createNode(ResourceProxy resource, Session session) throws 
RepositoryException, FileNotFoundException {
+
+        String parentLocation = Text.getRelativeParent(resource.getPath(), 1);
+        if (parentLocation.isEmpty()) {
+            parentLocation = "/";
+        }
+
+        if (!session.nodeExists(parentLocation)) {
+            throw new RepositoryException("No parent found at " + 
parentLocation + " ; it's needed to create node at "
+                    + resource.getPath());
+        }
+
+        String primaryType = (String) 
resource.getProperties().get(JCR_PRIMARYTYPE);
+
+        if (primaryType == null) {
+            throw new IllegalArgumentException("Missing " + JCR_PRIMARYTYPE + 
" for ResourceProxy at path "
+                    + resource.getPath());
+        }
+
+        return 
session.getNode(parentLocation).addNode(PathUtil.getName(resource.getPath()), 
primaryType);
+    }
+
+    private void updateNode(Node node, ResourceProxy resource) throws 
RepositoryException, IOException {
+
+        if (node.getPath().equals(getPath())) {
+            updateFileLikeNodeTypes(node);
+        }
+
         Set<String> propertiesToRemove = new HashSet<String>();
         PropertyIterator properties = node.getProperties();
         while ( properties.hasNext()) {
-            propertiesToRemove.add(properties.nextProperty().getName());
+            Property property = properties.nextProperty();
+            if (property.getDefinition().isProtected()
+                    || property.getDefinition().getRequiredType() == 
PropertyType.BINARY) {
+                continue;
+            }
+            propertiesToRemove.add(property.getName());
         }
         
-        propertiesToRemove.removeAll(serializationData.keySet());
+        propertiesToRemove.removeAll(resource.getProperties().keySet());
+
+
+        Session session = node.getSession();
 
         // TODO - review for completeness and filevault compatibility
-        for (Map.Entry<String, Object> entry : serializationData.entrySet()) {
+        for (Map.Entry<String, Object> entry : 
resource.getProperties().entrySet()) {
 
             String propertyName = entry.getKey();
             Object propertyValue = entry.getValue();
@@ -193,13 +243,63 @@ public class UpdateNodePropertiesCommand
         }
         
         for ( String propertyToRemove : propertiesToRemove ) {
-            Property prop = node.getProperty(propertyToRemove);
-            if (prop.getDefinition().isProtected()) {
-                continue;
+            node.getProperty(propertyToRemove).remove();
+        }
+
+    }
+
+    private void updateFileLikeNodeTypes(Node node) throws 
RepositoryException, IOException {
+        // TODO - better handling of file-like nodes - perhaps we need to know 
the SerializationKind here
+        // TODO - avoid IO
+        File file = new File(fileInfo.getLocation());
+
+        if (!storeFileInfo(node)) {
+            return;
+        }
+
+        Node contentNode;
+
+        if (node.hasNode(JCR_CONTENT)) {
+            contentNode = node.getNode(JCR_CONTENT);
+        } else {
+            if 
(node.getProperty(JCR_PRIMARYTYPE).getString().equals(NT_RESOURCE)) {
+                contentNode = node;
+            } else {
+                contentNode = node.addNode(JCR_CONTENT, NT_RESOURCE);
+            }
+        }
+
+        FileInputStream inputStream = new FileInputStream(file);
+        try {
+            Binary binary = 
node.getSession().getValueFactory().createBinary(inputStream);
+            contentNode.setProperty(JCR_DATA, binary);
+            // TODO: might have to be done differently since the client and 
server's clocks can differ
+            // and the last_modified should maybe be taken from the server's 
time..
+            contentNode.setProperty(JCR_LASTMODIFIED, Calendar.getInstance());
+        } finally {
+            try {
+                inputStream.close();
+            } catch (IOException e) {
+                // don't care
+            }
+        }
+    }
+
+    private boolean storeFileInfo(Node node) throws RepositoryException {
+
+        String nodeTypeName = node.getPrimaryNodeType().getName();
+        if (nodeTypeName.equals(NT_FILE) || nodeTypeName.equals(NT_RESOURCE)) {
+            return true;
+        }
+
+        for (NodeType supertype : node.getPrimaryNodeType().getSupertypes()) {
+            String superTypeName = supertype.getName();
+            if (superTypeName.equals(NT_FILE) || 
superTypeName.equals(NT_RESOURCE)) {
+                return true;
             }
-            prop.remove();
         }
 
+        return false;
     }
 
     private Value[] toValueArray(String[] strings, Session session) throws 
RepositoryException {

Propchange: 
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommand.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/AddOrUpdateNodeCommand.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: 
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/VltRepository.java
URL: 
http://svn.apache.org/viewvc/sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/VltRepository.java?rev=1524999&r1=1524998&r2=1524999&view=diff
==============================================================================
--- 
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/VltRepository.java
 (original)
+++ 
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/VltRepository.java
 Fri Sep 20 13:30:56 2013
@@ -45,14 +45,9 @@ public class VltRepository implements Re
     }
 
     @Override
-    public Command<Void> newAddNodeCommand(FileInfo fileInfo) {
-        return TracingCommand.wrap(new AddNodeCommand(jcrRepo, credentials, 
fileInfo), eventAdmin);
-    }
-
-    @Override
-    public Command<Void> newUpdateContentNodeCommand(FileInfo fileInfo, 
ResourceProxy resource) {
+    public Command<Void> newAddOrUpdateNodeCommand(FileInfo fileInfo, 
ResourceProxy resource) {
         // TODO implement
-        return TracingCommand.wrap(new UpdateNodePropertiesCommand(jcrRepo, 
credentials, fileInfo, resource),
+        return TracingCommand.wrap(new AddOrUpdateNodeCommand(jcrRepo, 
credentials, fileInfo, resource),
                 eventAdmin);
     }
 

Modified: 
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/serialization/VltSerializationManager.java
URL: 
http://svn.apache.org/viewvc/sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/serialization/VltSerializationManager.java?rev=1524999&r1=1524998&r2=1524999&view=diff
==============================================================================
--- 
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/serialization/VltSerializationManager.java
 (original)
+++ 
sling/branches/tooling-ide-vlt/tooling/ide/impl-vlt/src/org/apache/sling/ide/impl/vlt/serialization/VltSerializationManager.java
 Fri Sep 20 13:30:56 2013
@@ -43,6 +43,7 @@ import org.apache.jackrabbit.vault.util.
 import org.apache.sling.ide.impl.vlt.VaultFsLocator;
 import org.apache.sling.ide.serialization.SerializationDataBuilder;
 import org.apache.sling.ide.serialization.SerializationException;
+import org.apache.sling.ide.serialization.SerializationKind;
 import org.apache.sling.ide.serialization.SerializationManager;
 import org.apache.sling.ide.transport.ResourceProxy;
 import org.xml.sax.InputSource;
@@ -130,9 +131,19 @@ public class VltSerializationManager imp
     }
 
     @Override
-    public String getSerializationFilePath(String baseFilePath) {
-        // TODO - validate if this is correct
-        return baseFilePath + File.separatorChar + Constants.DOT_CONTENT_XML;
+    public String getSerializationFilePath(String baseFilePath, 
SerializationKind serializationKind) {
+
+        switch (serializationKind) {
+            case FOLDER:
+            case METADATA_PARTIAL:
+                return baseFilePath + File.separatorChar + 
Constants.DOT_CONTENT_XML;
+            case METADATA_FULL:
+                return baseFilePath;
+            case FILE:
+                return baseFilePath + ".dir" + File.separatorChar + 
Constants.DOT_CONTENT_XML;
+        }
+
+        throw new IllegalArgumentException("Unsupported serialization kind " + 
serializationKind);
     }
 
     protected void bindVaultFsLocator(VaultFsLocator fsLocator) {
@@ -170,7 +181,12 @@ public class VltSerializationManager imp
         String repositoryPath;
         File file = new File(filePath);
         if (file.getName().equals(Constants.DOT_CONTENT_XML)) {
-            repositoryPath = 
PlatformNameFormat.getRepositoryPath(file.getParent());
+            // TODO - generalize instead of special-casing the parent name
+            String parentPath = file.getParent();
+            if (parentPath != null && parentPath.endsWith(".dir")) {
+                parentPath = parentPath.substring(0, parentPath.length() - 
".dir".length());
+            }
+            repositoryPath = PlatformNameFormat.getRepositoryPath(parentPath);
         } else {
             if (!filePath.endsWith(EXTENSION_XML)) {
                 throw new IllegalArgumentException("Don't know how to extract 
resource path from file named "


Reply via email to