output parsing refactored;
authorClaus Gittinger <cg@exept.de>
Thu, 12 Jun 2003 13:20:20 +0200
changeset 1246 1eefc3a60863
parent 1245 99e070f7c351
child 1247 4c628a0455c1
output parsing refactored;
Archiver.st
--- a/Archiver.st	Wed Jun 11 10:37:18 2003 +0200
+++ b/Archiver.st	Thu Jun 12 13:20:20 2003 +0200
@@ -8,6 +8,13 @@
 	category:'System-Support-FileFormats'
 !
 
+Object subclass:#ArchiverOutputParser
+	instanceVariableNames:'firstLineRead archiver'
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:Archiver
+!
+
 Archiver subclass:#GZipArchive
 	instanceVariableNames:''
 	classVariableNames:''
@@ -113,6 +120,22 @@
     ^ ZipArchive
 ! !
 
+!Archiver class methodsFor:'columns'!
+
+columns
+    self subclassResponsibility
+! !
+
+!Archiver class methodsFor:'commandOutputReader'!
+
+commandOutputParser
+    ^ self commandOutputParserClass new
+!
+
+commandOutputParserClass
+    ^ ArchiverOutputParser
+! !
+
 !Archiver class methodsFor:'queries'!
 
 canAddFiles
@@ -299,6 +322,20 @@
     ]
 !
 
+isValidOutputLine:line
+    "return true, if line contains a valid list-files output line"
+
+    self subclassResponsibility
+!
+
+listFilesReader
+    |reader|
+
+    reader := ArchiverOutputParser new.
+    reader archiver:self.
+    ^ reader
+!
+
 outStream:aOutStream errorStream:aErrorStream
 
     outStream := aOutStream.
@@ -320,20 +357,84 @@
     self removeTemporaryDirectory.
 ! !
 
-!Archiver::GZipArchive class methodsFor:'columns'!
+!Archiver::ArchiverOutputParser class methodsFor:'instance creation'!
+
+new
+    ^ self basicNew initialize.
+! !
+
+!Archiver::ArchiverOutputParser methodsFor:'accessing'!
+
+archiver:something
+    "set the value of the instance variable 'archiver' (automatically generated)"
+
+    archiver := something.
+! !
+
+!Archiver::ArchiverOutputParser methodsFor:'initialization'!
 
-columns
+initialize
+    firstLineRead := false.
+! !
+
+!Archiver::ArchiverOutputParser methodsFor:'parsing'!
+
+parseLine:line forItemClass:itemClass
+    |words archiverColumns item index key|
+
+    (firstLineRead not and:[archiver class hasTitleLine]) ifTrue:[
+        firstLineRead := true.
+        ^ nil.
+    ].
+
+    (archiver isValidOutputLine:line) ifFalse:[
+        ^ nil.
+    ].
+
+    words := line asCollectionOfWords.
+    archiverColumns := archiver columns.
+    item := itemClass new.
+    index := 1.
 
-    "/ columns in stream order
-    "/  colums id          words to read
-    ^ #( #(#method          1)      
-         #(#crc             1)    
-         #(#dateAndTime     3)   
-         #(#compressSize    1)  
-         #(#size            1) 
-         #(#ratio           1) 
-         #(#fileName        #rest)
-    ) 
+    archiverColumns do:[:colDescr |
+        | itemWordCount itemStream itemFieldSelector itemWriter |
+
+        itemWordCount := colDescr second.
+        itemFieldSelector := colDescr first.
+        itemFieldSelector notNil ifTrue:[
+            itemWriter := (itemFieldSelector , ':') asSymbol.
+        ].
+        itemStream := WriteStream on:''.
+        itemWordCount == #rest ifTrue:[
+            index to:(words size) do:[:i|
+                itemStream nextPutAll:(words at:i).
+                itemStream space.
+            ].
+        ] ifFalse:[
+            index to:(index + itemWordCount - 1) do:[:i|
+                itemStream nextPutAll:(words at:i).
+                itemStream space.
+            ].
+            index := index + itemWordCount.
+        ].
+        itemWriter notNil ifTrue:[
+            item perform:itemWriter with:(itemStream contents).
+        ].
+        itemStream close.
+    ].
+    ((archiverColumns collect:[:el| el first]) includes:#permissions) ifTrue:[
+        (item permissions startsWith:$d) ifTrue:[
+            key := #directory.
+            item isDirectory:true.
+        ] ifFalse:[
+            key := MIMETypes mimeTypeForFilename:(item fileName asFilename baseName).
+            item isDirectory:false.
+        ].
+    ] ifFalse:[
+        key := MIMETypes mimeTypeForFilename:(item fileName asFilename baseName).
+    ].
+    item icon:(FileBrowser iconForKeyMatching:key).
+    ^ item
 ! !
 
 !Archiver::GZipArchive class methodsFor:'command strings'!
