home *** CD-ROM | disk | FTP | other *** search
/ PC World 1998 October / PCWorld_1998-10_cd.bin / software / prehled / komix / DATA.Z / fstorage.tcl < prev    next >
Text File  |  1997-11-12  |  15KB  |  556 lines

  1. #---------------------------------------------------------------------------
  2. #
  3. # Copyright (c) 1993-1997 by Cayenne Software Inc.
  4. #
  5. # This software is furnished under a license and may be used only in
  6. # accordance with the terms of such license and with the inclusion of
  7. # the above copyright notice. This software or any other copies thereof
  8. # may not be provided or otherwise made available to any other person.
  9. # No title to and ownership of the software is hereby transferred.
  10. #
  11. # The information in this software is subject to change without notice
  12. # and should not be construed as a commitment by Cayenne Software Inc.
  13. #
  14. #---------------------------------------------------------------------------
  15. #
  16. #    File        : @(#)fstorage.tcl    /main/titanic/11
  17. #    Author        : frmo, Lex Warners
  18. #    Original date    : 23-2-1994
  19. #    Description    : File storage functions. The functions in this file
  20. #                         define the interface to the VCM system used to
  21. #                         store the files.
  22. #---------------------------------------------------------------------------
  23. #
  24.  
  25. # Start user added include file section
  26. global fstorage::custObjHandler
  27. set fstorage::custObjHandler ""
  28. require caynutil.tcl
  29.  
  30. # ugly but effective hack to make sure we are running in
  31. # otsh, otherwise sourcing these files may have disastrous results
  32. if [isCommand OTShRegister::check] {
  33.     require s_otsh.tcl
  34.     require vss_otsh.tcl
  35. }
  36.  
  37. global fstorage::vsFiles
  38. set fstorage::vsFiles ""
  39.  
  40. global fstorage::cacheValid
  41. set fstorage::cacheValid 0
  42. # End user added include file section
  43.  
  44. Class fstorage : {GCObject} {
  45.         constructor
  46.         method destructor
  47. }
  48.  
  49. constructor fstorage {class this} {
  50.         set this [GCObject::constructor $class $this]
  51.         # Start constructor user section
  52.         # End constructor user section
  53.         return $this
  54. }
  55.  
  56. method fstorage::destructor {this} {
  57.         # Start destructor user section
  58.         # End destructor user section
  59. }
  60.  
  61.  
  62. # internal proc that returns current system
  63. # issues error if not a system level
  64. #
  65. proc fstorage::currentSystem {} {
  66.     set clientContext [ClientContext::global]
  67.     set vsSystem [$clientContext currentSystem]
  68.  
  69.     if [$vsSystem isNil] {
  70.     error "Not at system level"
  71.     }
  72.  
  73.     return $vsSystem
  74. }
  75.  
  76. # Return a list of objects that have a type that is listed in $fileTypes
  77. # $fileTypes == {} means all file types
  78. #
  79. proc fstorage::dir {{fileTypes ""}} {
  80.     set vsSystem [fstorage::currentSystem]
  81.     
  82.     if [$vsSystem isNil] {
  83.     return
  84.     }
  85.    
  86.     global fstorage::cacheValid
  87.     global fstorage::vsFiles
  88.  
  89.     if ${fstorage::cacheValid} {
  90.     set vsFiles ${fstorage::vsFiles}
  91.     } else {
  92.     set vsFiles [$vsSystem vsFiles]
  93.         set fstorage::vsFiles $vsFiles
  94.         set fstorage::cacheValid 1
  95.     }
  96.  
  97.     set fileList ""
  98.     
  99.     foreach vsFile $vsFiles {
  100.     set fileName [$vsFile name]
  101.     set fileType [$vsFile type]
  102.     set fullName ${fileName}.${fileType}
  103.  
  104.     if {$fileTypes == ""} {
  105.         lappend fileList $fullName
  106.     } else {
  107.         foreach type $fileTypes {
  108.         if {$fileType == $type} {
  109.             lappend fileList $fullName
  110.             break;
  111.         }
  112.         }
  113.     }
  114.     }
  115.  
  116.     return $fileList
  117. }
  118.  
  119. proc fstorage::getVSFile {fileSpec} {
  120.     set vsSystem [fstorage::currentSystem]
  121.     if [$vsSystem isNil] {
  122.     return ""
  123.     }
  124.  
  125.     set fileName [nt_get_name $fileSpec]
  126.     set fileType [nt_get_type $fileSpec]
  127.  
  128.     set vsFile [$vsSystem findVSFile $fileName $fileType]
  129.     if { $vsFile == "" } {
  130.     # create VSFile object for this file
  131.     if [$vsSystem fileExists $fileName $fileType] {
  132.         set vsFile [$vsSystem importVSFile $fileName $fileType]
  133.     }
  134.     }
  135.  
  136.     return $vsFile
  137. }
  138.  
  139. # Return whether the file with the given file specification exists in the 
  140. # VCM system. file specification is in the form "name.type" where type
  141. # is a browser type.
  142.  
  143. proc fstorage::exists {fileSpec} {
  144.     set vsSystem [fstorage::currentSystem]
  145.     if [$vsSystem isNil] {
  146.     return 0
  147.     }
  148.  
  149.     set name [nt_get_name $fileSpec]
  150.     set type [nt_get_type $fileSpec]
  151.  
  152.     return [$vsSystem fileExists $name $type]
  153. }
  154.  
  155. proc fstorage::getMakeType {objType} {
  156.     return [[fstorage::getObjectSpec $objType] makeType]
  157. }
  158.  
  159. proc fstorage::getFsExtension {objType} {
  160.     set extension [[fstorage::getObjectSpec $objType] fsExtension]
  161.  
  162.     #
  163.     # Hack for persistent classes with target Gen
  164.     #
  165.  
  166.     if {$extension == "" && $objType == "esqlc++"} {
  167.         return [[fstorage::getObjectSpec c++] fsExtension]
  168.     }
  169.  
  170.     return $extension
  171. }
  172.  
  173. proc fstorage::getObjectSpec {objType} {
  174.     set vsSystem [fstorage::currentSystem]
  175.     if [$vsSystem isNil] {
  176.     return
  177.     }
  178.  
  179.     return [$vsSystem getTypeSpec $objType]
  180. }
  181.  
  182. proc fstorage::isAscii {objType} {
  183.     return [[fstorage::getObjectSpec $objType] isAscii]
  184. }
  185.  
  186. #
  187. # Open $obj for $mode. Mode is one of "r" and "w"
  188. # If $mode == w the object is created if it doesn't exist
  189.  
  190. proc fstorage::open {fileSpec {mode r} {fileClass externalText}} {
  191.     global fstoragePathCache
  192.     global fstorageObjectCache
  193.  
  194.     set vsSystem [fstorage::currentSystem]
  195.  
  196.     if [$vsSystem isNil] {
  197.     return 0
  198.     }
  199.  
  200.     set fileName [nt_get_name $fileSpec]
  201.     set fileType [nt_get_type $fileSpec]
  202.     set vsFile [$vsSystem findVSFile $fileName $fileType]
  203.  
  204.     case $mode {
  205.     r {
  206.         if { $vsFile == "" } {
  207.         # file does not exist in the repository but may exist
  208.         # in VCM system. Do an import in the latter case
  209.         if [$vsSystem fileExists $fileName $fileType] {
  210.             set vsFile [$vsSystem importVSFile $fileName $fileType]
  211.         }
  212.         if { $vsFile == "" } {
  213.             error "Unable to open file '$fileSpec' for read"
  214.             return ""
  215.         }
  216.         }
  217.  
  218.         set filePath [$vsFile getReference]
  219.         set handle [open $filePath r]
  220.         set fstorageObjectCache($handle) $vsFile
  221.         set fstoragePathCache($handle) $filePath
  222.  
  223.         return $handle
  224.     }
  225.     w {
  226.         # Create file if it does not exist
  227.         if { $vsFile == "" } {
  228.         if [$vsSystem fileExists $fileName $fileType] {
  229.             set vsFile [$vsSystem importVSFile $fileName $fileType]
  230.         } else {
  231.             set comment "Created by ObjectTeam"
  232.             set vsFile [$vsSystem createVSFile \
  233.                 $fileName $fileType "$comment"]
  234.         }
  235.         }
  236.  
  237.         if { $vsFile == "" } {
  238.         error "Creation of '$fileSpec' failed"
  239.         return ""
  240.         }
  241.  
  242.         global fstorage::cacheValid
  243.         set fstorage::cacheValid 0
  244.  
  245.         # try to check it out if it is not writable
  246.         set filePath [$vsFile path]
  247.         if { ![$vsFile isCheckedOut] } {
  248.         if {![file writable $filePath]} {
  249.             set comment "Checked out by ObjectTeam"
  250.             if {![$vsFile checkOut $comment]} {
  251.             error "Cannot obtain writable copy of '$fileSpec'"
  252.             }
  253.         } else {
  254.             # there is a writable copy but the file is not checked
  255.             # out: dangerous; let user do something about it
  256.             error "Cannot check out '$fileSpec': a writable copy exists in the user environment"
  257.         }
  258.         }
  259.  
  260.         # we have a writable copy: finish work
  261.         set handle [open $filePath w]
  262.         if { $handle == "" } {
  263.         error "Open file '$fileSpec' for write failed"
  264.         return ""
  265.         }
  266.         set fstorageObjectCache($handle) $vsFile
  267.         return $handle
  268.     }
  269.     default {
  270.         error "Invalid option '$mode' for fstorage::open"
  271.     }
  272.     }
  273. }
  274.  
  275. # Close $handle
  276. #
  277. proc fstorage::close {handle} {
  278.     global fstoragePathCache
  279.     global fstorageObjectCache
  280.  
  281.     if [info exists fstorageObjectCache($handle)] {
  282.     set vsFile $fstorageObjectCache($handle)
  283.     unset fstorageObjectCache($handle)
  284.     if [info exists fstoragePathCache($handle)] {
  285.         $vsFile deleteReference $fstoragePathCache($handle)
  286.         unset fstoragePathCache($handle)
  287.     }
  288.     } else {
  289.         puts "Warning fstorage::close called for unknown handle"
  290.     }
  291.  
  292.     close $handle
  293. }
  294.  
  295. # Return the path of $fileSpec in the "user environment"
  296. # if $is_absolute == absolute the path is absolute, else relative
  297. #
  298. proc fstorage::get_uenv_path {fullName {absolute relative}} {
  299.     set vsFile [fstorage::getVSFile $fullName]
  300.     return [fstorage::getFilePath vsFile $fullName 0 $absolute]
  301. }
  302.  
  303. # Get file system path. If the fileVersion does not exist and newFile is true a
  304. # new fileVersion is created. The absolute parameter can be set to "relative" or
  305. # "absolute" and will determine the kind of path returned.
  306. #
  307. proc fstorage::getFilePath {fileVRef {fullName ""} {newFile 0} {absolute "relative"} {fileClass "externalText"}} {
  308.     upvar $fileVRef vsFile
  309.  
  310.     set fileName [nt_get_name $fullName]
  311.     set fileType [nt_get_type $fullName]
  312.     set vsSystem [fstorage::currentSystem]
  313.     if [$vsSystem isNil] {
  314.     return ""
  315.     }
  316.  
  317.     set filePath [$vsSystem vsFileUserPath $fileName $fileType]
  318.  
  319.     if {$absolute == "absolute"} {
  320.     return $filePath
  321.     }
  322.  
  323.     # make relative path: strip path to system
  324.     set systemPath [$vsSystem path]
  325.     set relativeIndex [expr [string length $systemPath] +1]
  326.     return [string range $filePath $relativeIndex end]    
  327. }
  328.  
  329.  
  330. # Goto "system" $sys in phase $phase
  331. #
  332. proc fstorage::goto_system {sys {phase ""}} {
  333.     set clientCont [ClientContext::global]
  334.     set currentLevel [$clientCont currentLevel]
  335.     if { $currentLevel == "Project" ||  $currentLevel == "Corporate" } {
  336.         puts "invalid level: $currentLevel"
  337.         return
  338.     }
  339.  
  340.     set oldLevelPath [m4_var get M4_levelpath]
  341.     while { [$clientCont currentLevel] != "Phase" } {
  342.         $clientCont upLevel
  343.     }
  344.  
  345.     if {$phase != "" } {
  346.         $clientCont upLevel
  347.         if [catch {$clientCont downLevel $phase} msg] {
  348.         #puts $msg
  349.         $clientCont setLevelPath $oldLevelPath
  350.         return
  351.         }
  352.     }
  353.  
  354.     if [catch {$clientCont downLevel $sys} msg]  {
  355.         #puts $msg
  356.         $clientCont setLevelPath $oldLevelPath
  357.         return
  358.     }
  359. }
  360.  
  361. # Return the "Imported From" attribute from $obj
  362. #
  363. proc fstorage::get_imp_from {fileSpec} {
  364.     set vsFile [fstorage::getVSFile [path_name file $fileSpec]]
  365.  
  366.     if { $vsFile == "" } {
  367.     return ""
  368.     }
  369.  
  370.     return [$vsFile getClass]
  371. }
  372.  
  373. # Set the "Imported From" attribute of $obj to $value
  374. #
  375. proc fstorage::set_imp_from {fileSpec value} {
  376.     set vsFile [fstorage::getVSFile [path_name file $fileSpec]]
  377.  
  378.     if { $vsFile == "" } {
  379.     error "Unable to set property for '$fileSpec': it is not a file within this system"
  380.     }
  381.  
  382.     return [$vsFile setClass $value]
  383. }
  384.  
  385. # return path of object in user environment
  386. #
  387. proc fstorage::getObjectUserPath {object} {
  388.     global VSSystem
  389.     return [$VSSystem::vsObjectUserPath $object]
  390. }
  391.  
  392. # return path of object in VCM environment
  393. #
  394. proc fstorage::getObjectVSPath {object} {
  395.     global VSSystem
  396.     return [$VSSystem::vsObjectVSPath $object]
  397. }
  398.  
  399. # Remove '$fullName' from VCM system
  400. #
  401. proc fstorage::remove {fullName} {
  402.     set vsFile [fstorage::getVSFile $fullName]
  403.  
  404.     if { $vsFile == "" } {
  405.     error "Unable remove '$fullName': it is not a file within this system"
  406.     }
  407.  
  408.     $vsFile removeFromVS
  409.     global fstorage::cacheValid
  410.     set fstorage::cacheValid 0
  411. }
  412.  
  413. # Construct the path from level (read from the client-context) and subdir.
  414. # This is the user environment path
  415. proc fstorage::getFsPath {level {subDir ""} {pathType "User"}} {
  416.     set path ""
  417.     set cc [ClientContext::global]
  418.  
  419.     set errorMessage "Unknown level $level"
  420.     switch -glob $level {
  421.     corp* {
  422.         set path [m4_var get M4_home]
  423.         set errorMessage ""
  424.     }
  425.     proj* {
  426.         set proj [$cc currentProject]
  427.         if [$proj isNil] {
  428.         set errorMessage "The current level should at least be Project"
  429.         } else {
  430.         set path [fstorage::getObject${pathType}Path $proj]
  431.         set errorMessage ""
  432.         }
  433.     }
  434.     conf* {
  435.         set confV [$cc currentConfig]
  436.         if [$confV isNil] {
  437.         set errorMessage "The current level should at least be Configuration"
  438.         } else {
  439.         set path [fstorage::getObject${pathType}Path $confV]
  440.         set errorMessage ""
  441.         }
  442.     }
  443.     phase {
  444.         set phaseV [$cc currentPhase]
  445.         if [$phaseV isNil] {
  446.         set errorMessage "The current level should at least be Phase"
  447.         } else {
  448.         set path [fstorage::getObject${pathType}Path $phaseV]
  449.         set errorMessage ""
  450.         }
  451.     }
  452.     system {
  453.         set systemV [$cc currentSystem]
  454.         if [$systemV isNil] {
  455.         set errorMessage "The current level should at least be System"
  456.         } else {
  457.         set path [fstorage::getObject${pathType}Path $systemV]
  458.         set errorMessage ""
  459.         }
  460.     }
  461.     }
  462.     if {$errorMessage != ""} {
  463.     puts stderr $errorMessage
  464.     return ""
  465.     }
  466.  
  467.     return [path_name concat $path $subDir]
  468. }
  469.  
  470.  
  471. # Copy a file to a certain directory, if this directory does not exist 
  472. # the directory is created. (Returns the complete filePathName).
  473. #
  474. proc fstorage::copyFile {fromFilePath toLevel toSubDir toFileName} {
  475.     global VSSystem
  476.     set toDirUserPath [fstorage::getFsPath $toLevel $toSubDir]
  477.     set toDirVSPath [fstorage::getFsPath $toLevel $toSubDir "VS"]
  478.  
  479.     # create paths if necessary
  480.     if { ![$VSSystem::createUserPath $toDirUserPath] } {
  481.     return ""
  482.     }
  483.     if { ![$VSSystem::createVSPath $toDirVSPath] } {
  484.     return ""
  485.     }
  486.  
  487.     # get an object for the file 
  488.     set toFilePath [path_name concat $toDirUserPath $toFileName]
  489.     set toFileVSPath [path_name concat $toDirVSPath $toFileName]
  490.     set vsFile [$VSSystem::getFileObject $toFilePath $toFileVSPath]
  491.     if { $vsFile == "" } {
  492.     return ""
  493.     }
  494.  
  495.     set mustCopy 1
  496.     # compare file if they existed already
  497.     if [$vsFile existsInVS] {
  498.     set vsRef [$vsFile getReference]
  499.     if [catch {set fromDesc [open $fromFilePath r]}] {
  500.         $vsFile deleteReference $vsRef
  501.         return ""
  502.     }
  503.     if [catch {set toDesc [open $vsRef r]}] {
  504.         $vsFile deleteReference $vsRef
  505.         if { $fromDesc != "" } {
  506.         close $fromDesc
  507.         return ""
  508.         }
  509.     }
  510.     if { ($fromDesc == "") || ($toDesc == "") } {
  511.         $vsFile deleteReference $vsRef
  512.         if { $fromDesc != "" } {
  513.         close $fromDesc
  514.         }
  515.         if { $toDesc != "" } {
  516.         close $toDesc
  517.         }
  518.     }
  519.     if { ![string compare [read $fromDesc] [read $toDesc]] } {
  520.         set mustCopy 0
  521.         puts "Skipping $toFilePath: already installed"
  522.     }
  523.     close $fromDesc
  524.     close $toDesc
  525.     $vsFile deleteReference $vsRef
  526.     } else {
  527.     if {![$vsFile createInVS {"Installed by ObjectTeam"}] } {
  528.         return ""
  529.     }
  530.     }
  531.  
  532.     if $mustCopy {
  533.     set canCopy 1
  534.     if { ![$vsFile isCheckedOut] } {
  535.         if {![file writable $toFilePath]} {
  536.         set comment "Checked out by ObjectTeam"
  537.         if {![$vsFile checkOut $comment]} {
  538.             puts "Cannot obtain writable copy of '$toFileName'"
  539.             set canCopy 0
  540.         }
  541.         } else {
  542.         puts "Cannot check out '$toFileName': a writable copy exists in the user environment"
  543.         set canCopy 0
  544.         }
  545.     }
  546.     if $canCopy {
  547.         BasicFS::copyFile $fromFilePath $toFilePath
  548.         return $toFilePath
  549.     }
  550.     }
  551.     return ""
  552. }
  553.  
  554. # Do not delete this line -- regeneration end marker
  555.