Save a system call in #remove.
authorStefan Vogel <sv@exept.de>
Wed, 09 Feb 2005 14:17:10 +0100
changeset 8738 4c100f8830b1
parent 8737 8ddb74dc1833
child 8739 ddfd4829a6c3
Save a system call in #remove. Common ConcreteClass delegation.
Filename.st
--- a/Filename.st	Wed Feb 09 13:37:13 2005 +0100
+++ b/Filename.st	Wed Feb 09 14:17:10 2005 +0100
@@ -46,19 +46,19 @@
     for being correct or existing.
     Thus, it is possible to do queries such as:
 
-	'/fee/foo/foe' asFilename exists     
-	'/not_existing' asFilename isDirectory 
-	'/foo/bar' asFilename isReadable 
+        '/fee/foo/foe' asFilename exists     
+        '/not_existing' asFilename isDirectory 
+        '/foo/bar' asFilename isReadable 
 
     (all of the above examples will probably return false on your machine ;-).
 
     examples:
 
-	'Makefile' asFilename readStream
-
-	'newFile' asFilename writeStream
-
-	Filename newTemporary writeStream
+        'Makefile' asFilename readStream
+
+        'newFile' asFilename writeStream
+
+        Filename newTemporary writeStream
 
     Beside lots of protocol to query for a files attributes, the class
     protocol offers methods for filename completion, to construct pathes
@@ -67,14 +67,21 @@
     recommended in order to avoid having OS details (like directory separators
     being slash or backslash) spreaded in your application.
 
+    Since Filenames have different semantics under different operating systems,
+    class methods are delegated to concrete implementations in various subclasses like
+    UnixFilename, PCFilename, ...
+    The delegation is implemented in a way, so that some methods of
+    specific OS Filenames might be used, even if ST/X is currently running 
+    on a different OS (as long as the method does not depend on the OperatingSystem class).
+
     [author:]
-	Claus Gittinger
+        Claus Gittinger
 
     [see also:]
-	String
-	FileStream DirectoryStream PipeStream Socket
-	OperatingSystem
-	Date Time
+        String
+        FileStream DirectoryStream PipeStream Socket
+        OperatingSystem
+        Date Time
 "
 !
 
@@ -216,7 +223,7 @@
 initialize
     "initialize for the OS we are running on"
 
-    ConcreteClass isNil ifTrue:[
+    (ConcreteClass isNil or:[ConcreteClass == Filename]) ifTrue:[
         self initializeConcreteClass
     ].
 
@@ -231,17 +238,18 @@
     "initialize for the OS we are running on"
 
     OperatingSystem isMSDOSlike ifTrue:[
-	ConcreteClass := PCFilename
+        ConcreteClass := PCFilename
     ] ifFalse:[
-	OperatingSystem isVMSlike ifTrue:[
-	    ConcreteClass := OpenVMSFilename
-	] ifFalse:[
-	    OperatingSystem isUNIXlike ifTrue:[
-		ConcreteClass := UnixFilename
-	    ] ifFalse:[
-		ConcreteClass := nil
-	    ]
-	]
+        OperatingSystem isVMSlike ifTrue:[
+            ConcreteClass := OpenVMSFilename
+        ] ifFalse:[
+            OperatingSystem isUNIXlike ifTrue:[
+                ConcreteClass := UnixFilename
+            ] ifFalse:[
+                "Fall back. I can handle the common cases"
+                ConcreteClass := self
+            ]
+        ]
     ]
 
     "
@@ -252,7 +260,7 @@
 !
 
 reinitialize
-    "initialize for the OS we are running on"
+    "initialize for the OS we are running on (after a restart)"
 
     self initializeConcreteClass
 
@@ -268,7 +276,7 @@
 currentDirectory
     "return a filename for the current directory"
 
-    (self ~~ ConcreteClass) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass currentDirectory
     ].
 
@@ -287,7 +295,7 @@
 currentDirectoryName
     "return a filename for the current directory"
 
-    (self ~~ ConcreteClass) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass currentDirectoryName
     ].
 
@@ -336,7 +344,7 @@
      aCollectionOfDirectoryNames. If the first component is the name of the
      root directory (i.e. '/') an absolute path-filename is returned."
 
-    (self == Filename) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass fromComponents:aCollectionOfDirectoryNames
     ].
 
@@ -364,12 +372,12 @@
     |name|
 
     name := Dialog 
