home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 1998 October
/
PCWorld_1998-10_cd.bin
/
software
/
prehled
/
komix
/
DATA.Z
/
modelcheck.tcl
< prev
next >
Wrap
Text File
|
1997-09-05
|
15KB
|
587 lines
#---------------------------------------------------------------------------
#
# (c) Cayenne Software Inc. 1997
#
# File: @(#)modelcheck.tcl /main/titanic/9
# Author: <generated>
# Description:
#---------------------------------------------------------------------------
# SccsId = @(#)modelcheck.tcl /main/titanic/9 5 Sep 1997 Copyright 1997 Cayenne Software Inc.
# Start user added include file section
require wmt_util.tcl
require caynutil.tcl
require legacy.tcl
require chktcl_msg.tcl
require libsql.tcl
require checkutil.tcl
global booleanOptions; set booleanOptions {
{-debug debug 0}
{-global global 0}
{-usecase usecase 0}
}
OTShRegister::reportWriter
# next variable and procs should be redefined in 'checkconf.tcl'
#
global dbobject_name; set dbobject_name DBObject
proc set_name {class {ordered 0}} {
return "${class}Set"
}
proc set_type_name {class {ordered 0}} {
return "SetOf[$class getName]"
}
proc add_predefined_methods {ooplmodel} {
}
proc prepare_db_class {class model} {
}
# End user added include file section
Class ModelChecker : {GCObject} {
method destructor
constructor
method check
method checkModel
method checkLangModel
method loadModel
method parseCmdLine
method parseOptions
method setCheckStatus
method getSelectedOoplClasses
method getSelectedOoplSubjects
method getSourceClasses
attribute sources
attribute eventTypes
attribute eventDiagram
attribute srcCount
attribute exclClassFilter
attribute ooplClasses
attribute ooplSubjects
attribute codNames
attribute ooModel
attribute ooplModel
}
method ModelChecker::destructor {this} {
# Start destructor user section
# End destructor user section
}
constructor ModelChecker {class this {sources {}} {eventTypes {}}} {
set this [GCObject::constructor $class $this]
# Start constructor user section
set sources [flatten $sources]
$this sources $sources
if {[llength $sources] == 1} {
set diagType [nt_get_type $sources]
if {$diagType == "ccd" || $diagType == "etd" || $diagType == "std"} {
lappend eventTypes $diagType
$this eventDiagram $sources
}
}
$this eventTypes [flatten $eventTypes]
# End constructor user section
return $this
}
method ModelChecker::check {this} {
#
# Check UseCase or Local/Global Model.
#
m4_message $M_STARTING_EXTENDED_CHECKING
M4CheckManager::resetErrorCount
$this parseOptions
if {$usecase} {
uplevel #0 {
require chkucmodel.tcl
#
# Load user customizations, if present.
#
set cc [ClientContext::global]
if {[$cc customFileExists u_check tcl "" 0]} {
require u_check.tcl
}
}
puts stdout "\nChecking the Use Case model.\n"
checkUseCaseModel
CheckUtil::showErrors
return
}
OTShRegister::check
uplevel #0 {
require chkmodel.tcl
require chkcomodel.tcl
set cc [ClientContext::global]
if {[$cc customFileExists checkconf tcl "" 0]} {
require checkconf.tcl
}
#
# Load user customizations, if present.
#
if {[$cc customFileExists u_check tcl "" 0]} {
require u_check.tcl
}
#
# Load language dependent checks, if present.
#
if {[$cc customFileExists langcheck tcl tcl]} {
OTShRegister::codeGeneration
require langcheck.tcl
}
#
# Load user customizations, if present.
#
if {[$cc customFileExists u_langcheck tcl "" 0]} {
require u_langcheck.tcl
}
}
$this checkModel
}
method ModelChecker::checkModel {this} {
#
# Main entry point for extended checking
#
$this parseCmdLine
set cc [ClientContext::global]
if {[$cc currentLevel] == "File"} {
$cc upLevel
}
$this loadModel $global 0 1
if {[$this ooModel] == ""} {
m4_message $M_LOADING_OOPL_FAILED
CheckUtil::showErrors
return
}
set modelKind local
if {$global} {
set modelKind global
}
#
# Check the language/target model
# Note that this done *before* preparing the model
#
if {[nt_get_type [$cc levelNameAt Phase]] == "ObjectDesign"} {
$this checkLangModel $modelKind
}
#
# Prepare the model for local/global checking
#
puts stdout "\nPreparing the $modelKind model for checking.\n"
[$this ooplModel] prepare [$this ooplClasses] [$this ooplSubjects] check
if {[[$this ooModel] error] > 0} {
m4_message $M_PREPARE_CHECK_FAILED
[$this ooModel] delete
return
}
#
# Check the internal model
#
set classNames {}
foreach ooplClass [$this ooplClasses] {
lappend classNames [$ooplClass getName]
}
[$this ooplModel] check $classNames
unset classNames
#
#set sqlmodel [[$this ooModel] sqlModel]
#$sqlmodel check
#
# Check the local/global model
#
puts stdout "\nChecking the $modelKind model.\n"
[$this ooplModel] mcheck [$this ooplClasses] [$this ooplSubjects]
#
# Check the Collaboration model
#
if {$global || [$this codNames] != {}} {
puts stdout "\nChecking the Collaboration model.\n"
if {$global} {
$this codNames {}
}
checkCollaborationModel [$this codNames]
}
CheckUtil::showErrors
#
# Update check statusses of all specified diagrams.
#
# Note that this may set the status of a diagram incorrectly, for
# example if a diagram was specified that did not contain any
# incorrect classes.
#
foreach diagram [$this sources] {
if {[string first "." $diagram] > 0} {
set status [expr {([M4CheckManager::getErrorCount] == 0) ? "ok" : "failed"}]
if {[catch {$this setCheckStatus $diagram $status} msg]} {
puts stdout "$diagram: $msg\n"
}
}
}
}
method ModelChecker::checkLangModel {this modelKind} {
#
# If possible, call proc langCheck
#
if {[info procs langCheck] != ""} {
#puts stdout "\nDoing language dependent checking on model.\n"
puts stdout "\nChecking the $modelKind target language model.\n"
set classList [List new]
foreach class [$this ooplClasses] {
if {![$class isExternal]} {
$classList append $class
}
}
langCheck $classList
}
}
method ModelChecker::loadModel {this global {quiet 0} {subjects 1}} {
#
# Set this ooModel, this ooplModel, this ooplClasess and this ooplSubjects
# (Un)set this sources and this exclClassFilter, if needed
#
$this ooModel [OOModel::createModel]
if {[[$this ooModel] error] > 0} {
[$this ooModel] delete
$this ooModel ""
return
}
$this ooplModel [[$this ooModel] ooplModel]
if {$global} {
#
# Global checking
# - load all classes, except the ones specified.
# - if (subjects) load all Subjects in the system.
#
$this exclClassFilter [$this sources]
$this sources {}
if {!$quiet} {
m4_message $M_LOADING_MODEL
}
} else {
#
# Local checking
# - load the specified classes.
# - if (subjects) load the Subjects in the specified diagrams.
#
$this exclClassFilter {}
if {[lempty [$this sources]]} {
if {!$quiet} {
m4_message $M_NO_CLASSES_SPECIFIED
}
return
}
if {!$quiet} {
m4_message $M_LOADING_SPECIFIED
}
}
$this ooplClasses [$this getSelectedOoplClasses]
foreach ooplClass [$this ooplClasses] {
$ooplClass setReceivedEvents [$this eventTypes] [$this eventDiagram]
}
if {$subjects} {
$this ooplSubjects [$this getSelectedOoplSubjects]
foreach ooplSubject [$this ooplSubjects] {
$ooplSubject setReceivedEvents [$this eventTypes] [$this eventDiagram]
}
}
}
method ModelChecker::parseCmdLine {this} {
set sources {}
set eventTypes {}
set srcCount 0
set codNames {}
foreach src [CommandLineInterface::getSourceObjects] {
incr srcCount
set diagType [nt_get_type $src]
if {[string first "." $src] == -1 || ![isLegalDiagType $diagType]} {
# src is a class
lappend sources $src
continue
}
# src is a diagram
set diagName [nt_get_name $src]
if {$diagType == "cdm"} {
# src refers to a class after all
lappend sources $diagName
continue
}
if {$diagType == "cod"} {
lappend codNames $diagName
} elseif {$diagType == "ccd" || $diagType == "etd" || $diagType == "std"} {
# remember which kinds of events are needed
lappend eventTypes $diagType
#
# remember if just one event diagram is specified; if so,
# we only check events in that diagram
$this eventDiagram $src
} elseif {$diagType != "cad"} {
m4_message $M_CANNOT_CHECK_DIAG_TYPE $diagName $diagType
continue
}
# add the src/diagram to sources
lappend sources $src
}
# if more than 1 class/diagram specified then clear this eventDiagram,
# unconditionally
#
if {$srcCount != 1} {
$this eventDiagram ""
}
#
# If no event diagrams specified or doing global checking,
# get events sent in any diagram
#
if {[lempty $eventTypes] || $global} {
set eventTypes {ccd etd std}
}
#
# Check(s) needing specific types of events to be loaded.
#
if {[M4CheckManager::errorControl $E_NO_CORR_CCDMSG_FOUND] != "off"} {
lappend eventTypes ccd
}
$this srcCount $srcCount
$this sources [flatten $sources]
$this eventTypes [flatten $eventTypes]
$this codNames [flatten $codNames]
}
method ModelChecker::parseOptions {this} {
#
# See if any boolean options were specified, set the appropriate
# variables, and remove any options from argv.
#
global booleanOptions argv
foreach opt $booleanOptions {
set i [lsearch $argv [lindex $opt 0]]
set optvar [lindex $opt 1]
eval "global $optvar"
if {$i == -1} {
set optdef [lindex $opt 2]
eval "set $optvar $optdef"
} else {
set argv [lreplace $argv $i $i]
eval "set $optvar 1"
}
}
}
method ModelChecker::setCheckStatus {this diagName {newStatus ""}} {
#
# Set check status for specified diagram
#
set fileName [nt_get_name $diagName]
set fileType [nt_get_type $diagName]
if {$fileName == "" || $fileType == ""} {
puts stderr "ERROR: ModelChecker::setCheckStatus: filename '$diagName' not of format 'diagram.type'"
return 0
}
set cc [ClientContext::global]
set sysV [$cc currentSystem]
set fileV [$sysV findFileVersion $fileName $fileType]
if {[$fileV isNil]} {
#
# Exceptional case: A.B.cdm
#
set fileV [$sysV findFileVersion $fileName.$fileType cdm]
if {[$fileV isNil]} {
puts stderr "ERROR: ModelChecker::setCheckStatus: '$diagName': no such fileVersion"
return 0
}
}
switch -exact -- "$newStatus" {
"" -
reset { set status "not checked" }
ok { set status "checked OK" }
failed { set status "checked with errors" }
default { puts stderr "ERROR: ModelChecker::setCheckStatus: '$newStatus': bad status; should be one of \[reset|ok|failed]" ; return 0 }
}
if 0 {
#
# Cannot set property while diagram is locked ...
#
if {[catch {$fileV setProperty check_status "$status"} reason]} {
# for now, ignore failure message...
#m4_warning $W_CHECK_STATUS "$status"
#puts stderr "WARNING: Unable to set property 'check_status' to value '$status'"
#puts stderr $reason
return 0
}
} # 0
return 1
}
method ModelChecker::getSelectedOoplClasses {this} {
#
# Return the set of oopl classes, selected by this sources and this
# exclClassFilter
# If this sources == {} then the global model is loaded, else a local
# model is loaded
# this exclClassFilter is always applied
#
# determine sources from this sources
#
set sources [$this sources]
if {$sources == {}} {
# global model: let sources be all classes of the oopl model
foreach class [[$this ooplModel] getClassNames] {
if {[lsearch $sources $class] == -1} {
lappend sources $class
}
}
}
# determine classes from sources
#
set classes [$this getSourceClasses $sources]
# apply this exclClassFilter to classes, if needed
#
if {[$this exclClassFilter] != {}} {
#
# determine classes from this exclClassFilter
#
foreach class [$this getSourceClasses [$this exclClassFilter]] {
set idx [lsearch $classes $class]
if {$idx != -1} {
# delete class from classes
set classes [lreplace $classes $idx $idx]
}
}
}
# determine oopl classes
#
set ooplClasses {}
foreach class $classes {
if {$class == ""} {
puts stderr "Skipping class without name"
continue
}
set ooplClass [[$this ooplModel] classByName $class]
if {$ooplClass == ""} {
puts stderr "Unable to load class '$class'"
continue
}
if {[lsearch $ooplClasses $ooplClass] == -1} {
lappend ooplClasses $ooplClass
}
}
return $ooplClasses
}
method ModelChecker::getSelectedOoplSubjects {this} {
#
# Return the set of oopl subjects, selected by the CCD's in this sources
# If nothing has been selected, then return all subjects present in the
# oopl model
#
if {[$this sources] == {}} {
return [[$this ooplModel] subjectSet]
}
set subjects {}
foreach source [$this sources] {
if {[nt_get_type $source] == "ccd"} {
lappend subjects [get_diagram_subjects $source]
}
}
#
# select those oopl subjects with their name present in subjects
#
set ooplSubjects {}
foreach subject [[$this ooplModel] subjectSet] {
if {[lsearch $subjects [$subject getName]] != -1} {
lappend ooplSubjects $subject
}
}
return $ooplSubjects
}
method ModelChecker::getSourceClasses {this sources} {
#
# Return the set of classes belonging to 'sources'
# A source may be the name of one of:
# - class
# - diagram, may contain classes and/or be qualified by a class
#
set classes {}
foreach source $sources {
if {[string first "." $source] == -1} {
# it is a class; add it
if {[lsearch $classes $source] == -1} {
lappend classes $source
}
continue
}
# it is a diagram; add all classes in the diagram
foreach class [get_diagram_classes $source] {
if {[lsearch $classes $class] == -1} {
lappend classes $class
}
}
set diagType [nt_get_type $source]
if {$diagType == "etd" || $diagType == "std"} {
#
# the diagram is qualified by a class; add the class
#
set diagName [nt_get_name $source]
set class [lindex [split $diagName '/'] 0]
if {[lsearch $classes $class] == -1} {
lappend classes $class
}
}
}
return $classes
}
# Do not delete this line -- regeneration end marker