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 >
Wrap
Text File
|
1997-11-12
|
15KB
|
556 lines
#---------------------------------------------------------------------------
#
# Copyright (c) 1993-1997 by Cayenne Software Inc.
#
# This software is furnished under a license and may be used only in
# accordance with the terms of such license and with the inclusion of
# the above copyright notice. This software or any other copies thereof
# may not be provided or otherwise made available to any other person.
# No title to and ownership of the software is hereby transferred.
#
# The information in this software is subject to change without notice
# and should not be construed as a commitment by Cayenne Software Inc.
#
#---------------------------------------------------------------------------
#
# File : @(#)fstorage.tcl /main/titanic/11
# Author : frmo, Lex Warners
# Original date : 23-2-1994
# Description : File storage functions. The functions in this file
# define the interface to the VCM system used to
# store the files.
#---------------------------------------------------------------------------
#
# Start user added include file section
global fstorage::custObjHandler
set fstorage::custObjHandler ""
require caynutil.tcl
# ugly but effective hack to make sure we are running in
# otsh, otherwise sourcing these files may have disastrous results
if [isCommand OTShRegister::check] {
require s_otsh.tcl
require vss_otsh.tcl
}
global fstorage::vsFiles
set fstorage::vsFiles ""
global fstorage::cacheValid
set fstorage::cacheValid 0
# End user added include file section
Class fstorage : {GCObject} {
constructor
method destructor
}
constructor fstorage {class this} {
set this [GCObject::constructor $class $this]
# Start constructor user section
# End constructor user section
return $this
}
method fstorage::destructor {this} {
# Start destructor user section
# End destructor user section
}
# internal proc that returns current system
# issues error if not a system level
#
proc fstorage::currentSystem {} {
set clientContext [ClientContext::global]
set vsSystem [$clientContext currentSystem]
if [$vsSystem isNil] {
error "Not at system level"
}
return $vsSystem
}
# Return a list of objects that have a type that is listed in $fileTypes
# $fileTypes == {} means all file types
#
proc fstorage::dir {{fileTypes ""}} {
set vsSystem [fstorage::currentSystem]
if [$vsSystem isNil] {
return
}
global fstorage::cacheValid
global fstorage::vsFiles
if ${fstorage::cacheValid} {
set vsFiles ${fstorage::vsFiles}
} else {
set vsFiles [$vsSystem vsFiles]
set fstorage::vsFiles $vsFiles
set fstorage::cacheValid 1
}
set fileList ""
foreach vsFile $vsFiles {
set fileName [$vsFile name]
set fileType [$vsFile type]
set fullName ${fileName}.${fileType}
if {$fileTypes == ""} {
lappend fileList $fullName
} else {
foreach type $fileTypes {
if {$fileType == $type} {
lappend fileList $fullName
break;
}
}
}
}
return $fileList
}
proc fstorage::getVSFile {fileSpec} {
set vsSystem [fstorage::currentSystem]
if [$vsSystem isNil] {
return ""
}
set fileName [nt_get_name $fileSpec]
set fileType [nt_get_type $fileSpec]
set vsFile [$vsSystem findVSFile $fileName $fileType]
if { $vsFile == "" } {
# create VSFile object for this file
if [$vsSystem fileExists $fileName $fileType] {
set vsFile [$vsSystem importVSFile $fileName $fileType]
}
}
return $vsFile
}
# Return whether the file with the given file specification exists in the
# VCM system. file specification is in the form "name.type" where type
# is a browser type.
proc fstorage::exists {fileSpec} {
set vsSystem [fstorage::currentSystem]
if [$vsSystem isNil] {
return 0
}
set name [nt_get_name $fileSpec]
set type [nt_get_type $fileSpec]
return [$vsSystem fileExists $name $type]
}
proc fstorage::getMakeType {objType} {
return [[fstorage::getObjectSpec $objType] makeType]
}
proc fstorage::getFsExtension {objType} {
set extension [[fstorage::getObjectSpec $objType] fsExtension]
#
# Hack for persistent classes with target Gen
#
if {$extension == "" && $objType == "esqlc++"} {
return [[fstorage::getObjectSpec c++] fsExtension]
}
return $extension
}
proc fstorage::getObjectSpec {objType} {
set vsSystem [fstorage::currentSystem]
if [$vsSystem isNil] {
return
}
return [$vsSystem getTypeSpec $objType]
}
proc fstorage::isAscii {objType} {
return [[fstorage::getObjectSpec $objType] isAscii]
}
#
# Open $obj for $mode. Mode is one of "r" and "w"
# If $mode == w the object is created if it doesn't exist
#
proc fstorage::open {fileSpec {mode r} {fileClass externalText}} {
global fstoragePathCache
global fstorageObjectCache
set vsSystem [fstorage::currentSystem]
if [$vsSystem isNil] {
return 0
}
set fileName [nt_get_name $fileSpec]
set fileType [nt_get_type $fileSpec]
set vsFile [$vsSystem findVSFile $fileName $fileType]
case $mode {
r {
if { $vsFile == "" } {
# file does not exist in the repository but may exist
# in VCM system. Do an import in the latter case
if [$vsSystem fileExists $fileName $fileType] {
set vsFile [$vsSystem importVSFile $fileName $fileType]
}
if { $vsFile == "" } {
error "Unable to open file '$fileSpec' for read"
return ""
}
}
set filePath [$vsFile getReference]
set handle [open $filePath r]
set fstorageObjectCache($handle) $vsFile
set fstoragePathCache($handle) $filePath
return $handle
}
w {
# Create file if it does not exist
if { $vsFile == "" } {
if [$vsSystem fileExists $fileName $fileType] {
set vsFile [$vsSystem importVSFile $fileName $fileType]
} else {
set comment "Created by ObjectTeam"
set vsFile [$vsSystem createVSFile \
$fileName $fileType "$comment"]
}
}
if { $vsFile == "" } {
error "Creation of '$fileSpec' failed"
return ""
}
global fstorage::cacheValid
set fstorage::cacheValid 0
# try to check it out if it is not writable
set filePath [$vsFile path]
if { ![$vsFile isCheckedOut] } {
if {![file writable $filePath]} {
set comment "Checked out by ObjectTeam"
if {![$vsFile checkOut $comment]} {
error "Cannot obtain writable copy of '$fileSpec'"
}
} else {
# there is a writable copy but the file is not checked
# out: dangerous; let user do something about it
error "Cannot check out '$fileSpec': a writable copy exists in the user environment"
}
}
# we have a writable copy: finish work
set handle [open $filePath w]
if { $handle == "" } {
error "Open file '$fileSpec' for write failed"
return ""
}
set fstorageObjectCache($handle) $vsFile
return $handle
}
default {
error "Invalid option '$mode' for fstorage::open"
}
}
}
# Close $handle
#
proc fstorage::close {handle} {
global fstoragePathCache
global fstorageObjectCache
if [info exists fstorageObjectCache($handle)] {
set vsFile $fstorageObjectCache($handle)
unset fstorageObjectCache($handle)
if [info exists fstoragePathCache($handle)] {
$vsFile deleteReference $fstoragePathCache($handle)
unset fstoragePathCache($handle)
}
} else {
puts "Warning fstorage::close called for unknown handle"
}
close $handle
}
# Return the path of $fileSpec in the "user environment"
# if $is_absolute == absolute the path is absolute, else relative
#
proc fstorage::get_uenv_path {fullName {absolute relative}} {
set vsFile [fstorage::getVSFile $fullName]
return [fstorage::getFilePath vsFile $fullName 0 $absolute]
}
# Get file system path. If the fileVersion does not exist and newFile is true a
# new fileVersion is created. The absolute parameter can be set to "relative" or
# "absolute" and will determine the kind of path returned.
#
proc fstorage::getFilePath {fileVRef {fullName ""} {newFile 0} {absolute "relative"} {fileClass "externalText"}} {
upvar $fileVRef vsFile
set fileName [nt_get_name $fullName]
set fileType [nt_get_type $fullName]
set vsSystem [fstorage::currentSystem]
if [$vsSystem isNil] {
return ""
}
set filePath [$vsSystem vsFileUserPath $fileName $fileType]
if {$absolute == "absolute"} {
return $filePath
}
# make relative path: strip path to system
set systemPath [$vsSystem path]
set relativeIndex [expr [string length $systemPath] +1]
return [string range $filePath $relativeIndex end]
}
# Goto "system" $sys in phase $phase
#
proc fstorage::goto_system {sys {phase ""}} {
set clientCont [ClientContext::global]
set currentLevel [$clientCont currentLevel]
if { $currentLevel == "Project" || $currentLevel == "Corporate" } {
puts "invalid level: $currentLevel"
return
}
set oldLevelPath [m4_var get M4_levelpath]
while { [$clientCont currentLevel] != "Phase" } {
$clientCont upLevel
}
if {$phase != "" } {
$clientCont upLevel
if [catch {$clientCont downLevel $phase} msg] {
#puts $msg
$clientCont setLevelPath $oldLevelPath
return
}
}
if [catch {$clientCont downLevel $sys} msg] {
#puts $msg
$clientCont setLevelPath $oldLevelPath
return
}
}
# Return the "Imported From" attribute from $obj
#
proc fstorage::get_imp_from {fileSpec} {
set vsFile [fstorage::getVSFile [path_name file $fileSpec]]
if { $vsFile == "" } {
return ""
}
return [$vsFile getClass]
}
# Set the "Imported From" attribute of $obj to $value
#
proc fstorage::set_imp_from {fileSpec value} {
set vsFile [fstorage::getVSFile [path_name file $fileSpec]]
if { $vsFile == "" } {
error "Unable to set property for '$fileSpec': it is not a file within this system"
}
return [$vsFile setClass $value]
}
# return path of object in user environment
#
proc fstorage::getObjectUserPath {object} {
global VSSystem
return [$VSSystem::vsObjectUserPath $object]
}
# return path of object in VCM environment
#
proc fstorage::getObjectVSPath {object} {
global VSSystem
return [$VSSystem::vsObjectVSPath $object]
}
# Remove '$fullName' from VCM system
#
proc fstorage::remove {fullName} {
set vsFile [fstorage::getVSFile $fullName]
if { $vsFile == "" } {
error "Unable remove '$fullName': it is not a file within this system"
}
$vsFile removeFromVS
global fstorage::cacheValid
set fstorage::cacheValid 0
}
# Construct the path from level (read from the client-context) and subdir.
# This is the user environment path
proc fstorage::getFsPath {level {subDir ""} {pathType "User"}} {
set path ""
set cc [ClientContext::global]
set errorMessage "Unknown level $level"
switch -glob $level {
corp* {
set path [m4_var get M4_home]
set errorMessage ""
}
proj* {
set proj [$cc currentProject]
if [$proj isNil] {
set errorMessage "The current level should at least be Project"
} else {
set path [fstorage::getObject${pathType}Path $proj]
set errorMessage ""
}
}
conf* {
set confV [$cc currentConfig]
if [$confV isNil] {
set errorMessage "The current level should at least be Configuration"
} else {
set path [fstorage::getObject${pathType}Path $confV]
set errorMessage ""
}
}
phase {
set phaseV [$cc currentPhase]
if [$phaseV isNil] {
set errorMessage "The current level should at least be Phase"
} else {
set path [fstorage::getObject${pathType}Path $phaseV]
set errorMessage ""
}
}
system {
set systemV [$cc currentSystem]
if [$systemV isNil] {
set errorMessage "The current level should at least be System"
} else {
set path [fstorage::getObject${pathType}Path $systemV]
set errorMessage ""
}
}
}
if {$errorMessage != ""} {
puts stderr $errorMessage
return ""
}
return [path_name concat $path $subDir]
}
# Copy a file to a certain directory, if this directory does not exist
# the directory is created. (Returns the complete filePathName).
#
proc fstorage::copyFile {fromFilePath toLevel toSubDir toFileName} {
global VSSystem
set toDirUserPath [fstorage::getFsPath $toLevel $toSubDir]
set toDirVSPath [fstorage::getFsPath $toLevel $toSubDir "VS"]
# create paths if necessary
if { ![$VSSystem::createUserPath $toDirUserPath] } {
return ""
}
if { ![$VSSystem::createVSPath $toDirVSPath] } {
return ""
}
# get an object for the file
set toFilePath [path_name concat $toDirUserPath $toFileName]
set toFileVSPath [path_name concat $toDirVSPath $toFileName]
set vsFile [$VSSystem::getFileObject $toFilePath $toFileVSPath]
if { $vsFile == "" } {
return ""
}
set mustCopy 1
# compare file if they existed already
if [$vsFile existsInVS] {
set vsRef [$vsFile getReference]
if [catch {set fromDesc [open $fromFilePath r]}] {
$vsFile deleteReference $vsRef
return ""
}
if [catch {set toDesc [open $vsRef r]}] {
$vsFile deleteReference $vsRef
if { $fromDesc != "" } {
close $fromDesc
return ""
}
}
if { ($fromDesc == "") || ($toDesc == "") } {
$vsFile deleteReference $vsRef
if { $fromDesc != "" } {
close $fromDesc
}
if { $toDesc != "" } {
close $toDesc
}
}
if { ![string compare [read $fromDesc] [read $toDesc]] } {
set mustCopy 0
puts "Skipping $toFilePath: already installed"
}
close $fromDesc
close $toDesc
$vsFile deleteReference $vsRef
} else {
if {![$vsFile createInVS {"Installed by ObjectTeam"}] } {
return ""
}
}
if $mustCopy {
set canCopy 1
if { ![$vsFile isCheckedOut] } {
if {![file writable $toFilePath]} {
set comment "Checked out by ObjectTeam"
if {![$vsFile checkOut $comment]} {
puts "Cannot obtain writable copy of '$toFileName'"
set canCopy 0
}
} else {
puts "Cannot check out '$toFileName': a writable copy exists in the user environment"
set canCopy 0
}
}
if $canCopy {
BasicFS::copyFile $fromFilePath $toFilePath
return $toFilePath
}
}
return ""
}
# Do not delete this line -- regeneration end marker