Getting and setting attachment information
Attachments are files saved in a database. You can add any kind of file to a database using Rational® ClearQuest®. For example, you can save text, word processing, spreadsheet, image, and diagram files.
When you save a file as part of a change request entity (record), you can also add a description of the file, which will make it easier to identify the file at a later time. Other information, such as the original file name, will also be stored, and the database will automatically create a unique identifier for the file.
Attachments, like other types of values, are held in a database field. The data type of a field holding attachments is AttachmentField. Because attachments are usually stored in logical groups, as when a defect is being discussed, an attachment field is a collection. The instances of the collection, each of which holds a single file, are of data type Attachment.
Methods to find and access attachment fields are available in a special object of type AttachmentFields. Each Entity always has an AttachmentFields object, even if no attachments are actually stored in it. Then, in each attachment field, there is an Attachments object that allows you to manage individual Attachment objects.
For other kinds of fields, you get field values by getting a FieldInfo object and then invoking GetValue() or GetValueAsList(). For GetValue(), a single string will be returned. If invoked on an attachment field, GetValue() might produce something meaningful if, say, your attachment is a one line text file. However, in general, using GetValue() on an attachment field will not produce a useful result. Instead, for attachments, you usually get values by first traversing to an Attachment object, then writing the file to disk and opening it with an application program.
Suppose that you have defined an Entity with two attachment fields. When you traverse this structure, you will iterate over two AttachmentField collections. To distinguish the collections, you can use the field names of each AttachmentField. To identify individual attachment files, you can use the descriptions in each instance of Attachment.
The following code fragment iterates over all the attachment fields of a record. For each of the attachment fields, this code:
- Prints the field names of the attachment_list type, which is a list of attached files (for more information, see GetValueAsList).
- Iterates over that attachment field's attachments to print the file name, file size, description, and content of each attachment.
To illustrate that the attachment's description is a read/write property, the code also:
- Alters the description of the attachment
- Prints the new description
VBScript
REM Start of Global Script ShowAttachmentInfo
Sub ShowAttachmentInfo(actionname, hookname)
DBGOUT "Entering '" & actionname & "' action's " & hookname & "_
script (VB version)"
DIM MyAttachmentFields ' The list of attachment fields
DIM MyAttachmentField ' An attachment field (contains a list of
'attachments)
DIM MyAttachment ' An Attachment object
' Tell how many attachment fields there are and show their
' names...
M = "This entity contains " & AttachmentFields.Count & "_
attachment field(s)" & VBCrLf
For Each MyAttachmentField in AttachmentFields
M = M & " " & MyAttachmentField.Fieldname & VBCrLf
Next
DBGOUT M
' Iterate over the attachment fields; for each one, list the
' attachments it contains in the current record...
For Each MyAttachmentField in AttachmentFields
M = "Attachment field '" & MyAttachmentField.Fieldname & "'_
contains:" & VBCrLf
' Iterate over the attachments in this field...
AtCount = 0
For Each MyAttachment in MyAttachmentField.Attachments
AtCount = AtCount + 1
' Demonstrate how to set an attachment's description...
If (Len(MyAttachment.Description) = 0 or _
MyAttachment.Description = " ")
Then
' DBGOUT "Description before: '" & _
MyAttachment.Description & "'"
MyAttachment.Description = "Not very descriptive!"
' DBGOUT "Description after: '" & _
MyAttachment.Description & "'"
End If
' Demonstrate how to write out the attachment's contents
' to an external file...
If (MyAttachment.Filename = "test.doc") Then
F = "C:\TEMP\" & GetDisplayName() & "_" & _
MyAttachment.FileName
MyAttachment.Load F
DBGOUT "Attachment " & MyAttachment.FileName & " was _
written to " & F
End If
' Report info about this attachment...
M = M & "Filename='" & MyAttachment.FileName & "'" & _
" FileSize=" & MyAttachment.FileSize & _
" Description='" & MyAttachment.Description & "'"_
& VBCrLf
Next
M = M & "Total attachments: " & AtCount
DBGOUT M
Next
DBGOUT "Exiting '" & actionname & "' action's " & hookname & _
" script (VB version)"
End Sub
REM End of Global Script ShowAttachmentInfo
REM Start of Global Script DBGOUT
sub DBGOUT(Msg)
Dim MySession ' a Session
set MySession = GetSession()
MySession.OutputDebugString & Msg & VbCrlf
end sub
REM End of Global Script DBGOUT
Perl
# Start of Global Script ShowAttachmentInfo
# ShowAttachmentInfo() -- Display information about
# attachments...
sub ShowAttachmentInfo {
# $actionname as string
# $hookname as string
my($actionname, $hookname) = @_;
my($M) = "Entering '".$actionname."' action's ".$hookname."
script (Perl version)\n\n";
# DBGOUT($M); $M="";
# Get a list of the attachment fields in this record type...
my($AttachmentFields) = $entity->GetAttachmentFields();
# Tell how many attachment fields there are and show their
# names...
$M = $M . "This entity contains " . $AttachmentFields->Count() .
" attachment field(s)\n";
for ($A = 0; $A < $AttachmentFields->Count(); $A++)
{
$M = $M . " " . ($AttachmentFields->Item($A) )->GetFieldName() . "\n";
}
$M .= "\n";
# Iterate over the attachment fields; for each one, list the
# attachments it contains in the current record...
for (my($AF) = 0; $AF < $AttachmentFields->Count(); $AF++) {
my ($AttachmentField) = $AttachmentFields->Item($AF);
$M = $M ."Attachment field '"
. $AttachmentField->GetFieldName().
"' contains:\n";
# Iterate over the attachments in this field...
my($Attachments) = $AttachmentField->GetAttachments();
for (my($A) = 0; $A < $Attachments->Count(); $A++) {
my($Attachment) = $Attachments->Item($A);
# Demonstrate how to set an attachment's description...
if ($Attachment->GetDescription() eq " ") {
# DBGOUT("Description before:
'".$Attachment->GetDescription()."'");
$Attachment->SetDescription("Not too descriptive!");
# DBGOUT("Description after:
'".$Attachment->GetDescription()."'");
}
# Demonstrate how to write out the attachment's contents
# to an external file...
if ($Attachment->GetFileName() eq "test.doc") {
my($F) = "C:\\TEMP\\" . $entity->GetDisplayName()
. '_' . $Attachment->GetFileName();
$Attachment->Load($F);
DBGOUT("Attachment written to $F
}
# Report info about this attachment...
$M = $M .
" Filename='" . $Attachment->GetFileName() . "'" .
" FileSize=" . $Attachment->GetFileSize() .
" Description='" . $Attachment->GetDescription() . "'" .
"\n";
}
$M = $M . "Total attachments: " . $Attachments->Count() .
"\n\n";
}
# Display the results...
DBGOUT($M); $M="";
}
# End of Global Script ShowAttachmentInfo
# Start of 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");
}
# End of Global Script DBGOUT