@@ -408,6 +509,22 @@
     ].
 ! !
 
+!Archiver::GZipArchive methodsFor:'columns'!
+
+columns
+
+    "/ columns in stream order
+    "/  colums id          words to read
+    ^ #( #(#method          1)      
+         #(#crc             1)    
+         #(#dateAndTime     3)   
+         #(#compressSize    1)  
+         #(#size            1) 
+         #(#ratio           1) 
+         #(#fileName        #rest)
+    ) 
+! !
+
 !Archiver::GZipArchive methodsFor:'command strings'!
 
 getCommandToGZip:aFile asNew:newFile
@@ -432,23 +549,31 @@
 
     tempDir := self temporaryDirectory.
     archivInTemp := tempDir construct:(archivFile baseName).
-    "/ copy files to be added to tempDir
-    colOfFiles do:[:file |
-        file recursiveCopyTo:(tempDir construct:(file asFilename baseName))
-    ].
 
     "/ copy archiv to tempDir
     archivFile copyTo:archivInTemp.
-
-    "/ addFiles to the tar archive
-    cmd := self getCommandToAdd:colOfFiles toArchive:archivInTemp.
-    self executeCommand:cmd directory:tempDir.
+    "/ keep a save copy
+    archivFile renameTo:(archivFile withSuffix:'sav').
+    [
+        "/ copy files to be added to tempDir
+        colOfFiles do:[:file |
+            file recursiveCopyTo:(tempDir construct:(file asFilename baseName))
+        ].
 
-    "/ copy tar archiv back
-    archivInTemp copyTo:(self fileName).
+        "/ addFiles to the tar archive
+        cmd := self getCommandToAdd:colOfFiles toArchive:archivInTemp.
+        self executeCommand:cmd directory:tempDir.
 
-    "/ cg: remove the tempFile
-    archivInTemp remove.
+        "/ copy tar archiv back
+        archivInTemp copyTo:archivFile.
+    ] ensure:[
+        "/ cg: remove the tempFile
+        archivInTemp remove.
+        "/ cg: remove copied files
+        colOfFiles do:[:file |
+            (tempDir construct:(file asFilename baseName)) remove.
+        ].
+    ].
 !
 
 extractFiles:aColOfFilesOrNil to:aDirectory
@@ -513,19 +638,6 @@
     self subclassResponsibility
 ! !
 
-!Archiver::TarArchive class methodsFor:'columns'!
-
-columns
-
-    "/  colums id          words to read
-    ^ #( #(#permissions     1)      
-         #(#ownerGroup      1)    
-         #(#size            1)   
-         #(#dateAndTime     2)  
-         #(#fileName        #rest)
-    ) 
-! !
-
 !Archiver::TarArchive class methodsFor:'command strings'!
 
 stringWithQuotedFileBaseNames:aColOfFiles
@@ -563,6 +675,24 @@
     ^ true
 ! !
 
+!Archiver::TarArchive methodsFor:'columns'!
+
+columns
+
+    "/  colums id          words to read
+    ^ #( #(#permissions     1)      
+         #(#ownerGroup      1)    
+         #(#size            1)   
+         #(#dateAndTime     2)  
+         #(#fileName        #rest)
+    ) 
+!
+
+isValidOutputLine:line
+    ('[-d][-r][-w][-x]' match:(line copyTo:4)) ifTrue:[^ true].
+    ^ false.
+! !
+
 !Archiver::TarArchive methodsFor:'command strings'!
 
 getCommandToAdd:aColOfFiles toArchive:archiveFile
@@ -574,7 +704,7 @@
 
     "/ 'r'  TarArchivAddOption
     "/ 'f'  TarArchivFileOption