-	requestFileName:'filename:' 
-	default:nil
-	fromDirectory:(FileSelectionBox lastFileSelectionDirectory).
-
-    name size > 0 ifTrue:[
-	^ self named:name
+        requestFileName:'filename:' 
+        default:nil
+        fromDirectory:(FileSelectionBox lastFileSelectionDirectory).
+
+    name notEmptyOrNil ifTrue:[
+        ^ self named:name
     ].
     ^ nil
 
@@ -404,13 +412,10 @@
     "return a filename for a directory named aString.
      This is the same as 'aString asFilename'."
 
-    |cls|
-
-    cls := self.
-    cls == Filename ifTrue:[
-        ^ self concreteClass named:aString
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
+        ^ ConcreteClass named:aString
     ].
-    ^ (cls basicNew) setName:aString
+    ^ self basicNew setName:aString
 
     "
      Filename named:'/tmp/fooBar'
@@ -429,7 +434,7 @@
      Notice, that no file is created by this - only a unique name
      is generated."
 
-    ^ self newTemporaryIn:(self tempDirectory) pathName
+    ^ self newTemporaryIn:self tempDirectory
 
     "
      Filename newTemporary    
@@ -488,36 +493,37 @@
      whatever to it in order to really create something).
      See also: #newTemporary which looks for a good temp directory."
 
-    |pid nameString fn|
-
-    (self == Filename) ifTrue:[
+    |nameString newTempFilename|
+
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass newTemporaryIn:aDirectoryPrefix nameTemplate:template
     ].
 
-    "/ care for existing leftOver tempFiles
-    "/ from a previous boot of the OS
-    "/ (i.e. my pid could be the same as when executed
-    "/  the last time before system reboot ...)
-
-    [fn isNil or:[fn exists]] whileTrue:[
-        "/ although the above allows things to be redefined in concrete classes,
-        "/ the following should work on all systems ...
-
-        NextTempFilenameIndex isNil ifTrue:[
-            NextTempFilenameIndex := 1.
-        ].
-
-        pid := OperatingSystem getProcessId printString.
-        nameString := template bindWith:pid with:(NextTempFilenameIndex printString).
+    "although the above allows things to be redefined in concrete classes,
+     the following should work on all systems ..."
+
+    NextTempFilenameIndex isNil ifTrue:[
+        NextTempFilenameIndex := 1.
+    ].
+
+    [
+        nameString := template bindWith:OperatingSystem getProcessId with:NextTempFilenameIndex.
         NextTempFilenameIndex := NextTempFilenameIndex + 1.
 
         (aDirectoryPrefix isNil or:[aDirectoryPrefix asString isEmpty]) ifFalse:[
-            fn := aDirectoryPrefix asFilename construct:nameString
+            newTempFilename := aDirectoryPrefix asFilename construct:nameString
         ] ifTrue:[
-            fn := self named:nameString
+            newTempFilename := self named:nameString
         ]
+    ] doWhile:[
+        "care for existing leftOver tempFiles
+         from a previous boot of the OS
+         i.e. my pid could be the same as when executed
+         the last time before system reboot ...)"
+
+        newTempFilename exists
     ].
-    ^ fn
+    ^ newTempFilename
 
     "temp files in '/tmp':
 
@@ -569,7 +575,7 @@
      aCollectionOfDirectoryNames on a host named remoteHostString. 
      An absolute network-filename is returned."
 
-    self == Filename ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass remoteHost:remoteHostString 
                         rootComponents:aCollectionOfDirectoryNames
     ].
@@ -584,7 +590,7 @@
 
     |sep s|
 
-    (self == Filename) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass rootComponents:aCollectionOfDirectoryNames
     ].
 
@@ -619,7 +625,7 @@
 rootDirectory
     "return a filename for the root directory"
 
-    (self == Filename) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass rootDirectory
     ].
 
@@ -637,7 +643,7 @@
 rootDirectoryOnVolume:aVolumeName
     "return a filename for the root directory on some volume"
 
-    (self == Filename) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass rootDirectoryOnVolume:aVolumeName
     ].
 
@@ -670,16 +676,17 @@
         tempDir isNil ifTrue:[
             tempDir := OperatingSystem getEnvironment:envVar.
             tempDir notNil ifTrue:[
-                tempDir asFilename exists ifFalse:[
+                tempDir := self named:tempDir.
+                tempDir exists ifFalse:[
                     tempDir := nil.
                 ].
             ].
         ].
     ].
     tempDir isNil ifTrue:[
-        tempDir := self defaultTempDirectoryName
+        tempDir := self named:self defaultTempDirectoryName
     ].
-    ^ self named:tempDir
+    ^ tempDir
 
     "
      Filename tempDirectory           
@@ -721,8 +728,8 @@
      This is used, if no special preferences were defined in
      any of the TEMP-environment variables (see tempDirectory)."
 
-    (self ~~ ConcreteClass) ifTrue:[
-	^ ConcreteClass defaultTempDirectoryName
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
+        ^ ConcreteClass defaultTempDirectoryName
     ].
 
     ^ '/tmp'
@@ -817,7 +824,7 @@
 
     |sep f vol rest components|
 
-    (self == Filename) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass components:aString
     ].
 
