En el ejemplo siguiente se muestra cómo utilizar la API de Rational ClearQuest para obtener información sobre valores de campo y después de que el usuario actualiza un registro. Este ejemplo se estructura como un enganche global al que se puede llamar desde otro enganche como, por ejemplo, desde el enganche ACTION_COMMIT.
REM Inicio de Global Script ShowOldNewValues
REM TODO -- put your script code here
Sub ShowOldNewValues (actionname, hookname)
Dim fieldnames
Dim FN
Dim OldFV
Dim FieldValueStatus
Dim FieldInfo
Dim i
Dim NewFV
Dim FieldType
Dim is_short
M = "'" & actionname & "' action's " & hookname & " script (VB" & _
"version):" & VBCrLf & VBCrLf
' Obtener una lista de los campos de este tipo de registro...
fieldnames = GetFieldNames
' Bucle a través de los campos, mostrando el nombre, el tipo,
'los valores anterior/nuevo...
if IsArray(fieldnames) Then
i = LBound(fieldnames)
Do While i <= UBound(fieldnames)
FN = fieldnames(i)
M = M & FN & ":"
' Obtener el valor original del campo...
set FieldInfo = GetFieldOriginalValue(FN)
FieldValueStatus = FieldInfo.GetValueStatus()
If FieldValueStatus = AD_HAS_NO_VALUE Then
OldFV = "<no value>"
ElseIf FieldValueStatus = AD_VALUE_NOT_AVAILABLE Then
OldFV = "<value not available>"
ElseIf FieldValueStatus = AD_HAS_VALUE Then
OldFV = FieldInfo.GetValue()
Else
OldFV = "<Invalid value status: " & FieldValueStatus & ">"
End If
' Obtener el valor actual (se puede haber actualizado durante
' esta acción)...
set FieldInfo = GetFieldValue(FN)
FieldValueStatus = FieldInfo.GetValueStatus()
If FieldValueStatus = AD_HAS_NO_VALUE Then
NewFV = "<no value>"
ElseIf FieldValueStatus = AD_VALUE_NOT_AVAILABLE Then
NewFV = "<value not available>"
ElseIf FieldValueStatus = AD_HAS_VALUE Then
NewFV = FieldInfo.GetValue()
Else
NewFV = "<Invalid value status: " & FieldValueStatus & ">"
End If
' Obtener y reformatear el tipo del campo...
FieldType = FieldInfo.GetType()
is_short = 1
If FieldType = AD_SHORT_STRING Then
FieldType = "Short String"
ElseIf FieldType = AD_MULTILINE_STRING Then
FieldType = "Multiline String"
is_short = 0
ElseIf FieldType = AD_INT Then
FieldType = "Integer"
ElseIf FieldType = AD_DATE_TIME Then
FieldType = "Date time"
ElseIf FieldType = AD_REFERENCE Then
FieldType = "Reference"
ElseIf FieldType = AD_REFERENCE_LIST Then
FieldType = "Reference List"
is_short = 0
ElseIf FieldType = AD_ATTACHMENT_LIST Then
FieldType = "Attachment List"
is_short = 0
ElseIf FieldType = AD_ID Then
FieldType = "ID"
ElseIf FieldType = AD_STATE Then
FieldType = "State"
ElseIf FieldType = AD_JOURNAL Then
FieldType = "Journal"
is_short = 0
ElseIf FieldType = AD_DBID Then
FieldType = "DBID"
ElseIf FieldType = AD_STATETYPE Then
FieldType = "STATETYPE"
ElseIf FieldType = AD_RECORDTYPE Then
FieldType = "RECORDTYPE"
Else
FieldType = "<UNKNOWN TYPE: " & FieldType & ">"
is_short = 0
End IF
M = M & " Type=" & FieldType & "."
' Visualizar los resultados. Para este ejemplo,
' se muestran los valores siguientes:
' 1. Identificar si el valor del campo ha cambiado o
' no durante la acción actual e indicarlo
' en la salida.
' 2. Para campos de una sola línea (integer, short_string, etc.)
' mostrar el valor del campo.
' 3. Para campos de una sola línea cuyos valores han cambiado
' durante la acción actual, mostrar los valores anterior
' y nuevo.
If OldFV = NewFV Then
M = M & " Value is unchanged."
If is_short = 1 Then
M = M & " Value='" & OldFV & "'"
End If
Else
M = M & " Value has changed."
If is_short = 1 Then
M = M & " Old value='" & OldFV & "' New value='" & _
NewFV & "'"
End If
End If
M = M & VBCrLf
i = i + 1
Loop
Else
M = M & "fieldnames is not an array" & VBCrLf
End If
' En este punto, se puede escribir esta información en un archivo,
' presente en un recuadro de mensaje, o bien, escribirla en la ventana de
' depuración utilizando el método session.OutputDebugString(). Aquí se utiliza
' la API "MsgBox" de Windows para presentar los resultados al usuario
' en un recuadro de mensaje (se debe tener en cuenta que esto sólo funciona
' para los primeros 1024 caracteres de "M" debido a las limitaciones de la API
' MsgBox de Windows...)
MsgBox M
End Sub
REM Fin de Global Script ShowOldNewValues
# Inicio de Global Script ShowOldNewValues
# ShowOldNewValues: Mostrar valores de campo en el registro
# actual, prestando atención a los campos cuyos valores han
# cambiado durante la acción actual.
sub ShowOldNewValues {
# $actionname as string
# $hookname as string
my($actionname, $hookname) = @_;
my($M) = "'".$actionname."' action's ".$hookname." ccript (Perl
version):\n\n";
# Obtener una lista de los campos de este tipo de registro
# (NOTA: GetFieldNames() devuelve una *REFERENCE* a una matriz)...
my($FieldNamesRef) = $entity->GetFieldNames();
# Bucle a través de los campos, mostrando el nombre, el tipo,
# los valores anterior/nuevo...
foreach $FN (@$FieldNamesRef) {
$M .= $FN . ":"; # Mostrar el nombre de campo...
# Obtener el valor original del campo...
$FieldInfo = $entity->GetFieldOriginalValue($FN);
$FieldValueStatus = $FieldInfo->GetValueStatus();
if ($FieldValueStatus == $CQPerlExt::CQ_HAS_NO_VALUE) {
$OldFV = "<no value>";
} elsif ($FieldValueStatus ==
$CQPerlExt::CQ_VALUE_NOT_AVAILABLE) {
$OldFV = "<value not available>";
} elsif ($FieldValueStatus == $CQPerlExt::CQ_HAS_VALUE) {
$OldFV = $FieldInfo->GetValue();
} else {
$OldFV = "<Invalid value status:
" . $FieldValueStatus . ">";
}
# Obtener el valor actual (se puede haber actualizado durante
# esta acción)...
$FieldInfo = $entity->GetFieldValue($FN);
$FieldValueStatus = $FieldInfo->GetValueStatus();
if ($FieldValueStatus == $CQPerlExt::CQ_HAS_NO_VALUE) {
$NewFV = "<no value>";
} elsif ($FieldValueStatus ==
$CQPerlExt::CQ_VALUE_NOT_AVAILABLE) {
$NewFV = "<value not available>";
} elsif ($FieldValueStatus == $CQPerlExt::CQ_HAS_VALUE) {
$NewFV = $FieldInfo->GetValue();
} else {
$NewFV = "<Invalid value status:
" . $FieldValueStatus . ">";
}
# Obtener y reformatear el tipo del campo...
$FieldType = $FieldInfo->GetType();
$is_short = 1;
if ($FieldType == $CQPerlExt::CQ_SHORT_STRING) {
$FieldType = "Short String";
} elsif ($FieldType == $CQPerlExt::CQ_MULTILINE_STRING) {
$FieldType = "Multiline String";
$is_short = 0;
} elsif ($FieldType == $CQPerlExt::CQ_INT) {
$FieldType = "Integer";
} elsif ($FieldType == $CQPerlExt::CQ_DATE_TIME) {
$FieldType = "Date Time";
} elsif ($FieldType == $CQPerlExt::CQ_REFERENCE) {
$FieldType = "Reference";
} elsif ($FieldType == $CQPerlExt::CQ_REFERENCE_LIST) {
$FieldType = "Reference List";
$is_short = 0;
} elsif ($FieldType == $CQPerlExt::CQ_ATTACHMENT_LIST) {
$FieldType = "Attachment List";
$is_short = 0;
} elsif ($FieldType == $CQPerlExt::CQ_ID) {
$FieldType = "ID";
} elsif ($FieldType == $CQPerlExt::CQ_STATE) {
$FieldType = "State";
} elsif ($FieldType == $CQPerlExt::CQ_JOURNAL) {
$FieldType = "Journal";
$is_short = 0;
} elsif ($FieldType == $CQPerlExt::CQ_DBID) {
$FieldType = "DBID";
} elsif ($FieldType == $CQPerlExt::CQ_STATETYPE) {
$FieldType = "STATETYPE";
} elsif ($FieldType == $CQPerlExt::CQ_RECORDTYPE) {
$FieldType = "RECORDTYPE";
} else {
$FieldType = "<UNKNOWN TYPE: " . $FieldType . ">";
$is_short = 0;
}
$M .= " Type=" . $FieldType . ".";
# Visualizar los resultados. Para este ejemplo,
# los valores se muestran tal como se indica a continuación:
# 1. Identificar si el valor del campo ha cambiado o
# no durante la acción actual e indicarlo
# en la salida.
# 2. Para los campos de una sola línea (integer, short_string, etc.)
# mostrar el valor de campo.
# 3. Para los campos de una sola línea cuyos valores han cambiado
# durante la acción actual, mostrar los valores anterior y nuevo.
if ($OldFV eq $NewFV) {
$M .= " Value is unchanged.";
if ($is_short) {
$M .= " Value='".$OldFV."'";
}
} else {
$M .= " Value has changed.";
if ($is_short) {
$M .= " Old value='".$OldFV."' New
value='".$NewFV."'";
}
}
$M .= "\n";
}
$M .= "\n'".$actionname."' action's notification script
(Perl version) exiting.\n";
# En este punto, se puede escribir esta información en un archivo,
# presente en un recuadro de mensaje, o bien, escribirla en la ventana de
# depuración utilizando $session->OutputDebugString().
# Aquí se llama a una subrutina 'DBGOUT' que escribe el mensaje
# en un archivo e invoca 'Notepad' en el mismo...
DBGOUT($M);
}
# Fin de Global Script ShowOldNewValues
# Inicio de Global Script DBGOUT
sub DBGOUT {
my($Msg) = shift;
my($FN) = $ENV{'TEMP'}.'\STDOUT.txt';
open(DBG, ">>$FN") || die "Failed to open $FN";
print DBG ($Msg);
close(DBG);
system("notepad $FN");
system("del $FN");
}
# Fin de Global Script DBGOUT