-    stream nextPutAll:('%1 -rf "%2"' 
+    stream nextPutAll:('%1 rf "%2"' 
                     bindWith:self class tarCommand
                     with:archiveFile asString string).
 
@@ -638,13 +768,6 @@
     ^ stream contents
 ! !
 
-!Archiver::TarGZipArchive class methodsFor:'columns'!
-
-columns
-
-    ^ Archiver tarArchive columns
-! !
-
 !Archiver::TarGZipArchive class methodsFor:'queries'!
 
 canAddFiles
@@ -699,10 +822,10 @@
     tarArchiver extractFiles:aColOfFiles to:aDirectory.
 !
 
-extractFiles:aColOfFiles withOutDirectoryTo:aDirectory
+extractFiles:aColOfFiles withoutDirectoryTo:aDirectory
 
     self setCommandOptions.
-    tarArchiver extractFiles:aColOfFiles withOutDirectoryTo:aDirectory.
+    tarArchiver extractFiles:aColOfFiles withoutDirectoryTo:aDirectory.
 !
 
 listFiles:aColOfFiles
@@ -734,6 +857,16 @@
     gzipArchiver zipFile:(tarArchiver fileName) to:(self fileName).
 ! !
 
+!Archiver::TarGZipArchive methodsFor:'columns'!
+
+columns
+    ^ tarArchiver columns
+!
+
+isValidOutputLine:line
+    ^ tarArchiver isValidOutputLine:line
+! !
+
 !Archiver::TarGZipArchive methodsFor:'initialization & release'!
 
 release
@@ -742,22 +875,6 @@
     tarArchiver release.
 ! !
 
-!Archiver::ZipArchive class methodsFor:'columns'!
-
-columns
-
-    "/  colums id          words to read
-    ^ #( (#permissions     1)      
-         (#version         2)    
-         (#size            1)     
-         (#type            1)    
-         (#ratio           1)    
-         (nil              1)  
-         (#dateAndTime     2)  
-         (#fileName        #rest)
-    ) 
-! !
-
 !Archiver::ZipArchive class methodsFor:'command strings'!
 
 unzipCommand
@@ -793,8 +910,39 @@
     ^ true
 ! !
 
+!Archiver::ZipArchive methodsFor:'columns'!
+
+columns
+
+    "/  colums id          words to read
+    ^ #( (#permissions     1)      
+         (#version         2)    
+         (#size            1)     
+         (#type            1)    
+         (#ratio           1)    
+         (nil              1)  
+         (#dateAndTime     2)  
+         (#fileName        #rest)
+    ) 
+!
+
+isValidOutputLine:line
+    ('[-d][-r][-w][-x]' match:(line copyTo:4)) ifTrue:[^ true].
+    ^ false.
+! !
+
 !Archiver::ZipArchive methodsFor:'command strings'!
 
+addDoubleQuotedFilenames:collectionOfFilenames toStream:aStream
+    collectionOfFilenames notNil ifTrue:[
+        collectionOfFilenames do:[:el | 
+            aStream nextPutAll:' "'.
+            aStream nextPutAll:(el asString).
+            aStream nextPutAll:'"'
+        ].
+    ].
+!
+
 getCommandToAdd:aColOfFiles toArchive:archiveFile
     |stream|
 
@@ -806,16 +954,14 @@
                     bindWith:self class zipCommand
                     with:archiveFile asString string).
 
-    aColOfFiles do:[:el | 
-        stream nextPutAll:' "'.
-        stream nextPutAll:(el asFilename baseName).
-        stream nextPutAll:'"'
-    ].
+    self 
+        addDoubleQuotedFilenames:(aColOfFiles collect:[:each | each asFilename baseName])
+        toStream:stream.
 
     ^ stream contents
 !
 
-getCommandToExtractFiles:sel intoDirectory:dir
+getCommandToExtractFiles:aColOfFiles intoDirectory:dir
     |stream|
 
     stream := WriteStream on:''.
@@ -828,13 +974,7 @@
                     with:dir asString string
                     with:self fileName asString).
 
-    sel notNil ifTrue:[
-        sel do:[:el | 
-            stream nextPutAll:' "'.
-            stream nextPutAll:(el asString).
-            stream nextPutAll:'"'
-        ].
-    ].
+    self addDoubleQuotedFilenames:aColOfFiles toStream:stream.
     ^ stream contents.
 !
 
@@ -850,12 +990,10 @@
                         bindWith:self class unzipCommand
                         with:self fileName asString string).
 
-    aColOfFiles notNil ifTrue:[
-        aColOfFiles do:[:el | 
-            stream nextPutAll:' "'.
-            stream nextPutAll:(el baseName).
-            stream nextPutAll:'"'
-        ]
+    aColOfFiles notNil ifTrue:[       self halt.
+        self 
+            addDoubleQuotedFilenames:(aColOfFiles collect:[:each | each asFilename baseName])
+            toStream:stream.
     ].
     ^ stream contents.
 !
@@ -869,16 +1007,12 @@
                         bindWith:self class zipCommand
                         with:self fileName asString string).
 
-    aColOfFiles do:[:el | 
-        stream nextPutAll:' "'.
-        stream nextPutAll:(el asString).
-        stream nextPutAll:'"'
-    ].
+    self addDoubleQuotedFilenames:aColOfFiles toStream:stream.
     ^ stream contents.
 ! !
 
 !Archiver class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/Archiver.st,v 1.16 2003-05-16 18:16:36 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/Archiver.st,v 1.17 2003-06-12 11:20:20 cg Exp $'
 ! !