@@ -879,7 +886,7 @@
     "Return the OS dependent directory suffix string, or nil if there is none.
      The default is nil here, redefined for VMS"
 
-    (self == Filename) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass directorySuffix
     ].
 
@@ -904,7 +911,7 @@
      (this may be different from the inDirectory argument, if aString is absolute
       or starts with ../)"
 
-    (self ~~ ConcreteClass) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass 
             filenameCompletionFor:aString 
             directory:inDirectory       
@@ -1022,8 +1029,8 @@
 
     |basePattern dir d files|
 
-    (self ~~ ConcreteClass) ifTrue:[
-	^ ConcreteClass filesMatching:aPattern
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
+        ^ ConcreteClass filesMatching:aPattern
     ].
 
     "/ the following works on Unix & MSDOS (but not on openVMS)
@@ -1047,7 +1054,7 @@
 isBadCharacter:aCharacter
     "return true, if aCharacter is unallowed in a filename."
 
-    (self == Filename) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass isBadCharacter:aCharacter
     ].
 
@@ -1058,7 +1065,7 @@
     "return true, if filenames are case sensitive.
      We ask the OS about this, to be independent here."
 
-    (self == Filename) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass isCaseSensitive
     ].
 
@@ -1075,7 +1082,7 @@
 
     |sep|
 
-    (self == Filename) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass localNameStringFrom:aString
     ].
 
@@ -1093,7 +1100,7 @@
     "return the maximum number of characters a filename component may
      be in size. This depends on the OperatingSystem."
 
-    (self == Filename) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass maxComponentLength
     ].
     ^ OperatingSystem maxFileNameLength
@@ -1103,7 +1110,7 @@
     "return the maximum number of characters a filename may be in size.
      This depends on the OperatingSystem."
 
-    (self == Filename) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass maxLength
     ].
     ^ OperatingSystem maxPathLength
@@ -1116,7 +1123,7 @@
     "Return the OS dependent filename for /dev/null, or nil if there is none.
      The default is nil here"
 
-    (self == Filename) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass nullFilename
     ].
 
@@ -1130,7 +1137,7 @@
      This is '..' for unix and dos-like systems. 
      (there may be more in the future."
 
-    (self == Filename) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass parentDirectoryName
     ].
 
@@ -1149,7 +1156,7 @@
      the following default usually leads to a flat view of
      the fileSystem (huh - BS2000 ?)"
 
-    (self == Filename) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
        ^ ConcreteClass separator
     ].
     ^ $_
@@ -1191,7 +1198,7 @@
      This is expanded with the current processID and a sequenceNumber
      to generate a unique filename."
 
-    (self == Filename) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass tempFileNameTemplate
     ].
 
@@ -1206,7 +1213,7 @@
      GUESS: does it return the available drives on MSDOS systems ?
      Q: what does this do on Unix systems ? (used in FileNavigator-goody)."
 
-    (self ~~ ConcreteClass) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass volumes
     ].
 
@@ -1226,7 +1233,7 @@
 
     |sep s|
 
-    (self == Filename) ifTrue:[
+    (self == Filename and:[self ~~ ConcreteClass]) ifTrue:[
         ^ ConcreteClass nameFromComponents:aCollectionOfDirectoryNames
     ].
 
@@ -2709,8 +2716,7 @@
 
     |ok|
 
-
-    (self isSymbolicLink not and:[self isDirectory]) ifTrue:[
+    (self linkInfo isDirectory) ifTrue:[
         ok := OperatingSystem removeDirectory:(self osNameForFile)
     ] ifFalse:[
         ok := OperatingSystem removeFile:(self osNameForFile)
@@ -2729,9 +2735,8 @@
     "
      'foo' asFilename makeDirectory.
      'foo/bar' asFilename writeStream close.
-     ('foo' asFilename remove) ifFalse:[
-        Transcript showCR:'could not remove foo'
-     ]
+     'foo' asFilename remove.   'expect an exception'
+     'foo' asFilename recursiveRemove.   
     "
 
     "Modified: / 20.11.1997 / 17:40:22 / stefan"
@@ -2780,12 +2785,10 @@
      Use #remove if it is not known if the receiver is a directory or file.
      Use #recursiveRemove in order to (recursively) remove non empty directories."
 
-    |ok|
-
-    ok := OperatingSystem removeFile:(self osNameForFile).
-    ok ifFalse:[
-	self exists ifFalse:[ ^ self].
-	self removeError:self
+    (OperatingSystem removeFile:self osNameForFile) ifFalse:[
+        self exists ifTrue:[
+            self removeError:self
+        ].
     ].
 
     "
@@ -5038,7 +5041,7 @@
 !Filename class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Filename.st,v 1.285 2005-01-14 11:22:53 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Filename.st,v 1.286 2005-02-09 13:17:10 stefan Exp $'
 ! !
 
 Filename initialize!