[Ngms-svn] SVN-Commit: [57] [NMTree] implements FileSystemTree

Back to archive index

svnno****@sourc***** svnno****@sourc*****
2009年 12月 10日 (木) 17:26:26 JST


Revision: 57
          http://sourceforge.jp/projects/ngms/svn/view?view=rev&revision=57
Author:   osiire
Date:     2009-12-10 17:26:26 +0900 (Thu, 10 Dec 2009)

Log Message:
-----------
[NMTree] implements FileSystemTree

Modified Paths:
--------------
    trunk/source/NMTree/src/info/ngms/nmtree/NMFileSystemTree.scala
    trunk/source/NMTree/src/info/ngms/nmtree/NMPath.scala
    trunk/source/NMTree/test/NMFileSystemTreeTest.scala
    trunk/source/NMTree/test/NMPathTest.scala

Modified: trunk/source/NMTree/src/info/ngms/nmtree/NMFileSystemTree.scala
===================================================================
--- trunk/source/NMTree/src/info/ngms/nmtree/NMFileSystemTree.scala	2009-12-10 07:49:52 UTC (rev 56)
+++ trunk/source/NMTree/src/info/ngms/nmtree/NMFileSystemTree.scala	2009-12-10 08:26:26 UTC (rev 57)
@@ -17,9 +17,7 @@
     var mountPoint : NMPath = mnt
 
     implicit def ofRealPath( path : NMPath ) : String = {
-        //未実装
-        //NMPath.diff( mnt.canonical, path.canonical )
-        ""
+	NMPath.concat(realRoot, NMPath.diff(path.canonical,mnt.canonical))
     }
 
     implicit def toNMPath( path : String ) : NMPath = {
@@ -29,7 +27,7 @@
     trait Identifier {
         val id = 0L // 未実装
     }
-
+
     def createStream( path : NMPath ) : NMTree.TStreamElement = {
         val file = new File( path )
         new {
@@ -85,7 +83,7 @@
          * 自身のパスに子供がいない場合は空リストになる。
          */
         def children( path : NMPath ) : List[NMPath] = {
-            (new File(path)).list().toList.map(toNMPath)
+            (new File(path)).list().toList.map(path.concat(_))
         }
 
         /**
@@ -95,7 +93,7 @@
         def attribute( path : NMPath ) : NMElementAttribute = {
             var file = new File( path )
             new NMElementAttribute {
-                val size = 0L
+                val size = file.length()
                 val lastUpdateDate = new Date( file.lastModified() )
                 val versionStatus = Neutral
             }
@@ -113,12 +111,56 @@
     }
 
     object TreeOperations {
-        def move( src : NMPath, dst : NMPath ) : Unit = { }
+        def move( src : NMPath, dst : NMPath ) : Unit = {
+	    (new File(src)).renameTo(new File(dst))
+	}
 
-        def copy( src : NMPath, dst : NMPath, overwrite : Boolean, recursive : Boolean ) : Unit = { }
+	private def copyFile(in : File, out : File ) {
+	    if( in.isDirectory ) {
+		out.mkdir
+	    } else {
+		var sourceChannel = new FileInputStream(in).getChannel
+		var destinationChannel = new FileOutputStream(out).getChannel
+		sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel)
+		sourceChannel.close
+		destinationChannel.close
+	    }
+        }
 
-        def delete( path : NMPath, recursive : Boolean ) : Unit = { }
+	private def copyFileRec(in : File, out : File){
+	    if( in.isDirectory ) {
+		out.mkdir
+	        for( file <- in.listFiles )
+		    copyFileRec( file, new File( out, file.getName ) )
+	    } else {
+		copyFile(in, out)
+	    }
+	}
 
+        def copy( src : NMPath, dst : NMPath, overwrite : Boolean, recursive : Boolean ) {
+	    if(!overwrite && PathOperations.exists(dst)) {
+		return;
+	    }
+
+	    if(recursive)
+		copyFileRec(new File( src ) , new File( dst ))
+	    else {
+		copyFile(new File( src ) , new File( dst ))
+	    }
+	}
+
+	private def deleteFileRec(root : File) {
+	    if(root.isDirectory)
+		root.listFiles.foreach( deleteFileRec( _ ) )
+	    root.delete()
+	}
+        def delete( path : NMPath, recursive : Boolean ) : Unit = {
+	    if(recursive)
+		deleteFileRec( new File( path ) )
+	    else
+		( new File( path ) ).delete
+	}
+
         def symLink( src : NMPath, dst : NMPath ) : Unit = { }
 
         def changePermission( src : NMPath, permission : NMElementPermission ) : Unit = { }
@@ -134,4 +176,4 @@
 
     def pathOp : NMTree.TPathOperations = PathOperations
     def treeOp : NMTree.TTreeOperations = TreeOperations
-}
\ No newline at end of file
+}

Modified: trunk/source/NMTree/src/info/ngms/nmtree/NMPath.scala
===================================================================
--- trunk/source/NMTree/src/info/ngms/nmtree/NMPath.scala	2009-12-10 07:49:52 UTC (rev 56)
+++ trunk/source/NMTree/src/info/ngms/nmtree/NMPath.scala	2009-12-10 08:26:26 UTC (rev 57)
@@ -54,6 +54,32 @@
             }
         }
 
+	def diff(other : InnerPath) : String = {
+	    if(isAbsolute && other.isAbsolute)
+		diffElems(this.elems,other.elems) match {
+		    case Some(elems) =>
+			elems2str(elems)
+		    case _ =>
+			this.canonical
+		}
+	    else
+		this.canonical
+	}
+
+	private def diffElems(lhs : List[Element], rhs : List[Element]) : Option[List[Element]] = {
+	    (lhs,rhs) match {
+		case (_, Nil) =>
+		    Some(lhs.reverse)
+		case ((x :: xs),(y :: ys)) =>
+		    if(x == y)
+			diffElems(xs,ys)
+		    else
+			None
+		case _ =>
+		    None
+	    }
+	}
+
         private def isDot( e : Element ) : Boolean = {
             e match {
                 case DOT => true
@@ -112,7 +138,9 @@
              case _ => false
            }
        }
-       def path = opt(separator) ~ repsep( elem, separator ) ~ opt(separator) ^^
+       def seps = separator <~ rep(separator)
+
+       def path = opt(seps) ~ repsep( elem, seps ) ~ opt(seps) ^^
            { case head ~ elems ~ _ => new InnerPath( head, elems.filter( e => !emptyName(e)))}
        def elem = "[^/]+".r ^^ {
            case "." => DOT
@@ -146,6 +174,10 @@
         path + separator + child
     }
 
+    def diff( path : String, base : String) : String = {
+	makeInnerPath(path).diff(makeInnerPath(base))
+    }
+
 }
 
 /**
@@ -271,4 +303,21 @@
      def diff( revision : Int ) : String = {
         ""
      }
+
+     /**
+      * パス同士が等しいかを調べる
+      *
+      * @param 比較するインスタンス
+      * @return 等しいなら真
+      */
+     override def equals(other : Any) : Boolean =
+	 other match {
+	     case that: NMPath =>
+		 (that canEqual this) &&
+		 this.canonical == that.canonical
+	     case _ => false
+	 }
+
+     def canEqual(other : Any) : Boolean =
+	 other.isInstanceOf[NMPath]
 }

Modified: trunk/source/NMTree/test/NMFileSystemTreeTest.scala
===================================================================
--- trunk/source/NMTree/test/NMFileSystemTreeTest.scala	2009-12-10 07:49:52 UTC (rev 56)
+++ trunk/source/NMTree/test/NMFileSystemTreeTest.scala	2009-12-10 08:26:26 UTC (rev 57)
@@ -2,7 +2,140 @@
 
 import org.scalatest.FunSuite
 import org.scalatest.BeforeAndAfterEach
+import java.util.Date
+import java.io._
 
+
 class NMFileSystemTreeTest extends FunSuite with BeforeAndAfterEach {
+    implicit def s2p( path : String ) : NMPath = {
+        new NMPath(path)
+    }
 
+    val test_dir = "./test/NMFileSystemTreeTest/"
+    val today = new Date
+
+    def rm_rf(path : String) {
+	val file = new File(path)
+	if(file.isDirectory()){
+	    file.listFiles.foreach(f => rm_rf(f.toString))
+	    file.delete()
+	}else {
+	    file.delete()
+	}
+    }
+
+    def mkdir(path : String){
+	val file = new File(path)
+	file.mkdirs()
+    }
+
+    def touch(path : String, content : String){
+        val output = new OutputStreamWriter(new FileOutputStream( path ))
+	output.write(content)
+	output.close()
+    }
+
+    override def beforeEach() {
+	mkdir( test_dir )
+	touch( test_dir + "foo.txt" , "123\n")
+	mkdir( test_dir + "bar" )
+	touch( test_dir + "bar/bar.txt", "" )
+
+	(new File( test_dir + "foo.txt")).setLastModified( today.getTime() )
+    }
+
+
+    override def afterEach()  {
+	rm_rf( test_dir )
+    }
+
+    val fs = new NMFileSystemTree( "./test/NMFileSystemTreeTest", "/" )
+    val pathOp = fs.pathOp
+    val treeOp = fs.treeOp
+
+    // PathOperationsのテスト
+    test( "パスが実際に存在するかの確認" ) {
+	assert (pathOp.exists("/foo.txt")    === true )
+	assert (pathOp.exists("/bar")        === true )
+	assert (pathOp.exists("/non-exists") === false)
+    }
+
+    test ( "パスがディレクトリかの確認" ) {
+	assert (pathOp.isNode("/foo.txt")    == false)
+	assert (pathOp.isNode("/bar")        == true)
+	assert (pathOp.isNode("/non-exists") == false)
+    }
+
+    test ( "サブファイルの取得" ) {
+	assert (pathOp.children("/")    === List[NMPath]("/bar","/foo.txt"))
+	assert (pathOp.children("/bar") === List[NMPath]("/bar/bar.txt"))
+    }
+
+    test ( "ファイルの属性" ) {
+	val attr = pathOp.attribute( "/foo.txt" )
+	assert(attr.size === 4)
+	assert(attr.lastUpdateDate.toString() === today.toString())
+	assert(attr.versionStatus === Neutral)
+    }
+
+    test ( "権限" ) ( pending )
+
+    test ( "バージョン" ) {
+	assert( pathOp.versionStatus( "/foo.txt" ) === Neutral )
+    }
+
+    // tree operation
+    test( "move" ) {
+	assert( pathOp.exists( "/foo.txt" )  === true  )
+	assert( pathOp.exists( "/foo2.txt" ) === false )
+
+	treeOp.move("/foo.txt","/foo2.txt")
+
+	assert( pathOp.exists( "/foo.txt" )  === false )
+	assert( pathOp.exists( "/foo2.txt" ) === true  )
+    }
+
+    test( "copy-1" ) {
+	assert( pathOp.exists( "/foo.txt" )  === true  )
+	assert( pathOp.exists( "/foo2.txt" ) === false )
+
+	treeOp.copy("/foo.txt","/foo2.txt",false,false)
+
+	assert( pathOp.exists( "/foo.txt" )  === true )
+	assert( pathOp.exists( "/foo2.txt" ) === true )
+    }
+
+    test( "copy-2" ) {
+	treeOp.copy("/foo.txt","/bar/bar.txt", false ,false)
+	assert( pathOp.attribute( "/bar/bar.txt" ).size === 0)
+    }
+
+    test ("copy-overwrite" ){
+	treeOp.copy("/foo.txt","/bar/bar.txt", true ,false)
+	assert( pathOp.attribute( "/bar/bar.txt" ).size === 4)
+    }
+
+    test( "copy-3" ) {
+	treeOp.copy("/bar","/baz",false,false)
+	assert( pathOp.exists( "/baz/bar.txt" )  === false )
+    }
+
+    test( "copy-4") {
+	treeOp.copy("/bar","/baz",false,true)
+	assert( pathOp.exists( "/baz/bar.txt" )  === true  )
+    }
+
+    test( "delete-1" ) {
+	assert( pathOp.exists( "/foo.txt" )  === true  )
+	treeOp.delete( "/foo.txt",false )
+	assert( pathOp.exists( "/foo.txt" )  === false )
+    }
+
+    test( "delete-2" ) {
+	treeOp.delete( "/bar",false )
+	assert( pathOp.exists( "/bar" )  === true )
+
+	treeOp.delete( "/bar",true )
+	assert( pathOp.exists( "/bar" )  === false )
+    }
 }

Modified: trunk/source/NMTree/test/NMPathTest.scala
===================================================================
--- trunk/source/NMTree/test/NMPathTest.scala	2009-12-10 07:49:52 UTC (rev 56)
+++ trunk/source/NMTree/test/NMPathTest.scala	2009-12-10 08:26:26 UTC (rev 57)
@@ -34,6 +34,9 @@
     test("canonical-9") {
         assert( NMPath.canonical("/usr/../../../../../bin") == "/bin" )
     }
+    test("canonical-10") {
+        assert( NMPath.canonical("//foo.txt") === "/foo.txt" )
+    }
 
     test("parent-1") {
         val parent = (new NMPath("/bin/sh")).parent
@@ -61,4 +64,22 @@
     test("basename-3") {
         assert( (new NMPath("/bin/../../")).basename == "/" )
     }
+
+    test("diff-1"){
+	assert ( NMPath.diff( "/foo/bar", "/foo" ) === "bar")
+    }
+    test("diff-2"){
+	assert ( NMPath.diff("/" , "/foo" ) === "/")
+    }
+    test("diff-3"){
+	assert ( NMPath.diff("/foo" , "/foo" ) === "")
+    }
+    test("diff-4"){
+	assert ( NMPath.diff("/bar/foo" , "/foo" ) === "/bar/foo")
+    }
+    test("diff-5"){
+	assert ( NMPath.diff("/foo/bar/baz" , "/foo" ) === "bar/baz")
+    }
 }
+
+




Ngms-svn メーリングリストの案内
Back to archive index