Fixed JavaClass>>fileOutAs:
authorJan Vrany <jan.vrany@fit.cvut.cz>
Mon, 11 Aug 2014 01:19:19 +0100
changeset 3215 1f63ee2cdd97
parent 3214 c38fcee7b0da
child 3216 1d977d2d3abb
Fixed JavaClass>>fileOutAs:
JavaClass.st
--- a/JavaClass.st	Fri Aug 08 11:02:10 2014 +0100
+++ b/JavaClass.st	Mon Aug 11 01:19:19 2014 +0100
@@ -1520,6 +1520,118 @@
     "Created: 22.3.1997 / 14:35:43 / cg"
 !
 
+fileOutAs:filenameString
+    "create a file consisting of all methods in myself in
+     sourceForm, from which the class can be reconstructed (by filing in).
+     The given fileName should be a full path, including suffix.
+     Care is taken, to not clobber any existing file in
+     case of errors (for example: disk full).
+     Also, since the classes methods need a valid sourcefile, the current
+     sourceFile may not be rewritten."
+
+    |filename fileExists needRename sameFile s mySourceFileID anySourceRef outStream savFilename|
+
+    self isLoaded ifFalse:[
+        ^ FileOutErrorSignal
+            raiseRequestWith:self
+                 errorString:' - will not fileOut unloaded class: ', self name
+    ].
+
+    filename := filenameString asFilename.
+
+    "
+     if file exists, copy the existing to a .sav-file,
+     create the new file as XXX.new-file,
+     and, if that worked rename afterwards ...
+    "
+    [
+        fileExists := filename exists.
+        fileExists ifTrue:[
+            sameFile := false.
+
+            "/ check carefully - maybe, my source does not really come from that
+            "/ file (i.e. all of my methods have their source as string)
+
+            anySourceRef := sourceString isNil.
+
+            anySourceRef ifTrue:[
+                s := self sourceStream.
+                s notNil ifTrue:[
+                    OperatingSystem isUNIXlike ifTrue:[
+                        mySourceFileID := s pathName asFilename info id.
+                        sameFile := (filename info id) == mySourceFileID.
+                    ] ifFalse:[
+                        mySourceFileID := s pathName asFilename asAbsoluteFilename.
+                        sameFile := (filename asFilename asAbsoluteFilename) = mySourceFileID.
+                    ].
+                    s close.
+                ] ifFalse:[  
+                    sameFile := false.
+                ].
+            ].
+
+            sameFile ifTrue:[
+                ^ FileOutErrorSignal
+                    raiseRequestWith:filenameString
+                    errorString:(' - may not overwrite sourcefile: %1\try again after loading sources in the browser' withCRs bindWith:filenameString)
+            ].
+
+            outStream := FileStream newTemporaryIn:filename directory.
+            outStream fileName accessRights:filename accessRights.
+            needRename := true
+        ] ifFalse:[
+            "/ another possible trap: if my sourceFileName is
+            "/ the same as the written one AND the new files directory
+            "/ is along the sourcePath, we also need a temporary file
+            "/ first, to avoid accessing the newly written file.
+
+            self instAndClassMethodsDo:[:m |
+                |mSrc mSrcFilename|
+
+                (anySourceRef isNil and:[(mSrc := m sourceFilename) notNil]) ifTrue:[
+                    mSrcFilename := mSrc asFilename.
+                    (mSrcFilename baseName = filename baseName 
+                     and:[mSrcFilename exists]) ifTrue:[
+                        anySourceRef := mSrcFilename.
+                    ]
+                ]
+            ].
+            anySourceRef notNil ifTrue:[
+                outStream := FileStream newTemporaryIn:filename directory.
+                outStream fileName accessRights:anySourceRef accessRights.
+                needRename := true
+            ] ifFalse:[
+                outStream := filename writeStream.
+                needRename := false
+            ]
+        ].
+    ] on:FileStream openErrorSignal do:[:ex|
+        ^ FileOutErrorSignal
+                raiseRequestWith:filename name
+                errorString:(' - cannot create file:', filename name)
+    ].
+    self fileOutOn:outStream.
+    outStream syncData; close.
+
+    "
+     finally, replace the old-file
+     be careful, if the old one is a symbolic link; in this case,
+     we have to do a copy ...
+    "
+    needRename ifTrue:[
+        fileExists ifTrue:[
+            savFilename := filename addSuffix:'.sav~'.
+            filename renameTo:savFilename.
+        ].
+        outStream fileName renameTo:filename.
+        fileExists ifTrue:[
+            savFilename delete.
+        ].
+    ].
+
+    "Created: / 08-08-2014 / 21:41:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 fileOutInto: directory 
     "writes itself into the given directory including package hierarchy"