From a0c27d5904d4fd28bb5555bbc24686033f0cd744 Mon Sep 17 00:00:00 2001 From: Tomas Remes Date: Tue, 7 Aug 2012 15:07:33 +0200 Subject: [PATCH] FORGE-605 copy plugin added --- .../shell/plugins/builtin/CopyPlugin.java | 145 +++++++++ .../test/plugins/builtin/CopyPluginTest.java | 283 ++++++++++++++++++ 2 files changed, 428 insertions(+) create mode 100644 shell/src/main/java/org/jboss/forge/shell/plugins/builtin/CopyPlugin.java create mode 100644 shell/src/test/java/org/jboss/forge/shell/test/plugins/builtin/CopyPluginTest.java diff --git a/shell/src/main/java/org/jboss/forge/shell/plugins/builtin/CopyPlugin.java b/shell/src/main/java/org/jboss/forge/shell/plugins/builtin/CopyPlugin.java new file mode 100644 index 0000000000..a080125860 --- /dev/null +++ b/shell/src/main/java/org/jboss/forge/shell/plugins/builtin/CopyPlugin.java @@ -0,0 +1,145 @@ +package org.jboss.forge.shell.plugins.builtin; + +import java.util.List; + +import javax.inject.Inject; + +import org.jboss.forge.project.services.ResourceFactory; +import org.jboss.forge.resources.DirectoryResource; +import org.jboss.forge.resources.FileResource; +import org.jboss.forge.resources.Resource; +import org.jboss.forge.resources.ResourceFlag; +import org.jboss.forge.shell.plugins.Alias; +import org.jboss.forge.shell.plugins.DefaultCommand; +import org.jboss.forge.shell.plugins.Help; +import org.jboss.forge.shell.plugins.Option; +import org.jboss.forge.shell.plugins.Plugin; +import org.jboss.forge.shell.plugins.RequiresResource; +import org.jboss.forge.shell.plugins.Topic; +import org.jboss.forge.shell.util.PathspecParser; + +/** + * + * Builtin copy plugin + * + * @author tremes@redhat.com + * + */ +@Alias("cp") +@Topic("File & Resources") +@RequiresResource(DirectoryResource.class) +@Help("Copy a file or directory") +public class CopyPlugin implements Plugin { + + private final ResourceFactory resourceFactory; + + @Inject + public CopyPlugin(final ResourceFactory resourceFactory) + { + this.resourceFactory = resourceFactory; + } + + @DefaultCommand + public void rename( + @Option(description = "source", required = true) final Resource source, + @Option(description = "target", required = true) final String target ) + { + if (isDirectory(source)) + { + Resource directory = source.getParent(); + copyRecursively( source, directory, target ); + } + else if (isFile(source)) + { + Resource directory = source.isFlagSet(ResourceFlag.Leaf) ? source.getParent() : source; + copy(source, directory, target); + } + else + { + throw new RuntimeException("cannot copy resource type: " + source.getClass().getSimpleName()); + } + } + + private void copy(final Resource source, Resource directory, final String target ) + { + List> results = new PathspecParser(resourceFactory, directory, target).resolve(); + + if (results.size() > 1) + { + throw new RuntimeException("ambiguous target file name: " + target); + } + else + { + Resource targetResource = results.get(0); + if (targetResource.exists()) + { + if (isDirectory(targetResource)) + { + targetResource = targetResource.getChild(source.getName()); + } + } + ((FileResource) targetResource).setContents(source.getResourceInputStream()); + } + } + + private void copyRecursively(final Resource source, Resource directory, final String target ) + { + List> results = new PathspecParser(resourceFactory, directory, target).resolve(); + + if (results.size() > 1) + { + throw new RuntimeException("ambiguous target file name: " + target); + } + else + { + Resource targetResource = results.get(0); + List>childs = source.listResources(); + Resource newTargetDir=null; + + if (isDirectory(source)){ + + if(!targetResource.exists()){ + + newTargetDir=((DirectoryResource) source.getParent()).getOrCreateChildDirectory( targetResource.getName() ); + + }else{ + + newTargetDir = ((DirectoryResource) targetResource).getOrCreateChildDirectory(source.getName()); + + } + + }else if(isFile(source)){ + + Resource child = targetResource.getChild(source.getName()); + + if(child==null){ + + ((DirectoryResource) targetResource).getOrCreateChildDirectory(source.getName()).setContents( source.getResourceInputStream() ); + + }else{ + + ((FileResource) child).setContents( source.getResourceInputStream() ); + + } + newTargetDir = (DirectoryResource) targetResource; + } + + if(childs.size()> 0){ + for ( Resource resource : childs ) { + copyRecursively( resource, directory,newTargetDir.getFullyQualifiedName() ); + } + } + } + } + + private boolean isFile(Resource source) + { + return source instanceof FileResource; + } + + private boolean isDirectory(Resource source) + { + return source instanceof DirectoryResource; + } + +} diff --git a/shell/src/test/java/org/jboss/forge/shell/test/plugins/builtin/CopyPluginTest.java b/shell/src/test/java/org/jboss/forge/shell/test/plugins/builtin/CopyPluginTest.java new file mode 100644 index 0000000000..faee9df484 --- /dev/null +++ b/shell/src/test/java/org/jboss/forge/shell/test/plugins/builtin/CopyPluginTest.java @@ -0,0 +1,283 @@ +package org.jboss.forge.shell.test.plugins.builtin; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileInputStream; + +import org.jboss.forge.resources.DirectoryResource; +import org.jboss.forge.resources.FileResource; +import org.jboss.forge.resources.Resource; +import org.jboss.forge.shell.Shell; +import org.jboss.forge.test.AbstractShellTest; +import org.junit.Test; + +/** + * Test for Copy Plugin + * + * @author tremes@redhat.com + * + */ + +public class CopyPluginTest extends AbstractShellTest { + + @Test + public void testCopyFileToFolder() throws Exception { + + String testFolder= "testFolder"; + String file = "copyFile"; + + initializeJavaProject(); + Shell shell = getShell(); + shell.execute( "mkdir "+testFolder ); + shell.execute( "touch "+file ); + + Resource fileToCopy = shell.getCurrentDirectory().getChild(file); + assertTrue( fileToCopy.exists() ); + + shell.execute( "cp "+file+" "+testFolder ); + assertTrue( fileToCopy.exists() ); + + shell.execute( "cd "+testFolder ); + Resource copy = shell.getCurrentDirectory().getChild(file); + + assertTrue( copy.exists() ); + + } + + @Test + public void testCopyFileToNewFile() throws Exception { + + String file = "copyFile"; + String nonExisting = "newNoneExisting"; + + initializeJavaProject(); + Shell shell = getShell(); + shell.execute( "touch "+file ); + + Resource fileToCopy = shell.getCurrentDirectory().getChild(file); + assertTrue( fileToCopy.exists() ); + + shell.execute( "cp "+file+" "+nonExisting ); + Resource copy = shell.getCurrentDirectory().getChild(nonExisting); + assertTrue( copy.exists() ); + + } + + @Test + public void testCopyFileWithRewrite() throws Exception { + + String testFolder= "testFolder"; + String file = "copyFile"; + + initializeJavaProject(); + Shell shell = getShell(); + shell.execute( "mkdir "+testFolder ); + shell.execute( "touch "+file ); + shell.execute( "cd "+testFolder ); + shell.execute( "touch "+file ); + shell.execute( "cd .." ); + + FileResource fileToCopy = (FileResource) shell.getCurrentDirectory().getChild(file); + assertTrue( fileToCopy.exists() ); + + shell.execute( "cd "+testFolder ); + FileResource copy = (FileResource) shell.getCurrentDirectory().getChild(file); + shell.execute( "cp "+file+" "+testFolder ); + assertTrue( fileToCopy.exists() ); + assertTrue( copy.exists() ); + assertTrue( compareFiles( fileToCopy.getUnderlyingResourceObject(), copy.getUnderlyingResourceObject() ) ); + + } + + @Test + public void testCopyEmptyFolder() throws Exception { + + String testFolder= "testFolder"; + String newFolder= "newFolder"; + + initializeJavaProject(); + Shell shell = getShell(); + shell.execute( "mkdir "+testFolder ); + + Resource dirToCopy = shell.getCurrentDirectory().getChildDirectory(testFolder); + assertTrue( dirToCopy.exists() ); + + shell.execute( "cp "+testFolder+" " + newFolder ); + Resource copy = shell.getCurrentDirectory().getChild(newFolder); + assertTrue( copy.exists() ); + assertTrue( ( (DirectoryResource) copy ).isDirectory() ); + + } + + @Test + public void testCopyEmptyFolderToExisting() throws Exception { + + String testFolder= "testFolder"; + String newFolder= "newFolder"; + + initializeJavaProject(); + Shell shell = getShell(); + shell.execute( "mkdir "+testFolder ); + shell.execute( "mkdir "+newFolder ); + + Resource dirToCopy = shell.getCurrentDirectory().getChildDirectory(testFolder); + assertTrue( dirToCopy.exists() ); + + shell.execute( "cp "+testFolder+" "+newFolder ); + Resource targetParent = shell.getCurrentDirectory().getChild(newFolder); + Resource copy = ( (DirectoryResource) targetParent ).getChildDirectory(testFolder); + assertTrue( copy.exists() ); + assertTrue( ( (DirectoryResource) copy ).isDirectory() ); + + } + + @Test + public void testCopyNonEmptyFolder() throws Exception{ + + String testFolder= "testFolder"; + String newFolder= "newFolder"; + String subFolderA= "subFolder1"; + String subFolderB= "subFolder2"; + String fileA= "file1"; + String fileB= "file2"; + + initializeJavaProject(); + Shell shell = getShell(); + shell.execute( "mkdir "+testFolder ); + shell.execute( "cd "+testFolder ); + shell.execute( "mkdir "+subFolderA ); + shell.execute( "mkdir "+subFolderB ); + shell.execute( "touch "+fileA ); + shell.execute( "cd "+subFolderA ); + shell.execute( "touch "+fileB ); + shell.execute( "cd .." ); + shell.execute( "cd .." ); + + Resource dirToCopy = shell.getCurrentDirectory().getChildDirectory(testFolder); + assertTrue(dirToCopy.exists()); + FileResource file1 = (FileResource) dirToCopy.getChild(fileA); + assertTrue(file1.exists()); + Resource subFolder1 = ((DirectoryResource) dirToCopy).getChildDirectory(subFolderA); + Resource file2 =((DirectoryResource) subFolder1).getChild( fileB ); + assertTrue(file2.exists()); + + assertTrue(((DirectoryResource) subFolder1).isDirectory()); + assertTrue(((DirectoryResource) subFolder1).exists()); + + Resource subFolder2= ((DirectoryResource) dirToCopy).getChildDirectory(subFolderB); + assertTrue(((DirectoryResource) subFolder2).isDirectory()); + assertTrue(((DirectoryResource) subFolder2).exists()); + + + shell.execute("cp "+testFolder+" "+newFolder); + + Resource copy = shell.getCurrentDirectory().getChildDirectory(newFolder); + assertTrue(copy.exists()); + assertTrue(((DirectoryResource)copy).isDirectory()); + + FileResource copyfile1 = (FileResource) copy.getChild(fileA); + assertTrue(copyfile1.exists()); + + DirectoryResource copySubFolder1 = ((DirectoryResource) copy).getChildDirectory(subFolderA); + assertTrue(copySubFolder1.exists()); + Resource copyfile2 =((DirectoryResource) copySubFolder1).getChild( fileB); + assertTrue(copyfile2.exists()); + + DirectoryResource copySubFolder2 = ((DirectoryResource) copy).getChildDirectory(subFolderA); + assertTrue(copySubFolder2.exists()); + + + } + + @Test + public void testCopyFolderToExistingFolder() throws Exception { + + String testFolder= "testFolder"; + String newFolder= "newFolder"; + String subFolderA= "subFolder1"; + String subFolderB= "subFolder2"; + String fileA= "file1"; + String fileB= "file2"; + + initializeJavaProject(); + Shell shell = getShell(); + shell.execute( "mkdir "+testFolder ); + shell.execute( "cd "+testFolder ); + shell.execute( "mkdir "+subFolderA ); + shell.execute( "mkdir "+subFolderB ); + shell.execute( "touch "+fileA ); + shell.execute( "cd "+subFolderA ); + shell.execute( "touch "+fileB ); + shell.execute( "cd .." ); + shell.execute( "cd .." ); + shell.execute( "mkdir "+newFolder ); + + Resource dirToCopy = shell.getCurrentDirectory().getChildDirectory( testFolder ); + assertTrue( dirToCopy.exists() ); + FileResource file1 = (FileResource) dirToCopy.getChild( fileA ); + assertTrue( file1.exists() ); + Resource subFolder1 = ( (DirectoryResource) dirToCopy ).getChildDirectory( subFolderA ); + FileResource file2 = (FileResource) subFolder1.getChild( fileB ); + assertTrue( file2.exists() ); + + assertTrue( ( (DirectoryResource) subFolder1 ).isDirectory() ); + assertTrue( ( (DirectoryResource) subFolder1 ).exists() ); + + Resource subFolder2 = ( (DirectoryResource) dirToCopy ).getChildDirectory( subFolderB ); + assertTrue( ( (DirectoryResource) subFolder2 ).isDirectory() ); + assertTrue( ( (DirectoryResource) subFolder2 ).exists() ); + + shell.execute( "cp "+testFolder+" "+newFolder ); + + Resource targetParent = shell.getCurrentDirectory().getChildDirectory( newFolder ); + assertTrue( targetParent.exists() ); + assertTrue( ( (DirectoryResource) targetParent ).isDirectory() ); + + Resource copy = ( (DirectoryResource) targetParent ).getChildDirectory( testFolder ); + assertTrue( copy.exists() ); + assertTrue( ( (DirectoryResource) copy ).isDirectory() ); + + FileResource copyfile1 = (FileResource) copy.getChild( fileA ); + assertTrue( copyfile1.exists() ); + assertTrue( compareFiles( copyfile1.getUnderlyingResourceObject(), file1.getUnderlyingResourceObject() ) ); + + DirectoryResource copySubFolder1 = ( (DirectoryResource) copy ).getChildDirectory( subFolderA ); + assertTrue( copySubFolder1.exists() ); + FileResource copyfile2 = (FileResource) copySubFolder1.getChild( fileB ); + assertTrue( copyfile2.exists() ); + assertTrue( compareFiles( copyfile2.getUnderlyingResourceObject(), file2.getUnderlyingResourceObject() ) ); + + DirectoryResource copySubFolder2 = ( (DirectoryResource) copy ).getChildDirectory( subFolderB ); + assertTrue( copySubFolder2.exists() ); + } + + private boolean compareFiles(File f1, File f2) { + try { + if ( f1.length() == f2.length() ) { + FileInputStream fis1 = new FileInputStream( f1 ); + FileInputStream fis2 = new FileInputStream( f2 ); + + while ( true ) { + int a = fis1.read(); + int b = fis2.read(); + if ( a != b ) { + return false; + } + if ( a == -1 ) { + return true; + } + } + } + else { + return false; + } + + } + catch ( Exception e ) { + e.printStackTrace(); + } + return false; + } + +}