Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы

advertisement
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
V_UNKNOWN
"V_UNKNOWN"
233
Только
(значение OLE-объекта)
Variant
Объект определенного
Имя класса в символах верхнего регистра
пользователем класса или
(для объекта из класса EMPOYEE объект
встроенного класса
возвращается значение "EMPLOYEE")
Массив
Имя типа массива + круглые скобки, содержащие
пробел, в символах верхнего регистра (для массива типа Integer возвращается
строка: "INTEGER( )").
Список
Имя типа списка + слово "List" в символах верхнего
регистра (для списка типа Integer возвращается строка: "STRING LIST").
Пример, Определения типа данных.
Dim a As Variant Print
Выводит "EMPTY"
TypeName(a)
a = 1
Print
Выводит "INTEGER"
TypeName(a)
a = "hello" . Print TypeName
Выводит "STRING"
( a ) Dim b As String Print
TypeName(b$)
Выводит "STRING"
' Массивы
Dim arrayl (1 To 4} As Long
Print TypeName(arrayl&) ' Выводит "LONG( )"
Dim arrayV(l To 4)
Print TypeName(arrayV)
' Выводит "VARIANT( )"
Dim у As Variant
' •
у - arrayl
Print TypeName (y)
' Выводит "LONG ( )"
' Списки
Dim listStr List As String
Print TypeName(listStr$) ' Выводит "STRING LIST"
Dim listVar List
Print TypeName(listVar) ' Выводит "VARIANT LIST"
Dim p As Variant
p = listStr$
Print. TypeName (p)
' Выводит "STRING LIST"
LotusScript классов
Class Employee
' определение класса Employee End
Class
Dim temp As Employee
Print. TypeName (temp)
Set hire = New Employee
Print TypeName(hire)
Dim emps(3) As Employee
Print. TypeName (emps ())
' Выводит "EMPLOYEE"
' Выводит "EMPLOYEE"
' Выводит "EMPLOYEE ( )"
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
234
' Объекты OLE классов
Set obj = CreateObject("Word.Application")
Print TypeName(obj)
' Выводит "OBJECT"
2.8.3. Операторы и функции обработки строковых данных
Оператор Bin
Bin[$] ( numExpr)
Возвращает двоичное представление числа в строковом виде. Параметр
numExpr-числовое выражение. Если значение выражения numExpr имеет дробную часть, то
оно округляется до ближайшего целого значения. Значение, возвращаемое оператором Bin,
имеет тип Variant DataType 8 (строка), оператор Bin$ возвращает значение типа String.
Возвращаемое значение - число в двоичной системе исчисления. Максимальная длина
результата - 32 символа.
Если тип данных выражения numExpr не Integer и не Long, LotusScript производит
попытку привести значение выражения к типу Long. Если подобное преобразование
невозможно, выдается ошибка («Overflow»).
Пример.
'
'
'
.9)
'
Выводит "11"
Выводит "11"
Выводит "11"
Выводит "11" (результат вычисления
' выражения - 2,79 - округляется,
'а затем преобразуется)
Функция Oct
Oct[$] ( numExpr)
Возвращает восьмеричное представление числа в строковом виде. Параметр numExpr
-числовое выражение. Если numExpr является числом с дробной частью, LotusScript округляет
его до ближайшего целого перед преобразованием в восьмеричный вид.
Oct возвращает значение типа Variant DataType 8 (строка), a Oct$ возвращает значение
типа String. Возвращаемое значение содержит только цифры от 0 до 7 включительно и имеет
длину 11 символов.
Если тип значения numExpr не Integer или не Long, LotusScript производит попытку
преобразовать выражение к типу Long. При невозможности преобразования типа выводится
ошибка («Overflow»).
Пример.
Print Oct$(17)
' Выводит "21"
' Преобразование аргумента из типа Double в тип Long
Print Oct$(17.0)
' Выводит "21"
' Округляет аргумент типа Double, а затем преобразует в Long
Print Oct$(17.3)
' Выводит "21"
1
Результат вычисления - 16.587 - округляется до 1 7 . 0 и затем
преобразуется в Long
Print Oct$(17.1 * . 9 7 )
' Выводит "21"
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
235
Оператор LSet
LSet stringVar= stringExpr
Присваивает содержимое строки stringExpr строковой переменной stringVar и
выравнивает эту строку по левой границе. Параметр stringVar - имя строковой переменной
типа String фиксированной или переменной длины, или типа Variant.
Если длина stringVar превышает длину stringExpr, то происходит выравнивание по левой
границе stringExpr в stringVar и дополняет пробелами справа. Если длина stringVar меньше
длины stringExpr, то копируется только возможное количество символов из stringExpr в
stringVar. Если stringVar содержит числовое значение, то оно преобразуется в строковое, и
далее используется длина уже строкового представления. Если переменная stringVar имеет
тип Variant, то она не может иметь значение NULL (в этом случае «емкость» приемника была
бы неопределена). Попытка заместить значение NULL вызывает ошибку с кодом 94
-«Invalid use of null».
Оператор LSet не может быть использован для операций с переменными типов,
определенных пользователем.
Иллюстрация работы оператора LSet.
Пример.
Dim x As Variant
x - "qq"
LSet x = "abc"
Print x
LSet x = "с"
' Присвоение символа
' т.к. длина х Print x & "high"
х == "с"
Print х & "high"
Dim someV as Variant
Lset someV = "abc"
Print someV
someV = Null
Lset someV = "abc"
' Длина x - 2
' Присвоение двух левых символов
' Выводит "ab"
"с"
2
'
'
'
и дополнение остатка строки пробелами
Выводит "с high"
Обычное присвоение. Новая длина х - 1
Выводит "chigh"
' Выводит "", т.к. размер значение Empty О
' Ошибка «Invalid use of null»
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
236
Оператор RSet
RSet stringVar = stringExpr Присваивает содержимое строки stringExpr строковой
переменной stringVar и выравнивает эту строку по правой границе.
Использование данного оператора как бы фиксирует емкость переменной-приемника и
заполняет её, начиная с правой стороны. Если длина строки stringVar превышает длину
строки stringExpr, LotusScript выравнивает вправо строку stringExpr внутри переменной
stringVar и добавляет пробелами недостающие символы слева в stringVar. Если длина
stringVar меньше длины строки stringExpr, LotusScript копирует только нужное количество
символов из строки stringExpr, взятых от ее левой границы, и присваивает значение этой
подстроки переменной stringVar. Если stringVar содержит числовое значение, LotusScript
сначала преобразует его к с роковому виду, а уже потом устанавливает длину результата.
Иллюстрация работы оператора Rset:
Длина строкового предст.
значения переменной
Длина строкового предст. значения
переменной
Переменная
-приемник
Переменная
-приемник
Строка
Строка
Уместившаяся подстрока
Непоместившая
ся подстрока
Дополняющие
пробелы
Значение
целиком
Пример 1,
Dun positFin As String * 20
RSet positFin$ = "Right"
Print positFin$
' Строка "Right" выравнена по
' 15 символов строки positFin
' Строка фиксированной длины 20
' "Right" заведомо короче positFin
' Выводит "
Right"
правому краю строки positFin и первые
являются пробелами
Пример 2.
' Выводит "а"
Строка "q" присвоена переменной х типа Variant и тем самым установила
её длину равной 1. Таким образом, только один символ строки "ab", а
именно самый левый - "а", записан в переменную х.
Функция Left
Left[S] ( expr , n )
Возвращает подстроку, состоящую из первых n символов преобразованного в строку
параметра expr.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R, 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
237
Параметр expr - числовое выражение или строковое выражение для функции Left;
выражение типа Variant или String для функции Left$. Если значение выражения expr
является числом, то перед выделением символов 'это число преобразуется в строку.
Параметр п - число возвращаемых символов,
Функция Left возвращает значение типа Variant DataType 8 (String), а функция
Left$ возвращает значение типа String. Если п = 0, то функция возвращает пустую строку ("")•
Если n больше, чем длина исходной строки из expr, функции возвращают всю строку.
Функция Left(Null,l) возвращает значение Null. Функция Left$(Null,l) выдает ошибку с
кодом 94 — «Invalid use of null».
Пример.
Print Left$("ABC", 2)
Print Left$("ABC", 0)
Print Left(Null, 2)
Dim someV
someV = Null
Print Left$(someV, 2)
' Выводит "АВ" '
Выводит
"" '
Выводит
Null
Ошибка "Invalid use of null"
Функция LeftB
Функция LeftB выполняет ту же операцию что и Left. Отличием является то, что LeftB
измеряет длину подстроки не в символах, а в байтах. Во внутреннем представлении
LotusScript строки кодированы Unicode, где символы кодируются двумя байтами. По этой
причине использование функции LeftB может приводить к непредсказуемым результатам.
Вместо LeftB следует использовать либо Left, либо LeftB Р.
Функция LeftBP
LeftBP[$] ( expr , n )
Для указанной строки возвращает подстроку слева из указанного числа байт.
Подсчет байт ведется в кодировке текущей платформы.
expr - числовое выражение или строковое выражение для функции LeftBP; выражение
типа Variant или String для функции LeftBP$. Если значение выражения expr является
числом, то перед выделением символов это значение преобразуется в строку.
n - длина извлекаемой подстроки в байтах.
Функция LeftBP возвращает значение типа Variant DataType 8 (String), а функция LeftBPS
возвращает значение типа String. Если n = 0, функция возвращает пустую строку («»). Если n
больше, чем длина исходной строки из expr, функции возвращают всю строку.
Функция LeftBP(Null) возвращает значение Null. Функция LeftBP$(Null) выдает ошибку с
кодом 94 - «Invalid use of null».
Функция производит посимвольное выравнивание результата. Это означает, что, если
кодировка строки многобайтная и в результат справа попадает не целый код символа, а,
например, один байт, то такой символ не включается в результат функции.
Пример.
Print LeftBP$("ABB", 2)
Print LeftBP$("ABB", 0)
' Выводит "АБ" '
Выводит ""
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
238
5 Функция LeftC
LeftC ( expr, n )
Используется только для систем письма в колонку (тайская, малайская, арабская, урду,
персидская (фарси), лаоская)!
Из указанной строки извлекает указанное количество колонок слева.
Параметр expr - строковое выражение, содержащее колонки символов.
Параметр n - число извлекаемых из исходной строки колонок символов.
Если n = 0, функция возвращает пустую строку («»). Если n больше, чем число колонок в
исходной строке expr, функции возвращают всю строку.
Функция поддерживает следующие системы письма:
© Функция StrLeft
StrLeft ( stringExpr 1, stringExpr2, [compMethod [, Occurences ]] )
Функция просматривает указанную строку-источник слева направо в поиске
подстроки-образца и возвращает подстроку из символов, находящихся слева от найденного
образца.
Параметр stringExpr1 - строка, в которой производится поиск и выборка
(строка-источник).
Параметр stringExpr2 — строка, вхождение которой отыскивается в строке-источнике
(строка-образец).
Параметр compMethod - числовое выражение, задающее правило сравнения строк. Флаг
может иметь следующие значения:
compMethod
Способ сравнения
0
С учетом регистра. С учетом
«Pitch»
1
Без учета регистра. С учетом
«Pitch»
4
С учетом регистра. Без учета
«Pitch»
5
Без учета регистра. Без учета
«Pitch»
Если аргумент compMethod не указан, то действуют установки оператора Option Compare,
если таковой присутствует в текущем модуле. Подробнее о способах сравнения строк см. в
описании оператора Option Compare на стр. 163. Использование значения вне этого списка
приводит к ошибке с кодом 173 - «Argument out of range».
Параметр Occurences — числовое выражение, задающее необходимое число вхождений
строки-образца в строке-источнике, которое должно быть достигнуто для получения
результата. Значение по умолчанию - 1.
© InterTrust Со. Тел. (095) 9567928
Lotus Domino R. 5: @.-формулы, LotusScript, встроенные классы LotusScript и Java
239
Иллюстрация работы функции StrLeft:
Пример, Вызовы функции StrLeft с различными значениями параметров.
Const SourceStr$ = "Во поле березка стояла"
Print Strleft(SourceStr$, "бере")
..
' Выводит "Во поле " Print
Strleft(SourceStr$, "беРе")
' Выводит "" (по умолчанию сравнение идет с учетом регистра)
Print Strleft(SourceStr$, "беРе", 0)
Print Strleft(SourceStr$, "беРе", 4)
' Выводит "" (явно задано сравнение с учетом регистра)
Print Strleft(SourceStr$, "беРе", 1) Print Strleft(SourceStr$,
"беРе", 5)
' Выводит "Во поле " (задано сравнение без учета регистра) Print
Strleft(SourceStr$, "о", 1, 3)
' Выводит "Во поле березка ст" (все, что до 3-ей буквы "о") Print
Strleft(SourceStr$, "о", 1, 4)
' Выводит "" (4-го вхождения не найдено - букв "о" всего 3) Print
Strleft(SourceStr$, "")
' Выводит "" (нет строки-образца)
© Функция StrLeftBack
StrLeftBack ( stringExpr1, stringExpr2, [compMethod [, Occurences ]] )
Функция просматривает указанную строку-источник справа налево в поиске
подстроки-образца и возвращает подстроку из символов, находящихся слева от найденного
образца.
stringExpr1 - строка, в которой производится поиск и выборка (строка-источник).
stringExpr2 - строка, вхождение которой отыскивается в строке-источнике
(строка-образец).
compMethod - числовое выражение, задающее правило сравнения строк. Флаг может
иметь следующие значения:
compMethod
0
Способ сравнения
С учетом регистра. С учетом
«Pitch»
Без учета регистра. С учетом
«Pitch»
4
С учетом регистра. Без учета
«Pitch»
5
Без учета регистра. Без учета
«Pitch»
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
240
Если аргумент compMethod не указан, то действуют установки оператора Option Compare,
если таковой присутствует в текущем модуле. Подробнее о способах сравнения строк см. в
описании оператора Option Compare на стр. 163. Использование значения вне этого списка
приводит к ошибке с кодом 173 - «Argument out of range».
Occurences — числовое выражение, задающее необходимое число вхождений
строки-образца в строке-источнике, которое должно быть достигнуто для получения
результата. Значение по умолчанию — 1.
Иллюстрация работы функции StrLeftBack:
Пример. Вызовы функции StrLeftBack с различными значениями параметров.
Const SourceStr2$ = "Слово! слово2 словоЗ"
Print Strleftback(SourceStr2$, "ло")
' Выводит "Слово! слово2 с" Print
Strleftback(SourceStr2$, "Ло")
' Выводит "" (по умолчанию сравнение идет с учетом регистра) Print
Strleftback(SourceStr2$, "Ло", 0) Print Strleftback (SourceStr2$, "Ло",
4)
1 Выводит "" (явно задано сравнение с учетом регистра)
Print Strleftback(SourceStr2$, "Ло", 1) Print
Strleftback(SourceStr2$, "Ло", 5)
' Выводит "Слово! слово2 с" (сравнение без учета регистра) Print
Strleftback(SourceStr2$, "Ло", 1, 2)
' Выводит "Слово! с" (искалось второе вхождение справа) Print
Strleftback(SourceStr2$, "Ло", 1, 4)
' Выводит "" (вхождений "Ло" всего три)
Print Strleftback(SourceStr2$, "")
' Выводит "" (нет строки-образца)
Функция Right
Right[$] ( expr, n )
Выделяет из преобразованного в строку параметра ехрг заданное количество символов п,
начиная с правого конца строки.
ехрг - числовое или строковое выражение для функции Right; любое выражение типа
Variant или String для функции Right$. Числовое выражение предварительно переводится в
строковое.
п — числовое выражение - количество выделяемых символов.
Функция Right возвращает значение типа Variant DataType 8 (String), функция
Right$ -типа String. Если п равно 0, то возвращается пустая строка (""); если п больше,
чем количество символов в исходной строке, то возвращается вся исходная строка.
Функция Right(Null,l) возвращает значение Null. Функция Right$(Null,l) выдает ошибку
с кодом 94 — «Invalid use of null».
Пример.
Print Right $("ABCDEF", 3)
© InterTrust Co. Тел. (095) 9567928
'Выводит "DEF"
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
241
Функция RightB
Функция RightB выполняют ту же операцию что и Right. Отличием является то, что
RightB измеряет длину подстроки не в символах, а в байтах. Во внутреннем представлении
LotusScript строки кодированы Unicode, где символы кодируются двумя байтами. По этой
причине использование функции RightB может приводить к непредсказуемым результатам.
Вместо RightB следует использовать либо Right, либо RightBP.
Функция RightBP
RightBP[$] ( expr , n )
Для преобразованного в строку параметра expr возвращает подстроку из указанного
числа байт n, начиная с левого конца строки.
Подсчет байт ведется в кодировке текущей платформы.
expr - числовое выражение или строковое выражение для функции RightBP; выражение
типа Variant или String для функции RightBP$. Если значение выражения expr является
числом, то перед выделением символов оно преобразуется в строку.
n — длина извлекаемой подстроки в байтах.
Функция RightBP возвращает значение типа Variant DataType 8 (String), а функция
RightBP$ возвращает значение типа String. Если n = 0, то функция возвращает пустую строку
(""')• Если n больше, чем длина исходной строки из expr, то функции возвращают всю строку.
Функция RightBP(Null, 1) возвращает значение Null. Функция RightBP$(Null, 1) выдает
ошибку с кодом 94 - «Invalid use of null».
Функция производит посимвольное выравнивание результата. Это означает, что, если
кодировка строки многобайтная и в результат справа попадает не целый код символа, а,
например, один байт, то такой символ не включается в результат функции.
Пример.
Print RightBP$("АБВ", 2)
Print RightBP$("АБВ", 4)
Print RightBP$ ( "АБВ", 0)
' Выводит "БВ"
' Выводит "АБВ"
' Выводит ""
© Функция RightC
RightC ( expr, n )
Используется только для систем письма в колонку (тайская, малайская, арабская, урду,
персидская (фарси), лаоская)!
Из указанной строки извлекает указанное количество колонок справа.
expr - строковое выражение, содержащее колонки символов.
n - число извлекаемых из исходной строки колонок символов.Если n = 0, функция
возвращает пустую строку ('"'). Если n больше, чем число колонок в исходной строке expr, то
функции возвращают всю строку.
© Функция StrRight
StrRight ( stringExpr1, stringExpr2, [compMethod [, Occurences ]] )
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
242
Функция просматривает указанную строку-источник справа налево в поиске
подстроки-образца и возвращает подстроку из символов, находящихся справа от найденного
образца.
stringExpr1 — строка, в которой производится поиск и выборка (строка-источник).
stringExpr2 — строка, вхождение которой отыскивается в строке-источнике
(строка-образец).
compMethod - числовое выражение, задающее правило сравнения строк. Флаг может
иметь следующие значения:
compMethod
Способ сравнения
0
С учетом регистра. С учетом
«Pitch»
1
Без учета регистра. С учетом
«Pitch»
4
С учетом регистра. Без учета
«Pitch»
5
Без учета регистра. Без учета
«Pitch»
Если параметр compMethod не указан, то действуют установки оператора Option
Compare, если таковой присутствует в текущем модуле. Подробнее о способах сравнения
строк см, в описании оператора Option Compar . Использование значения вне этого списка
приводит к ошибке с кодом 173 - «Argument out of range».
Occurences — числовое выражение, задающее необходимое число вхождений
строки-образца в строке-источнике, которое должно быть достигнуто для получения
результата. Значение по умолчанию — 1.
Иллюстрация работы функции StrRight:
Пример. Вызовы функции StrRight с различными аргументами.
Const SourceStr$ = "Во поле березка стояла"
Print Strright(SourceStr$,
"бере")
' Выводит "зка стояла" Print
Strright
(SourceStr$, "беРе")
' Выводит "" (по умолчанию сравнение идет с учетом регистра)
Print Strright (SourceStr$, "беРе", 0)
Print Strright (SourceStr$, "беРе", 4)
" Выводит "" (явно задано сравнение с учетом регистра)
Print Strright (SourceStr$, "беРе", 1) Print Strright (SourceStrS,
"беРе", 5)
' Выводит "зка стояла" (задано сравнение без учета регистра) Print
Strright (SourceStr$, "о", 1, 3}
' Выводит " поле березка стояла" (все, что до 3-ей буквы "о") Print
Strright (SourceStr$, "о", 1, 4)
' Выводит "" (4-го вхождения не найдено - букв "о" всего 3) Print
Strright (SourceStr$, " " )
'
Выводит ""
(нет строки-образца)
© InterTrust Со. Тел. (095) 9567928
Lotus Domino R. 5: (@-формулы, LotusScript, встроенные классы LotusScript и Java
243
© Функция StrRightBack
StrRightBack ( stringExpr1, stringExpr2, [compMethod [, Occurcnces ]] )
Функция просматривает указанную строку-источник слева направо в поиске
подстроки-образца и возвращает подстроку из символов, находящихся справа от найденного
образца.
stringExpr 1 — строка, в которой производится поиск и выборка (строка-источник).
Параметр stringExpr2, - строка, вхождение которой отыскивается в строке-источнике
(строка-образец).
compMethod - числовое выражение, задающее правило сравнения строк. Это выражение
может иметь следующие значения:
compMethod
Способ сравнения
0
С учетом регистра. С учетом «Pitch»
1
Без учета регистра. С учетом «Pitch»
4
С учетом регистра. Без учета «Pitch»
5
Без учета регистра. Без учета «Pitch»
Если аргумент compMethod не указан, то действуют установки оператора Option Compare,
если таковой присутствует в текущем модуле. Подробнее о способах сравнения строк см. в
описании оператора Option Compare. Использование значения вне этого списка приводит к
ошибке с кодом 173 — «Argument out of range».
Необязательный параметр Occurences - числовое выражение, задающее необходимое
число вхождений строки-образца в строке-источнике, которое должно быть достигнуто для
получения результата. Значение по умолчанию - 1.
Иллюстрация работы функции StrRightBack:
Пример. Вызовы функции StrRightBack с различными значениями параметров.
Const SourceStr2$ = "Слово1 слово2 словоЗ"
Print Strrightback(SourceStr2$ ,
"ло")
' Выводит "во1 слово2 словоЗ"
Print Strrightback (SourceStr2$, "Лo")
' Выводит "" (по умолчанию сравнение идет с учетом регистра) Print
Strrightback(SourceStr2$, "Ло", 0) Print Strrightback (SourceStr2$, "Jlo",
4)
' Выводит "" (явно задано сравнение с учетом регистра)
Print Strrightback(SourceStr2$, "Ло", 1) Print
Strrightback(Sourcestr2$,
"Ло",
5)
' Выводит "во1 слово2 словоЗ" (сравнение без учета регистра) Print
Strrightback(SourceStr2$, "Ло", 1, 2)
' Выводит "во2 словоЗ" (искалось второе вхождение справа)
Print Strrightback(SourceStr2$, "Ло", 1, 4)
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
244
' Выводит "" (вхождений "Ло" всего три)
Print Strrightback(SourceStr2$, "")
' Выводит "" (нет строки-образца)
Функция Len
Len ( { stringExpr | variantExpr numericExpr typeName } )
Возвращает количество символов в строке или число байтов, необходимых для хранения
числового значения.
stringExpr - строковое выражение. Для строкового выражения функция Len возвращает
число символов.
variantExpr - выражение типа Variant. Для выражения типа Variant функция Len
возвращает число символов, содержащихся в значении variantExpr, преобразованном к типу
String.
numericExpr - имя переменной, элемент массива, элемент списка, элемент типа или
класса, определенного пользователем, должен иметь числовой тип данных. В этом случае
функция Len возвращает число байт, необходимых для хранения значения выражения
numericExpr.
typeName - простая переменная, массив, список, экземпляр типа или объект класса,
определенного пользователем. В этом случае функция Len возвращает число байтов,
содержащихся во всех элементах typeName, кроме элементов типа Variant или типа String
переменной длины. Если тип или класс имеет элементы типа Variant или строки переменной
длины, то результат функции Len для такой переменной может отличаться от простой суммы
размеров элементов.
Len(Null) выдает ошибку. Len(v), где v есть Empty, возвращает 0.
Если длину строки предпочтительнее вычислить в байтах, а не в символах, используется
функция LenB. Функция LenBP используется для вычисления длины строки в байтах в
кодировке текущей платформы.
Пример 1. Длина строки в символах и числового значения в байтах
Dim theString As String
theString$ = "alphabet."
. -.
Print Len(theString$)
' Выводит 8
' Число байт, необходимых для хранения значения типа Single
Dim singleVar As Single
Print Len(singleVar!)
' Выводит 4
Пример 2. Тип, определенный пользователем содержит элемент типа String переменной длины.
Type Orderlnfo
ordID As String * б
custName As String End
Type
Dim ord As Orderlnfo ord.ordID$ = "OR1234"
ord.custName$ = "John R. Smith" ' Суммарный
размер элементов - 19. Print Len(ord.ordID$)
+ Len(ord.custName) ' Размер переменной
такого типа - 16 Print Len(ord)
© InterTrust Co, Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
245
Функция LenB
LenB ( { stringExpr | variantExpr | numericExpr | typeNarne } )
Аналогична функции Len, но всегда возвращает длину строки в байтах.
Пример. Длина строки из 8 символов в байтах.
Dim theString As String
theString$ = "alphabet"
Print LenB(theString$) ' Выводит 16
' Число байт, необходимых для хранения значения типа Single
Dim singleVar As Single
Print LenB (singleVar!)
' Выводит 4
Следует иметь в виду, что число байт в строке вычисляется по кодировке, используемой
LotuScript для внутренней кодировки строк. Этой кодировкой является Unicode.
Функция LenBP
LenBP ( { stringExpr variantExpr numericExpr | typeName } )
Аналогична функции Len, но возвращает длину строки в байтах. При этом подсчет байт
ведется по кодировке текущей платформы.
© Функция LenC
LenC ( stringExpr)
Только для систем письма в колонку (например, тайской)!
Возвращает длину строки, измеренную в колонках.
stringExpr - строковое выражение, содержащее колонки символов.
Результат имеет тип Integer.
LenC(Null) выдает ошибку. LenC(v), где v есть Empty, возвращает 0.
Оператор Mid
Mid[$] ( stringVar, start [, length ]) = stringExpr
Замещает часть строки или всю строку символами другой строки.
stringVar - переменная типа String или Variant, содержащая строковое значение, не может
быть строковым литералом.
start - позиция первого символа в stringVar, с которого начинается замена.
length - число символов, извлекаемых из stringExpr для вставки.
stringExpr - строковое выражение. Символы из stringExpr замещают символы в stringVar.
Оператор Mid может изменить размер stringVar в байтах, если, например, stringExpr
-строка символов в многобайтовой кодировке (LMBCS), а заменяемые символы строки в
stringVar - в однобайтовой. Но длина строки в stringVar, измеренная в символах, всегда
остается неизменной.
© InterTrust Со. Тел. (095) 9567928
Язык LotusScript
246
Оператор Mid использует из строки stringExpr столько символов, сколько указано
параметром length. Если необходимо использовать всю строку stringExpr целиком, то можно
указать значение length заведомо превышающее длину stringExpr, Того же результата можно
добится просто не указывая аргумента length. Если оказывается, что start + length превышает
длину stringVar, то используются не все символы stringExpr, а только необходимые для
заполнения в stringVar позиций с start до (start + length - 1).
Если номер позиции start превосходит длину строки stringVar, то выдается ошибка с
кодом 5 - «Illegal function call».
Пример.
Dim string1 As.String, string2 As String
stringl$ = "ABCDEF"
string2$ = "12345"
.
Mid$(stringl$, 2, 3) = string2$
Print. stringl$
' Выводит A123EF
stringl$ = "ABCDEF"
Mid$(stringl$, 2, 10) = string2$
Print stringl$
' Выводит А12345
stringl$ = "ABCDEF"
Mid$(stringl$, 2} = string2$
Print stringl$
' Выводит А12345
stringl$ = "ABCDEF"
. - '
Mid$(stringl$, 7} = string2$
' Ошибка «Illegal function call»
Функция Mid
Mid[$] ( expr , start [, length ] )
Возвращает подстроку указанной длины (в символах) из строки с определенной позиции
(номер символа). Параметр expr - числовое или строковое выражение. LotusScript
преобразует числовое выражение в строковое перед извлечением подстроки. Параметр start
-позиция первого символа извлекаемой подстроки, отсчитываемая от первого левого символа
исходной строки. Параметр length - число извлекаемых из исходной строки символов. Если
аргумент length не указан, то возвращается подстрока строки expr с позиции start до конца
строки.
Функция Mid возвращает значение типа Variant: DataType 8 (String), а функция
Mid$ -типа String.
Пример.
Print Mid$("ABCDEF",
2,
Print Mid$("ABCDEF",
2)
3)
' Выводит BCD
' Выводит BCDEF
Оператор и функция MidB
Оператор и функция MidB выполняют те же операции что и функция Mid. Отличием
является то, что MidB измеряет стартовую позицию и длину подстроки не в символах, а в
байтах. Во внутреннем представлении LotusScript строки кодированы Unicode. В Unicode
символы кодируются двумя байтами.Таким образом, использование оператора и функции
MidB может приводить к непредсказуемым результатам.
Вместо MidB следует использовать либо Mid, либо MidBP.
© InterTrust Со. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
247
Функция MidBP
MidBP[$] ( expr, start [, length ])
Возвращает подстроку указанной длины в байтах из строки, начиная с указанного байта.
Подсчет байт ведется в кодировке текущей платформы.
expr - числовое или строковое выражение. LotusScript преобразует числовое выражение в
строковое перед извлечением подстроки.
start - порядковый номер первого байта извлекаемой подстроки, отсчитываемый от
начала исходной строки.
length - число извлекаемых из исходной строки байт.
Если параметр length не указан, то возвращается подстрока строки expr с позиции start до
конца строки. Если позиция start превышает длину строки expr, то результатом будет пустая
строка.
Функция МidBР возвращает значение типа Variant DataType 8 (String), а функция MidBP$ типа String.
Функция производит посимвольное выравнивание результата. Это означает, что, если
кодировка строки многобайтная и в результат попадает не целый код символа, а, например,
один байт, то такой символ не включается в результат функции.
Пример.
Выводит БВГ
Выводит БВГДЕ
Выводит ><
© Функция MidC
MidC ( expr, off [, n ] )
Только для систем письма в колонку (например, тайской)!
Из указанной строки извлекает указанное количество колонок, начиная с колонки
указанной по счету слева направо.
expr - строковое выражение, содержащее колонки символов.
off - позиция первой колонки извлекаемой подстроки, отсчитываемая от в исходной
строке слева направо.
n - число извлекаемых из исходной строки колонок символов.
Если указанное смещение off превышает длину строки expr, то результатом функции
будет пустая строка. Если n превышает длину остатка строки ехrр с позиции off, либо
аргумент n не указан, возвращается весь остаток строки expr с позиции off целиком.
Функция InStr
InStr ( [ begin , ] string1 , string2 [, compMethod ] )
Возвращает номер позиции первого символа строки, заключенной внутри другой строки.
begin - опция, положительное целое числовое выражение. Эта опция определяет позицию
внутри строки stringl, начиная с которой функция InStr ищет начало строки string2. Если
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
248
опция begin пропущена, ее значение по умолчанию равно 1 (первый символ — начало строки).
Если указан аргумент compMethod, то должна быть указана и опция begin.
string 1 - строка, в которой функция InStr ищет строку string2.
string2 - строка, которую функция InStr ищет в строке string1.
compMethod - числовое выражение, задающее правило сравнения строк. Флаг может
иметь следующие значения:
compMethod
Способ сравнения
О
С учетом регистра. С учетом
«Pitch»
1
Без учета регистра. С учетом
«Pitch»
4
С учетом регистра. Без учета
«Pitch»
5
Без учета регистра. Без учета
«Pitch»
Если аргумент compMethod не указан, то действуют установки оператора Option Compare,
если таковой присутствует в текущем модуле. Подробнее о способах сравнения строк см. в
описании оператора Option Compare на стр. 163.
Следующая таблица демонстрирует, каким образом функция InStr реагирует на
возможные ситуации.
Условие
Возвращаемое значение
stringl - пустая строка ("")
0
string2 не найдена после начала stringl
0
начало string2 выходит за пределы stringl
0
string2 - пустая строка ("")
Значение begin. Если пропущен begin,
InStr возвращает значение 1 .
Stringl -Null
Null
string2 -Null
Null
begin или compMethod - Null
Ошибка с кодом 94 — «Invalid use of null»
Пример. Значение 5 (позиция первого символа строки LittleString от начала BigString), назначаемое
переменной positionOfChar.
Dim big As String, little As String
Dim positionOfChar As Long
big$ = "abcdefghi"
little$ = "efg"
positionOfChars = InStr(I, big$, little$)
Print positionOfChar& ' Выводит 5
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @,-формулы, LotusScript, встроенные классы LotusScript и Java
249
В случае, если позицию подстроки необходимо получить в байтах, следует
воспользоваться функцией InStrB.
Функция InStrB
InStrB ([ begin , ] stringl , string2 )
Аналогична функции InStr, но в отличие от оной возвращает не позицию символа, а
номер байта. При этом используется внутренняя кодировка строки в LotusScript (LotusScript
для внутреннего кодирования строк использует Unicode).
Функция InStrB не учитывает кодировку текущей платформы. Для этой цели следует
использовать функцию InStrBP.
Пример. Значение 9 - позиция, которую занимает первый байт littleStr от начала 'bigStr.
Dim bigStr As String, littleStr As String
Dim positionOfByte As Long
bigStr$ - "abcdefghi"
littleStr$ = "efg"
positionOfByte& = InStrB (1, bigStr$, LittleStr$)
Print positionOfByte&
' Выводит
9
Функция InStrBP
InStrB ([ begin , ] stringl , string2 )
Аналогична функциям InStr и InStrB, но в отличие от оных возвращает не позицию
символа и не номер байта во внутренней кодировке LotusScript, а номер байта в кодировке
текущей платформы.
Пример. Значение 9 - позиция, которую занимает первый байт littleStr от начала 'bigStr.
Dim bigStr As String,
littleStr As String Dim positionOfByte As Long
,
bigStr$ = "abcdefghi"
littleStr$ = "efg"
positionOfByte& = InStrB (1, bigStr$,
Print positionOfByte&
' Выводит 5
.
.
• '
littleStr$)
"
'"
'
'
'
"
© Функция InStrC
InStrC ( off, stringl , string2 )
Только для систем письма в колонку (например, тайской)!
Для указанной строки возвращает позицию колонки, с которой начинается первое
вхождение указанной подстроки.
off - положительное целое числовое выражение. Задает номер колонки, с которой
начинается поиск.
stringl - строковое выражение, содержащее колонки символов; строка, в которой
производится поиск.
stringl - строковое выражение, содержащее колонки символов; строка, вхождение
которой отыскивается.
© InterTrust Co. Тел. (095) 9567928
г
Язык LotusScript
250
Функция Space
Space[$] ( numExpr)
Возвращает, строку, содержащую указанное количество пробелов. Параметр numExpr
-числовое выражение, задающее необходимое число пробелов. Если оно содержит дробную
часть, LotusScript округляет значение выражения до ближайшего целого. Функция Space
возвращает значение типа Variant DataType 8 (String), а функция Space$ возвращает значение
типа String.
Пример. Определяет строку из 4-х пробелов значением переменной smallTab.
Выводит
Выводит
Функция Spc
Spc (numExpr)
Вставляет указанное количество пробелов в данные, выводимые операторами Print или
Print #, начиная с текущей позиции. Параметр numExpr - числовое выражение, значение
которого лежит в интервале от 0 до 32000 включительно.
Если для файла определена ширина (длина) выводимой строки (см. оператор Width на
стр. 306), действие numExpr определяются следующими условиями:
• если значение numExpr меньше ширины, LotusScript выводит numExpr пробелов.
* если значение numExpr больше ширины, LotusScript выводит допустимое количество
пробелов, перенося "остаток" на следующие строки.
Если для файла длина выводимой строки не определена, функция Spc выводит все
пробелы в одну строку.
Пример. Оператор Print # выводит в файл числа. При этом после каждого числа добавляется
пробел. Также пробел вставляется перед числом, если оно неотрицательно. Мы намеренно добавляем в
конец вывода еще один пробел - Spc(l). Вторая и четвертая строки начинаются с двух пробелов:
первый пробел добавлен Spc(I), а второй является лидирующим пробелом перед выводимым числом (3
или 8). Во второй строке число 4 следует за тремя пробелами: первый пробел является концевым для
«3», второй вставлен Spc(l), а третий является лидирующим для «4».
Open "SPC.TST" For Output As #1
Width #1, 10 For i = 0 To 9
Print #1, i; Spc(1);
Next i Close #1
' Содержимое полученного файла. Конец каждой строки намеренно '
обозначен символом « | » (в файле такого нет) ' 0 1 2 |
3
4
|
' 5 6 7 |
8
9 |
InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
251
Функция Str
Str[$] (numExpr)
Возвращает строковое представление числа. Параметр numExpr - числовое выражение.
Функция Str возвращает значение типа Variant DataType 8 (String), а функция Str$ - типа
String.
Когда LotusScript представляет в виде значения типа String неотрицательное число,
впереди добавляется пробел.
Пример. Присваивает строковые значения 123 и -123 переменным string1 и string2, соответственно.
Для положительного значения добавляется лидирующий пробел.
Dim stringl As String,
stringl$ = Str$(123)
string2$ = Str$(-123)
string3$ = Str$(0)
Print string2$; stringl$;
string2
string3$
As
String, string3$
' Присваивает " 123"
' Присваивает "-123"
' Присваивает " О"
' Выводит: -123 123 0
Функция StrCompare
StrCompare ( stringl , string2 [, compMethod ] )
Сравнивает две строки и возвращает результат,
stringl и string2 - строковые выражения.
compMethod - опция, числовое выражение, задающее правило сравнения строк. Флаг
может иметь следующие значения:
Способ сравнения
compMethod
0
С учетом регистра. С учетом «Pitch»
1
Без учета регистра. С учетом «Pitch»
")
2
Побитно
в
платформы
4
С учетом регистра. Без учета «Pitch»
5
Без учета регистра. Без учета «Pitch»
кодировке
текущей
Если аргумент compMethod не указан, то действуют установки оператора Option Compare,
если таковой присутствует в текущем модуле. Так, например, действие оператора Option
Compare Case, NoPitch равносильно значению опции compMethod = 4. Если в текущем
модуле нет оператора Option Compare, то по умолчанию действуют настройки «Case» и
«Pitch». Подробнее о способах сравнения строк см. в описании оператора Option Compare на
стр. 163.
Следующая таблица определяет результат действия StrCompare, в зависимости от
сравниваемых строк.
Аргументы
Оба Null
stringl меньше string2
Результат сравнения
Null
_]
© InterTrust Co. Тел. (095) 9567928
252
Язык LotusScript
stringl равна string2
0
string1 больше string2
1
Пример. Результат получен в ОС Windows 98
Print
Print
Print
Print
Print
Print
Print
Strcompare("abc","ab",0)'Выводит
Strcompare("ab","abc",0)'Выводит
Strcompare("AB","ab",0) 'Выводит
Strcompare("AB","ab",1) 'Выводит
Strcompare("AB","ab",2) 'Выводит
Strcompare("AB","ab",4) 'Выводит
Strcompare("AB","ab",5) 'Выводит
1
-1
1
О
-1
1
О
(abc > ab)(Case Pitch)
(ab < abc)(Case Pitch)
(AB > ab)(Case Pitch)
(идентичны)(NoCase Pitch)
(AB < аb(побитно)
(AB > ab) (Case NoPitch)
(идентичны)(NoCase NoPitch)
Функция String
String[$] ( stringLen , { charCode stringExpr } )
Возвращает строку, состоящую из символов, определенных указанным кодом в
кодировке текущей платформы или первым символом в строке-аргументе.
stringLen - числовое выражение, значение которого определяет число символов в
возвращаемой строке. Если значение вырадения дробное, LotusScript округляет значение
выражения stringLen до ближайшего целого значения.
charCode - числовое выражение типа Long, значение которого определяет код символа на
используемой платформе. Диапазон допустимых кодов определяется используемой
платформой.
stringExpr - строковое выражение. Первый символ этой строки "размножается" в
возвращаемой строке.
Функция String возвращает значение типа Variant DataType 8 (String), а функция
String$ -типа String.
Пример.
Dim stars As String, moreStars As String
stars$ = String$(4, Asc ("*"))
moreStars$ = String$(8, "* characters")
Print stars$, moreStars$
'Выводит ****
********
Функция LTrim
LTrim ( stringExpr )
Удаляет пробелы (если они есть) в начале строки stringExpr и возвращает результат.
Функция LTrim возвращает значение типа Variant DataType 8 (String), а функция
LTrim$ -типа String.
Пример.
Dim trimLeft$ As String
trimLeft$ = LTrim$("
abc ")
Print trimLeft$
Print Len(trimLeft$)
'
' Выводит "abc " (пробел в конце остался)
' Выводит 4
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
253
Функция RTrim
RTrim[S] ( stringExpr )
Удаляет концевые пробелы из строки и возвращает результирующую строку.Параметр
stringExpr - выражение типа String.
Функция RTrim возвращает значение типа Variant DataType 8 (String), а функция
RTrim$ -типа String.
Пример,
Dim trimRight As String
trimRight$ = RTrim$("
abc ")
Print trimRight$ ' Выводит "
abc" (лидирующие пробелы остались)
Print Len(trimRiqht$)
' Выводит 6
Функция Trim
Trim[$] ( stringExpr)
Удаляет незначащие лидирующие и концевые строки и возвращает результирующую
строку, stringExpr - строковое выражение.
Возвращаемое значение имеет тип Variant DataType 8 (String), а функция Trim$ - типа
String.
Функция оставляет пробелы внутри строки. Для их удаления используйте функцию
FullTrim.
Пример.
Dim trimAll As String, testString As String
testString$ = "
a bc
"
trimAll$ = Trim$ (testString$ )
Print testString$
'Выводит "
a bc
"
Print. trimAll$
'Выводит "a bc" (пробел в середине остался)
© Функция FullTrim
FullTrim ( expr )
Имеет двойное назначение:
из строки удаляет лидирующие, концевые и повторяющиеся внутренние пробелы;
из массива удаляет «пустые» элементы.
expr - может быть строкой, массивом или выражение типа Variant, содержащим массив
или строку.
Результат функции имеет тип Variant и содержит строку, если аргумент был строкой, и
массив, если аргумент был массивом.
Из аргумента-строки удаляются лидирующие, концевые и повторяющиеся внутренние
пробелы. Кроме того, из строки удаляются и повторяющиеся внутренние табуляции и
переводы строки.
Для аргумента-массива функция удаляет «пустые» элементы. То, какой элемент
считается «пустым», зависит от типа массива. Так, в ма ссиве строк «пустыми» считаются
© InterTrust Со. Тел. (095) 9567928
Язык LotusScript
254
элементы «» (пустая строка). В числовом массиве «пустые» элементы - это нулевые
элементы. В массиве типа Variant «пустыми» также считаются элементы со значениями
Empty и Null. Очевидно, что после удаления «пустых» элементов размерность
результирующего массива может уменьшиться. Если все элементы массива оказались
«пустыми», возвращается массив с единственным «пустым» элементом.
На момент написания этих строк была доступна только версия Notes 5.O. И в ней, вопреки
утверждениям документации, значения элементов массива Empty и Null не считались
пустыми и оставлялись функцией FullTrim без изменений. Этот факт иллюстрируется
примером на стр. 271.
Пример. Удаление пустого пространства в строке
' в середине две табуляции
Выводит "abc 123 qwerty" между
abc и 123 одна табуляция
Функция LCase
LCase[$] ( expr )
Возвращает строку, преобразованную к символам нижнего регистра. Параметр expr
-числовое или строковое выражение в функции LCase или выражение типа Variant или String
в функции LCase$. Функция LCase возвращает значение типа Variant (String), а функция
LCase$ возвращает значение типа String.
Функция LCase(Null) возвращает Null. Функция LCase$(Null) возвращает ошибку.
Пример.
' Выводит
Print LCase$("ABC")
"abc"
Функция UCase
UCase[$] (expr)
Преобразует любые символы алфавита в символы верхнего регистра и возвращает
результирующую строку.
expr - для функции UCase, числовое или строковое выражение, для функции
UCase$ -выражение, типа Variant или строковое выражение.
Функция UCase возвращает значение типа Variant(String), а функция UCase$ - типа String.
Функция UCase(Null) возвращает значение Null, функция UCase$(Null) возвращает
ошибку.
Пример. Заданная строка символов преобразуется к строке символов верхнего регистра.
Dim uppercase As String
Print UCase$("abc")
' Выводит "ABC"
Функция StrConv
.
. . i ;•••'••
StrConv ( expr , conversionType )
Преобразовывает строку к другому регистру или кодировке.
€) InterTrust Co. Тел. (095) 9567928
.....
. . . . .. . •
Lotus Domino R. 5: @гформулы, LotusScript, встроенные классы LotusScript и Java
255
expr - строковое или числовое выражение. Числовое выражение преобразуется к
строковому виду.
conversionType - целое число, определяющее тип преобразования, может принимать
следующие значения:
Имя константы
Значение
Тип преобразования
SC UpperCase
1
К верхнему регистру
SC LowerCase
2
К нижнему регистру
SC ProperCase
3
К заглавным буквам
SC_Wide
4
Из однобайтной кодировки в двухбайтную
SC_Narrow
8
Из двухбайтной кодировки в однобайтную
SC_Katakana
16
Из Hiragana в Katakana
SC Hiragana
32
Из Katakana в Hiragana
Приведенные в таблице константы описаны в файле Isconst.lss.
Результат работы функции имеет тип Variant.
Если expr есть пустая строка, то результат будет пустой строкой; если expr - Null, то и
результат Null.
ФУНКЦИЯAsc
'• '.'
:
•: • ' • ' - ' . • ' • :>.•-'•'." ••."•; '.'.-':.- • ; . '''•' i:'-'• ' : ' :':'ул:"-':-'Л' •'.'-:''..':/:";;,;: ; : ,•:-.,.-..:.:::.-.,.-:::-: .;••-:•-.;: :;-:" ;••'-..
Asc ( stringExpr )
Возвращает код (в кодировки текущей платформы) первого символа строки stringExpr.
Тип возвращаемого числа - Long. Если значением выражения stringExpr является Null или
пустая строка (""), то функция возвращает ошибку.
Пример.
Dim bigA As Long
Dim littleA As Long
bigA&. = Asc ("A")
littleA& = Asc("a")
Print bigA&; littleA&
' Выводит 65
97
ФУНКЦИЯChr
Возвращает символ, соответствующей на используемой платформе
заданному коду символа. Параметр numExpr - числовое выражение типа Long.
Действительным будет только значение, лежащее внутри диапазона значений кодов,
представляющих символы на используемой платформе. Функция Chr возвращает результат
типа Variant (String). Функция Chr$ возвращает результат типа String.
Если значение numExpr является дробным числом, то оно округляется до целого
значения.
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
256
Пример.
Dim myAlph As String
Dim letterCode As Long
'Генерация и конкатенация символов из кодов ASCII
For letterCode& = Asc("a") To Asc("z")
myAlph$ =- myAlp.h$ & Chr$ (letterCode&}
Next
Print myAlph$
'Выводит abcdefghijklmnopqrstuvwxyz
Функция UChr
l)Chr[$]( longExpr)
Возвращает символ, заданный числовым кодом Unicode, Параметр longExpr - выражение,
числовое значение которого лежит в диапазоне от 0 до 65535 включительно.
Функция UChr возвращает значение типа Variant(String), функция UChr$ возвращает
значение типа String.
Пример.
Dim azAlphabet As String
Dim letterCode As Long
For letterCode& = Uni("a") To Uni("z")
azAlphabet$ = azAlphabet$ + UChr$(letterCode&) Next Print
azAlphabet$
'Выводит abcdefghijklmnopqrstuvwxyz
Функция Uni
Uni (stringExpr)
Возвращает числовой код Unicode для первого символа строки. Параметр stringExpr
-строковое выражение. Возвращаемое значение имеет тип Long.
Если значением выражения stringExpr является значение Null или пустая строка (""), то
функция возвращает ошибку.
Пример. Выводит коды Unicode, соответствующие символам А и а.
' Выводит 65
97
Функция UString
UString[$] ( stringLen , { charCode | stringExpr } )
Возвращает строку из одинаковых символов. Повторяющийся символ можно определить
или числовым кодом или первым символом строки - аргумента.
stringLen - числовое выражение, значение которого определяет количество
повторяющихся символов в возвращаемой строке. LotusScript округляет значение выражения
stringLen до ближайшего целого значения.
charCode - числовое выражение, значение которого определяет числовой код
повторяющегося символа. Если это необходимо, значение charCode округляется до
ближайшего целого значения. Значение кодов Unicode лежат в диапазоне от 0 до 65535
© InterTrust Со. Тел, (095)9567928
Lotus Domino R. 5: (а),-формулы, LotusScript, встроенные классы LotusScript и Java
257
включительно. Если значение выражения charCode меньше 0 или больше 65535, функция
возвращает ошибку.
stringExpr - строковое выражение. Первый символ этой строки используется, как
повторяющийся символ.
Функция UString возвращает значение типа Variant(String),. функция UString$ возвращает
значение типа String.
Пример.
Dim stars As String, moreStars As String
stars$ = UString$(4, Uni("*"))
moreStars$ = UString$(8, "*chars")
Print stars$, moreStars$
'Выводит ****
********
2.8.4. Операторы и функции обработки данных типа «дата-время»
Оператор Time (установить системное время)
Time[$] = timeExpr
Устанавливает значение системного времени. Параметр timeExpr - выражение, значением
которого является дата-время типа String или Variant.
Функция NOW
- . ... . . . . . . . . .
..;;;:
•• • .......................:
•;
........... --
•• . . • . . - - - • • „ . • . . . . . .
.. -. . . .
Now
Возвращает текущее системное значение даты-времени. Возвращаемое значение имеет
тип Variant DataType7 (Date/Time). .
.
Значение дата-время представляет собой восьмибайтовое число с плавающей точкой.
Целая часть представляет собой порядковый номер текущего дня, считая с 1 января 100 г. н.э.
Дробная часть представляет время текущего дня, считая с полночи предыдущего дня.
Пример. Вывод на экран текущей даты и времени в формате Long Date.
Print Format(Now( ) , "Long Date")
'Выводит Tuesday, June 06, 1995
Функция Date
Date[$]
Возвращает текущую дату. Возвращаемое функцией Date значение является целой
частью значения, возвращаемого функцией Now и имеет тип Variant DataType 7 (Date/Time), а
функцией Date$ - типа String.
Функция Date эквивалентна функции Today.
Пример: Выводится строка "05/25/99" если установлена текущая системная дата 25 мая 1999.
Print DateS
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
258
Функция Today
Today
Возвращает значение системной даты. Тип Variant DataType 7 (Date/Time). Это значение
является целой частью выражения, возвращаемого функцией Now.
Пример. Значение, возвращаемое функцией Today, присваивается переменной whenNow типа
String.
Dim whenNow As String
whenNow$ = Today()
Print whenNow$
'Выводит 6/7/95
Функция Time
Time[$]
Функция Time возвращает значение текущего времени. Возвращаемое значение является
дробной частью значения, возвращаемого функцией Now. Функция Time возвращает
значение типа Variant DataType7 (Date/Time), a Time$ - типа String.
Пример.
Dim current As String
current$ = Time$()
Print current$
'Выводит системное время
Функция DateNumber
DateNumber ( год, месяц, день )
Возвращает дату, соответствующую указанным году, месяцу и дню. Возвращаемое
значение имеет тип Variant DataType7 (Date/Time).
год - числовое выражение, определяющее год.
месяц - числовое выражение, определяющее месяц года, принимающее значения от 1 до 12
включительно. Если месяц представлен отрицательным значением, функция DateNumber
пересчитывает его, вычитая текущее значение из 12 и относит полученное значение месяца к
прошедшему году. Например, если год равен 1999, а месяц равен -2, будет получена дата
Октябрь. 1998.
день - числовое выражение, определяющее день месяца, принимающее значения в
диапазоне от 1 до 31. Если значение выражения является отрицательным числом, то функция
DateNumber вычисляет значение дня, как разность между максимальным значением дня для
предыдущего месяца и этим значением. Например, DateNumber(1995, 5, -3) соответствует
дате Апрель, 27, 1995.
Пример. Вычисление значения даты с использованием отрицательных аргументов.
Print DateNumber(1947, 10, 8)
Print DateNumber(95, 2 - 5 ,
4 - 10}
Print DateNumber( 9 5 , -3, -б)
Функция TimeNumber
TimeNumber ( hour , minute , second )
© InterTrust Co. Тел. (095) 9567928
х
Выводит 10/8/47
' Выводит 8/25/94
Л
Выводит 8/25/94
Язык LotusScript
260
Пример.
Dim x As Variant
Dim yy As Integer
x - DateNumber (1995, 4, 1)
yy% = Year(x)
Print yy%
' Выводит 1995
Функция Month
Month (dateExpr )
Возвращает месяц в виде числа от 1 до 12 для аргумента типа время-дата. Параметр
dateExpr - выражение "дата-время" типа String или Variant. Тип данных возвращаемого
значения - Variant (Integer).
Функция Month(Null) возвращает значение Null.
Пример.
Dim x As Long
Dim mm As Integer
.
x& = DateNumber(1994, 4, 1)
mm% = Month(x&)
Print mm%
' Выводит 4
Функция Day
Day ( dateExpr )
Возвращает день месяца (целое число от 1 до 31) для аргумента дата-время. Параметр
dateExpr - допустимая строка дата-время типа String или типа Variant. Возвращаемое
значение имеет тип Variant. (Integer).
Значение года, определенное двумя цифрами (см. пример выше) определяется как число
из 4 цифр.
Функция Day(Null) возвращает значение Null.
•*
Пример,
Dim x As Variant, dd As Integer
x = DateNumber(1992, 4, 7)
dd% = Day(x)
Print dd%
' Выводит 7
Функция Hour
Hour ( dateExpr)
Возвращает время дня - только час в интервале 0 - 23 - для аргумента дата-время.
Параметр dateExpr - допустимая строка, содержащая значение даты-времени типа String или
Variant. Возвращаемое значение имеет тип Variant (Integer).
Если выражение dateExpr типа Variant содержит значение Null, то функция Hour
возвращает значение Null.
Пример. Формируется сообщения о текущем времени: часе, минутах и секундах текущего дня.
Dim timeFrag As String,
hoursFrag As String
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные массы LotusScript и Java
Dim minutesFrag As String, secondsFrag As
Dim crlf As String, message As String
timeFrag$ = Format(Time, "h:mm:ss AM/PM")
hoursFrag$ = Str( 2 3 - Hour(Time))
minutesFrag$ = Str(59 - Minute(Time))
secondsFrag$ = Str( 6 0 - Second(Time))
crlf$ = Chr(13) & Chr(lO)
261
String
message$ = "Current time: " & timeFrag$ & ". " & crlf$
& "Time remaining in the day: "
& hoursFrag$ & " hours, "
& minutesFragS & " minutes, and "
& secondsFrag$ & " seconds."
MessageBox(message$)
Функция Minute
Minute ( dateExpr )
Возвращает значение минут (целое число от 0 до 59) для аргумента дата-время. Параметр
dateExpr - выражение, содержащее значение даты/времени, тина String или Variant. Тип
возвращаемого значения - Variant (Integer).
Функция Minute(Null) возвращает значение Null.
Пример. Формируется сообщение о значении текущего времени в виде чисел, представляющих
час, минуту и секунду текущего дня
Dim timeFrag As String, hoursFrag As String
Dim minutesFrag As String, secondsFrag As String
Dim crlf As String, message As String
timeFrag$ = Format (Time, "h:mm:ss AM/PM")
hoursFrag$ = Str(23 - Hour(Time))
minutesFrag$ = Str( 5 9 - Minute(Time))
.
secondsFrag$ =- Str(60 - Second (Time) )
crlf$ = Chr(13) & Chr(10)
message? = "Current time: " & timeFrag$ & ". " & crlf$
& "Time remaining in the day: " _
& hoursFrag$ & " hours, "
& minutesFrag$ & " minutes, and " _
& secondsFrag$ & " seconds."
MessageBox(message$)
Функция Second
Second (dateExpr)
Возвращает секунды (целое значение от 0 до 59) для аргумента дата-время. Параметр
dateExpr - строка дата-время типа String или Variant. Возвращаемое значение имеет тип
Variant (Integer).
Функция Second(Null) возвращает значение "Null.
Пример. Формируется и выводится сообщение о значении текущего времени.
Dim timeFrag As String, hoursFrag As String
Dim minutesFrag As String, secondsFrag As
Dim crlf As String, message As String
timeFrag$ = Format(Time, "h:mm:ss AM/PM")
hoursFrag$ = Str( 2 3 - Hour(Time))
minutesFrag$ = Str(59 - Minute (Time) )
String
.
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
262
secondsFrag$ - Str(60 - Second(Time))
crlf$ = Chr(13) & Chr(lO)
message$ = "Current time: " & timeFrags$ & ".
message$ = "Current time: " & timeFrag$ & ". " & crlf$
& "Time remaining in the day: "
& hoursFrag$ & " hours, "
& minutesFrag$ & " minutes, arid "
& secondsFrag$ & " seconds."
MessageBox(message$)
Функция Timer
Timer
Возвращает время в секундах от полуночи до текущего момента. Возвращаемое значение
имеет тип Single.
Пример. Определяется длительность выполнения цикла из 10 000 итераций.
Dim startTime As Single
Dim elapsedTime As Single
.
startTime! = Timer(}
For counter% = 1 To 10000
Next counter!
elapsedTime! = Timer() - startTime!
Print "10000 iterations in "; elapsedTime; " seconds"
Функция Weekday
Weekday ( dateExpr)
Возвращает номер дня недели (в интервале от 1 до 7) для аргумента типа дата-время.
Параметр dateExpr - значение даты-времени типа String или Variant DataType7 (Date/Time).
Тип возвращаемого значения - Variant (Integer). Первым днем недели считается воскресенье,
вторым - понедельник, и т.д.
Функция Weekday(NulI) возвращает значение Null.
Пример.
Dim
x =
wd%
Print
x As Variant, wd As Integer
DateNumber(1993, 7, 7)
= Weekday(x)
wd%
'Выводит: 4
2.8.5. Форматирование данных (функция Format)
Format[$] ( expr [, fmt ] )
Форматирует число, значение дата-время или строку, для которых возможна эта.
операция. Параметр expr - любое выражение, которое оценивается:
• как числовое, если fmt имеет числовой формат;
• как дата-время, если fmt имеет формат даты-времени;
• как строка, если fmt имеет формат строки.
fmt - опция, являющаяся строкой форматирования, которая может быть:
• строкой, содержащей имя предварительно определенного формата;
• строкой символов формата.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @~формулы, LotusScript, встроенные классы LotusScript и Java
263
Если строка fmt не является строкой формата, то функция FormatS выполняется, как
функция Str[$].
Функция Format возвращает строку типа Variant, а функция FormatS возвращает строку
типа String. Если значением выражения ехрг является строка и значением опции fmt - число в
строковом формате, то предпринимается попытка преобразовать строку в число. При
успешном выполнении этой операции результат форматируется.
Если строка преобразуется в число, то предпринимается попытка преобразовать строку в
формат даты-времени и в число. В случае успешного выполнения этих преобразований
результат форматируется.
Если значением выражения ехрг является число, го можно использовать одно из имен
форматов, представленных ниже, или создать свой числовой формат, использующий
числовые коды форматирования.
Имя числового формата
Отображаемое значение для ехрг
с разделением тысяч
General Number
Отображение, использующее системные назначения ОС. В
OS/2, функция не будет добавлять знак $ к числу
Currency
Fixed
Наименьшее значение изображается с одним знаком слева от
десятичного разделителя, и двумя знаками справа
Standard
С разделителем тысяч
Percent
Значение ехрг в интервале от 0 до 100, с добавлением (%)
после числа
Scientific.
Научное представление (в экспоненциальной форме) с
добавлением в конце символа Е и показателя степени со
знаком
Yes/No
No, если число равно 0, в противном случае - Yes
False, если число равно 0, в противном случае - True
Off, если число равно 0, в противном случае - On
On/Off.
Коды числового форматирования
Следующая таблица
форматирования.
Код
представляет
символы,
используемые
для
числового
Значение
"" (Empty)
Вывод не форматированного числа
0 (ноль)
Специальный цифровой режим. Выводит нуль для любой незначащей
цифры в формате, показывая все значащие цифры слева и справа от
разделителя целой и дробной части. Если количество цифр в числе
превышает определенное в формате, число округляется до ближайшего
подходящего значения.
# (знак фунта)
Условное цифровое отображение. Соответствует использованию 0 с
исключением значащих цифр справа и слева от десятичного разделителя.
. (точка)
Десятичный разделитель. Позиция десятичного разделителя в формате.
Если форматный код включает в себя 0 непосредственно слева от
десятичного разделителя, а число между ними -1 и с 1 начинается
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
264
отделяемая часть, то будет использовано положение десятичного
разделителя определенное используемой операционной платформой.
% (процент)
Процентная величина. Определяет число, значение которого не
превышает 100, имеющее в последней позиции знак %.
, (запятая)
Разделитель тысяч. Разделяет число на группы по три значащих цифры,
начиная с первой после десятичного разделителя.
- + ()
Буквенные символы. Показываются в числе, если они использованы в
строке форматирования.
\
Буквенная приставка. Обеспечивает отображение следующего за ней
символа, например \# отображает #. Для отображения самого знака \
используется \\.
"ABC"
Литеральная строка, заключенная в кавычки. Для спецификации
значения кавычек используется Chr(34). Символы, заключенные в
кавычки определяют символы, отображаемые форматной строкой.
Разделяет секции формата - положительную, отрицательную, нулевую 0 и
Null-секцию. Если пропущена отрицательная или 0 секция, но
присутствуют разделители этих секций, форматирование происходит
также, как и при их наличии.
Строка форматирования может содержать в себе от одной до четырех секций,
разделенных знаком точка с запятой ( ; ). При наличии в формате более одной секции,
секции, следующие за первой определяют форматирование других значений числового
выражения. Следующая таблица определяет использование секций в одно - и
многосекционной строке форматирования.
Секции
Описание
Одна
Формат, используемый для всех чисел
Две
Первая секция форматирует положительные числа и 0.
Три
Четыре
Вторая секция форматирует отрицательные числа
Первая секция форматирует положительные числа.
Вторая секция форматирует отрицательные числа.
Третья секция форматирует 0.
Первая секция форматирует положительные числа.
Вторая секция форматирует отрицательные числа.
Третья секция форматирует 0. Четвертая секция
форматирует Null.
Форматирование данных дата-время
Т.к. -значение дата-время имеет внутреннее представление в виде числа с плавающей
точкой, то это значение может форматироваться, как число, или как дата-время. Возможное
использование любого из указанных форматов, или формата, созданного пользователем,
представлено в следующей секции.
Представление переменной дата-время
Название формата
дата-время
Общий формат-
Стандартный формат. Преобразуется в формат числа с плавающей
точкой дата-время. Если число имеет дробную часть, то
представляется только дата. Если число не имеет целой части,
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: (a-формулы, LotusScript, встроенные классы LotusScript и Java
265
Long Date
представляется только время .
Long Date определяется используемой ОС в
рамках международного стандарта.
Medium Date
dd-mmm-yy (yy/mmm/dd в Японии)
Short Date
Short Date определяется используемой ОС в
рамках международного стандарта.
Long Time
Long Time определяется используемой ОС в рамках
международного стандарта. Long Time всегда показывает
текущее значение времени (час, минута, секунда).
Medium Time
Часы (0 - 12) и минуты, использующие разделитель для дата-время и
описание АМ/РМ (АМРМ в Японии)
Short Time
Часы (0 - 23) и минуты, используется только разделитель
дата-время.
Коды форматирования данных дата-время
Следующая таблица описывает символы, которые могут использоваться в форматах,
созданных для представления значений дата-время.
Код
Значение:
/
Разделитель времени. Разделяет часы, минуты, секунды в формате значения
времени.
Разделитель даты. Разделяет день, месяц и год в формате значения даты.
с
Представляет дату в виде ddddd, и время в виде ttttt (см. ниже).
у
Номер дня в годе (1 - 366).
d
День в месяце (1 -31).
dd
День в месяце (0 ! -31).
Odd
Сокращенное название дня недели (Sun - Sat).
dddd
Промежуток времени между днями недели (Sunday - Saturday).
Ddddd
Положение цифр в дате (день, месяц, год) в международном формате строка Short
Date. В противном случае, по умолчанию используется формат mm/dd/yy.
Dddddd
Положение цифр в дате (день, месяц, год)в международном формате строка Short
Date. В противном случае, по умолчанию используется формат mmmm dd, yyyy.
\v
Номер дня недели (1 - 7). Воскресенье - 1 .
vvw
Номер недели в году (1 - 53).
m
Номер месяца в году (1 - 12). Если в этом формате присутствует символ h минуты
представляются в диапазоне 0 - 59.
mm
Mmm
Номер месяца в году в виде (01 - 12). Если в этом формате присутствует символ h
минуты представляются в диапазоне 00 - 59.
Сокращенное 3-х символьное название месяца (Jan - Dec).
mtnmm
Промежуток времени между месяцами года (January - December),
q
Номер квартала в году (1 - 4).
УУ
Две последние цифры года (00 - 99).
:
) InterTrust Co. Тел. (095) 9567928
Язык LotusScript
266
Yyyy
Полное значение года (0100 - 9999).
h
Значение часа дня в виде (0 - 23).
hh
Значение часа дня в виде (00 - 23).
n
Значение минуты в часе в виде (0 - 59).
nn
Значение минуты в часе в виде (00 - 59).
s
Значение секунды в минуте в виде (0 - 59).
ss
Значение секунды в минуте в виде ((00 - 59).
Ttttt
Значение времени, включающее значения часа, минут, секунд, использующее
разделитель, предусмотренный используемой ОС. Если используется
дополняющее значение 0 (01), предусмотренное в системе, то время имеет формат
10:00 AM или РМ. По умолчанию формат времени имеет вид h:mm:ss.
AМ/РМ
Используется часовой интервал от 1 до 12, с указанием AM или am/pm PM в
зависимости от половины дня (до и после полудня).
Используется часовой интервал от 1 до 12, с указанием А или Р в зависимости от
половины дня (до и после полудня). Используются значения часа дня в интервале от
1 до 12. В файле WIN. INI время содержится в виде строки 1 159 для дополуденных
значений часа, и в виде 2359 для послеполуденных. Для АМРМ не имеет
значения используемый регистр клавиатуры. По умолчанию используется
представление АМ/РМ.
A/P a/p
AMPM
Следующая таблица демонстрирует использование форматирования даты/времени для
даты 12 апреля 1995 г. и времени 6:43:04:
Формат
Представление
m/d/yy
4/12/95
d-mmm-yy
12-Apr-95
d-mmmm
12-April
mmmm-yy
April-95
У
102
hh:mm AM/PM
06:43 PM
h:mm:ss a/p
6:43 :04p
h:mm
18:43
h:mm:ss
18:43:04
m/d/yy h:mm
4/12/95 18:43
Коды форматирования строковых данных
Форматировать строку можно с помощью функций Format или Format$, использующих
коды форматирования. Строка форматирования может состоять из одной или двух секций,
разделенных знаком (;). Односекционный формат воздействует на все стро ки, в
двухсекционном, первая секция воздействует на не пустую строку, а вторая на строку со
значением Null или ("").
Следующая таблица определяет символы, использующихся при создании формата для
строки.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: (формулы, LotusScript, встроенные классы LotusScript и Java
267
Код
Значение
@
Представление данного символа. Если строка формата включает в себя этот
символ, то он выводится в соответствующую позицию, иначе выводится пробел.
При наличии (@) формат должен содержать знак (!).
&
Опция представления символа. Если строка формата включает в себя этот символ, то
он выводится в соответствующую позицию. В противном случае ничего не
выводится. При наличии (&) формат должен содержать знак (!).
<
Все символы форматируемой строки, соответствующие нижнему регистру.
>
Все символы форматируемой строки, соответствующие верхнему регистру.
i
Заполнение символами @ или & слева направо
Пример.
Dim rev As Currency, expense As Currency, bal As Currency rev@
= CCur(InputBox("How much did we make this month?"}) expenses
= CCur(InputBox("How much did we spend?")) bal@ = rev@ - expensed
MessageBox "Our balance this month is "
& Format(bal@, "Currency")
2.8.6. Функции работы с массивами
ОператорOptionBase
Option Base base
Оператор устанавливает нижнюю границу по умолчанию для всех измерений массивов в
значение base (0 или 1). По умолчанию нижняя граница измерений массивов установлена в 0.
Option Base действует в пределах, содержащего его модуля и может использоваться в
модуле только один раз. Если он используется, то должен предшествовать объявлениям всех
массивов и операторам ReDim в этом модуле.
Пример. Создание одномерного массива из 20 элементов (sample(l) - sample(20)) с начальным
значением индекса равным 1.
Option Base I
Dim sample (20) As Integer
.
ФункцияLBound
LBound ( arrayName [, dimension ] )
Возвращает значение нижней границы указанного измерения массива. arrayName - имя
массива. Параметр dimension - опция, целое число, определяющее измерение массива,
значение нижней границы которого необходимо получить. Возвращаемое значение имеет
тип Integer.
По умолчанию нижняя граница размерности массива есть 0 или 1, что определяется
назначениями в Option Base (см. описание опции Option Base на стр. 149).
Пример.
Dim minima(10 То 20)
Print LBound(minima)
' Выводит:
10
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
268
Функция UBound
i;
UBound ( arrayName [, dimension ])
"
Возвращает значение верхней границы указанного измерения dimension массива
arrayName. Возвращаемое значение имеет тип Integer.
Пример.
Dim maxima(10 То 20)
Dim upperBound As Integer
.
upperBound% = UBound(maxima)
Print upperBound%
'Выводит: 20
- .
..
© Функция ArrayAppend • ..::-:: :::;;>,- ... .......... .•--'":...-..
... ..;..•>•; • -•-•;.... -:.
ArrayAppend (array], v2 ) Добавляет
массив к другому массиву.
Если вы уже знакомы с языком @-формул Notes, то функцию ArrayAppend удобно
понимать как аналог оператора «:».
Аргументы:
array! - значение типа Variant, содержащее массив.
v2 - произвольное значение типа Variant.
Возвращаемый результат является значением типа Variant, содержащим массив. Данный
массив обладает следующими свойствами:
•
размерность получаемого массива равна сумме размерностей аргументов (если v2 скалярное значение, то оно рассматривается как одноэлементный массив);
* если объединяются массивы одинаковых типов, то результирующий массив
получается того же типа;
• если объединяются массивы разных типов, то результирующий массив содержит
значения типа Variant, но реальные типы элементов совпадают с типами
соответствующих элементов исходных массивов;
* нижнее значение измерения совпадает с оным в vl
Функция не затрагивает оригинальных значений аргументов — vl и v2.
Притом, что второй аргумент - v2 - может быть скалярным значением или одномерным
массивом, первый аргумент обязан быть одномерным массивом. В противном случае
возникает ошибка времени исполнения «Type Mismatch».
Превышение максимально допустимой размерности массива также приводит к ошибке
времени исполнения - «Subscript out of range».
Пример 1. Объединение двух массивов различных типов.
Dim vl(2) As Integer
Dim v2( 1 ) As String
Dim v3 As Variant
Dim i%
.
vl ( 0 ) = 1
v l ( l ) =2
vl( 2 ) = 3
v2( 0 ) - "4"
v 2 ( l ) = "5"
v3 -- Arrayappend (vl, v2)
For i% = Lbound(v3) To Ubound(v3)
© InterTrust Co. Ten. (095) 9567928
•
.-
•
-
Lotus Domino R. 5: (а^формулы, LotusScript, встроенные классы LotusScript и Java
269
Print i%, Typename(v3(i%})
Next
' Вывод в строке состояния: х 1
INTEGER v 2
INTEGER ' 3
INTEGER 1 4 STRING ' 5 STRING
© Функция ArrayGetlndex
ArrayGetlndex ( arrayName, value [, optCompare] )
Возвращает позицию значения value в массиве arrayName.
Если вы уже знакомы с языком @-формул Notes, то функцию ArrayGetlndex удобно
понимать как аналог функции @Member.
Аргументы:
arrayName — массив или значение типа Variant, содержащее массив
value - произвольное значение
optCompare - числовая опция, задающая правила сравнения значений.
Если искомое значение присутствует в массиве, то результатом является значение Variant
типа Long, содержащее номер позиции искомого значения в массиве. Е.СЛИ значение value не
содержится в массиве аrr, то возвращается NULL.
При выполнении сравнения и элементы массива АДГ и значение value значения
предварительно преобразуются к строковому виду. Те элементы, преобразование которых в
строковом виде невозможно, в сравнении не участвуют.
В случае если массив АДГ имеет несколько измерений, позиция элемента определяется по
следующему правилу. Массив виртуально представляется имеющим одно измерение с
размерностью равной сумме размерностей всех его измерений. Индекс представляется
состоящим из нескольких частей - по числу измерений оригинального массива. «Быстрее»
изменяется первая часть индекса, соответствующая первому измерению. Данное правило
иллюстрирует пример 2.
Опция optCompare является числом 0, 1 , 4 или 5. Определение этих значений аналогично
определению для функции InStr (см. описание функции InStr на стр. 247). В случае если
опция пропущена, используется значение по умолчанию, определяемое наличием или
отсутствием для текущего модуля опции Option Compare (стр. 163).
Пример 1. Использование функции ArrayGetlndex
Dim arr{2) As Integer
arr(O) - 1
arr(l) = 3
arr(2) = 4
Print. Arraygetindex(arr, 1), Arraygetindex(arr, "4"), Arraygetindex(arr,
8)
' Вывод в строке состояния
' 0
2
Null
Пример 2. Случай массива с несколькими измерениями
Dim arr(l, 1) As Variant
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
270
H
arr(0, 0) - "1"
arrfl, 0) = "3"
arr (0, 1) = "4"
arr(l, 1) = "7"
Print Arraygetindex (arr, "1"), Arraygetiridex (arr, "4"),
Arraygetindex(arr, "8")
' Вывод в строке состояния
' 0
2.
Null
.•;;.V
© Функция ArrayReplace
ArrayReplace ( arrayName, v2, v3)
Функция возвращает копию массива arrayName, в котором элементы, имеющие аналоги в
v2. заменяются на соответствующие элементы v3.
Если вы уже знакомы с языком @-формул Notes, то функцию ArrayReplace удобно
понимать как аналог функции @Replace.
arrayName - значение типа Variant, содержащее массив.
v2, v3 — значения типа Variant, содержащие массивы; могут быть скалярными значениями тогда они понимаются как массив размерности 1.
Результат возвращается в виде значения Variant, содержащего массив. Результирующий
массив строится по следующему правилу. Функция создает копию массива arrayName и в
процессе поэлементного копирования проверяет, имеется ли очередной элемент массива
arrayName в массиве v2. Если совпадение обнаружено, в результирующий массив
помещается элемент массива v3, находящийся на той же позиции в v3, что и совпавший в v2.
Если индекс совпавашго элемента в массиве v2 больше размерности массива v3, то
копируется пустой элемент - 0 или пустая строка. Очевидно, что размерность
массива-результата равна размерности исходного массива arrayName.
При выборе элемента из массива v3 используется не абсолютное значение индекса
элемента в v2, а относительное. Лучше показать это на примере. Предположим, массив v2
имеет индекс (-10, 0), а массив v3 - (1, 10). Тогда элементу v2(-10) соответствует элемент
v3(l), элементу v2(-l) — v3(10), а индекс элемента v2(0) уже выходит за пределы размерности v3.
В первой реализации функции (на момент написания этих строк имеется только версия
5.0) не производится никакого преобразования типов данных элементов массивов. Это
означает, что совпадение элементов массивов arrayName и v2 может быть обнаружено только
тогда, когда элементы имеют одинаковый тип. Это видно и из примеров 2 и 3,
Кроме того, первый опыт использования этой функции показывает, что не производится
сравнение элементов типа дата/время. Это видно в примере 1.
Пример 1.
Option Declare
Dim vl(2) As Integer, v2(2) As Integer, v3(0) As Variant, __
v4 ( 0) as Variant
Dim resl, res2, res3
Dim i as Integer
vl(0) = 1
vl(1) = 2
vl(2) = 9
' массив vl = [1, 2, 9]
v2(0) = 1
v2(l) = 2
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
271
v2(2) = 3
' массив v2 = [1, 2, 3]
v3(0) = Today
' массив v3 - [ 2 0 . 0 5 . 9 9 ]
v 4 ( 0 ) = Cstr (v3 ( 0 ) ) ' массив v4 = [ " 2 0 . 0 5 . 9 9 " ]
resl = Arrayreplace (vl, v2, v3)
' resl = [ 2 0 . 0 5 . 9 9 , 0, 9] For
i% = Lbound(resl) To Ubound (resl )
Print r e s l ( i % ) , Typename (resl ( i% ) ) Next
' выводит :
1
20.05.99 DATE
' 0
INTEGER
' 9
INTEGER
res2 = Arrayreplace (v3, v3, 999)
1
res2 = [ 2 0 . 0 5 . 9 9 ]
1
не работает сравнение элементов типа DATE
гезЗ = Arrayreplace (v4 , v4 , 999)
' res3 = [999]
но работает сравнение Variant,
' содержащего строку
1
Пример 2. Не сравниваются элементы массивов разных типов
Dim v l ( l )
As Integer,
= "some value"
resl = Arrayreplace (vl ,
resl = [1, 9]
v2(l)
As String, v3(0) As Variant
v2, v3) %
Пример З. Даже для массивов одинаковых типов Variant сравниваются элементы только
одинаковых типов. Если бы преобразование типа имело место, то 2 и "2" считались бы одинаковыми и
массив-результат имел бы вид ["some value", 0]
Dim v l ( l ) As Variant, v 2 ( l ) As Variant, v3(0) As Variant
Dim resl
vl ( 0 ) = 1
vl( 1 ) - 2
v2(0) - 1
'
- •
v2(l) = "2"
v3( 0 ) = "some value"
resl = Arrayreplace(vl, v2, v3)
" resl = ["some value", 2]
. .
.
© Функция FullTrim
FullTrim ( expr )
expr - выражение типа Variant, содержащее массив или строку.
Для аргумента-массива функция удаляет «пустые» элементы. То, какой элемент
считается пустым, зависит от типа массива.
Для аргумента-массива функция удаляет «пустые» элементы. То, какой элемент
считается «пустым», зависит от типа массива. Так, в массиве строк «пустыми» считаются
элементы "" (пустая строка). В числовом массиве «пустые» элем енты — это нулевые
© InterTrust Со. Тел. (095) 9567928
Язык LotusScript
272
элементы. В массиве типа Variant «пустыми» также считаются элементы со значениями
Empty и Null. Очевидно, что после удаления «пустых» элементов размерность
результирующего массива может уменьшиться. Если все элементы массива оказались
«пустыми», возвращается массив с единственным «пустым» элементом.
На момент написания этих строк была доступна только версия Notes 5.O. И в ней, вопреки
утверждениям документации, значения элементов массива Empty и Null не считались
пустыми и оставлялись функцией FullTrim без изменений. Этот факт иллюстрируется
примером.
Об использовании этой функции для удаления пустого пространства из строки на стр.
253.
Пример. Удаление "пустых" элементов массива.
Dim StrArr(2) As String Dim
NumArr(2) As Integer Dim
VarArr(6) As Variant
StrArr(O) = "aaa" : StrArr(l) = "" : StrArr(2) = "bbb" '
Массив StrArr: ["aaa", "", "bbb"]
NumArr(O) = 1 : NumArr (1) = 0 : NumArr (2) -- 2
Массив StrArr: [1, 0, 2]
1
'
VarArr(O)- специально не заполняем - он останется Empty
VarArr(l) = "QWERTY"
VarArr(2) = ""
VarArr(3) = 0
VarArr(4) = 1 2
VarArr(5) = Now
VarArr(6) = Null
' Массив VarArr: [,"QWERTY", "", 0, 12, 23.05.99 20:21:34, Null]
Dim vl, v2, v3
vl = Fulltrim(StrArr}
v2 = Fulltrim(NumArr;
v3 = Fulltrim(VarArr)
1 Массив v3: [,"QWERTY", 12, 28.05.99 20:21:34, Null]
' Значения Empty и Null остались!
2.8.7. Операции с окнами
Функция InputBox
InputBox[$] ( prompt f, [ title ] [, [ default ] [, xpos , ypos ] ] ] )
Выводит на экран диалоговое окно с сообщением, определенным пользователем, и
возвращает введенную пользователем строку.
prompt - строковое выражение, значение которого выводится в диалоговое окно, длина
выражения prompt не должна превышать 128 символов.
title - опция, являющаяся строковым выражением. Значение title выводится в заголовок
диалогового окна. Максимальная длина значения title не должна превышать 128 символов.
Если значением опции title является пустая строка - заголовок окна будет пустым. Если для
пустого значения title установлены координаты xpos и ypos, в заголовок окна выводится
запятая.
© InterTrust Со. Тел. (095)9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
273
default - опция, являющаяся строковым выражением. Значение опции default выводится в
диалоговое окно, как установленный по умолчанию, ответ пользователя. Длина строки
default не должна превышать 512 символов. Если значением опции default является пустая
строка и определены координаты xpos и ypos, в поле ввода ответа пользователя выводится
запятая.
xpos - опция, являющаяся числовым выражением, определяющим смещение левой
границы диалогового окна от левой границы экрана в специальных единицах 1/1440 inch (.05
point). Если определено значение xpos, необходимо определить и значение ypos.
ypos - опция. , являющаяся числовым выражением, определяющая смещение верхней
границы диалогового окна от верхней границы экрана в специальных единицах 1/1440 inch
(.05 point). Если определено значение ypos, необходимо определить и значение xpos.
Функция InputBox возвращает значение типа Variant, содержащее строку. Функция
InputBoxS возвращает строку типа String.
Функция InputBox выводит на экран диалоговое окно, содержащее кнопки OK, Cancel,
поле для ввода текста пользователем, при этом выполнение скрипта приостанавливается до
момента, пока пользователь не нажмет кнопку ОК или Cancel. Если нажата кнопка Cancel, то
возвращается пустая строка ("")•
Пример. Введенный пользователем текст преобразуется в целое число.
Dim num As Integer
. . .
num% '= Cint(Inputbox$("How many do you want?",_
"Numeric value input","2"))
Функция и оператор MessageBox
Функция:
MessageBox ( message [, f buttons + icon + default •+ mode ] [, boxTitle ] ] )
Оператор:
MessageBox message [, [ buttons + icon + default + mode ] [, boxTitle ] ]
Выводит на экран сообщение в окне сообщения и ждет ответа пользователя. Функция
возвращает значение, приписанное кнопке, нажатой пользователем. Функция и оператор
MessageBox идентичны, только функция возвращает значение, а оператор - нет.
message - сообщение, выводимое в окно сообщений, длиной до 512 символов.
buttons - определенные числами или значениями констант из следующей таблицы кнопки,
представленные в окне сообщений.
Имя константы
Значение
Кнопка
МВ_ОК
0
OK
MB_OKCANCEL
1
OK и Cancel
MB_ABORTRETRY1GNORE
2
Abort, Retry, и Ignore
MB_YESNOCANCEL
3
Yes, No, и Cancel
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
274
MB_YESNO
4
Yes и No
MB_RETRYCANCEL
5
Retry и Cancel
icon - определяет пиктограммы, выводимые в окно сообщения. Значение icon
определяется из следующей таблицы.
Имя константы
Значение
Пиктограмма
MBJCONSTOP
16
Знак Stop
MBJCONQUESTION
32
Знак вопроса
MB ICONEXCLAMATION
48
Восклицательный знак
MBJCONINFORMATION
64
Информация
default - определяет по умолчанию специальные кнопки, выводимые в окно сообщения.
Нажатие клавиши ENTER для такой кнопки эквивалентно клику по клавише "мыши".
Значения кнопок "мыши" в окне определяются следующей таблицей:
Имя константы
Значение Кнопка "мыши"
MB_DEFBUTTON1
0
1 -я кнопка
MB_DEFBUTTON2
256
2-я кнопка
MB_DEFBUTTON3
512
3-я кнопка
mode - определяет действие кнопок окна сообщений. Следующая таблица представляет
список действий, производимых кнопками окна сообщений.
Имя константы
MB_APPLMODAL
MB SYSTEMMODAL
Значение
0
4096
Действие
Останавливает выполнение текущего приложения до
тех пор, пока пользователь не отреагирует в окне
сообщения нажатием кнопки.
Останавливает выполнение всех приложений до тех
пор. пока пользователь не отреагирует в окне
сообщения нажатием кнопки.
boxTitle - строка, выводимая в заголовок окна сообщения, длиной до 128 символов.
Функция MessageBox возвращает целое число от 1 до 7, включительно. Это значение
определяет, какая кнопка была нажата пользователем в окне сообщения. Соответствие между
значениями функции и значением кнопок приведено в следующей таблице.
Возвращаемое Кнопка
значение
Константа
1
ОК
IDOK
2
Cancel
IDCANCEL
3
Abort
LDABORT
4
Retry
1DRETRY
5
Ignore
IDIGNORE
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
6
Yes
IDYES
7
No
IDNO
275
Все значения констант, представленные в этих таблицах, содержатся в ф айле
LSCONST.LSS. Для использования значений констант, хранящихся в этом файле, его
необходимо включить в скрипт с помощью директивы %Include.
Пример 1. Вывод запроса: " Вас еще не утомили эти функции?" в окне с заголовком " Вопрос
толстой книги ", содержащем кнопки Yes и No. Значение, возвращаемое функцией MessageBox
присваивается переменной answer.
% Include "LSCONST.LSS"
Dim boxType As Long, answer" As Integer
boxTypeS = MB YESNO + MB_ICONQUESTION '
answer% = MessageBox("Вас еще не утомили эти функции?", ЬохТуре&, _
"Вопрос толстой книги")
Л
После нажатия кнопки
Print answer%
(предположим,
' Выводит 6
Yes)
'
выводим результат
Пример 2. Оператор MessageBox выводит в окно сообщений с заголовком "Demo" и кнопкой ОК
несколько строк.
%Include "LSCONST.LSS"
Dim twoLiner$ As String
twoLiner$ = !Многострочное сообщение!
MessageBox twoLiner$, MB_OK, "Demo"
twoLiner$ = {Многострочное}+Chr$(10)+{ сообщение}
MessageBox twoLiner$, MB OK, "Demo"
Л Получаем подряд два одинаковых сообщения:
. . .
. •-,.---.
Оператор ActivateApp (активизировать окно)
ActivateApp windowName
Активизирует окно приложения, имеющее указанный заголовок. windowName - текст
заголовка активизируемого окна - строковое выражение, без учета регистра.
При поиске окна учитывается лишь вхождение текста из строки windowName слева в
заголовок. Например, если необходимо активизировать окно Notes с заголовком "Lotus Notes Workspace", то в качестве windowName достаточно задать "Lotus Notes". Если в списке
имеющихся окон окажется несколько с одинаковым или подобным заголовком, будет
активизировано первое найденное окно.
| InterTrust Co. Тел. (095) 9567928
Язык LotusScript
276
Учтите, что ActivateApp только активирует окно (т.е. передает ему фокус ввода), но не
может восстановить в нормальный размер или максимизировать, если окно свернуто. Для
восстановления размеров окна или максимизации следовало бы послать этому окну "серию
нажатий клавиш, используя оператор SendKeys.
Пример. Активирует окно с заголовком "Lotus Notes - Workspace".
ActivateApp "Lotus Notes"
,-,,
Оператор SendKeys
SendKeys string [, processNow ]
Строка string содержит последовательность клавиш клавиатуры, имитацию нажатий
которых в активном окне выполняет этот оператор. Имеется целый ряд соглашений, как в
строке кодируются клавишные комбинации: {F4}, {CAPSLOCK}, {RIGHT 3}...
К сожалению, в реализации LotusScript для Notes этот оператор не поддерживается. В
качестве компенсации читателю предлагается пример, в котором необходимый эффект
достигается путем вызова соответствующих функций Windows API. Пример можно найти в
главе, посвященной обращению к внешним С-функциям на стр. 337.
2.8.8. Специальные функции и операторы
Оператор Веер (звуковой сигнал)
Веер
Издает простой звуковой сигнал.
Для воспроизведения более сложных звуков можно воспользоваться либо новым методом
Play Tune класса NotesUlWorkspace (см. стр. 711), либо использовать средства Winodws API
(см. пример на стр. 331)
ФункцияCommand. ":; .-'••.".•.'. : •••' •••:••">-,•••:'/•'•:.:.:.;•-:--:.".•••..••:•"": •:•••••;•••••'-'•:--••". ........... •
.;
Command[S]
Возвращает строку параметров, которая была передана при запуске приложению Lotus,
использующему LotusScript, или пустую строку (""), если приложение было запущено без
параметров. Функция Command возвращает значение типа Variant (String). Функция
Commands возвращает строку.
Пример. Определяется наличие параметров в командной строке.
If Command$() = "" Then
Print "Notes запущен без параметров"
Else
Print " Notes запущен с параметрами: " + Command$() End
If
ФункцияEnviron.';•/•.: ••:•."'•••: "•.. -..-:•'••• ~^-~•••• • •...". ••:. ... -;.'.'.•'•••.•••••'-^--у••/•'.:.:•;.:;.......•::...•.;.•--.:--........•
Environ[$] ( { environName | n } )
Возвращает информацию, содержащуюся в переменной среды операционной системы.
environName - строка символов верхнего регистра, определяющая имя переменной среды, n число от 1 до 255, включительно, определяющее положение переменной среды в таблице
i InterTrust Co. Тел, (095) 9567928
Lotus Domino R. 5: (^-формулы, LotusScript, встроенные классы LotusScript и Java
217
переменных среды. Функция Environ возвращает значение типа Variant, а функция EnvironS
возвращает значение типа String.
Если для определения имени переменной среды используется environName, возвращается
значение, определенное переменной среды. Если переменная среды не найдена, возвращается
пустая строка (""). Если строка environName - пустая строка, или строка содержащая
значение Null или Empty, то генерируется ошибка.
Если позиция переменной среды определена числом п, возвращается строка с именем
переменной среды и ее значением. Если значение п превышает действительное число строк в
таблице, то возвращается пустая строка (""). Если п меньше 1 или больш е 255, то
генерируется ошибка.
Пример. Microsoft Windows 3.1 хранит временно существующие рабочие файлы в каталоге,
объявленном в переменной среды с именем Temp. Введенная пользователем строка выводится в файл
MYAPP.TMP в этом каталоге. Для определения пути к временному каталогу см. команду Set Temp в
своем AUTOEXEC.BAT.
Dim TempDir As String, tempFile As Integer
.
•
.Dim tempFileName As String, tempStuff As String
tempStuff$ = InputBox("Enter some temporary information")
TempDir$ = Environ("Temp")
,
ChDir TempDir$
tempF.ile% = FreeFileO
tempFileName$ = "myapp.tmp"
Open terrtpFileName$ For Output As tempFile%
Print #tempF.ile%, tempStuff $
"
Close tempFile%
.
..
Функция Shell
Shell (program [, windowStyle ] )
Запускает программу. Program - строковое выражение, значение которого определяет имя
запускаемой на выполнение программы, program должно быть именем исполняемого файла с
расширением ВАТ, COM, PIF, или ЕХЕ. Указание расширения или включение полного пути в
спецификацию файла программы необязательно. Запуск с помощью функции Shell на
выполнение внутренней команды DOS вызывает ошибку.
WindowStyle - опция, являющаяся числом, определяющим стиль окна запускаемого
приложения; она дается следующей таблицей.
Стиль (Style)
Описание
Константа
1,5 или 9
Нормальное с фокусом
SHELL_NORMAL_FOCUS
2
Минимизированное с
фокусом (по умолчанию)
SHELLJV11NJFOCUS
3
Максимизированное с
фокусом
SHELL JV1AX_FOCU S
4 или 8
Нормальное без фокуса
SHELL_NORMAL_NO_FOCU S
6 или 7
Минимизированное без
фокуса
SHELL_MIN_NO_FOCUS
Эти константы определены в файле LSCONST.LSS. Для обеспечения возможности
использования этих констант включите этот файл в скрипт.
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
-" ' ' ; '-'-
278
"
•>
,v
Если используется операционная система Windows 3.1 и LotusScript успешно запускает
программу, Shell возвращает идентификатор запущенной задачи. Если используется ОС
Windows NT и LotusScript успешно запускает программу, Shell возвращает число 33. Если
LotusScript не может запустить программу, Shell возвращает ошибку. • , '--.-••*-•
Shell может вызываться из выражения или оператора присваивания, если они возвращают
используемое этим оператором значение. После выполнения Shell, LotusScript продолжает
выполнение скрипта, не ожидая завершения выгюлнеуия запущенной программы.
Пример. Запуск приложения Windows Calculator в нормальном режиме.
Dim taskld As Integer
taskld% = Shell("CALC.EXE",
1}
,
>
.
Функция и оператор Yield
,
' '•'
,
*- ':-: • '
^
Yield
Функция и оператор Yield передают управление операционной системе, а выполнение
текущего процесса "встает в очередь". ОС Windows не может вернуть управление процессу
до тех пор, пока не обработает все стоящие в очереди запросы. Оператор и функция Yield
допустимы внутри процедуры или класса и не допустимы в модуле. Функция Yield
возвращает значение типа Integer равное 0.
.,
Пример. Объявление для Windows 3.1 API функции, передача управления программе CALC.EXE,
ожидание завершения ее выполнения, выдача сообщения о завершении выполнения программы
CALC.EXE и продолжение выполнения скрипта.
Авторы не рекомендуют относиться к этому примеру как к "боевому приему" для разработки
приложений Notes. Во-первых, в 16-разрядной версии Windows пример хотя и работает, но не вполне
корректно. Во-вторых, в 32-разрядных версиях Windows функция Shell возвращает 33, а не
идентификатор задачи, а функция GetModuleUsage более не применяется.
Declare Fun ctio n GetMod uleUsage Lib "Kernel"^
. . . "'
;
(ByVal taskID As Integer) As Integer
.
* ' ' ' : • ". i " ', :'.' -':
'
""
Sub DoCalc
' '...-. ,:• !; n:;" i"« . - • . - ! . • - - • : . ••:•.•'••..-.
v.
/'";. '
'
•-.•••••••
Dim taskID As Integer
-.-• . ' • • ' • •
- •'•
• - ' • ' ' ' •-"•'••'''
taskID% = Shell ("CALC.EXE", ! ) • •
'
'
' '
":";"' \-v'^ :^-> •'•• ":.
Do While GetModuleUsage (taskID%) > 0
_• .
.,
......
;
Yield
"' " _
. - ' - . ; / ..-::
:
Loop
'
'
. . . . . . . . .
MessageBox "Calculations done"
End Sub
.
,
DoCalc
. 'Вызов подпрограммы DoCalc
" • ' ''
'" ' : ' :
;
Оператор Stop
Stop
, . . . . . . ,
В режиме отладки скрипта имитирует наличие точки останова (breakpoint). При
выполнения скрипта вне отладчика никак себя не проявляет.
Очень простой и в то же время полезный оператор. Используя данный оператор можно
съэкономить ощутимое время на отладке скрипта (особенно таких, как скрипт события
QuerySave формы). , ' • • _ • . ' ] • ' " ' • ; • '
. • ' • . * • -••• •••••'
.•'•:'"
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @гформулы, LotusScript, встроенные классы LotusScript и Java
279
2.8.9. Функции проверки значений
Функция IsEmpty
IsEmpty (expr )
Проверяет, является ли значение выражения ехрг значением Empty. Возвращает True,
если значением выражения ехрг является значение Empty. Это бывает только в случае, когда
значение выражения ехрг имеет тип Variant и является пустой строкой. В противном случае
функция IsEmpty возвращает значение False (0).
Пример.
Dim dynaVar As Variant
Print IsEmpty(dynaVar)
dynaVar = PI
Print IsEmpty(dynaVar)
'Выводит:
True
'Выводит:
False
Функция IsNull
IsNull (expr )
Возвращает True, если значением выражения ехрг является значение Null. В противном
случае возвращает False.
Пример.
Dim v As Variant
Print IsNull(v)
Print IsEmpty(v)
v = Null
Print IsNull(v)
Функция IsNumeric
.
'Выводит:
'Выводит:
False
True
'Выводит:
True
. . . .
•...... • .•-••..•;. :. •.....:...•-•...•:... .•:••-:••:...
IsNumeric ( expr )
Возвращает True, если значение выражения ехрг является числом или может быть
преобразовано в число. Значения следующих типов являются числом: Integer, Long, Single,
Double. Currency, Date/Time, Empty, String (если преобразуется в число), OLE-ошибка,
Boolean (True, False). Если значение выражения ехрг не является числом и не может быть
преобразовано в число, функция возвращает False. Следующие значения или типы не могут
быть числовыми: Null, Array, List.
Пример.
Dim v As Variant
Print IsNumeric(v)
'Выводит:
v = 12
Print IsNumeric(v)
'Выводит:
'Строка, не преобразуемая в число
v = "Twelve"
Print IsNumeric (v)
'Выводит:
'Строка, преобразуемая в число
v = "12"
Print IsNumeric(v)
'Выводит:
True (v имеет значение Empty)
True
E'alse
•-
•
True
ФуНКЦИЯ' IsDate' '"• ; v:-: Г. :..• -- -:•':--. -•; •::;:," • :.-: -.' •. ••;.. . . . . • .....
::-••...••...•-:..'.••.• '•••..
.....-...:••.....•..,. . ' . . . ...'..-. .
IsDate (expr )
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
280
'
•
Проверяет, является ли значение выражения expr значением даты-времени. Возвращает
значение True, если значением выражения expr является:
• выражение типа Variant DataType? (Date/Time);
• выражение типа Variant (String), представляющее значение даты-времени;
• выражение типа String, представляющее значение даты-времени.
В противном случае возвращает значение False.
Пример. Функция IsDate проверяет значения переменных х, у, z на соответствие значению
даты/времени.
Dim x As Variant, у As Variant,
x =~ 100
у = CDat(lOO)
z - "Nov 2, 1983"
P r in t I s D a te ( x )
Print IsDate( у )
Print IsDate( z )
Print: IsDate ("100")
P r in t I s Da te(" N ov 2, 1983")
z As Variant
'Числовое значение
'Числовое значение
'Строка, представляющая дату
'Выводит:
False
'Выводит:
True
'Выводит:
True
'Выводит:
False
'Выводит:
True
Функция IsScalar
IsScalar ( expr)
Проверяет, является ли тип значения выражения expr скалярным типом. Возвращает True,
если значение выражения expr равно или имеет тип: Empty, Integer, Long, Single, Double,
Currency, Date/Time, String, OLE-ошибка, Boolean (True, False). Иначе (если значением
выражения expr являются: массив, список, объект, значения Nothing или Null), функция
возвращает значение False.
Пример.
Dim var As VariantPrint IsScalar(var)
var = 1
Print. IsScalar (var)
•
var == "hello"
Print IsScalar(var)
Class SenClass
' . . . объявление класса
End Class
Set var = New SenClass
Print IsScalar(var)
Dim senArray(l To 5)
var - senArray
Print IsScalar(var)
Dim senList List
var = senList
Print IsScalar(var)
'Выводит:
True
'Выводит:
True
'Выводит:
True
;
'Выводит:
False
'Выводит:
False
'Выводит:
False
.(
Функция IsArray
IsArray ( expr)
Проверяет, является ли значение выражения expr массивом. Возвращает значение True,
если значение выражения expr является массивом, в противном случае False.
Пример. © InterTrust Co. Тел.
(095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
Dim arrayFixed(1 To 5)
Dirr. arrayDynam ( )
Print IsArray(arrayFixed)
Print IsArray(arrayDynam)
' Выводит:
' Выводит:
Dim v As Variant.
Print IsArray(v)
v = arrayFixed
Print IsArray(v)
281
True
True
' Выводит:
False
' Выводит:
True
Функция IsList
IsList ( expr)
Проверяет, является ли значение выражения expr списком. Возвращает True, если
значение выражения expr является списком. В противном случае возвращает False.
Пример.
Dim nryList List.
Print IsList(myList)
Dim v As Variant
Print IsList(v)
v - myList
Print IsList(v)
' Выводит:
True
' Выводит:
False
' Выводит:
True
Функция ListTag
ListTag ( refVar)
Возвращает имя текущего элемента из списка, поэлементно обрабатываемого оператором
ForAll. Параметр refVar - ссылка на переменную, определяющую в операторе ForAll.
Функция применяется только внутри блока ForAll. Выдает ошибку, если значение refVar
не является ссылкой на переменную, определенную в операторе ForAll.
Пример. Печать имен элементов списка Loft.
Dim loft. List As Integer
loft%("first") = 0 loft.%
("second") = 1 lo ft%("third")
=2 ForAll i In Loft%
Print ListTag( i )
End ForAll
' Выводит :
'- i
' first
' second
'third
;
'
•-....
Функция IsElement
IsElement ( listlN'ame ( stringExpr ) )
Проверяет, является ли строковое выражение stringExpr элементом списка HstName.
Возвращает значение True, если в списке HstName содержится элемент с именем stringExpr,
иначе возвращает False.
Если предложение HstName не является именем объявленного списка, LotusScript выдает
ошибку. Если значением выражения expr является числовое выражение, LotusScript
преобразует его значение в строковое выражение.
© InterTrust Со. Тел. (095) 9567928
282
;
Язык LotusScript
Пример. Создается список элементов, которым присваиваются некоторые значения. Выдается
запрос на идентификацию удаляемых из списка элементов. Если в empNameS есть элементы для
удаления из списка, то происходит удаление указанных элементов из списка. В противном случае
выдается соответствующее сообщение и выполнение скрипта прекращается
Dim empList List As Double
Dim empName As String, Id As Double, found As Integer
empList#("Maria Jones") = 12345
empList#("Roman Minsky") = 23456
empListtt("Joe Smith") = 34567
empListJ ("Sal Piccio") = 91234
empName$ = InputBox$("Which employee is leaving?")
If IsElement(empList#(empName$)) = True Then
Id# = CDbl(InputBox$("What's " & empName$ & "'s Id?"))
found% = False
' Initialize found to 0 (False)
ForAll empld In empList# If
empld = Id# Then
found% = True
' Set found to -1 (True). If
ListTag(empld) = empName$ Then Erase
empListt(empName$)
'Проверка элемента, удаляемого из списка. If
IsElement(empList#(empName$)) = False Then
MessageBox empName$ &
" has been removed from the list." End If
Else
MessageBox "Employee name and Id do not match." End.
If Exit ForAll End If
•' '
End ForAll
' '
If found* = False Then
MessageBox "Not a valid employee Id." End If
Else
MessageBox "We have no such employee." End
If
Функция IsUnknown
IsUnknown ( expr)
Проверяет, является ли значение выражения expr значением OLE V_I UNKNOWN.
Возвращает значение True, если значение выражения expr имеет тип Variant и равно
V_I UN KNOWN. Такое значение может иметь только ссылка на OLE-объект. В противном
случае функция возвращает False.
Функция IsDefined
IsDefmed ( stringExpr)
Проверяет, является ли значение строкового выражения stringExpr именем константы,
определенной в Lotus-продукте. Возвращает значение True, если значение выражения
stringExpr определено в Lotus-продукте, иначе возвращает False.
Обычно функция используется для проверки значения констант, идентифицирующих
используемую платформу. Такие проверки могут использоваться в %lf директиве условной
компиляции скрипта.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
283
2.8.10. Средства работы с файловой системой 2.8.10.1.
Операторы и функции для работы с устройствами и каталогами
Оператор ChDir (назначить каталог)
ChDir path
path - строковое выражение, представляющее каталог, назначаемый в качестве текущего.
Назначает в качестве текущего (рабочего) каталога каталог, путь к которому указан в
выражении path. Если первым символом выражения path не является символ, обозначающий
дисковое устройство (диск), то в качестве рабочего используется текущий диск, в противном
случае рабочим становится диск, обозначение которого присутствует в выражении path.
Формат и максимальная длина выражения path должны соответствовать соглашениям,
принятым в используемой платформе.
Пример 1. Назначает устройство (диск) D текущим устройством,
ChDrive "D"
.
Пример 2. Назначает каталог TEST текущим каталогом на устройстве С.
ChDir "C:\TEST"
Пример 3. Назначить каталог TEST текущим каталогом на текущем устройстве D.
ChDir "\TEST" Print
CurDir () 'Выводит
D:\TEST
Оператор ChDrive (назначить устройство)
ChDrive drive
drive - строка, представляющая существующее устройство.
Оператор ChDrive назначает текущее устройство согласно значению строки drive.
Текущее устройство - это устройство, которое используется, если происходит обращение к
указанному пользователем файлу, или при использовании пути, в котором отсутствует
спецификация устройства. Если значением строки drive является пустая строка (""), то
оператор ChDrive не меняет назначение, оставляя текущим устройство, используемое до
выполнения оператора ChDrive.
Если значением строки drive является строка, содержащая более одного символа, в
качестве обозначения переназначаемого устройства берется первый символ значения строки
drive. Оператор ChDrive не требует наличия знака двоеточие ( : ) после символа,
обозначающего назначаемое устройство. Символом, обозначающим устройство, может быть
любая буква от А до буквы, представленной опцией lastdrive в системном файле
CONFIG.SYS, включительно.
Пример. Назначить D текущим устройством.
ChDrive "D"
'
ФуНКЦИЯCurDir . . • . - . . . . . ...•:.•,•"••.••.•. ..... -•-•....
•
' .-.:.....', .-••'-...--.. ..
;•...... -...-..
.
.,....,
CurDir[$] [ ( drive ) ]
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
284
Определяет назначение текущего каталога заданного устройства. CurDir возвращает
значение типа Variant (String). CurDir$ возвращает значение типа String.
drive - опция, являющаяся строковым выражением, определяющая существующее
устройство. Если опция отсутствует, функция CurDir использует текущее устройство.
Если спецификация устройства представляет собой строку, состоящую более, чем из
одного символа, CurDir использует только первый символ строки. CurDir не требует наличия
знака ( : ) после буквы, определяющей устройство.
Пример.
ChDir "C:\TEST"
Print CurDir?()
'Выводит "C:\TEST"
Функция CurDrive
CurDrive[$]
Возвращает строку, идентифицирующую текущее устройство (диск), состоящую из
символа устройства, с последующим двоеточием. Функция CurDrive возвращает значение
типа Variant (String). Функция CurDriveS возвращает значение типа String.
Пример.
Dim tempDrive As String
tempDrive? = CurDrive?() If
tempDrive? <> "C:" Then
ChDrive "C"
End If
ChDir "\TEST"
Print CurDir?()
'Выводит "C:\TEST"
Функция Dir
. . .• •. . . . • •. . .
.,.:.... -• ....
Dir[$] [ ( fileSpec [, attributeMask ] ) ]
-. .
'
- . . . , :
Возвращает имя файла, каталога, или букву - название устройства.
fiieSpec - строковое выражение, определяющее путь к файлу. Этот аргумент является
обязательным только при первом обращении к функции Dir$ с указанием данного пути.
Составленное по правилам определения пути к файлам, fileSpec обеспечивает доступ к
файлам, синтаксис указателя пути к которым удовлетворяет принятой спецификации
(например, использование в указателе пути знаков "*" и "?").
attributeMask - любое целое выражение, значение которого является возвращаемым
именем. Если пропущен этот аргумент, имена существующих на устройстве файлов
сравниваются со значениями, содержащимися в fileSpec. Если есть аргумент attributeMask, то
должен быть и аргумент fileSpec. Для включения в возвращаемый список типов файлов,
используются суммарные значения графы Mask из следующей таблицы, представляющей
типы файлов:
Mask
Атрибуты файла
Константа
0
Normal file
ATTR NORMAL
2
Hidden file
ATTRJHDDEN
4
System file
ATTR SYSTEM
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
8
Volume label
ATTR_VOLUME
не
Атрибуты файла hidden, system, или
directory-имеют смысла для Volume label
16
285
Directory
ATTR DIRECTORY
Функция Dir возвращает значение типа Variant (String), а функция Dir$ - типа String.
Константы, использованные в таблице, хранятся в файле LSCONST.LSS. Включение
этого файла в скрипт позволяет использовать названия атрибутов вместо их численного кода.
Для определения существования файла используется его правильное (в рамках используемой
платформы) имя в качестве аргумента для функции Dir (Dir$). Возвращаемое значение может
быть либо именем файла, либо сообщением об отсутствии файла на указанном устройстве.
Первое обращение к функции Dir (Dir$) возвращает имя первого файла в указанном каталоге
согласно спецификации имени файла в fileSpec. Последующие вызовы функции Dir (Dir$) с
другими аргументами позволяют добавить имена файлов по списку fileSpec.
Если в указанном каталоге больше нет файлов, соответствующих спецификации, то
функция Dir возвращает значение типа Variant (String), а функция Dir$ возвращает пустую
строку (""). Если, после получения пустой строки, функция Dir (Dir$) вызывается еще раз с
той же спецификацией пути, то генерируется ошибка.
Пример. Получения списка каталогов на устройстве С:\
Dim pathName As String, fileName As String
pathName$ = "C:\*.*"
fileName$ = Dir$(pathName$, 0)
Do While fileName$ <> ""
•
Print fileNameS
fileName$ - Dir$()
Loop
.
•
.
Оператор MkDir (создать каталог)
MkDirpath
path - строковое выражение, значение которого является именем создаваемого каталога. В
выражении path буква, определяющая дисковое устройство, не является обязательной. Если
она отсутствует, то используется текущее назначение устройства. Правила указания каталога
должны соответствовать правилам используемой операционной платформы.
При невозможности создать требуемый каталог LotusScript выдает ошибку.
Пример. Создание каталога TEST в корневом каталоге устройства С.
MkDir
"C:\TEST"
-<•
'
"
Оператор Name (переименовать/переслать файл/каталог)
Name oidName As newName
Переименовывает (и/или пересылает) файл или каталог.
oldName - строковое выражение, определяющее имя существующего файла/каталога,
необязательно содержащее путь; newName - строковое выражение, определяющее новое имя
файла/каталога, необязательно содержащее путь.
Для пересылки файла необходимо указывать полный путь и для файла с именем oidName и
для файла с именем newName. Для переименования используйте имя файла в обоих
аргументах.
© InterTrust Со. Тел. (095) 9567928
Язык LotusScript
286
Для пересылки файла с одного устройство на другое необходима ОС Windows NT или
Windows 95.
Пример. Переименование файла с именем TEST], находящегося в каталоге WINDOWS на
устройстве С, в файл с именем TEST2 и пересылка переименованного файла в корневой каталог
устройства С.
Name? "C:\WINDOWS\TEST1" As "C:\TEST2"
.
, , - ;lf ,, ,.
Оператор RmDir (удалить каталог)
RmDir path
path - строковое выражение - указатель пути к удаляемому каталогу. Максимальная длина
указателя пути к каталогу определяется рамками используемой платформы. Если имя
каталога в указателе пути отсутствует, то вырабатывается ошибка.
Пример. Удаление каталог а C:\TEST из файловой системы
RmDir "C:\TEST"
2.8.10.2. Операторы и функции для работы с файлами
Функция FileAttr
FileAttr ( fileNumber, attribute )
Возвращает значение типа доступа или значения системных атрибутов для открытого
файла.
fileNumber - номер, присвоенный файлу при его открытии.
attribute - число (1 или 2), специфицирующее тип используемой информации Вместо 1
или 2 можно использовать для спецификации соответствующие этим значениям константы
ATTR MODE или ATTR_HANDLE. Эти константы определены в файле LSCONST.LSS.
Включение этого файл в скрипт с помощью директивы %Include позволит использовать
значения текстовых констант вместо числовых значений.
Если значением атрибута является строка ATTR_HANDLE, то функция FileAttr
возвращает системные атрибуты файла. Если значением атрибута является строка
ATTR_MODE, то функция FileAttr возвращает целое число, определяющее тип доступа к
файлу, согласно следующей таблице:
Возвращаемое значение
Тип доступа
Константа
1
Input
ATTR JN PUT
2
Output
ATTR_OUTPUT
4
Random
ATTR_RANDOM
8
Append
ATTR_APPEND
32
Binary
ATTRJBINARY
© InterTrust Co, Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
287
Пример. Открывается (создается) файл с именем DATA.TXT и на экран выводится значение типа
доступа к этому файлу.
'«Include "LSCONST.LSS"
Dim mode As String, msg As String
Dim hdl As Integer, fileNum As Integer
fileNum! = FreeFile()
Open "DATA.TXT" For Append As fileNum%
Select Case FileAttr(fileNum*, ATTR_MODE)
Case 1 : mode$ = "Input"
- .,.-Case 2 : mode$ = "Output"
Case 4 : mode$ = "Random"
Case 8 : mode$ = "Append"
Case 32: mode$ = "Binary"
End Select
.
Close fileNum% Print "DOS File Mode
= "; mode$
. -
Функция FileDateTime FileDateTime (fileName ) Возвращает дату и
время создания или последней модификации файла.
fileName - строковое выражение, которое может содержать путь к файлу в рамках
синтаксиса используемой платформы.
Функция возвращает дату и время создания или последней модификации файла в
формате, соответствующем используемой операционной платформе или в международном
формате. Если файла с указанным именем нет по указанному пути, возвращается сообщение
об ошибке.
Пример. Создается файл с именем DATA.TXT и выводится дата и время его создания.
% Include "LSCONST.LSS"
Dim fileName As String, fileNum As Integer
fileNum! = FreeFile()
fileName$ = "DATA.TXT"
Open fileName$ For Output As fileNum%
' Создание файла DATA.TXT
Close fileNum!
Print fileName$; " Nigaai "; FileDateTime(fileName$)
ФункцияFileLen v;:. ....... ....:..:••:••-.. ... .................. :-.. :.
FileLen ( fileName )
......
.......
.
.....
>
Возвращает длину файла в байтах (тип Long). fileName - строковое выражение; может
содержать путь и не может содержать специальные символы.
Пример. Переменной verLen присваивается значение длины файла C:\CONFIG.SYS (в байтах) и
выводится ее значение.
Dim verLen As Long
verLen& = FileLen("С:\CONFIG.SYS")
Print verLen&
-
Функция GetFile Attr. ..,.,. •; ............ -..;-......::...... ............ •......:.••• ......... :•/•• ...•-.:.--••:,. ...•.,•...:.•.-• ... .-,.., .
GetFileAttr (fileName )
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
288
Возвращает значения системных атрибутов файла или каталога.
<: :
fileName - имя файла или каталога; при необходимости может содержать указатель пути к
файлу или каталогу.
Возвращаемым значением является число, равное сумме целых значений кодов значений
атрибутов файла, согласно следующей таблице.
Код значения
Атрибут
Константа
0
Normal file
ATTR NORMAL
1
Read-only file
ATTRJREADONLY
2
Hidden file
ATTRJHIDDEN
4
System file
ATTR_SYSTEM
16
Directory
ATTR_DIRECTORY
32
File(archived)
ATTR_ARCH1VE
Константы представляют собой значения, определенные в файле LSCONST.LSS. Для
обеспечения возможности использования имен этих констант, необходимо включить этот
файл в скрипт.
Пример. В режиме Output открывается (создается) файл с именем DATA.TXT, Вызывается
функция SetFileAttr для установки ему аттрибутов Read-Only, System, Hidden, после чего с помощью
функции GetFileAttr проверяются атрибуты этого файла и выводится соответствующее сообщение.
?Include "LSCONST.LSS"
Dim fileNum As Integer, attr As Integer
Dim fileNarne As String, msg As String
ЈileNum% = FreeFile()
fileName$ = "DATA.TXT"
Open fileName$ For Output As fileNum%
Close fileNum!
SetFileAttr fileNaineS, ATTR READONLY + ATTR_SYSTEM + ATTR_HIDDEN
attr% = GetFileAttr(fileName$)
If (attr% And ATTR^READONLY) Then
msg$ - msg$ & " Read-Only " Else
msg$ = msg$ & " Normal "
.•--..
End If
If (attr% And ATTR_HIDDEN) Then msg$ = msg$ & " Hidden " If (attr%
And ATTR_SYSTEM)
Then msg$ = msg$ & " System " If (attr% And
ATTR_DIRECTORY) Then msg$ = msg$ & " Directory " Print msg$
SetFileAttr fileName$, ATTR_NORMAL
Kill fileName$
Оператор FileCopy (копировать файл)
<
FileCopy source , destination
source - строковое выражение, определяющее имя копируемого файла, может включать
указатель пути к этому файлу, destination - строковое выражение, определяющее имя файла
-копии, также может включать указатель пути к файлу - копии.
Перед копированием файл открывается в режиме Read. Выражения, определяющие
исходный и результирующий файлы могут содержать специальные символы. Если
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
289
результирующий файл уже существует, он будет замещен копируемым файлом. Во
избежание этого необходимо использовать функцию Dir, чтобы определить имена уже
существующих файлов. Для установки атрибута файла "только для чтение" используется
оператор SetFileAttr.
Пример. Копирует файл C:\WINDOWS\APP.BAT в корневой каталог 'устройства С: имя копии
APPLOAD.BAT.
FileCopy "C:\WINDOWS\APP.BAT",
"C:\APPLOAD.BAT"
Оператор Kill (удалить файл)
Kill fileName
fileName - строковое выражение, являющееся именем файла; оно может содержать букву,
определяющую устройство, и путь к файлу.
Использование оператора Kill требует особого внимания, хотя чаще всего ошибочно
удаленный файл можно восстановить с помощью соответствующей команды используемой
платформы. Перед удалением файл должен быть закрыт. Kill удаляет файлы, но не каталоги.
Пример. Удаление файла C:\TEST из файловой системы.
Kill
"C:\TEST"
Оператор SetFileAttr (назначить файлу атрибуты)
SetFileAttr fileName , attributes
fileName- строковое выражение; может включать путь к файлу, attributes - атрибуты
файла, определенные суммой любых кодов атрибутов из следующей таблицы.
Значение
Описание
Константа
0
Normal file
ATTR NORMAL
1
Read-only
ATTR_READONLY
2
Hidden
ATTRJrllDDEN
4
System
ATTR_SYSTEM
32
Changed since last back-up
ATTR_ARCHIVE
Значения всех этих констант определены в файле LSCONST.LSS. Для использования
значений констант необходимо включить этот файл в скрипт с помощью
директивы %lnclude.
SetFileAttr не применяется к открытому файлу, если только он не открыт в режиме
"только 4TeHHe"(read-only).
Пример. Создает файл и использует оператор SetFileAttr для назначения этому файлу атрибутов
Read-Only, System, и Hidden. Затем, для проверки значений атрибутов файла используется оператор
GetFileAttr и выводятся значения атрибутов.
^Include "LSCONST.LSS"
Dim fileNum As Integer, attr As Integer
Dim fileName As String, msg As String
fileNum% = FreeFile()
fileName? - "DATA.TXT"
. . . . .
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
290
Open fileName? For Output As fileNum%
. .-.-Close fileNum%
SetF.ileAt.tr fileName$, ATTR_READONLY + ATTR_SYSTEM + ATTR_H1DDEN
attr% = GetFileAttr(fileName$)
If (attrli And ATTR_READONLY) Then
msg$ = msg$ & " Read-Only "
.
Else
msg$ = msg$ & " Normal "
. ' . ' • •
;
End It
If (attr% And ATTR_HIDDEN)
Then msg$ = msg$ & " Hidden " If (attr%
And ATTR_SYSTEM)
Then msg$ = msg$ & " System " If (attr% And
ATTR_VOLUME)
Then msg$ = msg$ & " Volume " If (attr% And
ATTR_DIRECTORY) Then msg$ = msg$ & " Directory " Print msgS
SetFileAt.tr fileName$, ATTR_NORMAL 'Восстановление ATTR_NORMAL Kill
fileNameS
2.8.11. Операции ввода/вывода
2.8.11.1. Основные положения
Описание типов доступа к файлам, используемых в LotusScript, представлено в
следующей таблице.
Тип доступа
Последовательный
Прямой
Произвольный
Описание
Простой, чаще других встречающийся тип. Обычно, их содержимое -это
строки текста, ограниченные символом конца строки. Чтение этих
файлов чаще всего производится соответствующими текстовыми
редакторами
Содержит структурированные данные, которые не читаются
обычным образом из LotusScript.
Являются максимально удобными для манипулирования
информацией на уровне байта, который, в свою очередь является
минимально доступным уровнем в дисковых операциях
Для записи или чтения информации из файла необходимо открыть файл. Открываемый
файл идентифицируется номером в интервале от 1 до 255. Этот номер обычно используется,
как идентификатор файла при выполнении операций ввода/вывода. (Только некоторые
операции с файлом используют его имя вместо номера). Соответствие между именем и
номером файла, определенное при его открытии, сохраняется до момента закрытия этого
файла, после чего этот же номер может быть использован для операций с другим файлом.
Замечание: в описании файловой системы используются названия операторов
ввода/вывода. Подробное описание этих операторов представлено в конце раздела.
Файл последовательного доступа
Файл последовательного доступа является текстовым файлом, информация в котором
хранится в виде символьных строк произвольной длины. Концом строки файла является
символ перехода на новую строку. Данные файла не являются блочными записями. Такой
файл не удобен для хранения информации в виде чисел, т.к. числа в нем представлены в виде
символьных строк, что влечет за собой необходимость преобразования типа данных файла
при выполнении расчетов или записи числовой информации в файл.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
291
Открытие файла последовательного доступа
Файл последовательного доступа открывается в одном из следующих режимов:
• Input (ввод);
• Output (вывод);
• Append (добавление).
Уже открытый файл нельзя открыть еще раз. Для открытия файла последовательного
доступа используется оператор Open.
Файл, открываемый для чтения, обязательно должен присутствовать на диске, в
противном случае генерируется сообщение об ошибочной попытке открыть
несуществующий файл. Файл, открываемый для записи или добавления данных может не
существовать, но, оператором Open, он будет создан автоматически пустым.
Вывод (запись) данных в файл последовательного доступа
Для записи значения переменной в файл последовательного доступа, открытый в режиме
вывода или добавления, используется оператор Print # и Write #
Ввод (чтение) данных из файла последовательного доступа
Для чтения данных из файла последовательного доступа, последний открывается в
режиме Input. Возможно использование операторов Line Input #, Input # или функции Input
для ввода из файла значений переменных. Line Input # вводит из файла одну текстовую
строку до символа "Конец строки", не включая этот символ в введенную строку. Например:
"" .
Do Until EOF(idFile)
Line Input tidFile,
Print iLine
Loop
iLine
'
'
.
,
Эти операторы осуществляют чтение из файла по одной строке до конца файла. Оператор
Print осуществляет вывод этих строк на экран дисплея, добавляя при этом в конец каждой
строки признак "конец строки". Оператор input # может быть использован для ввода
форматированных записей и записей, сделанных оператором Write #.
Например, допустим, что файл с номером idFiie содержит следующую строку:
"Testing",123,456,#Null#.
Следующие операторы, считывая данные из этого файла, осуществляют присваивание
соответствующих значений переменным в следующем порядке: Testing в HLabel; 123 в infA;
56 в supA; Null в tailV.
Dim liLabel As String, tailV As Variant Dim
infA As Integer, supA As Integer Input tidFile,
liLabel, infA, supA, tailV
Если предполагается частое использование операторов Write # и Input # для операций с
файлами последовательного доступа, то лучше всего поменять стратегию организации
обмена и перейти к работе с файлами прямого доступа. Эти тип файлов являются лучшим с
точки зрения организации частого обмена данными между программой и диском. Для чтения
данных из файла последовательного доступа может также использоваться функция Input. В
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
292
' --'• ' •
качестве параметра она использует число, указывающее количество вводимых символов, и
возвращает строку из заданного количества символов при обращении к ней. Следующий
пример демонстрирует применение этой функции для вычисления количества символов,
содержащихся в файле:
Dim fulFile As String
fulFilea= lnput$(LOF(idFile), idFile)
' LOF возвращает длину файла, выраженную количеством символов в нем.
Файлы прямого доступа
Файл прямого доступа содержит ряд записей фиксированной длины. Запись может
содержать значения типа Integer или String. Если запись содержит тип данных, определенный
пользователем, то она может быть разбита на части соответствующего типа. По умолчанию,
файл прямого доступа открывается без указания режима, обязательного для открытия файлов
последовательного и произвольного доступа.
Открытие файла прямого доступа
Для открытия файла прямого доступа используется оператор Open.
Если к моменту исполнения оператора Open файл не существовал, то он будет создан
этим оператором пустым.
Определение типа записи
Т.к. все записи файла прямого доступа имеют одну и ту же, определенную длину, то тип
данных такого файла определен с фиксированной длиной В противном случае, данные,
прочитанные из файла прямого доступа, будут некорректны. Если длина выводимой в файл
записи меньше установленной длины, то запись дополняется пробелами слева, если же длина
больше установленной для данного файла запись "усекается" до нужной длины. Для
простоты, все внутренние поля записи, определенной пользователем, имеют фиксированную
длину.
Если заранее известно, что для вывода в файл будут использованы записи разной длины,
параметр Len должен иметь значение максимальной длины выводимых в файл строк, для
чего необходимо предварительно оценить длину выводимых строк. Можно выбрать для
операции ввода/вывода любую строку файла, указывая номер записи в операторах Get или
Put. Пользователь может определить свой тип записи, который может иметь достаточно
сложную структуру. Например,
Type emploRec
id As Integer
salary As Currency
hireDate As Double
lastName As String * 15
firstName As String * 15
End Type
'
'
'
'
'
тип Integers, длина 2 байта
тип Currency, длина 8 байта
тип Double, длина 8 байт
Строка фиксированной длины - 30 ааёо
Строка фиксированной длины - 30 ааёо
Эта запись, длиной 78 байт, поддерживается в операторе Open с помощью указателя
длины записи Len=78. Длина записи подобного типа может быть определена и в момент
выполнения операции ввода - вывода с^томощью использования функции Len. Например:
Dim recLen As Integer, idFile As Integer
Dim recHold As emploRec
idFile = 1
' Номер открытого файла
recLen = Len(recHold)
' Длина записи в этом файле
Open "DATA.TXT" For Random As idFile Len = recLen
© InterTrust Co. Ten. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
293
Ввод (чтение) данных из файлов прямого доступа
Для чтения данных их файла прямого доступа используется оператор Get. Следующий
пример демонстрирует чтение записи N 5 из файла с номером idFile в переменную recHold
(предполагается существование записи N 5 в файле):
Dim posit As Integer
posit = 5
..
.
-
Dim recHold As emploRec
Get idFile, posit, recHold
Вывод (запись) данных в файл прямого доступа
Для записи данных в файл прямого доступа используется оператор Put. Этот оператор
либо добавляет новую запись к уже имеющимся в файле, либо перемещает существующую в
файле запись на новое место (новый номер). Put используется со следующими параметрами:
номер файла, к которому происходит обращение, номер записи, которая записывается в
файл, имя переменной, содержащей выводимую в файл запись. Для перемещения записи в
файле необходимо просто указать ее номер среди записей файла:
Dim posit As Integer
posit = 5
Перемещение записи 5 с использованием переменной recHold:
Put idFile, posit, recHold
Для добавления новой записи к файлу достаточно использовать номер записи, на единицу
превышающий номер последней записи в файле. Так, чтобы добавить запись к файлу,
содержащему 5 записей, используется номер записи 6. Для удаления записи из файла
произвольного доступа надо перезаписать записи с номерами большими, чем номер
удаляемой записи, уменьшив номер каждой из них на 1, т.о. из файла будет исключена
запись, т.к. на ее место ( номер) будет записана следующая за ней запись. Например:
Dim tempRec As emploRec
For I = posit To lastRec - 1
Get idFile, I + 1, tempRec
Put idFile, 1, tempRec
Next I
•
Этот способ не исключает возникновения ошибок, связанных с появлением
дублирующих записей в файле из - за ошибки определения начального номера сканирования.
Более надежным, хотя и более сложным в реализации, является создание файла, в
который копируются все записи, кроме удаляемой, затем исходный файл удаляется, а
файл-копия переименовывается именем исходного файла.
Двоичные файлы (произвольного доступа)
Двоичные файлы представляют максимальные возможности управления операциями
ввода - вывода данных. Недостатком этого способа доступа, называемого также
произвольным доступом, является необходимость точно знать, как записывался этот файл,
чтобы обеспечить правильный порядок чтения из него данных. Хотя очень немногие
функции и операторы обеспечивают операции с двоичными файлами, в отличие от файлов
последовательного и прямого доступа, тем не менее, двоичные файлы являются наиболее
гибкими в смысле возможности управления ими.
© InterTrust Со. Тел. (095) 9567928
Язык LotusScript
294
Открытие двоичных файлов
.
;? •
Для открытия двоичного файла используется оператор Open. Если файл не существует, то
при исполнении оператора Open он будет создан, пустым независимо от режима выполнения
этого оператора (чтение или запись).
Использование переменной длины нолей
В отличие от файлов прямого доступа двоичные файла могут содержать записи
переменной (не фиксированной) длины. Тем не менее, необходимо знать длину записей в
порядке их следования в файле. Хорошим стилем программирования считается определение
длины каждой записи в двоичном файле. Однако, это необязательно, если строка является
составным, определенным пользователем типом. В этом случае, LotusScript автоматически
присвоит длину соответствующего поля для каждой строки переменной длины. Двоичной
доступ обеспечивает побайтный просмотр файла. Сам файл представляет собой
последовательность байтов, которые могут быть как символьной, так и цифровой
информацией.
Вывод (запись) данных в двоичный файл
Для записи в двоичный файл используется оператор Put.
Ввод (чтение) данных из двоичного файла
Для чтения данных из двоичного файла используется или оператор Get, или функция
Input. Оператор Get, при отсутствии ошибок, считывает информацию из двоичного файла с
указанного номера байта в переменную, которая может быть строкой переменной длины или
переменной целого типа. Для строки переменной длины количество считываемых символов
определяет длину этой строки. (Кстати, это количество может быть равным О,
соответствующим образом определяя длину строки переменной длины). Поэтому,
необходимо в первую очередь установить длину "принимающей" строки. Если строка в
файле находится внутри типа, определенного пользователем, длина строки определяется с
некоторым запасом. Например, можно удлинить строку для обеспечения разделения полей,
содержащихся в строке.
Функции Input и Input$ также используются для чтения данных из двоичного файла.
2.8.11.2. Операторы ввода/вывода
Оператор Close (закрыть файл(ы))
Close [ [ # ] fileNumbe [ , [ # } fileNumbe ] ... ]
Закрывает один или более открытых файлов, после записи содержимого всех внутренних
буферов в эти файлы.
fileNumbe - опция, являющаяся номером, присвоенным файлу в скрипте при его
открытии. Если опция fileNumbe отсутствует, оператор Close без параметров закрывает все
открытые файлы.
Отсутствие знака (#) перед fileNumbe не влияет на выполнение оператора. Перед
закрытием открытых файлов, оператор Close записывает содержимое всех внутренних
буферов в эти файлы. Если LotusScript встречается с ошибкой периода выполнения для
которой нет оператора On Error, LotusScript закрывает все открытые файлы.
Если значение опции fileNumbe содержит дробную часть, LotusScript округляет его
значение до целого значения.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-фортулы, LotusScript, «строенные классы LotusScript и Java
295
Пример.
Open "c:\rab.asc" For Input Access Read Shared As 1 Len = 128 Close
#1
Оператор Get (чтение из двоичного файла)
Get [#] fileNumber , [ recordNumber ] , variableName
fiieNumber - номер, присвоенный файлу при его открытии в операторе Open. Номеру
предшествует символ #, имя файла и имя переменной, в которую производится считывание
данных
recordNumber - опция, определяющая позицию в файле (в двоичном файле - позицию
байта, в файле произвольного доступа - позицию записи), из которой производится
считывание. Если параметр recordNumber пропущен, считывание данных производится из
текущей позиции файла.
variableName - переменная, "принимающая" данные из файла.
Первый байт или запись в файле имеют номер позиции 1. После выполнения каждого
оператора чтения, значение номера увеличивается. Оператор Get считывает данные в
переменную variableName определенного типа.
Следующая таблица определяет "реакцию" оператора Get на различные типы данных
переменной variableName.
Тип
variableName
Действие
Variant
Оператор Get преобразует первые два байта к значению типа DataType и
считывает их. Если значением DataType является значение Empty или Null,
оператор Get останавливает ввод и присваивает переменной variableName
значение Empty или Null. Если DataType - число, оператор Get считывает
столько байтов, сколько помещается в типе Data Type: Integer - 2 байта;
Long - 4 байта; Single - 4 байта; Double - 8 байт; Currency - 8 байт; Date/time
- 8 байт.
Строка
фиксированной
длины
Оператор Get считывает определенное число символов, например, если
переменная объявлена, как String* 10, оператор Get считает 10 символов.
Строка
переменной
длины
Оператор Get считывает данные в зависимости от типа файла.
Произвольный: два байта, считанные первыми, определяют длину строки и
Get считывает соответствующее число символов. Если значение
variableName меньше числа записей в файле, данные считываются до тех
пор, пока это позволяет значение variableName. После этого указатель
устанавливается на следующую непрочитан-ную запись.
Указанное число байтов считывается из файла в строку, длина которой
определена в опции variableName. Если начальное значение опции не
определено, данные из файла не считываются.
Число байтов, считываемых из файла равно сумме байтов всех
элеменотов определенного пользователем типа. Этот тип не может
содержать элементов типа массив, список или объект.
Двоичный
Тип,
определенный
пользователем
© InterTrust Со. Тел. (095) 9567928
Язык LotusScript
296
Пример. Открывается файл произвольного доступа, длина записи в котором равна длине записи,
указанной в переменной гее. Выводятся записи в указанные позиции файла. Выводятся значения
записей.
Type PersonRecord
empNumber As Integer
. .•
. ;t, .,
empName As String * 20
End Type
Dim fileNum% As Integer Dim
fileName$ As String Dim rec
As PersonRecord fileNuml =
FreeFile() fileName$ =
"DATA.TXT"
Open fileName? For Random As fileNum% Len = Len(rec) 'Вывод
записи в 1 позицию, rec.empNumber% = 123 rec.empName$ =
"John Smith" Put #fileNum%, 1, rec 'Вывод записи в 2
позицию, rec.empNumberl = 4 5 6 rec.empName$ = "Jane Doe"
Put #fileNum%, 2, rec 'Вывод записи в 3 позицию,
rec.empNumber% = 789 rec.empName$ = "Jack Jones" Put
#fileNum%, , rec
'Возврат к началу файла и печать всех записей. Seek
fileNum%, I Do While Not EOF(fileNum%)
Get #fileNum%, , rec
Print rec.empNumber%;
rec.empName$ Loop
Close fileNum%
'Печатаются следующие записи: '
123 John Smith ' 456 Jane Doe '
789 Jack Jones
Оператор Input #
; . . - • . , . . : ' • ' ; " . ; " " . . • ' ' • • . . ...- • • • - . . . - • . • , • • • . . • ; , , •-.-:. .•..•. :?:; : :: '*.::;.
Input #fileNumber, variableList
Читает данные из файла последовательного доступа в переменную.
tileNumber - число - номер открываемого файла. Номеру файла обязательно
предшествует символ #.
variableList - список переменных, разделенных запятой. Данные считываются из файла в
назначенные переменные. Тип данных файла должен соответствовать типу данных этих
переменных. Список variableList может включать в себя массивы, списки, переменные
определенного пользователем типа, или переменные -ссылки. Можно использовать
отдельные элементы массива, списка и, определенного пользователем типа или класса.
Следующая таблица представляет для оператора Input # режимы чтения символов в
зависимости от типа данных variableList.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
297
Тип данных в variableList
Как Input # считывает символы
Числовая переменная
Первый символ в файле, отличный от пробела, становится первой
цифрой числа. Встреченный пробел, запятая и символ конца строки в файле определяет конец
числа. Пустые строки и нечисловые символы преобразуются в цифры 0. Строковая переменная
Первый символ в файле, отличный от пробела, становится первой буквой строки. При
формировании строки выполняются следующие условия:
* если символ - ("), он игнорируется; но все символы следующие за ним, включая запятые,
пробелы, и символы конца строки, вплоть до следующего символа (") считываются в
строковую переменную;
• если первый символ не является символом ("), то следующий пробел, запятая или символ
конца строки заканчивают строку. Символ табуляции не является пробелом. Строкова
переменная
Считывается согласно указанной длине. фиксированной длины Переменная
типа Variant
Первый непустой символ файла начинает значение переменной. Если в файле
прочитана пустая строка, то переменной присваивается значение пустой строки. Символы
формата дата-время, LotusScript считывает в переменную с типом Variant(Data/Time). При
считывании значения Null переменной присваивается значение Null. При невозможности
определить тип переменной в файле, LotusScript формирует переменную, типа String.
Для всех используемых платформ, LotusScript вставляет символ "\п" в любую
многостроковую переменную. При печати этот символ трактуется как символ перевода
строки. Т.о. при чтении таких данных из файла последовательного доступа,
предпочтительнее использовать Input, а не Line Input. Также, при чтении данных из файла
произвольного доступа, предпочтительнее использовать Get вместо оператора Input #.
Пример. Файл с именем DATA.TXT открывается для записи в него данных. После закрытия файла,
он снова открывается для чтения из него данных. Данные считываются из файла и выводятся на печать.
Dim fileNum As Integer, empNumber As Integer, i As Integer
Dim fileName As String, empName As String
Dim empLocation As Variant
~"
'
Dim empSalary As Currency
..
..
.
.^
fileNum% = FreeFile()
file.Name$ = "DATA.TXT"
'" " '
. _ . . . . - .
Open fileName$ For Output As fileNum%
'
Write #fileNum%, "Joe Smith", 123, "1 Smith Road", 25000.99
Write #fileNum%, "Jane Doe", 456, "Two Cambridge Center", 98525.66
Write #fileNum%, "Jack Jones", 789, "Fourth Floor", 0
Close fileNum%
:
Open fileName? For Input: As fileNum%
'
•
For i% = 1 To 3
Input #fileNum%, empName$, empNumber%, empLocation, empSalary@
Print ernpName$, ernpNumber%, empLocation, empSalary@
Next i%
•
© InterTrust Co. Тел. (095) 9567928
298
Язык LotusScript
'Выводит следующие группы значений, которые содержат значения типа
'String, Integer, Variant, ё Currency.
'Joe Smith
123
I Smith Road
25000.99
'Jane Doe
456
Two Cambridge Center
98525.66
'Jack Jones
789
Fourth Floor
.
0
Close fileNum%
Оператор Line Input #
Line Input #fiIeNumber , varName
Считывает строку из файла последовательного доступа в переменную типа String или
Variant.
#fileNumber - номер, присваиваемый файлу при его открытии. Символ # должен
предшествовать номеру файла.
varName - переменная, типа String или Variant, в которую считывается строка из файла.
Оператор Line Input # считывает символы из файла последовательного доступа пока не
встретит символ "перевод строки", который Line Input # не считывает в переменную. При
считывании "многостроковой" строки из файла последовательного доступа используется
оператор Input #, а не Line Input #.
Пример. Вывод содержимого файла C:\CONFIG.SYS
Dim text As String, fileNum As Integer
fileNum% = FreeFile()
Open "C:\CONFIG.SYS" For Input As fileNum%
Do While Not EOF(fileNum%)
Line Input #1, texts
Print. textS
'Печать одной строки из CONFIG.SYS
Loop Close
fileNum%
Операторы Lock и Unlock
Lock [#]fileNumber [, recordNumber { [ start ] To end } J
Unlock [#]fileNumber [, recordNumber | { [ start ] To end } ]
Обеспечивают блокирование/разблокирование доступа к данным файлов.
fileNumber - номер, назначенный файлу при его открытии.
recordNumber - для файла произвольного доступа является номером записи, доступ к
которой блокируется/разблокируется; для двоичного файла является номером байта, доступ к
которому блокируется/разблокируется.
Первая запись в файле произвольного доступа - это запись номер 1; первый байт в
двоичном файле - это байт номер 1.
LotusScript блокирует/разблокирует доступ только к определенной записи или байту. Для
файла последовательного доступа блокируется/разблокируется доступ ко всему файлу,
независимо от значения, содержащегося в recordNumber.
start To end - для файла произвольного доступа это диапазон номеров записей, к которым
блокируется/разблокируется доступ (аналогично, для байтов двоичного файла). Если
предложение start пропущено, LotusScript определяет режим доступа в диапазоне от начала
файла до значения, указанного в позиции end. Независимо от указанного диапазона, для
файлов последовательного доступа LotusScript устанавливает режим доступа для всего
файла.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
299
Пример. Создание записи с номером recNum% в файле произвольного доступа с именем
DATA.TXT. В качестве номера открываемого файла используется первый свободный номер, значение
которого получено с помощью функции FreeFileQ. Затем, файл открывается и созданная запись,
модифицируется. Исходная и измененная записи выводятся на экран.
Type PersonRecord
empNumber As Integer
einpName As String * 20
End Type
Dim reel As PersonRecord, rec2 As PersonRecord
Dim fileNum As Integer, recNum As Integer
Dim fileName As String
recNum.% = 1
fileNum% = FreeFileU
fileName$ = "DATA.TXT"
Open fileName$ For Random As fileNumo
reel.empNumber% = 123 reel.empName$ =
"John Smith"
Put IfileNum, recNum%, reel
Print reel.empName$ ; reel.empNumber%
'Выводит John Smith
123
'Открытие и изменение записи. Lock
#fileNum%, recNum%
Get #fileNum%, recNum%, rec2
Print rec2 . empName$ ; rec2.. empNuraber%
'Выводит John Smith
123
rec2.empName$ = "John Doe"
Put #fileNurn%, recNum%, rec2
Print rec2.empName$ ; rec2.empNumber%
'Выводит John Doe
123
Unlock #fileNum%, recNum% - ' Close
fileNum%
...
• -
'
-
.
•
Оператор Open (открыть файл)
Open fileName [ For { Random Input Output Append | Binary } ] [ Access
{ Read | Read Write | Write }] [ { Shared | Lock Read | Lock
Read Write | Lock Write } ]
. As [#]fileNumber
[ Len = recLen ]
. . . . . .
.
^
:
.
Открывает файл для чтения/записи данных. Т.к. этот оператор должен быть записан
одной строкой, то при необходимости нужно использовать символ продолжения строки
-символ подчеркивания ( _ ).
fileName - строковое выражение, определяющее открываемый файл. Оно может включать
в себя полный путь к файлу. Если специфицированный файл не существует, то для режима
Input LotusScript вырабатывает ошибку; для других режимов LotusScript создает пустой файл
и открывает его.
For mode (режим) - опция, значение которой определяет режим доступа к файлу; по
умолчанию открывается файл произвольного доступа.
Random - режим по умолчанию. Определяет режим произвольного доступа к файлу. В
таком файле данные существуют в виде записей и доступ к ним осуществляется по номеру
записи. Для чтения данных из файла используется оператор Get, для записи данных в файл
используется оператор Put. Если предложение Access пропущено, LotusScript пытается
открыть файл в одном из трех режимов: доступ в режиме Read Write, затем в режиме Write и,
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R, 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
301
файл, потому, что длина записи в файле последовательного доступа не фиксирована.
Большой объем внутреннего буфера для файловых дисковых операций увеличивает их
скорость. По умолчанию размер буфера равен 512 байт.
• Для файлов Binary опция recLen игнорируется.
Если файл открыт, как Binary, Random, или Input, то данные из него могут быть
скопированы в открытый файл с другим номером. Если файл открыт, как Append или
Outpute, он должен быть закрыт прежде, чем будет открыт другой файл для его копирования.
Пример. LotusScript вводит данные файла c:\123w\work\thenames.txt в массив RecType. RecType
тип, определенный пользователем, c:\123w\work\thenames.txt содержит следующие значения: '"Maria
Jones", 12345; '"Roman Minsky", 23456; '"Joe Smith", 34567; '"Sal Piccio", 91234.
Type RecType
empId As Double
employee As String
End Type
Dim arrayOfRecs() As RecType
Dim txt As String
Dim fileNum As Integer
Dim counter As Integer
Dim countRec As Integer
fileNum% = FreeFile()counter?; = 0
'
'
Open "c:\123w\work\thenames.txt" For Input As fileNum%
Do While Not EOF(fileNum%)
Line Input #fileNum%, txt$
counter% = counter% + 1
Loop
Seek fileNum%, 1
ReDim arrayOfRecs(1 To counter%)
For countRec% = 1 To counter%;
Input #fileNum%, arrayOfRecs(countRec%).employee$, _
arrayOfRecs (countRec%) . empId#
Next
Close fileNum%
Print arrayOfRecs( 2 ) .employee$ & " " arrayOfRecs(2).empld#
'Выводит: 'Roman Minsky 23456
Оператор Print (вывод данных)
Print [ exprList ]
Выводит данные на экран (в строку состояния).
exprList - список выражений, разделенных точкой с запятой, пробелом или запятой. Если
пропущено exprList, оператор Print выводит пустую строку. Для вставки пробелов или
символов табуляции между выводимыми элементами данных используются функции Spc и
Tab. Оператор Print добавляет символ "перевод строки" (возврат каретки) в конце списка
exprList, если в конце списка нет запятой или точки с запятой. LotusScript вставляет символ
'\n" в любую "многостроковую" строку (например, строчный блок, заключенный в фигурные
скобки). Для всех используемых платформ этот знак интерпретируется как символ "перевод
строки".
Следующая таблица демонстрирует, как оператора Print "реагирует" на тип данных,
определенных в списке exprList.
© InterTrust Co. Тел, (095) 9567928
Язык LotusScript
302
Выводится
Элемент
данных
Переменная
Значение переменной
Строка
Строка
Дата-время
Variant/Empty
Строка, соответствующая в используемой платформе формату
Short Date и Time. Если одна из частей выражения дата-время
отсутствует, то выводится только та. которая присутствует в
выражении.
Пустая строка ("")•
Variant/Null
Строка #Null#.
Следующая таблица демонстрирует действие разделителей точки с запятой и запятой на
вывод элементов списка exprList.
Знак пунктуации
Действие
Точка с запятой или
пробел
Точка с запятой в конце
списка
Запятая
Следующий элемент списка выводится "вплотную" к
предыдущему элементу.
Следующий оператор Print продолжает выводить данные в ту-же
строку "вплотную" к предыдущему элементу.
Следующий элемент списка выводится в следующую позицию
(зону) табуляции (они следуют одна за другой; длина такой зоны 14 символов).
Следующий оператор Print продолжает вывод в ту-же строку в
следующую позицию табуляции.
Запятая в конце списка
Пример.
Dim a As Integer, b As Integer, с As Integer
a% = 5
b% = 10
c% = 15
Print. a%, b%, c%
'Выводит 5
10
15
ч
Оператор Print # (вывод данных)
Print #fileNumber ,[ exprList ]
Выводит данные в текстовый файл последовательного доступа.
fileNumber - номер файла, назначаемый ему при его открытии. Элементы: #,
fileNumber(номep файла) и запятая являются обязательными.
exprList - опция, являющаяся списком строковых и/или числовых выражений,
разделенных точкой с запятой, пробелом или запятой. При отсутствии списка exprList
оператор Print # выводит пустую строку. Максимальная длина выводимой строки равна 32 К
символов.
Оператор Print # используется только для файлов, открытых в режимах Output или
Append. В отличие от оператора Write #, оператор Print # не выводит такие форматирующие
символы, как запятая и двойные кавычки. Для вставки между выводимыми элементами
пробелов или табуляций используются функции Spc и Tab.
Если для установки ширины строки используется оператор Width, то запятая,
использованная в качестве разделителя выводного списка, перемещает позицию вывода в
© InterTrust Со. Тел. (095) 9567928
Lotus Domino R, 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
303
следующую позицию табуляции. Если такое перемещение выходит за рамки установленной
ширины, то следующий элемент выводится с начала новой строки. Если выводимый элемент
не помещается в рамки установленной ширины строки, то, т.к. Print # не обрезает значение
выводимого элемента, элемент никуда не выводится. Однако, если такой элемент
заканчивается символом "перевод строки", то он выводится сначала следующей строки.
Следующая таблица демонстрирует
определенными в списке exprList.
работу оператора Print # с элементами,
••-'.•
Элемент данных
Действие
Переменная
Значение переменной
Строка
Строка
Дата/время
Variant/Empty
Строка, соответствующая в используемой
платформе формату Short Date и Time. Если
одна из частей выражения дата-время
отсутствуют, то выводится только та, которая
присутствует в выражении.
Пустая строка ("")
Variant/Null
Строка #Null#
Следующая таблица демонстрирует действие разделителей точки с запятой и запятой на
вывод элементов списка exprList.
Знак пунктуации
Действие
Точка с запятой или Следующий элемент списка выводится "вплотную" к предыдущему
элементу.
пробел
Точка с запятой в
конце списка
Следующий оператор Print продолжает выводить данные в туже строку
"вплотную" к предыдущему элементу.
Запятая
Следующий элемент списка выводится в следующую позицию
табуляции
Пример. Открывается файл PrinText.txt. В файл выводятся две строки. Первая строка содержит
2 значение типа String, вторая строка содержит значение Null, значение Empty, переменную типа
Integer, значение типа String, разделенные символом табуляции, после чего файл закрывается и
открывается вновь для чтения. Результат чтения данных из файла представлен в последней строке
примера.
Dim nVar As Variant, eVar As Variant.
.
nVar = Null
Dim fileNum As Integer
'•
' •
fileNum% = FreeFile()
Open "PrinText.txt" For Output As fileNum%
Print #fileNum%, "First line, " ; "with two String items"
Print #fileNum%, nVar, eVar, fileNum%, "at next tab"
Close fileNum%
- . . ' . .
.
Dim text As String
Open "PrinText.txt" For Input As fileNum%
Do Until EOF(fileNuml)
Line Input #fileNum%, text$
Print text$
Loop
.
-
- '.' ''' '.;..'.•..: 1'
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
304
Close fileNum% .
.....
'Выводит:
'Первая строка: два элемента типа String
'#Null#
I
at next tab
Оператор Put (вывод данных)
Put [#] fileNumber, [ recordNumber ], variableName
Выводит значение переменной в двоичный файл или в файл произвольного доступа.
fileNumber - номер, присвоенный файлу при его открытии оператором Open. Наличие
знака #, номера файла fileNumber и variableName обязательно.
recordNumber - опция, определяющая позицию в файле (байта в двоичном файле и записи в
файле произвольного доступа), в которую выводится текущее значение переменной. Если эта
опция пропущена, вывод данных осуществляется в текущую позицию открытого файла.
variableName - переменная, содержащая выводимые данные. Она не может быть
обычным массивом, но может быть массивом фиксированной длины, определенным внутри
типа, с определенным количеством элементов.
Первая запись или байт в файле имеет номер 1. После каждого выполнения операции
вывода позиция вывода смещается:
• для двоичного файла - на длину выводимой переменной;
• для файла произвольного доступа - на длину выводимой записи.
Если длина значения в переменной variableName длиннее записи, определенной в файле,
то не происходит ни стирания, ни удаления уже существующей в файле записи при выводе
variableName.
Следующая таблица демонстрирует действия оператора Put в зависимости от типа
переменной variableName.
Тин variableName
Действие оператора Put
Variant
Выводятся первые два байта значения переменной
Empty или Null
Данные не выводятся
Числовой тип
Выводится количество байтов, соответствующего числового
типа: Integer - 2 байта, Long - 4 байта, Single - 4 байта, Double
- 8 байт, Currency - 8 байт, Date/time - 8 байт
Выводится указанное количество символов, например, для
переменной, объявленной, как String * 10, будет выведено 1
0 символов
Строка
фиксированной
длины
Строка переменной
длины
String
Вывод зависит от типа используемого файла
Файл произвольного доступа:
Первые два выводимых байта определяют длину
выводимой строки. Оператор Put выводит
соответствующее число символов. Если переменная
variableName не инициализирована, то выводится строка
нулевой длины. Если длина переменной variableName
больше длины записи в файле, LotusScript вырабатывает
ошибку. Если переменная variableName короче , чем
запись, определенная в файле, то вывод производится, но
О InterTrust Со. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
305
остаток предыдущей записи, на которую наложилась
выводимая запись, не стирается.
Двоичный файл:
Число выводимых байтов, равно длине строки, содержащейся в
переменной variableName. Если значение ее не
инициализировано - данные в файл не выводятся. Для типа,
определенного пользователем, Put выводит суммарное
количество байтов, содержащихся во всех элементах типа,
кроме динамических массивов, списков или объектов.
Пример.
Type PersonRecord
empNumber As Integer
empName As String * 20
End Type
-.
.. .
•
Dim fileNum As Integer Dim
fileName As String Dim rec
As PersonRecord fileNuml =
FreeFilet) fileNameS =
"DATA.TXT"
Open fileName$ For Random As fileNum% Len •-• Len(rec)
rec.empNumber% = 123 rec.empName$ = "John Smith"
Put #fileNum%, 1, rec
'Вывод записи в позицию 1.
rec.empNumber% = 4 5 6 rec.empName$ = "Jane Doe"
Put #fileNum%, 2, rec
'Вывод записи в позицию 2.
rec.empNumber% = 789 rec.empName$ = "Jack Jones" Put
#fileNum?i, , rec
'Вывод записи в позицию 3.
'Возврат к началу файла
Seek fileNumft, 1
Do While Not EOF(fiieNuml)
Get #fileNum%, , rec
Print rec.empNumber%,
rec.empName$ Loop
'Результат:
423
John Smith '456
Jane Doe ' 789
Jack Jones
Close fileNum°o
Оператор Reset
Reset
Закрывает все открытые файлы. Перед закрытием открытых файлов, оператор Reset
выводит, при необходимости, информацию из всех внутренних буферов в файлы.
Пример.
Reset
-. -
•
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
306
Оператор Seek
Seek [#]fileNumber , position
Назначает в открытом файле позицию для выполне ния очередной операции
ввода/вывода: для байта в двоичном файле; для записи в файле произвольного доступа
fileNumber - номер, назначенный файлу при его открытии в операторе Open.
position - позиция, необходимая пользователю для выполнения следующей операци и
ввода или вывода данных. В двоичном файле или файле последовательного доступа это
число (позиция байта) не равное 0, в файле произвольного доступа это номер записи в файле.
Первый байт или первая запись имеют номер позиции, равный 1. Если задано значение
позиции равное 0 или оно не задано, вырабатывается ошибка.
Номер записи в операторе Get или Put неприемлемы в файле, позиция ввода/вывода в
котором определена оператором Seek..
Вывод данных в позицию большую, чем позиция последнего элемента (байта или записи)
файла, определяет операцию добавления данных в конец файла.
Пример.
Type personRecord
empNumber As Integer
empName As String * 20
End Type
Dim reel As personRecord, rec2 As personRecord
Dim fileNum As Integer, recNum As Integer-Dim
fileName As String fileNum! = F'reeFile () fileName? =
"DATA.TXT" recNum'^ = 5
Open fileName? For Random As fileNum% Len = Len(recl)
reel.empNumbers = 123 reel.empName? = "John Smith"
Print Seek (fileNum?.)
'Выводит 1 в текущую позицию файла
Put #fileNura%, rec.Num%, reel
'Вывод 5-й записи в файл
Print Seek ( fileNum's )
'Выводит 6
Seek fileNum%, 1
'Возврат к 1-й записи в файле
Print Seek(fileNum%)
'Выводит 1
Rec2.empNumber! = 456
Rec2.empName? = "Jane Doe"
Put #fileNum%, , rec2
'Вывод данных в текущую позицию файла
Print Seek(fileNum%)
'Выводит 2
Close fileNurn%
Оператор Width # Width
#fileNumber , width
Назначает ширину (длину) строки, выводимой в текстовый файл последовательного
доступа.
#fileNumber - номер, присвоенный файлу в LotusScript во время его открытия; перед
номером должен стоять знак #. Файл обязательно должен быть открыт.
width - целое выражение, значение которого л ежит в интервале от 0 до 255
включительно, определяющее количество символов, выводимых, как одна строка, начиная с
начала строки до перехода на следующую строку. По умолчанию, это значение равно 0 и
определяет бесконечную по ширине строку.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
307
Если данные, выводимые обычным образом, выходят за пределы ширины текущей
строки, установленной оператором Width #, эти данные выводятся в начало следующей
строки. Назначение оператора Width # действительно только для оператора Print #; оператор
Write # игнорирует назначение Width #.
Пример.
Dim fileNum As Integer
Dim filename As String
fileName$ = "DATA.TXT"
fileNum% = FreeFile()
Open Filename$ For Output As fileNum%
Width #fileNum%, 20
Print #fileNum%, "First line";
Print #fileNum%, "This will go on one; line, though.";
Print #fileNum%, "But. this is on another.";
Print #fileNum%, "The End";
Close fileNum%
Оператор Write #
Write #fileNumber [, exprList ]
Выводит в файл последовательного доступа любую последовательность символов.
#fileNumber - номер файла, присвоенный ему при открытии. Наличие знака # перед
номером обязательно.
exprList - опция, являющаяся списком выражений числового типа или типа String,
выводимых в файл. Элементы списка разделяются запятыми. Если предложение exprList
пропущено, Write # выводит в файл пустую строку. Предложение exprList может включать
массивы, списки, переменные типы или объекты, а также отдельные элементы массива,
списка или типа.
Оператор Write # используется только для файлов, открытых в режиме Output или
Append. Для ввода данных, которые были выведены в файл с помощью оператора Write #,
используется оператор Input #. Оператор Write # игнорирует в файле установку ширины
линии оператором Width #. Элементы данных разделяются запятыми; символ "перевод
строки" вставляется после вывода в файл любых данных.
При выводе строки с продолжением, LotusScript вставляет символ "\n" (продолжение
строки) в любую мультистроку. Если для вывода строки в файл последовательного доступа
используется оператор Print #, символ \п для всех используемых платформ трактуется, как
символ "перевод строки". При использовании для этой же цели оператора Write # символ \n
интерпретируется так же, поэтому, для ввода из файла последовательного доступа
мультистрок, выведенных оператором Write #, используется только оператор Input, но не
Line Input.
Следующая таблица показывает действие оператора Write # в зависимости от типа
данных в списке exprList.
, '
Тип данных
Действие оператора Write #
Числовой
Отбрасываются пробелы впереди и сзади строки
String
Заключает все строки в двойные кавычки. Добавляет до необходимой
длины пробелами значение фиксированной длины.
Используется один из следующих форматов:
#yyyy-mm-dd hh:mrn:ss# #yyyy-mm-dd#
#hh:mm:ss#
Variant
(Date/Time)
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
308
Если отсутствует какая-либо часть выражения (определяющая дату и/или
определяющая время), выводится только присутствующая часть значения.
Variant, значение В файл выводится запятая. Если же пустой элемент является последним в
Empty
выводном списке, то запятая не выводится.
Variant, значение В файл выводится строка #Null#.
Null
Пример.
Dim
Dim
Dim
Dim
fileNum As Integer, empNumber As Integer, 1 As Integer
fileName As String, ernpName As String
empLocation As Variant
empSalary As Currency
fileNum% = FreeFile()
fileName$ = "DATA.TXT"
Open fileName$ For Output As fileNum%
Write #fileNum%, "Joe Smith", 123, "1 Rogers Street", 25000.99 456,
Write #fileNum%, "Jane Doe",
"Two Cambridge Center", 98525.66 , 789,
Write #fileNum%, "Jack Jones", "Fourth Floor", 0
'Чтение из файла и Close fileNum%
в
Open fileName$ For
fileNum%
ы
For I% = 1 To 3
вод.
Input
Input. #fileNum%,
As
empName$, empNumber%, empLocation, empSalary@
Print empName$ empNumber%, empLocation, empSalary@
Next I%
2.8.11.3, Функции ввода/вывода
Close fi .eNum%
Функция EOF
EOF (fileNumber)
Возвращает целое значение, определяющее достижение конца файла. fileNumber - номер.
идентифицирующий файл, присвоенный ему при его открытии.
Возвращаемое значение зависит от типа используемого файла. Следующая таблица
определяет значения функции EOF для двоичных файлов, файлов произвольного и
последовательного доступа.
Тип файла
Двоичный
Произвольный
Последовательный
EOF возвращает True (-1) если:
EOF возвращает False(0) если:
Последнее выполнение оператора
Оператор Get не смог выполнить
чтение затребованных номером
байтов данных.
Затребованная запись не может
быть прочитана по причине достижения конца записей в файле
Достигнут конец файла
Не последнее выполнение оператора
Оператор Get выполнил чтение
затребованных номером байтов
данных
Чтение затребованной записи
успешно выполнено
Не достигнут конец файла
Определяет достижение конца файла при чтении из него данных. Символ Ctrl+Z (ASCII
код = 26) не определяет маркер конца файла любого из вышеуказанных типов.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
309
Пример.
Dim text As String, fileNum As Integer
fileNum's = FreeFileO
Open "C:\CONFIG.SYS" For Input As fileNum!
Do Until EOF(l)
Line Input ttl, text$
Print
text$ Loop Close
fileNurr.%
Функция FreeFile
FreeFile
Возвращает свободный номер (тип Integer) для использования при открытии файла.
Функция FreeFile выдает номер файла, не являющийся номером ни одного уже открытого
файла. Если все возможные номера использованы, выдается сообщение об ошибке. Всего
таких номеров может быть от 1 до 255. Вызвать функцию можно в виде FreeFile или
FreeFile().
Пример. Использование функции FreeFile для получения свободного номера файла. Значение
номера хранится в переменной filNum%.
Dim fileNum As Integer
.
Dim cdr As String
•
cdr$ = CurDriveO + "\AUTOEXEC.BAT"
'Присваивает переменной fileNum значение следующего допустимого
1
номера файла.
fileNum% = FreeFile ()
Print FreeFileO
' Выводит 1 (1 не использован)
Open cdr$ For Input Access Read As fileNum!
' Открыт файл с № 1
Print FreeFile ()
'Выводит 2 (номер 1 использован)
Close fileNum%
"
Print FreeFile ()
'
'Выводит 1 (номер 1 не использован)
Функция Input
Input[S] ( count, [#]fileNumber )
Считывает последовательность символов из последовательного или двоичного файла в
строковую переменную без каких-либо преобразований. Возвращаемое значение для
функции Input - типа Variant, а для функции InputS - типа String.
count - число считываемых символов (не более 32000). fileNumber - число, определяющее
номер открываемого файла.
LotusScript возвращает определенное число символов, начиная с текущей позиции в
файле. Если количество запрашиваемых символов превышает разрешенное, возвращается
максимально разрешенное количество символов. Если длина возвращаемой строки
превышает значение count, выдается сообщение об ошибке. Если значение счетчика
считываемых символов (count) = 0, LotusScript возвращает (""). Возвращаются все
считываемые символы, включая символы "перевод строки", двойные кавычки, пробелы. При
необходимости, можно получить байтовые представления символов используя функции
InputB или InputB$.
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
310
Можно использовать функции Input, Input$, InputB, или InputB$ для чтения данных из
файла, открытого в режиме Output, Append, или Random.
Пример.
-
Dim fileNum As Integer Dim
fileName As String Dim
firstCheck As String
fileNum%; = FreeFile ( )
fi1eName $ = "DATA.TXT"
'Вывод данных.
Open fileName$ For Output. As fileNum%
Write #fileNum%, "Joe Smith", 123, "1 Smith Road", 25000.99 Write
#fileNum%, "Jane Doe", 456, "Two Cambridge Center", 98525.66 Close
fileNum%'Чтение первых 23 символов и печать данных. Open fileName$ For
Input As fileNum% firstCheck$ = Input$(23, fileNum%)
Print firstCheck$ ' Выводит: "Joe Smith",123,"1 Smit Close
fileNum%
Функция InputB
InputB[$] ( count, [#]fi!eNumber )
Возвращает указанное количество байтов из файлов последовательного доступа или
двоичных в строковую переменную без преобразования данных. Функция InputB возвращает
значение типа Variant, a InputBS - типа String.
count - количество считываемых байтов (не более 64000; это количество байтов
определяет 32000 символов). fileNumber - номер открываемого для чтения файла.
LotusScript возвращает указанное количество байтов, начиная с текущей позиции в
файле. Если количество запрошенных байтов превышает допустимое, будет возвращено
допустимое количество байтов и выдано сообщение об ошибке. Количество возвращаемых
символов равно половине количества возвращаемых байтов (при нечетном количестве
возвращаемых байтов их число автоматически приводится к четному с помощью операции
count + 1). Если count = 0, LotusScript возвращает пустую строку ("").
Считываемые данные не преобразуются. Все байты вводятся без изменения, включая
байты, представляющие "перевод строки", двойные кавычки, и пробел. Можно использовать
функции Input, InputS, InputB. или InputBS для чтения данных из файла, открытого в режиме
Output, Append, или Random.
Пример.
Print InputB$(4, 1)
' Выводит на печать 4 байта из файла с номером 1.
Функция LOC
LOC (fileNumber )
Возвращает текущую позицию в файла. fileNumber - номер, назначаемый файлу при его
открытии.
Следующая таблица представляет значение, возвращаемые функцией LOC для файлов
произвольного доступа, последовательного доступа и двоичных файлов.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
Тип файла
311
Возвращаемое значение
Произвольный
Номер последней записи считанной или записанной в файл
Последовательный
Номер позиции байта в файле, деленный на 128 и округленной
до целого значения.
Номер позиции последнего считанного или записанного в файл
байта.
Двоичный
Пример. Создается произвольный файл с именем DATA.TXT и в него записываются две записи. В
процессе записи контролируется длина файла. После перезаписи второй записи на место первой
(удаления первой записи) длина файла уменьшается на 1.
Type PersonRecord
encumber As Integer
empName As String *20
End Type
Dim rec1 As PersonRecord, rec2 As PersonRecord Dim
fileNum As Integer Dim filename As String fileNum% =
FreeFile() fileName$ = "DATA.TXT"
Open fileName$ For Random As fileNum%,
rec1.encumber% = 123 rec1,empName$ =
"John Smith" Put #fileNum%, 1, rec1
Print LOC(fileNum%)
' Выводит 1
rec2.empNumber% = 4 5 6
rec2.empName$ = "Jane Doe" Put
#fileNum%, 2, rec2
Print LOC(fileNum!)
' Выводит 2
Get #fileNum%, 1, rec2
<ч.
Print LOC(fileNum%}
' Выводит 1
Close fileNum%
ФУНКЦИЯ LOF • . . . ; . . • ........
,.;:'...,;••
............................................................................. :-...;....... - :-.. :'•-
....-.•:.
•,....;.-........
.......................... •....---.-
LOF (fileNumber )
Возвращает длину открытого файла в байтах (тип Long). fileNumber - номер,
назначенный файлу при его открытии.
Функция LOF работает только с открытым файлом.
Пример. Использование LOF для определения длины файла, и выполнение Input$ для чтения файла в
строковую переменную izFile.
Dim izFile As Integer
Dim fileName As String, fileContents as String
izFile% = FreeFile ()
tileName$ = "c:\autoexec.bat"
. . .
Open fileName$ For Input As izFile%
fileContents$ = Input$(LOF(izFile%), izFile%)
Print fileContents$
'Вывод на экран содержимого файла
ФункцияSeek .-/.•••...•-....••......•. ..... -':'•••-•,•.-..-.-.
.. -'::•;-••....•..-
•:•••. . ....
....•-.-:--••
Seek ( fileNumber )
Возвращает значение текущей позиции в открытом файле (позицию байта в двоичном
файле и позицию записи в файле произвольного доступа).
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
312
fileNumber - номер, назначенный файлу при его открытии в операторе Open.
Функция Seek возвращает значение типа Long, заключенное в интервале от 1 до 2.0Е31 -1
включительно, если номер позиции в файле не превышает этот диапазон. Для файла, в
котором номер позиции превышает 2.0ЕЗО, возвращается отрицательное значение.
Для двоичных файлов и файлов последовательного доступа, функция Seek возвращает
значение текущей позиции байта внутри файла. Для файла произвольного доступа, функция
Seek возвращает номер следующей записи внутри файла.
Первый байт или первая запись в файле всегда имеют номер позиции равный 1.
Пример.
Type personRecord
empNumber As Integer
empName As String * 20
End Type
Dim rec1 As personRecord, rec2 As personRecord Dim
fileNum As Integer, recNum As Integer Dim fileName
As String fileNum% = FreeFile() fileName$ =
"DATA.TXT" recNum% == 5
Open fileName$ For Random As fileNum"; Len = ben (reel)
reel.empNumber% = 123 reel.empNameS = "John Smith"
Print Seek(fileNum%)
'Выводит 1 в текущую позицию файла
Put #fileNum!, recNum%, reel
'Вывод 5-й записи в файл
Print Seek ( f ileNurn% )
'Выводит 6
Seek fileNum!, 1
.'Возврат к 1-й записи в файле
Print Seek(fileNum%)
'Выводит 1
Rec2.empNumber% = 456
Rec2.empName$ = "Jane Doe"
Put #fileNum%, , rec2
'Вывод данных в текущую позицию файла
Print Seek(fileNuml)
'Выводит 2
Close fileNum%
Функция Tab
Tab ( column )
7
При вызове из операторов Print или Print # функция Tab выводит в текущую позицию
указанное количество символов.
column - любое числовое выражение в интервале значений от 1 до 32000 включительно,
определяющее количество позиций вывода. Даже если значение column меньше 1, по
умолчанию функция Tab установит ее в 1 (левая граница вывода).
Если определена ширина для выводного файла, функция Tab проверяет значение column
на соответствие этой ширине и выполняет следующее:
• если вывод производится уже за пределами установленной ширины, функция Tab
выводит символ "перевод строки" и продолжает вывод оставшихся символов в
следующую строку;
• если количество символов, определенное значением column, помещается в текущую
позицию, функция Tab выводит необходимое количество символов, начиная с указанной
позиции в текущую строку. Если вывод производится в строку, ширина которой
установлена с помощью оператора Width #, функция Tab выполняет следующее:
© InterTrust Со. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
313
Tab выводит
Column
> ширины
column Mod width
<1
column 1
< текущей позиции вывода
(column - текущая позиция) следующая строка
> текущей позиции вывода
(column - текущая позиция)) та же строка
Пример. Выводится содержимое переменных firstN и iastN. Функция Tab() используется для
разделения следующих элементов: Bob Jeremiah, Jeremiah, Jeremiah, Jeremiah. Точка с запятой в
операторе Print является опцией; знак не влияет на формат вывода, если позиции вывода определяются с
помощью Tab.
Dim firstN As String,
firstN$ = "Bob"
IastN As String
lastN$ = "Jeremiah"
Print firstN$; Tab (5); lastN$; Tab (1) ; last.N$; Tab (2); lastN$; _Tab(3);
lastN$
2.8.12. Работа с OLE-объектами
Основные положения
Концепция связи и встраивания объектов (OLE - Object Linking and Embedding),
обеспечивает текущему приложению доступ к данным других приложений, включая
возможность их использования и, при необходимости, изменения.
OLE-объект - группа определенных данных, например, текст, графика, звук и вообще все,
что отображается и поддерживается каким-либо приложением - OLE-сервером.
Любое другое приложение, поддерживающее протокол OLE - OLE-клиент - может
обращаться к данным OLE-объекта. OLE-объект может быть или связан с использующим его
приложением (сам OLE-объект в этом случае хранится отдельно от приложения, а
приложение "знает", где он хранится), или встроен в текущее приложение (OLE-объект
"хранится" в самом приложении). И в том и в другом случае приложение -клиент может
получить доступ к данным OLE-объекта.
.
. . :
Функция CreateObject
CreateObject ( className )
Создает OLE-объект и возвращает ссылку на него.
className - строка типа Variant, удовлетворяющая спецификации вида appName.appClass и
определяющая тип создаваемого объекта, например, "WordPro.Document". appName - имя
приложения, которое поддерживает OLE-объект. appClass - класс создаваемого OLE-объекта
(одно приложение-сервер может поддерживать OLE-объекты нескольких классов).
Если приложение-сервер еще не выполняется, то CreateObject запускает его, чтобы
создать OLE-объект.
Оператор Set присваивает возвращаемое функцией CreateObject значение ссылки
переменной типа Variant. Ссылка на OLE-объект является допустимой только во время
выполнения поддерживающего его приложения. Если это приложение завершается, а
OLE-объект не сохранен, LotusScript возвращает ошибку периода выполнения.
LotusScript поддерживает OLE-коллекции оператором ForAll. Поддерживаются и
"параметрические" свойства OLE-объектов. Например, если OLE-объект, ссылку на который
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
314
"хранит" переменная v, имеет свойство Prop с двумя аргументами, чтобы присвоить этому
свойству значение 4, нужно "записать":
v . prop (argl,
arg2) = 4
Пример. Создание документа Word Pro, вставка в него строки текста и сохранение документа в
файле. StyleSheet, Insert, Save - свойства и методы OLE-объекта класса Document, поддерживаемого
сервером (текстовым процессором) WordPro.
; _.....
Dim myDoc As Variant
Set myDoc = CreateObject("WordPro.Document")
myDoc - StyleSheet, = " basic, sty"
myDoc.Insert = myText$
myDoc.save "c:\mydocs\" & fileName$
Функция GetObject
..
:.
.. ..
.
GetObject ( pathName [, className ] )
Открывает OLE-объект и возвращает ссылку на него.
pathName - строка, содержащая полный путь и имя файла OLE-объекта или пустая
строка. Если задана пустая строка, то должна быть определена строка className.
className - строка вида appName.appCIass, определяющая приложение, в котором создан
OLE-объект, и класс этого OLE-объекта. Например, "WordPro.Document".
Возвращаемая функцией GetObject ссылка на OLE-объект присваивается переменной
типа Variant оператором Set.
Если приложение, специфицированное, как appName, не выполняется, функция GetObject
запускает его. Ссылка на OLE-объект "имеет силу" только во время выполнения
поддерживающего его приложения. Если это приложение незапланированно завершается,
LotusScript: выдает ошибку периода выполнения.
Если pathName указано пустой строкой (""), функция GetObject пытается найти любой
текущий активный объект специфицированного класса. Если такой объект не найден
-выдается ошибка.
Пример. Файл c:\status.sam загружается в редактор WordPro (как в приложение-сервер). Оператор
Set присваивает переменной myDoc ссылку на OLE-объект. К OLE-объекту применяется метод Print
-документ печатается.
Dim myDoc As Variant
' Получение ссылки на OLE-объект из файла
Set myDoc = GetObject("с:\status.sam", "WordPro.Document")
' Вызов метода Print, определенного для объекта класса WordPro.Document
myDoc.Print
2.8.13. Синхронизации работы параллельно выполняемых Web-агентов
Типичной реализацией выполнения серии операций в базе данных при взаимодействии
Domino-приложения с Web-пользователем являются Web-агенты.
Начиная с версии Domino 4.5.1 возможно параллельное исполнение Web-агентов.
Каждый Web-агент исполняется в отдельном потоке серверного процесса HTTP. Если на
сервере не разрешено одновременное (асинхронное) выполнение нескольких Web-агентов, то
они выполняются последовательно (serialized). Это приводит к тому, пользователь может
долго ждать результата простой операции в случае, если более сложную (длительную)
операцию раньше запросил другой пользователь. Параллельное (asynchronous) исполнение
Web-агентов позволяет достичь оптимального времени отзыва системы, адекватного
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @гформулы, LotusScript, встроенные классы LotusScript и Java
315
сложности операции и зависящего от количества пользователей, но не от очередности
обращения пользователей.
В примере в таблицах видно, что параллельное исполнение агентов приводит к
относительно небольшому увеличению времени работы агента 1 (сложного) и в то же время к
ощутимому уменьшению времени реакции системы на запрос пользователя В (простой
агент 2).
Последовательное исполнение агентов:
Момент
времени
Операция
Комментарий
Пользователь А инициирует запуск агента 1
0
1
Вычисления
Стартует агент 1 . Пользователь В инициирует запуск
агента 2
2
Вычисления
Выполняется агент !
3
Вычисления
Выполняется агент 1
4
Вычисления
Выполняется агент 1
5
Вывод
результата
Завершает работу агент 1
6
Вычисления
Стартует агент 2
7
Вывод
результата
Завершает работу агент 2
Параллельное исполнение агентов:
Момент
времени
Поток 1
Поток 2
Комментарий
Пользователь А инициирует запуск
агента 1
0
1
Вычисления
Стартует агент 1 , Пользователь В
инициирует запуск агента 2
2
Вычисления
Выполняется агент 1
3
Вычисления
Агент 1 приостанавливается.
Стартует агент 2
4
Вывод
результата
Завершает работу агент 2
5
Вычисления
Выполняется агент 1
6
Вычисления
Выполняется агент 1
7
Вывод
результата
Завершает работу агент 1
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
316
Но простого разрешения параллельного исполнения Web-агентов на сервере
недостаточно. Необходимо обеспечение устойчивости такой многопотоковой системы.
Устойчивость многопотоковой системы предполагает:
*
либо отсутствие общих ресурсов потоков
:
либо наличие (и использование) механизмов блокировки ресурсов потоками
Общим ресурсом могут быть подлежащая модификации информация в БД. Для того,
чтобы избежать конфликтов необходимы механизмы синхронизации.
LotusScript 4.0 (в Domino R5) такие средства синхронизации Web-агентов имеет. Этими
средствами являются новые встроенные функции работы с семафорами (с терминологии
документации - lock).
* CreateLock - создание (подключение к) семафора
* DestroyLock - уничтожение (отключение от) семафора
* CodeLock - закрытие семафора
* CodeUnlock - открытие семафора
* CodeLockCheck - длина очереди к семафору
* Sleep - приостановка работы скрипта на указанное время
© Функция CreateLock
CreateUnlock ( name As String )
Возвращает целочисленный идентификатор семафора (lock) с именем, заданным строкой
пате. Если ссылок на семафор с таким именем до сих пор не было (например, в другом
потоке), то он создаётся и ему присваивается идентификатор.
Успешно полученный идентификатор является целым числом.
Можно сказать больше: значение идентификатора всегда число от 0 до 255 и нельзя
определить более 256 семафоров (такая попытка заканчивается ошибкой с номером 238
-«Maximum number of semaphores permitted reached»). Т.е. под хранение идентификатора
используется один байт.
Если переменная, хранящая значение идентификатора, оказалась за пределами области
видимости, идентификатор может быть безболезненно переполучен повторным вызовом
функции. Другими словами, в Web-агенте (т.е. в пределах одного потока) можно сколько
угодно раз подключаться к одному и тому же семафору, например, в каждой определенной
пользователем подпрограмме или функции. Имена семафоров уникальны в пределах текущей
области общей памяти, т.е. для всех Web-агентов, выполняющихся в рамках задачи HTTP.
При завершении работы потока все ссылки на использовавшиеся семафоры автоматически
удаляются и, если нет больше ссылок, удаляется семафор. Несмотря на это правильнее
удалять ссылки на семафоры явно, используя функцию DestroyLock.
Если платформа не поддерживает механизм семафоров или недостаточно общей памяти,
то будет возвращена ошибка.
© Функция CodeLock
CodeLock ( ID As Integer )
Выполняется попытка закрытия семафора с идентификатором, заданным целым числом
ID. Идентификатор ID должен быть предварительно получен вызовом функции CreateLock.
©InterTrust Co. Тел. (095)9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
317
При успешном закрытии семафора функция возвращает TRUE. Другое значение означает
неуспех операции. Этот исход принципиально отличается от ситуации, когда семафор уже
закрыт другим Web-агентом. В этом случае выполнение Web-агента приостанавливается, как
будто функция CodeLock долго не возвращает результат. В это время многопотоковая
система передает управление следующему Web-агенту и т.д. Таким образом, образуется
очередь агентов, пытающийся закрыть один и тот же семафор и все «ждут» пока семафор не
откроется.
Попытка закрыть семафор с неизвестным идентификатором (ссылка на семафор не была
создана вызовом CreateLock или уже была удалена вызовом DestroyLock) приводит к
возникновению ошибки с номером 235 - «Lock ID has not been created».
Любой семафор, закрытый функцией CodeLock, обязательно должен быть открыт
вызовом функции CodeUnLock. Несоблюдение этого правила приводит к непредсказуемым
результатам.
© Функция CodeUnLock
CodeUnlock (ID As Integer )
Открывает семафор, заданный идентификатором ID. Идентификатор ID должен быть
предварительно получен вызовом функции CreateLock. Открытый семафор становится
доступен следующему агенту в очереди на закрытие.
Любой семафор, закрытый вызовом функции CodeLock, обязательно должен быть открыт
вызовом функции CodeUnLock. Несоблюдение этого правила приводит к непредсказуемым
результатам.
0 Функция CodeLockCheck
CodeLockCheck (ID As Integer )
Для указанного идентификатором ID семафора возвращает число агентов закрывших
семафор или ожидающих своей очереди на закрытие. Другими словами, возвращается длина
очереди агентов «к закрытому семафору» плюс один. Результат является целым числом.
Эта функция никак не отражает число агентов ссылающихся на данный семафор
(получивших с помощью функции CreateLock его идентификатор).
Пример 1. Семафор «SomeLockName» закрыт неким агентом и других агентов, ожидающих его
открытия, нет.
Dim LickID as Integer
•-•-••
LickID = CreateLock(«SomeLockName») Print
CodeLockCheck(LockID) ' Печатает 1
. .
- .... ,
Пример 2. Семафор «SomeLockName» закрыт неким агентом и есть еще один агент, запросивший
закрытие семафора и ожидающий его открытия.
Dim LickID as Integer
LickID = CreateLock(«SomeLockName»)
Print CodeLockCheck(LockID)
x
Печатает 2
Пример З. Семафор «SomeLockName» открыт.
Dim LickID as Integer
LickID = CreateLock(«SomeLockName»)
Print CodeLockCheck(LockID) v Печатает
i InterTrust Co. Тел. (095) 9567928
Я) ы к L o t us Scr i pt
318
© ФункцияDestroyLock
' •.,••.--•••/- • ! .:
.::---..•:••-:'-•:.;;•;.-•;.:.•• i':.;.•••••;••..••-:•.•........ :'.;; ': ..':.'. ""• -
DestroyLock (ID As Integer)
':
,^ \ .
Удаляет ссылку текущего агента (т.е. потока) на указанный семафор. Если при этом
общее количество ссылок на этот семафор оказывается равным нулю, то семафор удаляется
(освобождается его идентификатор). Идентификатор ID должен быть предварительно
получен вызовом функции CreateLock.
При успешном удалении ссылки на семафор функция возвращает TRUE. Другое значение
означает неуспех операции.
Несмотря на то, что при завершении работы агента ссылки на использовавшиеся агентом
семафоры автоматически удаляются, рекомендуется удалять ссылки на семафоры явно,
используя функцию DestroyLock.
Пример. Удаление ссылок агента на семафоры
Dim LickID as Integer
LickID = CreateLock(«SomeLockName») % Получаем Q - идент. семафора Print
DestroyLock (LockID) ' Печатает True-Print DestroyLock(10) Л Ошибка № 235
- «Lock ID has not been created»
© OnepaTOp'Sleep • • • ; . : TV"-.. - г - : . ........ ,.....: •....•::;:•..: . ,
. . . . . . . . . . ,,'........................ ;•............... Л:...'...•.:.:.............. •••......: .v
Sleep ( time as Float)
Приостанавливает выполнение скрипта на указанное время. Время остановки
указывается в секундах дробным числом гг/ие.Приостановка выполнение скрипта с помощью
этого оператора имеет принципиальные отличия и преимущества от традиционной
реализации задержки в виде формального цикла:
•
•
при задержке по оператору Sleep не занимаются вычислительные ресурсы
освободившиеся ресурсы используются другим процессом
• в многопоточной системе управление передается другому потоку
В случае параллельного исполнения Web-агентов при приостановке одного из них
управление автоматически передается следующему.
Надо заметить, что реальное время задержки может оказаться и больше указанного. Это
определяется загруженностью системы.
•.•
Минимальное время задержки определяется платформой, на которой исполняется код.
Если минимальным квантом является милисекунда, то указанное дробное число будет
огруглено до тысячных.
Обширный пример использования оператора Sleep имеется в пункте «Пример
синхронизации работы параллельно выполняемых Web-агентов» этого параграфа.
Пример. На диаграмме загрузки процессора (см. ниже) хорошо видно, что при приостановке
скрипта оператором Sleep системные ресурсы не занимаются. Кстати, пики загрузки процессора
приходятся на формальные циклы.
E'or is. = 1 То 100000 ' занимает процессорное время
Next
Print Now
Print "-"
Print Now ' выполняется моментально вслед за
' предыдущим оператором (время попросту совпадает)
Print "-"
Sleep ( 5 )
' процессор не нагружается Print Now '
время отличается ровно на 5 секунд
For i& = 1 То 100000 ' занимает процессорное время
Next
© InterTrust Co. Тел. (095) 9567928
•
•
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
319
Kernel: Processor Usage (%)
© Функция GetThreadlnfo
GetThreadlnfo (InfoID )
Возвращает системную информацию о текущем потоке.
InfoID - числовой код, определяющий вид возвращаемого показателя.
Возможные значения и назначения данного кода приведены с таблице:
Код
Показатель
LSl_THREAD_LINE
Номер текущей строки
LSI_THREAD_PROC
Имя текущей процедуры
LSI „THREAD MODULE
Системное имя текущего модуля
LSI_THREAD_VERS1ON
Номер версии LotusScript
LSI_THREAD LANGUAGE
Текущие языковые настройки
LSI_THREAD_COUNTRY
Номер национальных настроек
LSIJTHREAD TICKS
Значение системного таймера
LSI THREADjriCKS_PER_SEC
Число квантов таймера в секунду
Функция возвращает значение типа Variant, содержащее строку или число в зависимости
от конкретного кода.
Пример. Результат раотобы функции GetTheadlnfo на рабочей станции Notes 5.O.
%INCLUDE «Isconst.Iss»
Sub Initialize
Print Getthreadinfo (LSI_THREAD__LINE) Print ' Выводит 4
1 Выводит INITIALIZE
Getthreadinfo(LSI_THREAD_PROC) Print
' Выводит *302EED4
Getthreadinfo(LSI JTHREADJMODULE) Print
1 Выводит 4.0.0.20
Getthreadinfo(LSI_THREAD_VERSION) Print
Getthreadinfo(LSI_THREAD_LANGUAGE) Print
' Выводит en
Getthreadinfo(LSI_THREAD_COUNTRY) Print
' Выводит О
Getthreadinfo(LSI_THREAD_TICKS) Print
' Выводит 35490733
Getthreadinfo(LSI_THREAD_TICKS_PER_ End
SEC)
' Выводит 1000
Sub
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
320
Разрешение параллельного исполнения Web-агентов
Для того чтобы Web-агенты выполнялись не последовательно (serialized), а параллельно
(asynchronous),
необходимо
в
файл
notes.ini
сервера
записать
строку
DominoAsynchronizeAgents^l и перезапустить серверную задачу HTTP.
Файл notes.ini можно (и лучше) не править напрямую, а включить соответствующую
опцию в серверном документе в базе данных Domino Directory (название в предыдущих
версиях - Public Address Book):
Basics
Security
Ports
Server Tasks (Internet Protocols) MTAs
(HTTP)] Domino Web Engine
I Run web agents
Web agent timeout (in
seconds)
Miscellaneous
Тransactional Logging
Administration
HOP | LDAP 1 NNTP 1
Enabled
"0;
Пример синхронизации работы параллельно выполняемых Web-агентов
Предположим, имеется некое Domino-приложение, выполняющееся на сервере Domino,
допускающем асинхронное исполнение Web-агентов. Запросы пользователей обрабатываются
Web-агентами, которые выполняют критичную для многопотоковой работы операцию, например,
модификацию одних и тех же данных. Во избежание конфликта агенты создают (и непосредственно
перед записью блокируют) специальный флаг. Назовем его «MyUpdateLock».
Таким образом, сценарий работы таков:
..
•
•
Агент Agentl стартует, создает флаг «MyUpdateLock» и выводит об этом сообщение. Далее агент
Agent 1 приостанавливает свою работу на секунду. Это сделано в примере специально для того, чтобы
заведомо смог начать параллельную работу агент Agent2 (в противном случае нельзя быть уверенным в
том когда именно будет переключен контекст потоков). Агент Agent2, стартовав, также создает флаг
«MyUpdateLock».
7
Далее один из агентов, например Agent2, захватавает (блокирует) флаг «MyUpdateLock» и выводит
об этом сообщение. Потенциально продолжительная работа агента по модификации данных в нашем
примере симитирована секундной задержкой. В это время опять может (и происходит) переключение
на другой поток. Но параллельный агент не может войти в критичный блок «модификации данных», так
как не может захватить флаг - флаг остался занят первым агентом - и ждет (фактически, результата
функции захвата флага). Контекст снова переключается. Первый агент, закончив критичную работу,
освобождает (разблокирует) флаг и выводит на консоль соответствующее сообщение. В этом месте
кода намеренно сделана очередная секундная задержка, — для того чтобы снова переключился контекст
потоков. Это происходит. Агент, пытающийся захватить флаг, наконец, его получает и так далее.
В нашем примере захват-освобождение флага повторяется в цикле 5 раз.
Option Public
Option Declare Sub
Initialize
Dim ID as String, lockName As String
Dim lockID As Integer, refcnt As Integer, i as Integer
Dim gotLock As Variant, releaseLock As Variant,_
cieleteLock As Variant
On Error Goto syn _error
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
321
' Присваиваем агенту имя (чтобы идентифицировать вывод)
ID = "Agent I "
Msgbox ID & "Started"
!
iockName = "MyUpdateLock"
,
' Создаем флаг
lockID = Createlock(IockName)
If (lockID <> -1) Then
Msgbox ID & "Created lock: " & lockID End
If
' Делаем задержку в одну секунду
1 Это позволит запуститься второму агенту.
Sleep 1
For i = 1 То 5
.
- •
1 Пытаемся захватить флаг, сообщаем об этом
' а также сообщаем длину очереди на захват флага
gotLock = CodeLock(lockID)
If (gotLock) Then
Msgbox ID & "Got: lock: " & lockID & " - at: " &
Now ()
refcnt = Codelockcheck(lockID)
Msgbox ID & "
Reference count is " & refcnt ' Выполняем
критичную работу. Для простоты просто ' создаем задержку в одну
секунду Sleep 1 - "
Else
Msgbox ID & "Failed to get lock"
End If
.
' Освобождаем флаг. Другой агент теперь может его захватить
releaseLock = Codeunlock(lockID) If (releaseLock) Then
Msgbox ID & "Releasing lock: " & lockID &
" - at: " & Now()
' Делаем задержку для того, чтобы другой агент мог захватить
' флаг прежде, чем данный агент снова его захватит
Sleep 1
Else
.
..
Msgbox ID & "Failed to release lock" End If
Next
' Критичная работа завершена. Отключаемся от флага.
deleteLock = DestroyLock(lockID) If (deleteLock ) Then
Msgbox ID & "Destroyed lock " & lockID Else
Msgbox ID & "Failed to destroy lock"
End If
...
Msgbox ID & "Done"
Exit Sub
.
-•
syn error:
errormsg = " * * Error: " & Err & " - " & Error() & _
"
~,
С* r-\
1 U " itГ
Т PidL Г
" 6:
-~ Г
41.. "
Г.1Г ( Vj -к- Т I \ J-. П
Msgbox errormsg
Resume Next
End Sub
- - ..
'
Так выглядит вывод на консоль сервера наших агентов: 09.06.99 13:16:04
Addin: Agent message box: Agentl Started 09.06.99 13:16:04 Addin:
Agent message box: Agentl Created lock: 0
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
322
09.06.99 13:16:04
Addin: Agent message box: Agent2 Started
09.06.99 13:16:04
Addin: Agent message box: Agent2 Created lock: 0
09.06.99 13:16:05
Addin: Agent message box: Agent2 Got lock: 0 - at: 09.06.99 13:16:05
09.06.99 13:16:05
Addin: Agent message box: Agent2 Reference count is 1
09.06.99 13:16:06
13:16:06
Addin: Agent message box: Agent:2 Releasing lock: 0 - at: 09.06.99
09.06.99 13:16:06
Addin: Agent message box: Agent1 Got lock: 0 - at: 09.06.99 13:16:06
09.06.99 13:16:06
Addin: Agent message box: Agent 1 Reference count is 1
09.06.99 13:16:08
13:16:08
Addin: Agent message box: Agent 1 Releasing lock: 0 - at: 09.06.99
09.06.99 13:16:08
Addin: Agent message box: Agent2 Got lock: 0 - at: 09.06.99 13:16:08
09.06.99 13:16:08
Addin: Agent message box: Agent2 Reference count is 1
09.06.99 13:16:09
13:16:09
Addin: Agent message box: Agent2 Releasing lock: 0 - at: 09.06.99
09.06.99 13:16:09
Addin: Agent message box: Agent 1 Got lock: 0 - at: 09.06.99 13:16:09
09.06.99 13:16:09
Addin: Agent message box: Agent 1
Reference count is 1
09.06.99 13:16:10
13:16:10
Addin: Agent message box: Agent 1 Releasing lock: 0 - at: 09.06.99
09.06.99 13:16:10
Addin: Agent message box: Agent2 Got lock: 0 - at: 09.06.99 13:16:10
09.06.99 13:16:10
Addin: Agent message box: Agent2 Reference count is 1
09,06.99 13:16:11
Addin: Agent message box: Agent 1 Got lock: 0 - at: 09.06.99 13:16:11
09.06.99 13:16:11
13:16:11
Addin: Agent message box: Agent2 Releasing lock: 0 - at: 09.06.99
09.06.99 13:16:11
09.06.99 13:16:12
Addin: Agent message box: Agent1
Reference count is 1
Addin: Agent message box: Agent 1 Releasing lock: 0 - at: 09.06.99
13:16:12
09.06.99 13:16:12
Addin: Agent message box: Agent2 Got lock: 0 - at: 09.06.99 13:16:12
09.06.99 13:16:12
Addin: Agent message box: Agent2 Reference count is 1
09.06.99 13:16:13
13:16:13
Addin: Agent message box: Agent2 Releasing lock: 0 - at: 09.06.99
09.06.99 13:16:13
Addin: Agent message box: Agent 1 Got lock: 0 - at: 09.06.99 13:16:13
09.06.99 13:16:13
09.06.99 13:16:14
Addin: Agent message box: Agentl
Reference count is 1
Addin: Agent message box: Agentl Releasing lock: 0 - at: 09.06.99
13:16:14
09.06.99 13:16:14
Addin: Agent message box: Agent2 Got lock: 0 - at: 09.06.99 13:16:14
09.06,99 13:16:14
Addin: Agent message box: Agent2 Reference count is 1
09.06.99 13:16:15
13:16:16
Addin: Agent message box: Agent2 Releasing lock: 0 - at: 09.06.99
09.06.99 13:16:15
Addin: Agent message box: Agent! Got lock: 0 - at: 09.06.99 13:16:16
09.06.9913:16:15
© InterTrust Co. Тел. (095) 9567928
Addin: Agent message box: Agentl
Reference count is 1
Lotus Domino R. 5.- @-формулы, LotusScript, вст^^енные классы LotusScript u Java
09.06.9913:16:17 Addin: Agent message box: Agent2 Destroyed lock 0
323
^ ^
09.06.9913:16:17 Addin: Agent message box: Agent2 Done ^^ ^ ^
09.06.99 13:16:17
Addin: Agent message box: Agent 1 Releasing lock: 0 - at: 09.06.99
13:16:17
09.06.9913:16:18 Addin: Agent message box: Agent 1 Destroyed lock 0
09.06.9913:16:18 Addin: Agent message box: Agentl Done
2.8.14. Обработка ошибок в LotusScript
2.8.14.1. Основные положения
При разработке скрипта ошибки могут возникнуть как на этапе создания скрипта, так и
на этапе его выполнения. Соответственно этому ошибки делятся на две группы:
• ошибки периода компиляции;
* ошибки периода выполнения.
-
*
-
- : - .,
:
Ошибки периода компиляции
Могут появляться во время обработки компилятором LotusScript исходного текста
скрипта. Ошибка компиляции останавливает процесс компиляции. При наличии ошибки
необходимо проанализировать синтаксис операторов скрипта и, после исправления ошибки,
запустить повторно процесс его компиляции.
, ,
Ошибки периода выполнения
Могут возникать во время выполнения скрипта. Ошибки периода выполнения скрипта
отражают нарушения условий выполнения и не могут быть обнаружены на этапе его
компиляции. Примерами ошибок периода выполнения могут служить, например, ошибка,
связанная с попыткой открыть для чтения несуществующий на диске файл, или ошибка,
связанная с попыткой использования в качестве делителя переменной, значение которой к
моменту выполнения этой операции равно нулю.
Ошибки периода выполнения останавливают выполнение скрипта, если пользователем в
тексте программы не предусмотрены "ловушки ошибок", т.е. специальные операторы, к которым происходит обращение при появлении соответствующей ошибки.
LotusScript идентифицирует большинство ошибок периода выполнения и выдает
соответствующие сообщения о них. Можно вставить в скрипт свои процедуры обработки
ошибок периода выполнения, которые будут идентифицировать возникающие ошибки,
выдавать соответствующие сообщения, а при необходимости, и обеспечивать продолжение
выполнения скрипта.
Номера ошибок
Каждая ошибка периода выполнения имеет свой собственный номер, однозначно
идентифицирующий ее. Когда во время выполнения скрипта возникает ошибка, LotusScript,
"зная" номер ошибки, ищет соответствующий ей оператор On Error. Если оператор имеется,
дальнейшая обработка ошибки проистекает в соответствии с этим оператором. Например,
при возникновении ошибки с номером 357 можно воспользоваться следующим оператором
-"ловушкой", передающим управление на метку.
On Error 357 GoTo аросбОО
.
.-.-..;•.-
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
324
.•.••-•-•-.:
Большинство ошибок периода выполнения уже предопределены в LotusScript. Файл
LSERR.LSS содержит константы, значениями которых являются номера ошибок периода
выполнения. При создании скрипта можно включить в него этот файл с помощью директивы
fe;
%Include "LSERR.LSS".
Можно также задать номера для "пользовательских" ошибок. Сигнал о том, что
случилась "пользовательская ошибка", обычно "подается" оператором Error номер_ошибки.
Если для пользовательской ошибки предусмотрен оператор On Error, он получает
управление. Например:
Const ooBounds = 677 ..... . . .
' Определяет номер "пользовательской" ошибки
' Этот номер выходит за рамки существующей спецификации ошибок
г
On Error ooBounds ... ' что делать при возникновении ошибки i
Error ooBounds
' сигнал о возникновении ошибки
•
Обработка ошибок периода выполнения
Итак, при выполнении скрипта возникает ошибка. Это или предопределенная ошибка,
обнаруженная внутренними средствами LotusScript, или "пользовательская ошибка", сигнал
о которой "подал" сам разработчик скрипта. В любом случае известен номер ошибки.
LotusScript проверяет текущую процедуру на наличие в ней оператора On Error n, где n
-номер ошибки. Если оператор On Error n не найден, проверяется наличие оператора On Error,
не связанного с номером конкретной ошибки. Если такие операторы не найдены, LotusScript
продолжает их поиск в процедуре, вызвавшей текущую, и т.д.
Если не найдено соответствующего оператора On Error, выводится сообщение об
возникшей ошибке и выполнение прекращается.
Если же соответствующий оператор On Error найден, то, если в On Error указан оператор
Resume Next, продолжается выполнение той процедуры, в которой возникла ошибка, с
оператора, следующего за оператором, при выполнении которого возникла ошибка.
Если оператор On Error определяет переход на метку (Goto метка), то выполнение
продолжается с оператора, помеченного этой меткой. Если в качестве метки указан О,
повторяется выполнение вызвавшего ошибку оператора.
т
Далее следует описание операторов, реализующих функции идентификации и обработки
ошибок.
2.8.14.2. Операторы обработки ошибок
Оператор Err (установить номер ошибки)
Err = errNumber
Устанавливает номер текущей ошибки. Параметр errNumber - числовое выражение,
значение которого является номером ошибки. Номер может принимать любое значение из
диапазона от 0 до 32767 включительно.
Оператор Error (установить номер и сообщение об ошибке)
Error errNumber [, msgExpr ]
Устанавливает номер ошибки и соответствующее ей сообщение. Параметр errNumber
-числовое выражение, значением которого является номер ошибки, определенной в
© InterTrust Co. Тел, (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
325
LotusScript или определенной пользователем. Аргумент errNurnber может принимать любое
значение из диапазона от 1 до 32767 включительно. Параметр msgExpr - строковое
выражение, содержащее сообщение об ошибке. Это строковое выражение замещает любое
существующее сообщение, соответствующее ошибке с данным номером.
Если значением errNumber является ошибка, определенная в LotusScript, то оператор
Error фиксирует ошибку LotusScript. Иначе фиксируется ошибка, определенная
пользователем. Если для данной ошибки не предусмотрена обработка (нет оператора On
Error), выдается соответствующее сообщение об ошибке. Это сообщение может быть
определено в параметре msgExpr. Если параметр msgExpr отсутствовал, LotusScript выдает
свое сообщение, соответствующее данному номеру ошибки, если таковое существует. В
противном случае выдается сообщение об ошибке, определенной пользователем.
Оператор On Error (реакция на ошибку)
On Error [ errNumber ] { GoTo label Resume Next GoTo 0 }
Определяет реакцию на ошибку, возникшую в период выполнения скрипта.
Параметр errNumber - выражение, значением которого является целое число, задающее
номер ошибки. При отсутствии этого параметра оператор описывает реакцию на любую
ошибку, возникающую в текущей процедуре во время выполнения.
Оператор GoTo label определяет адрес передачи управления при возникновении ошибки
с указанным номером. Обычно, это подпрограмма обработки ошибок.
Оператор Resume Next определяет, что при возникновении ошибки выполнение
процедуры должно продолжаться с оператора, следующего за оператором, в котором
возникла ошибка. В этом случае не инициируется функция обработки ошибок.
Оператор GoTo 0 определяет, что при возникновении ошибки не будет происходить ее
обработка.
Пример. При возникновении деления на нуль получает управление оператор On Error. В его теле
имеется оператор Resume Next, передающий управление на следующий оператор за тем, в котором
возникла ошибка. Если действительно имело место деление на нуль (номер ошибки равен константе
ErrDivisionByZero, определенной в файле LSERR.LSS), печатается сообщение, и функция завершается.
^Include "LSERR.LSS"
Function Best (}
Dim x As Integer, у As Integer,
On Error Resume Next i
y% = 3
z% = 0
'
z As
'*
Integer
х% = у% / z% ' Ошибка деления на ноль If
Err = ErrDivisionByZe.ro Then
Print "Attempt to divide by 0. Returning to caller."
Exit Function
End If
. • ••
t
End Function
Call Best ( )
Оператор Resume
Resume [ 0 | Next | label ]
Определяет, куда следует передать управление после обработки ошибки:
© InterTrust Со. Тел. (095) 9567928
Язык LotusScript
326
• 0 - управление получает оператор, в котором возникла ошибка;
• Next - управление получает оператор, следующий за оператором, в котором возникла
ошибка;
• label - управление получает оператор, помеченный меткой label.
Учтите, что если причины возникновения ошибки в процедуре обработки ошибки не
были устранены, оператор Resume [0] породит бесконечный цикл.
Оператор Resume устанавливает в 0 значение функций Err, Erl, Error.
Пример. Оператор Error сигнализирует об ошибке. Получает управление обработчик ошибки
(метка ErrHandler). После печати сообщения обработчик передает управление на следующий оператор
за тем, в котором возникла ошибка - в данном случае на следующий оператор Error.
Sub ResumeSubO
On Error GoTo ErrHandler
Error I
Error 10
Error 100
Exit Sub
ErrHandler:
Print "Error " & Err & " at line number" &Erl
Resume Next
End Sub
2.8.14.3. Функции обработки ошибок
ФункцияErl ...•-•••.•• ;•• '.;:.-•••.: :••••••• •-.- • ••• -••• ••- . .- :......,-.•• .-."."•
Erl
Возвращает номер строки (тип Integer) в тексте скрипта, в операторе из которой возникла
ошибка. Если ошибки нет, возвращается значение False (0).
Пример. Выводит 0, поскольку нет ошибки.
Sub RepErr
Dim x As Integer
x% = Erl ()
Print x%
End Sub Call
RepErr
Функция Err
...... •'.-....-••.••..• ••-.•••••.••:••-. • . . •• . . . . • . . . . • . . . . . . •..... :..
Err
Возвращает номер текущей ошибки (тип Integer). Если ошибки нет. возвращается
значение False (0).
Функция Error
Error[S] [ ( en-Number ) ]
Возвращает сообщение об ошибке с номером errNumber, либо, если номер не указан,
сообщение о последней имевшей место ошибке. Функция Error возвращает значение типа
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
327
Variant, а функция Error$ - типа String. Если отсутствует выражение errNumber и нет текущей
ошибки, функция возвращает пустую строку("").
Пример. Пользователь вводит число, значение которого должно находиться в диапазоне 1 - 100.
Если введенное значение не может быть приведено к 4-х байтовому целому значению, то выдается
ошибка. Определены и две пользовательские ошибки при выходе за диапазон значений 1 - 100.
Public x As Single
Const TOO_SMALL = 1001, TOO_BIG = 1002
Sub GetNum
Dim Num As String
On Error Goto Errhandle
Num$ = InputBox$("Enter a value between 1 and 100:")
'Преобразование строки 4-байтное single значение
x! = CSng (Num$)
• •-.
' Проверка введенного значения
If x! < 1 Then
Error TOO_SMALL, "Значение меньше допустимого"
ElseIf x! > 100 Then
Error TOO_BIG,
"Значение больше допустимого"
End If
'Вывод сообщения при отсутствии ошибок ввода
MessageBox "Хорошая работа! " & Num$ & " Введено правильно."
Exit Sub
' При наличии ошибок выводится номер ошибки и сообщение
Errhandle:
'Функция Err возвращает номер ошибки
'Функция Error$ возвращает диагностическое сообщение
MessageBox "10ёаёа" & Str(Err) & ": " & Error$
Exit. Sub
End Sub
'
GetNum
' Вызов подпрограммы GetNum •
•
•
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
328
2.9. Вызов внешних функций из библиотек динамической
•
компоновки
Основные положения
»
LotusScript поддерживает возможность вызова внешних функций, написанных обычно на
языке С и размещающихся в библиотеках функций. В терминах WINDOWS такая библиотека
функций называется библиотекой динамической компоновки - DLL (Dinamic Link Library).
При работе с внешними С-функциями необходимо знать их интерфейсы (виды
аргументов, вид возвращаемого функцией значения) и собственно назначения функций. Для
получения этой информации может потребоваться соответствующая документация. Если
говорить о функциях WINDOWS, то документация по Windows API входит в состав Windows
Software Developer's Kit. Кроме того данной теме посвящено множество книг.
DLL чаще пишут на языке С, хотя последнее необязательно. В любом случае внешние
функции должны удовлетворять следующим соглашениям по вызову:
« WINDOWS 3.1 (Winl6)-Pascal,
• WINDOWS 95, 98 и WINDOWS NT (Win32) - STDCALL,
• OS/2 - _System
• UNIX и Macintosh - соответствующее CDECL.
Вызываемая из LotusScript внешняя функция обязательно должна быть предварительно
объявлена в скрипте. Аргументы во внешнюю функцию могут передаваться по ссылке или по
значению.
На платформе Win32 (WINDOWS 95, 98 и WINDOWS NT) следует помнить, что имя
функции, экспортируемой DLL, чувствительно к регистру.
Пример. Объявляется внешняя функция из библиотеки C:\myxports.dll. Библиотека экспортирует
эту функцию под именем HelpOut (с учетом регистра). Из LotusScript функцию будут вызывать по
имени DirDLL (уже без учета регистра). Функция имеет два скалярных параметра, оба типа Long.
Параметры передаются ссылкой. DirDLL(5, 10) - уже пример вызова этой функции.
' Объявление
Declare Function DirDLL Lib "C:\myxports.dll"
Alias "_HelpOut" (II As Long, 12 As Long) '
Вызов DirDLL;5, 10)
Объявление С-функций
Любую С-функцию необходимо объявить прежде, чем она будет вызвана. Объявление
выполняется с помощью специальной формы оператора Declare. Оператор Declare следует
помещать в область Declarations модуля, внутри которого предполагается вызов (или вызовы)
С-функции.
В операторе Declare вы можете объявить С-функцию либо как функцию LotusScript, либо
как подпрограмму. Синтаксис таков:
Declare [Public | Private] {Function | Sub} LSFunctionName Lib libNaine [Alias aliasName )
( [ argList ] ) [ As return Type ]
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R, 5; @-формулы, LotusScript, встроенные классы LotusScript и Java
329
Если С-функция не возвращает результата или результат вас не интересует, то имеет
смысл объявлять С-функцию как подпрограмму LotusScript. В противном случае - как
функцию LotusScript. Проиллюстрируем сказанное с помощью примеров. Рассмотрим
функции находящиеся в библиотеке User Windows API.
Функция GetActiveWindow не требует параметров и возвращает дескриптор (целое
число) активного окна (окна, имеющего фокус).
Declare Function GetActiveWindow Lib "User" () As Integer
Функция SetWindowText ничего не возвращает, поэтому вы можете декларировать её как
процедуру. Функция требует два параметра: дескриптор окна и текстовую строку. В
оригинале имена обоих параметров удовлетворяют требованиям к идентификаторам
LotusScript. Поэтому при декларации функции можно использовать оригинальные имена
параметров, взяв их из документации по API (как сделано в примере), а можно ввести новые,
собственные имена.
Declare Sub SetWindowText Lib "User" (ByVal hWnd As Integer, _
ByVal IpString As String)
Оператор Declare (объявление внешних С-функций)
Declare f Public | Private ] { Function | Sub } LSname Lib libName
&.
[Alias aliasName ] ( [ argList ] ) [ As return Type ]
Объявляет внешние С-функции, содержащиеся в библиотеке функций, в качестве
функций или подпрограмм, вызываемых из LotusScript.
Public | Private - по выбору. Необязательно. Public определяет, что С-функция доступна в
LotusScript за пределами модуля, в котором она объявлена, пока этот модуль находится в
памяти. Private определяет, что С-функция доступна только внутри модуля, содержащего ее
объявление. По умолчанию С-функция считается Private.
Function | Sub - определяют способ вызова С-функции из LotusScript: как функцию или
как подпрограмму.
LSname - имя функции или подпрограммы, используемое в LotusScript. Если оператор
объявляет функцию (использовано ключевое слово Function), к LSname можно добавить
суффикс, определяющий тип возвращаемого функцией значения.
Если спецификатор Alias опущен, это имя должно совпадать с именем С-функции в
библиотеке функций. Для платформы Win32 существенно сохранение оригинального
регистра написания имени функции.
Lib libName - задается строка символов или символьная константа, специфицирующая
имя файла библиотеки функций. Стандартное расширение необязательно. Необязательно и
указание пути к файлу.
Alias aliasName - задается строка символов или символьная константа, содержащая одно
из следующих:
* с учетом регистра, имя С-функции, как оно объявлено в библиотеке функций.
• число с префиксом #, определяет положение (позицию) функции в библиотеке функций;
например, # 1.
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
330
Этот спецификатор полезно использовать в том случае, если имя С-функции не является
допустимым именем в LotusScript или попросту для того, чтобы сделать имя функции в
скрипте более простым для восприятия.
argList - список аргументов внешней функции, заключенный в круглые скобки. Скобки
должны использоваться даже в том случае, если функция не имеет аргументов. Аргументы в
списке разделяются запятыми, а каждый аргумент имеет формат:
[ By Val ] name As [ LMBCS | Unicode ] [ dataType Any ]
Если указано ключевое слово ByVal, то аргумент передается по значению, иначе по
ссылке. Необязательные ключевые слова LMBCS или Unicode могут использовать только для
аргументов типа String. DataType определяет тип аргумента. Ключевое слово Any
используют, когда аргумент должен передаваться в С-функцию без проверки типа.
As returnType имеет формат As [ LMBCS | Unicode ] dataType и определяет тип
возвращаемого функцией значения. Этот спецификатор не используется для С-функции,
вызываемой как подпрограмма. Для функций использую! или явную спецификацию As
returnType, или суффикс, определяющий тип возвращаемого функцией LSname значения, но
не оба варианта вместе. В качестве типа возвращаемого значения не должны использоваться
Any, Variant, Currency или String фиксированной длины. Если тип возвращаемых данных не
указан явно и в имени вызываемой функции нет суффикса, считается, что функ ция
возвращает значение типа согласно оператору описания типа DefT'ype для используемого
имени функции. Учтите, что тип dataType должен точно соответствовать типу возвращаемого
С-функцией значения - LotusScript не производит над возвращаемым значением каких-либо
преобразований типа. Ключевые слова LMBCS или Unicode могут использоваться только
тогда, когда функция возвращает значение типа String.
Передача аргументов. По умолчанию LotusScript передает аргументы во внешнюю
функцию по ссылке. Чтобы передавать аргументы по значению, следует указать в описании
аргумента ключевое слово ByVal. Однако это возможно только тогда, когда LotusScript
может привести передаваемое значение к типу данных аргумента С-функции. Массивы,
переменные определенных пользователем типов или объекты объявленных пользователем
классов могут передаваться только по ссылке. В С-функцию нельзя передать (ни по
значению, ни по ссылке) список. Объекты встроенных классов "представлены"
четырехбайтовым дескриптором объекта (instance handle), который может быть передан в
С-функцию как по значению, так и по ссылке. Для организации передачи объекта по значению
аргумент должен быть явно описан с использованием ключевого слова ByVal. Использование
круглых скобок при передаче фактического значения объекта не допускается
Параметр может быть объявлен как Any (любой), чтобы избежать ограничений,
накладываемых типом данных. Параметры "типа Any" всегда передаются ссылкой,
независимо от их действительного типа. Используя Any, вы, в принципе, можете передать в
С-функцию даже значение типа Variant, содержащее ссылку на массив или список. Вопрос
только в том, "понимает" ли С-функция данные этого типа.
Подробнее о передаче аргументов С-функции рассказано ниже в отдельных разделах.
Использование LMBCS или Unicode. Ключевые слова LMBCS или Unicode
применяются только для аргументов или возвращаемых функцией значений типа String. Они
определяют способ кодировки символов в строке. Unicode означает кодировку Unicode (2
байта на символ) с использованием зависящего от платформы порядка байтов. LMBCS
означает кодировку LMBCS фирмы Lotus (несколько байтов на символ, английские буквы
кодируются одним байтом, русские - двумя байтами, а символы японских, корейских и
китайских "алфавитов" - гремя байтами). Если ни LMBCS, ни Unicode не указаны,
предполагается, что символы в строке кодируются в соответствии с текущим способом
кодировки на используемой платформе.
© InterTrust Со. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
331
Пример 1. Объявление и вызов внешней функции StrUpr, содержащейся в библиотеке StrLib.
Dim strOut As String
'Объявление StrUpr
Declare Function StrUpr Lib "StrLib"
'Вызов StrUpr
strOutS = StrUpr ("abc")
•••••-•
(ByVal inVal As String) As String
Пример 2. Объявление и вызов С-функции _SendExportedRoutine (имя с учетом регистра),
экспортируемой библиотекой C:\myxports.dll, как внешней функции SendDLL в LotusScript.
Declare Function SendDLL Lib "C: \myxports.dll"
Alias "_SendExportedRoutine" (il As Long, 12 As Long)
'Вызов SendDLL SendDLL( 5 , 10)
Пример З. Объявление функции StrFun, получающей в качестве параметра amlStr строку в
кодировке Unicode и возвращающей строку в кодировке Unicode.
Declare
Function
(amlStr As
StrFun
Unicode
Lib
String)
"lib.dll"
As
Unicode
String
Пример 4. Объявление функции StrFun, получающей в качестве параметра amlStr строку в
кодировке LMBCS и возвращающей строку в текущей кодировке используемой платформы.
•
Declare Function StrFun Lib "lib.dll"
(amLStr As LMBCS String) As String
.
Пример 5. Вопроизведение звука средствами Windows API
Declare Function sndPlaySound Lib "winmm" Alias "sndPlaySoundA"
(ByVal IpszSoundName As String, ByVal uFlags As Long) As Long
Const SYNC =1
Dim res
Res = sndPlaySound("ohoh",
print Res
'
SYNC)
.
'
.
_
' • • • • ' "
'
•
.•
Передача аргументов по ссылке
При передаче аргумента по ссылке из LotusScript в С-функцию последняя получает в
стеке 4-х байтовый указатель на фактическое значение параметра в памяти LotusScript.
Правда, в некоторых случаях фактический параметр указывает только на "публично
читаемую структуру", не предоставляя доступа к закрытым данным. Однако во всех случаях
С-функция может изменить доступные ей "по указателю" данные, и эти изменения
произойдут в значениях переменных в LotusScript и в свойствах объектов встроенных
классов, как только управление вернется в LotusScript.
Следующая таблица поясняет, как параметры ссылкой передаются из LotusScript в
С-функцию.
Тип данных LotusScript
Что передается в С-функцию
String
4-х байтовый указатель на строку во внутреннем
формате строк LotusScript
Array
4-х байтовый указатель на массив во внутреннем
формате массивов LotusScript
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
332
Объект встроенного класса
(включая коллекцию)
4-х байтовый дескриптор (handle) объекта
Стандартный или определенный
пользователем тип
4-х байтовый указатель на данные этого типа
Определенный пользователем
объект
4-х байтовый указатель на члены-данные в
объекте
этом
Передача аргументов по значению
Вообще говоря, при передаче аргументов по значению С-функция получает в стеке
копию текущего значения аргумента.
По умолчанию аргумент во внешнюю функцию из LotusScript передается ссылкой.
Поэтому всякую передачу по значению следует специфицировать явно. Можно в операторе
Declare явно указать для каждого передаваемого по значению аргумента ключевое слово
ByVal - тогда при вызове функции из LotusScript соответствующие параметры всегда будут
передаваться по значению. Можно указать только при конкретном вызове внешний функции из
LotusScript, что некоторые параметры передаются по значению - такие параметры
записывают в круглых скобках или перед ними указывают ключевое слово ByVal.
Следующая таблица поясняет, как параметры по значению передаются из LotusScript в Сфункцию.
. . . . . . .
Тип данных
Какие данные передаются в С-функцию
2-х байтовое целое, записываемое в стек
lЈM_^___1 значение типа Long, записываемое в стек
Single
4-х байтовое значение типа Single, записываемое в стек
Double
8-и байтовое значение типа Double, записываемое в стек
Currency
8-и байтовое значение во внутреннем формате LotusScript, записываемое в
стек
String
4-х байтовый указатель на первый символ строки, записанный в стек. Это уже не
классическая передача по значению, поскольку С-функция может изменить
информацию в строке-параметре. С-функция не должна изменять информацию
в памяти "за пределами" строки.
Variant
16-и байтовая структура во внутреннем формате LotusScript, записываемая в
стек
4-х байтовый дескриптор объекта, записанный в стек
Объект
встроенного
класса
Any
Записанное в стек значение передаваемого параметра текущей длины.
Например, при одном обращении параметр может быть типа Integer, и будут
переданы 2 байта. При другом обращении параметр может иметь тип Long, и
будут переданы 4 байта. В результате затруднится разработка С-функции,
поскольку во время компиляции неизвестно, какого типа параметры она
получит.
Integer
Другие типы данных: массивы, списки, строки фиксированной длины, переменные
определенных пользователем типов или объекты определенных пользователем классов- не
могу! передаваться в С-функцию по значению. Однако их (кроме списков) можно передать
по ссылке. Обратите внимание, что список нельзя передать в С-функцию ни по значению, ни
по ссылке.
© InterTrust Co. Тел. (095) 9567928
Lotas Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
333
Если аргумент внешней функции объявлен в операторе Declare с типом Any, и должен
передаваться по значению, при вызове функции следует передаваемый параметр
специфицировать как By Val. Наконец, когда аргумент объявлен с типом Any, а параметр при
вызове передается как ByVal &0, С-функция получает "нулевой" указатель.
Пример. С-функция SemiCopy получает 4-х байтовый указатель на двухбайтовое целое значение
переменной vTestA, и двухбайтовое значение - копию значения переменной vTestB. Поскольку первый
аргумент передается по ссылке, С-функция может изменить значение переменной vTestA в LotusScript,
"записывая по указателю" наподобие *ptr = newValue. В то же время С-функция не может изменить
значение переменной vTestB в LotusScript.
Declare Sub SemiCopy Lib "mylib.dll" _
(valPtr As Integer, ByVal iVal As Integer)
Dim vTestA As Integer, vTestB As Integer
vTestA = 1
vTestB = 2
' вызов
SemiCopy vTestA, vTestB
'
'
'
'
Передача строк из LotusScript в С-функцию
Когда строка передается по ссылке, LotusScript передает 4-х байтовый указатель на эту
строку в "своей" памяти. При этом С-функция не может безопасно модифицировать
содержимое этой строки, если только она не написана специально для LotusScript (для этого
требуется знание внутренних форматов строк LotusScript).
Когда строка передается по значению, С-функция получает 4-х байтовый указатель на
копию строки LotusScript - "заканчивающуюся нулем строку", как это принято в языке С.
Если передается строка фиксированной длины, она сначала преобразуется в
"заканчивающуюся нулем строку". При этом С-функция может изменять данные в строке, но
не должна изменять длину строки. Когда С-функция завершается, изменения, внесенные ею в
копию строки, будут перенесены в соответствующую ей строку в формате LotusScript.
Если символы в передаваемой или возвращаемой строке заданы не в текущей кодировке
используемой платформы, а в кодировке Unicode или LMBCS, это должно быть
специфицировано явно.
Следующая таблица суммирует поведение строковых параметров при передаче в
С-функцию. В таблице предполагается, что С-функция имеет имя cF и один строковый
аргумент. Первый столбец содержит два возможных способа объявления этого аргумента в
операторе Declare: либо передача по значению, либо ссылкой. Второй и третий столбцы
показывают, что передается в С-функцию в зависимости от использованного способа ее
вызова из LotusScript (второй - по значению, а третий - по ссылке).
Объявление
Если функция cF вызывается
Если функция cF вызывается
строкового
из LotusScript в форме:
из LotusScript в форме:
аргумента в
_,„ , ,
,,
„,
, CF ( ( arg ) )
cF
( arg ) операторе
Declare СCF ( ByVal ( arg ))
cF ( ByVal arg ) функции cF
ByVal String
4-х байтовый указатель на
4-х байтовый указатель на копию
значения фактического
значение фактического параметра. Если функция cF
параметра. Если функция cF изменяет данные по этому
изменяет данные по этому
указателю, значение
указателю, изменяется и фактического параметра не
значение фактического
' InterTrust Co. Тел. (095) 9567928
Язык LotusScript
334
меняется. Если функция cF
параметра. Если функция cF "пишет" за границами
"пишет" за границами полученной строки, возможен
полученной строки, возможен
крах LotusScript.
крах LotusScript,
String
4-х байтовый указатель на
4-х байтовый указатель на копию
значения фактического
значение фактического параметра во внутреннем
параметра во внутреннем формате строк LotusScript. Если
формате строк LotusScript.
Если функция cF изменяет данные по
cF "не знакома" с этим этому указателю, значение
форматом, она может лишь фактического параметра не
заменить ссылку на эту
строку меняется.
ссылкой на другую (но корректную) строку.
Передача из LotusScript в С-функцию массивов, переменных определенных
пользователем типов и объектов определенных пользователем классов
Передать массив в С-функцию можно только по ссылке. Но массивы в LotusScript
хранятся в собственном внутреннем формате. При этом С-функция "должна понимать"
внутренний формат массивов LotusScript. Авторы не встречали в документации подробного
описания этих форматов. В некоторых простых случаях можно объявить в операторе Declare
аргумент, по которому должен передаваться массив, с "типом" Any, а в качестве значения
фактического параметра передать по ссылке первый элемент массива.
Пример 1. Третий аргумент функции SetBitmapBits объявлен с "типом" Any, а при вызове функции
по третьему аргументу передается ссылка на первый элемент этого массива.
Declare Sub SetBitmapBits Lib "_privDispSys"
(ByVal hBM As Integer, ВуVal cBytes As Long, pBits As Any)
SetB itmapB its(hB itmap,
cB ytesInA rra y,
bi tA rray(O ) )
Передать в С-функцию значение переменной определенного пользователем типа можно
тоже только по ссылке. При этом С-функция получит 4-х байтовый указатель
непосредственно на первый байт соответствующих данных в LotusScript. В простых случаях
этого бывает достаточно, чтобы "добраться" до необходимых элементов данных. В более
сложных случаях опять возникнут проблемы, связанные с "незнанием" внутренних форматов
некоторых типов данных LotusScript.
Отметим, что если в определенном пользователем типе в качестве элементов
присутствуют строки переменной или фиксированной длины (но не Variant типа String), для
указания способа кодировки символов во всех строках "внутри типа" в операторе Declare
можно использовать ключевые слова Unicode или LMBCS. Если ни Unicode, ни LMBCS не
указано, строки в определенном пользователем типе передаются в текущей кодировке
используемой платформы.
Пример 2. В первом операторе Declare все строки переменной или фиксированной длины в типе tl и
его вложенных типах передаются как строки Unicode, а во втором - как строки LMBCS.
Declare Function UniTest Lib "Unilib" (typArq As Unicode tl) As Long
Declare Function LMBCSTest Lib "Imbcslib" (typArg As LMBCS tl) As Long
Обратите также внимание, что LotusScript в целях обеспечения межплатформной
совместимости выравнивает некоторые элементы типа иначе, чем это принято по умолчанию
в компиляторе С на используемой платформе. Например, для типа с определением
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
Type telMet • . - • • •
A As Integer
В As Integer
End Type
•
v
•
• '.
-
335
•••.-:-.
...
LotusScript выравнивает элемент В на четырехбайтовую границу, тогда как выравнивание
по умолчанию в Windows 3.1 выполняется на двухбайтовую границу.
Пример 3. С-функции GetBrushOrgEx вторым аргументом передается определенный пользователем
тип Point.
Type Point
хР As Integer
уР As Integer End Type Declare Function GetBrushOrgEx
Lib "__pointLib" _
(ByVal hDC As Integer, pt As Point) As Integer Dim
p As Point
GetBrushOrgEx(hDC,p)
Когда в С-функцию передается объект определенного пользователем класса, С-функция
получает 4-х байтовый указатель на первый байт неупакованных данных объекта. В случае
простых объектов до их данных "удается добраться" сравнительно легко. Но для сложных
объектов, содержащих внутри списки, массивы, строки или объекты встроенных классов, это
может оказаться трудноразрешимой задачей.
Значение, возвращаемое С-функцйей в LotusScript ;;; •. у-... :: • •.::: ;••; '•. •> /• ••:;::-::: ••••;: :^\;::•'•;:::-;:::.: •.,
Тип возвращаемых С-функцией данных должен быть указан одним из следующих
способов:
• в операторе Declare явно,
• в операторе Declare с использованием суффикса,
г
• на основе оператора Deftype, предшествующего оператору Declare.
Если ничто из перечисленного не имеет места, по умолчанию в LotusScript будет
предполагаться, что функция возвращает значение типа Variant, тогда как этот тип
несовместим с языком С.
Следующая таблица показывает, данные каких типов могут быть возвращены
С-функцией в LotusScript.
Тип данных
Может ли быть возвращен С-функцией
Integer
Да
Long
Да
Single
Да
Double
Да
Currency
Нет
String
Variant
в LotusScript?
Да, за исключением строки фиксированной длины
Нет
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
336
Объект встроенного класса
Да (как 4-х байтовый дескриптор объекта (handle) типа Long)
Объект определенного
пользователем класса
Да
Переменная определенного
пользователем типа
Нет
Any
Нет
Array
Нет
List
Нет
Пример. Функция GetWindowsDirectory входит в состав API Windows. Функция определяет
каталог, в котором на текущем компьютере установлен Windows. Путь на каталог в форме строки
записывается по указателю, передаваемому функции первым аргументом. Вторым аргументом задается
максимальное количество байтов, которое функции "разрешается записать" по этому указателю.
Возвращает же функция действительное количество байтов, которое ею было записано по указателю.
Обратите внимание, что функция не записывает по указателю байт с нулевым кодом, являющийся в
языке С традиционным признаком конца строки.
Этот пример проверялся под Windows NT 3.51 и Windows 98. Библиотека, в которой находится
функция, называется Kernel32.dll. Внутреннее имя функции с учетом регистра в этой библиотеке
GetWindowsDirectoryA, а не GetWindowsDirectory, под которым она традиционно экспортируется.
В скрипте объявлена строка фиксированной длины WinDir, в которую вызываемая внешняя
функция заносит путь на каталог. Все параметры передаются во внешнюю функцию по значению. Уже
после вызова функции, чтобы избежать проблем с длиной строки, она "корректируется по месту"
функцией Mid$ LotusScript.
CONST MAX_DIR_SIZE = 255 '
DIM WinDir AS STRING*MAX_DIR_SIZE
DIM ActLen AS INTEGER
Declare Function GetWindowsDirectoryA Lib "Kernel32"
(ByVal IpBuffer As String, ByVal nSize As Integer)
1 MAX_ DIR_SIZE - максимальная длина буфера
'ActLen - текущая длина пути на каталог
ActLen = GetWindowsDirectoryA ( WinDir, MAX_DIR_SIZE )
WinDir = mid$(WinDir,1,ActLen)
Print WinDir
As
Integer
•
-...-,
т
'Печатает D:\WINNT351
При создании собственных библиотек С-функций
Если вы используете компилятор C++, то следует учитывать искажение имен функций. В
этом случае при написании собственных С-функций следует использовать конструкцию "С"
{. . . } для сохранения точного имени.
Символ "-" зарезервирован в Notes для специальных библиотек. Эта особенность впервые
появилась в версии 4.5.1. В версии 4.5.1 и старше (в том числе и 5.x) при попытке загрузки в
скрипте библиотеки (dll) с именем начинающимся с "-" выдается ошибка "Error in loading
DLL".
Под значение типа Integer в LotusScript отводится 2 байта. В тоже время на платформе
Win32 (Windows 95, 98, Windows NT) значение типа Integer занимает 4 байта. Поэтому, если
разрабатываемая вами С-функция должна вернуть в LotusScript значение типа Integer,
О InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
337
следует внутри С-функции использовать тип Short Integer, использующий 2 байта. Это
замечание относится исключительно к реализации под Windows.
Пример импорта строки текстового файла
Предположим имеется задача чтения в скрипте русского текста из текстового файла в кодировке
866. Эта операция выполняется с помощью стандартных LotusScript средств ввода-вывода. Но прежде,
чем строка станет «пригодной для использования» в Windows необходимо выполнить её перекодировку из кодировки 866 в кодировку 1251 (сама операция чтения строки из файли никакой перекодировки не
производит). Для этого используетс я функция Window s A PI " O emToA nsi". Скрипт в
нашем примере оформлен в виде агента. Так в разных поколениях Windows местоположение
необходимой нам функции различно, объявляется сразу две функции.
Declare Function OemToAnsi32 Lib "User32" Alias "OemToCharA" (Byval
IpOemStr As String, Byval IpAnsiStr As String) As Integer
Declare Function OemToAnsi16 Lib "Keyboard" Alias "OemToAnsi" _
(Byval IpOemStr As String, Byval IpAnsiStr As String) As Integer
Function OemToAnsi(IpOemStr As String, IpAnsiStr As String) As Integer Dim
Session As New NotesSession
' В зависимости от версии Windows
1
вызывается та или иная С-функция If
session.Platform = "Windows/32" Then
OemToAnsi = OemToAnsi32(IpOemStr, IpAnsiStr)
Elseif session.Plat form = "Windows/16" Then
OemToAnsi = OernToAnsil6 (IpOemStr, IpAnsiStr) End If
End Function
Sub
Initialize
Dim tfile%, res%
Dim Stroka$
tf.ile% = Freefile()
Open «c:\dos_file.txt» For Input As tfile%
Line Input #tFile%, Stroka$
л переменная Stroka$ получает значение f)r&6GE© в^ббв
res% = OemToAnsi(Stroka$, Stroka?)
print Stroka$
* петается Русский текст
End Sub
. •
Пример. Замена оператору SendKeys
Как известно, оператор SendKeys не поддерживается в реализации LotusScript для Lotus Notes. Но
благодаря имеющимся в LotusScript средствам обращения к внешним С-фукциям задачу решить можно
(по частному мнению автора этих строк, вряд ли «фирменная» реализация оператора была бы устроена
по-другому).
Данный прим ер публикуется с лю безного согласия его автора - Андрэ
Гайрарда (Andre Guirard) , сотрудника американской компании Systems Consulting Group,
inc.
'SendKey script library:
Option Public Option
Declare
© InterTrust Co. Тел. (095) 9567928
Язык LotusScript
338
%REM
Данная библиотека содержит функции для имитации ввода символов с
клавиатуры. Библиотека рассчитана на работу в среде Win32
Поддержка платформ Winl6 и OS/2 может быть достигнута путем использования
других (соответствующих) библиотек (DLL).
Функции операционной системы, выполняющие основную работу, взяты из
стандартных DLL и описаны, например, в документации к Visual Basic.
Данная библиотека включает следующие функции:
Sub SetKeyState(byval bVk As Integer, byval onoffstate As Integer) где
bVk - код клавиши с состояниями "вкл." и "выкл." (соотв. значения True
и False)
Функция устанавливает состояние одного и таких ключей, например Call
SetKeyState(VK SCROLL, False) выключает клавишу [Scroll Lock]
Sub PressKey(Byval vk As Integer)
где vk - код клавиши. Эта функция посылает ОС код клавиши для имитации
ее нажатия и отпускания.
Например, Call PressKey(VK_Fn + 3) эквивалентно нажатию клавиши [F3]. Функция
ориентирована на клавиши, для которых нет "непечатного" аналога
Sub HoldKey(byval vk As Integer)
Данная функция посылает ОС код клавиши, для которой нужно
симитировать нажатие и удержание в нажатом состоянии
Sub ReleaseKey(byval vk As Integer)
Данная функция "отпускает" ранее "нажатую" с пом.ощыо функции
HoldKey клавишу.
Например, если мы хотим передать последовательность [Alt]+[Enter], то
необходимо произвести следующие вызовы:
HoldKey VK MENU
PressKey VK_RETURN
ReleaseKey VK_MENU
Sub SendKey(Byval c$)
Печатает символ. Данная функция предназначена для упрощенного
"нажатия" клавиш, у которых есть "печатные" аналоги. Например, цифры,
буквы и т.п.
Sub SendString(Byval s$)
Имитирует ввод целой строки. Фактически выполняет серию
вызовов функции
SendKey %END REM
Const VK_MENU = &Н12 ' [Alt]
Const VK RETURN = SHOD Const VK
JLEFT = &H25 Const VK UP = &H26
Const VK_RIGHT = &H27 Const
VK_DOWN = &H28 Const VK_TAB =
&H09 Const VK_SHIFT = &H10 Const
VKJCONTROL = &H11 Const
VK_ESCAPE = &H1B Const VK_SCROLL
= &H91
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R, 5: @~формулы, LotusScript, встроенные классы LotusScript и Java
Const
Const
Const VK_Fn = &H6F
339
VK_CAPITAL
=
&H.14
VK_NUMLOCK
&H90
' Функциональные клавиши; для получения кода
1
конкретной клавиши надо добавить ее номер,
' например, VK_Fn+3 для [F3]
Const KEYEVENTF_KEYUP - &Н2 ' код для "отпускания" клавиши
Dim CapsLock%
Declare Sub keybd_event Lib "user32"
Int eger ,
(Byval bVk As Integer,
Byval bScan As
Byval dwflags As Long, Byval dwextrainfo As Long)
Declare Sub mouse_event Lib "user32" (Byval dwflags As Long, Byval dx As
Long, Byval dy As Long, _
Byval cbuttons As Long, Byval dwextrainfo As Long)
Declare Function OemKeyScan Lib "user32" (Byval wOemchar As Integer) As
Long
Declare Function CharToOem Lib "user32" Alias "CharToOemA" (Byval IpszSrc
As String, Byval IpszDst As String) As Long
Declare Function VkKeyScan Lib "user32" Alias "VkKeyScanA" (Byval cChar As
Integer) As Integer
Declare Function MapVirtualKeyS Lib "user32" Alias "MapVirtualKeyA" (Byval
wCode As Long, wMapType As Long)
Declare Function GetKeyState% Lib "user32" (Byval virtkey&)
Declare Sub GetKeyboardState Lib "User32" (LpKeyState As Any)
Declare Sub SetKeyboardState Lib "User32" (LpKeyState As Any)
Sub SendString(Byval s$)
CapsLock = ((1 Arid GetKeyState (VK _CAPITAL) ) <> 0)
Dim i%
For i = 1 To Len(s)
SendKey Mid$(s, i, 1)
Next
End Sub
Sub PressKey(Byval vk As Integer) Dim
scan%
' получаем scan code данной клавиши scan = MapVirtualKey(vk, 1) And
&HFF keybd_event vk, scan, 0, 0
' "нажимаем" клавишу keybd_event
vk, scan, KEYEVENTF_KEYUP, 0
' "отпускаем" клавишу
End Sub
Sub HoldKey(Byval vk As Integer) Dim
scan%
' получаем scan code данной клавиши scan =
MapVirtualKey(vk, 1) And &HFF keybd_event vk, scan, 0,
0
' "нажимаем" клавишу
End Sub
Sub ReleaseKey(Byval vk As Integer)
Dim scan% ' получаем scan code данной
клавиши
scan = MapVirtualKey(vk, 1) And &HFF
keybd__ event vk, scan, KEYEVENTF_ KEYUP, 0
Sub
-
' "отпускаем" клавишу End
Sub SetKeyState(Byval bVk As Integer, Byval onoffstate As Integer)
© InterTrust Co. Тел. (095) 9567928
340
Язык LotusScript
' Исп. для активации и деактивации клавиш Caps Lock, Mum Lock, or Scroll
Lock.
Dim a%(0 To 127), ind%, mask*
GetKeyboardState a(0) ind = bVk
\ 2
If (bVk And I) Then ' windows хранит впереди младший байт; если индекс
четный - нужен бит 1
.mask -= 1
•
Else-mask = &hOlOO End
If.
' Теперь, если необх. режим не явл. текущим,
' now, if the desired state doesn't match the existing state, меняем бит
активности и переписываем состояние
If ((a(ind) And mask) <> 0) о onoffstate Then a find) =
a(ind) Xor mask SetKeyboardState a(0) End If End Sub
Sub SendKey(Byval c$)
Dim vk%, scans, oemchar$, dl&, shifted*, scanshift* '
получаем виртуальный код данного символа vk =
VkKeyScan(Asc(c$)) And &HFF
oemchar = " " ' Иниуиализируем строку на необходимую длину
CharToOem Left$(c$, 1), oemchar dl = OEMKeyScan(Asc(oemchar)) scan
= dl And &HOOOOFFFF& If (c$ >= "a" And c$ <= "z") Or . (c$ >- "A" And
c$ <= "Z") Then
shifted = ((c = Ucase(c)) Xor CapsLock)
Else
shifted = (dl And &H00030000&) > 0 End
If
If shifted Then
scanshift = MapVirtualKey(VK_SHIFT, 1)
keybd_event VK_SHIFT, scanshift, О, О End
If
keybd_event vk, scan, О, О keybd_event vk,
scan, KEYEVENTF KEYUP, 0 If shifted Then
keybd_event VK_SHIFT, scanshift, KEYEVENTF_KEYUP, 0 End If
End Sub
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
341
2.10. Ограничения языка
В новой версии LotusScript 4, использующейся в Notes/Domino R5, по сравнению с
предыдущей версией (LotusScript 3 -Notes/Domino R4) сняты некоторые ограничения. Среди
них такие как органичение на размер исполняемого кода модуля, ограничение на размер
динамической строки. Большинство ограничений традиционно объединяют под общим
названием «ограничения 64К байт». Все наиболее существенные ограничения далее
рассматриваются отдельно.
-
2.10.1. Ограничения числовых типов данных
Тип данных
Диапазон допустимых значений
Объем
занимаемой
памяти
Integer
от -32,768 до 32,767
2 байта
Long
от -2, 1 47,483,648 до 2, 1 47,483,647
4 байта
Single .
от -3.402823Е+38 до 3.402823Е+38
4 байта
Double
от -1 .797693 1348623 1 58+308 до
1.7976931348623158+308
8 байт
Currency
от -922,337,203,685,477.5807 до
922,337,203,685,477.5807
8 байт
String
Ограничено доступной памятью
2 байт на символ
Диапазон допустимых значений двоичных, восьмеричных и шестнадцатиричных целых
чисел совпадает с диапазоном типа Long.
Следующая таблица описывает максимальное число символов, необходимых для
отображения соответственно двоичных, восьмеричных и шестнадцатиричных значений.
Одновременно эта же таблица описывает максимальное число символов, которое могут
вернуть функции Bin< Oct и Hex.
Целый тип
Максимальное число символов, необходимых для
значения
Двоичный
32
Восьмеричный
11
Шестнадцатиричный
8
отображения
© InterTrust Со. Тел. (095)9567928
Язык LotusScript
342
2.10.2. Ограничения строковых данных
Ограничения на представление строк:
Показатель
:
Notes версий 4.x
Общее число строк
Notes версий 5.x
Ограничено только доступной Ограничено
только
памятью
доступной памятью
Ограничено только
Общий объем строковых Для модуля в целом 32К
доступной памятью
данных в модуле
символов (64К байта). Для
динамических строк - строк,
получающих значение во
время исполнения скрипта
-ограничено только
доступной памятью
Длина строкового литерала 16,267 символов (32,000 байт).
16,267 символов (32,000
байт).
Длина строки
2 G байт
32,000 символов (64,000 байт)
Общий объем строковых
литералов в модуле
2 G байт
Несмотря на то, что в LotusScript 4 строки могут быть длинее 64К, остаются ограничения
на длину строк, которые могут быть прочитаны или записаны с использованием операторов
GET и PUT.
Строки фиксированной длины, переменные типа Variant, содержащие строки и файлы
произвольного доступа не работают со строками длиннее 64К. Более длинные строки могут
использоваться в двоичных файлах и строках переменной длины. Причина состоит в том, что
все они имеют 2-х байтный заголовок, задающий длину строки. Двумя байтами нельзя
описать большую длину, чем 64К.
2.10.3. Ограничения на массивы
Показатель
Объем данных
массива
Notes версий 4.x
64К байта
Число измерений
Notes версий 5.x
Ограничено только доступной
памятью
8
8
Размерности
измерений
от -32,768 до 32,767
(представляется значением типа
Integer)
от -32,768 до 32,767
(представляется значением типа
Integer)
Число элементов
Определяется объемом
доступной памяти и размером
отдельного элемента массива
(различен для разных типов
данных).
Определяется объемом
доступной памяти и размером
отдельного элемента массива
(различен для разных типов
данных).
© InterTrust Со. Тел. (095) 9567928
LotHS Domino R. 5: ^формулы, LotusScript, встроенные классы LotusScript и Java
343
Ограничение на число элементов массива обусловленно предельным объемом скалярных
данных на уровне модуля. Это 64К, Так, одноразмерный массив типа Long, объявленный на
уровне модуля может иметь не более 16,128 элементов. Общий объем скалярных данных на
уровне модуля ограничен 64К байтами, а каждый элемент типа Long занимает 4 байта.
2.10.4. Ограничения на файловые операции и операции ввода/вывода
Maximum
Item
Максимальное число одновременно открытых
файлов ...
Определяется конкретным
продуктом, использующим
LotusScript
Максимальный номер для оператора Open
255
Максимальное значение recLen в операторе Open
32767
Максимальная длина строки, которая может быть
записана операторов Write
255 символов
Максимальное число элементов в операторах Print,
Write, Input
255
Максимальное число символов в пути в операторах
MkDir, RmDir, ChDir
128 включая символ, задающий
имя устройства
2.10.5. Ограничения компилятора и структуры скрипта
Элементы языка:
Элемент
Максимальное число
Число символов в идентификаторе LotusScript, не считая
суффикс типа данных
40
Число аргументов процедуры или функции
31
Число меток в операторе On...GoTo
255
Показатель
Notes версий 4.x
Максимальное . число строк
скрипта или включаемого файла
(без
учета
файлов,
подключаемых
директивой %lnclude)
Notes версий 5.x
64К
64К
файлов,
16
16
Число ошибок компиляции до
прекращения
компиляции
скрипта
20
20
Различно
64К
Глубина
вложений
подключаемых
директивой %Inciude
Число символов в таблице
1 InterTrust Co. Тел (095) 9567928
344
Язык LotusScript
символов на уровне модуля
Число рекурсивных вызовов
(уровень рекурсии) функции
Ограничено 32К
байтным стеком
Ограничено 32К байтным
стеком
Объем данных в указанной
области видимости
Модуль: 64К bytes
Модуль: Ограничено только
доступной памятью
Класс: 64К bytes
Процедура: 32К bytes
Размер исполняемого кода
модуля
64К байт
Класс: 64К bytes Процедура:
32 К. bytes
Ограничено только
доступной памятью
Как видно из таблицы, ограничение на. размер стека времени исполнения остается;
возможно, оно будет снято в будущих версиях.
Снятие ограничения 64kb на размер исполняемого кода модуля значительно увеличивает
возможности разработчика создавать крупные модули на LotusScript, Раньше разработчики
были вынуждены разбивать модули на несколько библиотек скриптов. Данное
усовершенствование позволяет значительно повысить стройность приложений.
Ограничения на объем данных в указанных областях видимости распространяется только
на переменные со значениями фиксированного размера: переменные скалярных типов
данных исключая строки переменной длины; типы, определенные пользователем;
фиксированные массивы скалярных типов данных. Изменение порядка объявления
переменных может за счет изменения внутреннего выравнивания данных обеспечить
некоторый дополнительный выигрыш по емкости. Например, переменные типа Integer имеют
2-х байтное выравнивание, а переменные типа Long - 4-х байтное.
Максимальный объем данных «динамических» переменных (строки переменной длины, списки,
динамические массивы, экземпляры классов) ограничен только объемом доступной памяти. В то же
время каждая такая переменная занимает 4 байта в своей области видимости.
По внутренним причинам LotusScript может формировать ошибку «Out of stack»
непосредственно перед достижением предела емкости.
2.11. Отличия использования LotusScript на различных платформах
В силу наличия особенностей, присущих каждой операционной системе - платформе,
использование некоторых элементов языка LotusScript в скрипте так, как было описано
выше, может привести к совершенно неожиданному для пользователя результату, а в ряде
случаев использование некоторых элементов языка может вообще оказаться невозможным.
Далее, в виде сводных таблиц и пояснений, представлены особенности и отличия
функционирования этих элементов LotusScript версии 4 на наиболее широко
распространенных операционных платформах. Левая графа такой таблицы содержит имя
элемента LotusScript, правая графа содержит краткое описание отличий и особенностей
применения данного элемента в используемой платформе.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: (@-фармулы, LotusScript, встроенные классы LotusScript и Java
345
2.11.1. OS/2
Отличия и особенности использования элементов языка
Реакция системы на использование элемента в скрипте
Элемент
языка
Command
Аргументы командной строки не могут нормально
использоваться в OS/2. Однако, если используемый продукт
Lotus разрешает использование таких аргументов, их значения
передаются в скрипт при использовании функции Command,
хотя, возможно, и не всегда верно.
CreateObject
Не поддерживается. Вырабатывается ошибка периода выполнения.
GetObject
Не поддерживается. Вырабатывается ошибка периода выполнения.
Shell
Режим активации окна не поддерживается в OS/2 ни для системных
приложений, ни для приложений пользователя, использующих для
хранения элементы среды Profile.
Отличия файловой системы
LotusScript поддерживает файловые системы HPFS и FAT. Файловая система HPFS
допускает использование так называемых "длинных" имен файлов, количество символов в
которых может достигать 254. Для имен файлов можно использовать любой регистр
клавиатуры. Использование в скриптах длинных имен файлов вызовет ошибку в файловой
системе FAT.
2.11.2. UNIX
Отличия и особенности использования элементов языка
Элемент языка
Реакция системы на использование элемента в скрипте
ActivateApp
Не поддерживается. Вырабатывается ошибка периода выполнения.
ChDir
Вырабатывается ошибка периода выполнения, если LotusScript не может
интерпретировать аргумент ChDir. например, если в аргументе содержится
буква определяющая устройство.
ChDrive CurDir,
CurDir$
Вырабатывает ошибку периода выполнения, если спецификация
устройства по умолчанию не равна пустой строке ("").
CreateObject
Не поддерживается. Вырабатывается ошибка периода выполнения.
CurDrive,
Возвращают пустую строку (""), т.к. в UNIX нет буквенных
CurDrive$
обозначений устройств.
.
В UNIX секретность и целостность данных обеспечивается тем, что
только супервизор может изменять данные. Любая другая попытка
изменения данных (в данном случае системной даты и/или времени)
вызовет ошибку периода выполнения скрипта.
Date,
Date$ Time,
T'ime$
Declare
Не поддерживаются соглашения языка Pascal для вызова внешних
функций. Все внешние функции вызываются с использованием CDECL
соглашения о вызовах. Не поддерживается спецификация числа с
© InterTrust Со. Тел. (095) 9567928
Язык LotusScript
346
использованием предложения Alias.
Dir, Dir$.
Игнорируется опция attributeMask. Эти функции ведут себя так, как если
бы атрибут у всех файлов был Normal.
FileLen, Len,
LenB, LenBP,
LOF
В конце строки содержится такой же символ окончания строки, как и в
платформе DOS/Windows. Поэтому, значения, возвращаемые этими
функциями, могут незначительно отличаться в платформах UNIX и
Windows.
GetFileAttr
Вырабатывается ошибка периода выполнения, если буква,
обозначающая устройство включена в аргумент. Следующие атрибуты
файлов не возвращаются: ATTR HIDDEN, ATTR ARCHIVE, ATTR
VOLUME ATTR_SYSTEM.
GetObject
При попытке использования вырабатывается ошибка периода
выполнения.
Input #, Input,
lnput$, InputB,
InputBS, Line
Input, Print,
Write #
Составляются с использованием особенностей используемой платформы,
в частности - назначений символов в UNIX, используемого символа
окончания строки, порядка следования байтов и точности вычислений с
помощью функций LotusScript.
IsObject,
IslJnknown
См. ниже "Другие отличия".
Open, Lock,
Unlock
Явное и неявное обеспечение секретности доступа к файлу не
поддерживается в UNIX. LotusScript для UNIX допускает использование
операций копирования, открытия, и т.д., файлов уже открытых для чтения.
Оператор Open используется только для файлов статус доступа к которым
определен как Shared. Использование Lock, Unlock, Lock Read, Lock Write
и Lock ReadWrite вызывает ошибку периода выполнения.
SendKeys
Не поддерживается. Вырабатывается ошибка периода выполнения.
SetFileAttr
Игнорируются следующие атрибуты файла: ATTR HIDDEN,
ATTR_ARCH1VE, ATTR_VOLUME.
Shell
Игнорируется режим окна.
Отличия файловой системы
LotusScript поддерживает все аспекты обеспечения секретности в UNIX. Отличается
использование операторов Kill, Open, и RmDir, т.к. в платформе UNIX не используются
буквенные обозначения устройств, используемые в этих операторах.
При использовании пути к файлу, содержащего буквенное обозначение устройства,
возвращается ошибка. Использование директивы %lnclude порождает ошибку компиляции,
для остальных случаев выдается ошибка периода выполнения. (Заметим, что в UNIX
допускается использование символа двоеточие ( : ) в имени файла, поэтому, использование
оператора Dir$("a:") является законным. Просто, в этом случае в текущем каталоге ищется
файл с именем а: ).
UNIX использует символ "/" в качестве разделителя каталогов, в отличие от платформ
DOS/Windows, использующих символ "V. LotusScript поддерживает использование обоих
символов со следующими ограничениями:
© InterTrust Со. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
347
* буквенная строка: если символ "/" используется в буквенной строке, являющейся путем
к данным, файл .LSO порождается только в платформах, поддерживающих
использование этого символа, например, в платформе UNIX.
* строковые переменные: если переменной присваивается значение символьной строки,
содержащей символ "/" и значение этой переменной является указателем пути к файлу,
то, при передаче значения этой переменной операционной системе, будет порождаться
ошибка периода выполнения, если используемая платформа не поддерживает
использование символа "/" в указателе пути.
UNIX допускает более широкое использование символов в указателях пути к данным.
Так, например, в UNIX можно использовать более одной точки в указателе пути. LotusScript не
поддерживает использование таких имен.
UNIX использует в качестве символа "перевод строки" символ ASCII 10. Другие
платформы могут для этой цели использовать другие символы. Это может привести к
отличиям в размерах одних и тех же файлов в разных платформах, а также к неверной
трактовке содержащейся в них информации.
Другие отличия
Использование спецификатора Alias с номером С-функции в операторе Declare,
невозможно в UNIX, т.к. UNIX не использует нумерацию экспортируемых библиотекой
функций.
Функцию IsObject можно использовать, если используется ссылка на объект из данной
процедуры или на объект продукта, но не на объект OLE, т.к. объекты OLE не существуют в
платформе UNIX.
Функция IsUnknown в платформе UNIX всегда возвращает значение False, т.к. в UNIX
нет средств передачи значения VJUNKNOWN в выражение типа Variant.
2.11.3. Macintosh
Отличия и особенности использования элементов языка
Элемент языка
Реакция системы на использование элемента в скрипте
ActivateApp
Не поддерживается. Вырабатывается ошибка периода выполнения.
ChDir
Поддерживается, как средство смены устройства, т.к. в Macintosh
спецификация устройства имеет вид: "Hard drive:folderl : folder2:".
ChDrive
Вырабатывается ошибка периода выполнения, если аргумент не содержит
пустую строку (""), определяющую устройство по умолчанию. Для смены
устройства используется оператор ChDir.
Command
Командная строка аргументов не может нормально использоваться в
Macintosh Однако, если используемый продукт Lotus разрешает
использование таких аргументов, их значения, при использовании
функции Command, все таки передаются в скрипт.
CurDir
Вырабатывается ошибка периода выполнения, если аргумент,
определяющий устройство по умолчанию или в явном виде не содержит
пустую строку ("").
Declare
Не поддерживаются соглашения языка Pascal для вызова функции из
библиотек DLL.
© InterTrust Co. Тел. (095) 9567928
348
Язык LotusScript
Dir
Игнорирует атрибуты файлов Hidden Files, Volume Label и System. He
возвращает в спецификации каталогов символы "," и "..".
Environ
Возвращает пустую строку. Вырабатывает ошибку периода выполнения
только при передаче недопустимого значения аргумента, например, недопустимого числового
значения.
FileLen
Символ, ограничивающий строку в файле, отличается от используемого в
DOS. Длина файла может оказаться неверной.
GetFileAttr
Следующие атрибуты фалов не возвращаются: ATTR ARCFUVE,
ATTR_VOLUME, ATTR_SYSTEM.
ten, LenB
Строка, прочитанная из файла, содержит ограничитель строки,
отличающийся от такого символа в платформе DOS. Возможно неверное определение длины
строки.
SendKeys
Fie поддерживается. Вырабатывается ошибка периода выполнения.
SetFileAttr
Вырабатывается ошибка, если передается атрибуту ATTR ARCHIVE или
A1TRJSYSTEM.
Shell
He поддерживается. Вырабатывается ошибка периода выполнения.
Отличия файловой системы
Платформа Macintosh не использует для указания пути знак "\". Этот символ
используется для определения пути в платформе DOS. Имена файлов не ограничиваются, как в
DOS, 8-и символьными именами и 3-х символьными расширениями. Macintosh не хранит
назначение каталога по умолчанию для каждого устройства. Он поддерживает только
текущий каталог. Имя устройства может иметь длину 27 символов. Это огранич ивает
действие операторов ChDir, ChDrive, и CurDir.
Macintosh не поддерживает в спецификации каталогов символы "." и "..". что
ограничивает использование функции Dir.
В файловой системе Macintosh не поддерживается использование атрибутов файлов
Hidden, Volume, Archive, и System. Это ограничивает возможности использования операторов
Dir, GetFileAttr и SetFileAttr. Macintosh использует символ "возврат каретки" (ASCII 13) в
качестве символа конца, строки.
. . - •.
Эти отличия вынуждают LotusScript использовать при выполнении различные наборы
кодов, с учетом того, что даже одинаковые файлы в разных платформах могут иметь разные
размеры. Например, с учетом правил кодирования, в UNIX и в Macintosh размеры одних и
тех же файлов эквивалентны. Эти же файлы на платформе Windows будут иметь больший
размер, т.к. в Windows используется 2-х байтовая схема кодирования символов. Эти отличия
ограничивают эффективность использования функций FileLen, Len, LenB, и LenBP.
Maci nt osh допускав! выполнение ряда операций с уже открытыми файлами С
копирование, откпытие и т. л Л. что ограничивает использование Onen. Lock, и Unlock.
О InterTrust Со. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
349
3. Встроенные классы для создания
приложений Domino
Встроенные классы предназначены для разработки приложений Domino на LotusScript и
Java. Используя объекты этих классов, разработчик приложений получает из LotusScript или
Java доступ к базам данных Domino и содержащимся в них объектам (видам, документам,
полям в документе...), а из LotusScript так же и к объектам интерфейса пользователя.
В поставку Domino/Notes версии 5.0 входит 31 «почти общий» для LotusScript и Java
встроенный класс, еще 7 классов, доступных только в LotusScript, и несколько
специфических классов, присущих только Java. В версии 5.0 было добавлено 8 «совершенно
новых» встроенных классов. Если задаться целью проследить «общие» свойства и методы
классов для LotusScript и Java, то обнаружится, что их более 85%. В совокупности все
встроенные классы, без двойного подсчета «общих» для LotusScript и Java, имеют в
настоящее время около 800 свойств и методов.
Мотивы, по которым в данной главе было решено «проводить параллель» между
свойствами и методами встроенных классов LotusScript и Java, следующие.
• Многие разработчики приложений Notes, знакомые с LotusScript по версиям Notes 4.x,
еще не в полной мере владеют Java применительно к Domino, и такое сопоставление для
них окажется полезным.
• Хотя полного пересечения между методами и свойствами встроенных классов LotusScript
и Java нет, оно имеется ориентировочно на 85%, так что «параллельность» изложения
позволяет существенно сократить объем и степень дублирования излагаемого (и
изучаемого) материала.
• «В разных местах» приложений Domino приходится использовать «коктейль» из
нескольких разных языков: @-формулы, JavaScript, LotusScript и Java, и совсем не
удается обойтись только одним из языков.
В данной главе была использована следующая система обозначений и сокращений.
•
•
•
•
Конструкция [Notes]<Hci3eanue класса>, например, [NotesJDatabase, означает, что в
LotusScript класс называется NotesDatabase, а в Java - Database.
Конструкция <значение в LotusScript/<значение в Java>, например, ""/null, означает, что
в LotusScript это значение равно "", а в Java - null.
В описаниях синтаксиса свойств и методов Java в отличие от «классического стиля»
опущены public и throws Notes Exception (поскольку все свойства и методы имеют «тип
видимости» public и почти все свойства и методы могут возбуждать исключения) и
добавлены имя переменной, содержащей возвращаемое значение, знак равенства и
название класса, к которому применяется метод (чтобы «подчеркнуть подобие»
синтаксису в LotusScript). Так, вместо классического
public Java.Mil. Vector getAddressBooksQ throws NotesException дается
java.util Vector database Vector = Se^sTOn.getAddressBooksQ
В примерах на языке LotusScript обычно опускаются «заголовки» процедур. Так, для
следующего скрипта кнопки «останется» только то, что выделено жирным шрифтом.
Sub Click(Source As Button)
Dim db As New NotesDatabase( "", "names.nsf" )
Dim parentDb As NotesDatabase
Dim acl As NotesACL
Set acl = db.ACL
Set parentDb = acl.Parent
Messagebox( db.Title )
Messagebox( parentDb.Title )
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
350
End Sub
• Большинство примеров приложений на Java относится к агентам. Поскольку при
создании нового агента в интерфейсе Domino Designer версий 5 автоматически
генерируется «шаблон для его тела», в примерах приводится только то, что было
действительно добавлено вместо строки // (Your code goes here) в генерируемый при
создании агента шаблон, а так же «дополнительно добавленные» операторы import. При
этом переменные session и agentContext в примерах всегда нужно трактовать так, как это
определено в шаблоне. Например, для следующего скрипта агента «в примере остается»
только то, что выделено жирным шрифтом.
import lotus. domino .*;
.
import Java.util.*;
•
-:
.
'
"
public class JavaAgent extends AgentBase {
.
'
•
•
public void NotesMain()
•
{
try {
Session session = getSession(};
AgentContext agentContext = session.getAgentContext();
// (Your code qoes here)
Database db;
Vector books = session.getAddressBooks(); Enumeration & =
books.elements(); while (e.hasMoreElements())
-.-.-.-.{
db = (Database)e.nextElement();
String fn = db.getFileName();
к , ' ••
String server;
' "J
if (db.getServer(} != null) server = db.getServer()
else
server - "Local";
if (fn != null) db.open(); String
title = db.getTitle();
System.out.println (server + " " + fn + " \"" + title +
»\»") ;
....}
,
} catch(Exception e) {
e .print St. ackT race ();
•
}
}
-
.
:
•
} .
•
*
.
'
.
'
-
,
Имена методов всюду приведены с «малой буквы», а свойств - с «большой буквы». По
крайней мере по этому признаку можно отличить методы от свойств в предметном
указателе.
Свойства и методы, добавленные или модифицированные в Dornino версии 5.0,
«отмечены в заголовках значком» ©.
©InterTrust Со. Тел. (095) 9567928
Lotus Domino R. 5: @~формулы, LotusScript, встроенные классы LotusScript и Java
351
3.1. Введение в встроенные классы Domino
•
•
Встроенные классы Domino можно разделить на две группы:
классы интерфейса пользователя (User Interface, UI) или классы «переднего плана».
классы «заднего плана» (back-end).
Классы интерфейса пользователя доступны только из LotusScript и позволяют
разработчику приложений эмулировать многие действия, возможные в интерфейсе
пользователя Notes. Они обеспечивают доступ к таким объектам пользовательского
интерфейса, как рабочее пространство Notes (Workspace), окно вида (View window), окно
документа (Document window), поле, поле произвольного текста (RichText), кнопка в окне
документа... Действия, выполняемые над объектами классов интерфейса пользователя,
отображаются в пользовательском интерфейсе, т.е. «происходят» как бы «на сцене, на
переднем плане».
Класс NotesUIWorkSpacc представляет- интерфейс пользователя Notes (рабочее
пространство) и обеспечивает доступ к содержащемся в нем объектам. Класс
NotesUIDatabase представляет базу данных в интерфейсе пользователя, класс NotesUIView
• вид в интерфейсе пользователя, класс NotesUlDocument - документ, который в текущий
момент выбран или открыт в интерфейсе пользователя, класс NotesTimer - «таймер» механизм для получения событий через установленный интервал времени, класс Field редактируемое поле в форме, по которой открыт документ, класс Button - акцию, кнопку или
«активную площадку» (hotspot) в форме или поле типа RichText, а класс Navigator - кнопку,
«активную площадку» или другой объект в навигаторе, открытом в интерфейсе пользователя.
Классы «заднего плана» (back-end) доступны как в LotusScript, так и в Java, и
представляют такие объекты Domino, как базу данных, вид или папку, агента, документ, поле в
документе... Программисте использованием объектов этих классов может манипулировать
перечисленными объектами Domino из разработанных им приложений. При этом
выполняемые над объектами действия происходят без явного отображения в
пользовательском интерфейсе, как бы «за сценой, на заднем плане».
Класс [Notes]Session является «корневым» в «контейнерной» иерархии встроенных
классов Domino. Объект класса [NotesJSession представляет текущую сессию (сеанс). Он
обеспечивает доступ к переменным среды, адресным книгам, текущей базе данных и
текущему агенту, позволяет получать информацию о текущем пользователе, текущей
платформе и номере реализации Notes, используется для «отметки» обработанных агентом
документов и обеспечивает возможность создания объектов некоторых других классов без
явного создания объектов, являющихся контейнерами для создаваемых. Класс AgentContext
присутствует только в составе встроенных классов Java и инкапсулирует те свойства и
методы, которые присущи только выполняющемуся агенту и не имеют смысла в иных
контекстах.
Класс [NotesJDbDirectory представляет все базы, расположенные на указанном сервере
или локальном компьютере. Позволяет программисту «просмотреть» список имеющихся баз
и получить доступ к любой из них.
Класс [NotesJDatabase представляет конкретную базу Domino и обеспечивает доступ ко
всем содержащимся в ней объектам. Класс j'N'otesjRepIication позволяют определять и
устанавливать ряд свойств базы данных, касающихся ее поведения при репликациях.
Класс [Notes]ACL представляет список управления доступом (ACL) базы. Одной из
составляющих частей ACL является набор элементов (ACL Entry), каждый из которых
описывает права доступа к базе конкретного пользователя, сервера или группы. Класс
[NotesjACLEntry представляет один элемент из набора элементов в ACL.
© InterTrust Co. Тел. (095) 9567928
352
Встроенные классы LotusScript и Java
Класс [NotesjOutline представляет новый элемент дизайна Domino версий 5
-«иерархическую навигационную схему». Навигационная схема в свою очередь состоит из
набора иерархически («древовидно») упорядоченных элементов, выбор которых
пользователем влечет выполнение некоторого действия или переход по ссылке. Для работы с
элементом схемы используется объект класса [NotesJOutlineEntry.
Класс [NotesjAgent представляет конкретного агента, а класс [Notes]Form - конкретную
форму в базе.
Класс [NotesjDocumentColIection представляет коллекцию (подмножество) документов
из базы, отобранную в соответствии с некоторым критерием,
Класс [NotesJView представляет вид или папку в базе и обеспечивает доступ
содержащимся в виде или папке «строкам вида» и документам. Класс [Notes]ViewColumn
представляет столбец вида или папки.
Класс [Notes]ViewEntryCoIlection представляет коллекцию из всех строк вида или
только некоторое подмножество строк вида. Порядок следования элементов в такой
коллекции совпадает с порядком следования соответствующих строк в «родительском» виде.
Каждый элемент из коллекции - «строка вида» - является объектом класса [NotesjViewEntry.
Класс [Notes] ViewNavigator предоставляет более продвинутые возможности для
навигации на программном уровне по виду или части вида.
Класс [Notes]Document представляет один документ в базе.
Класс [Notes]Item представляет одно поле из документа - часть данных из документа,
которая обычно отображается в интерфейсе пользователя в одном поле формы. Когда
документ создается по некоторой форме, информация, введенная пользователем или
вычисленная, для каждого из полей формы (кроме вычисляемых для показа), сохраняется в
документе и образует одно поле этого документа. Однако, используя LotusScript или .lava,
программист имеет возможность создавать документы и работать с существующими
документами, никак не привязываясь при этом к конкретной форме для показа этих
документов. Поэтому поле в форме (Field) и поле в документе (Item) - это совершенно разные
объекты, хотя часто и связанные между собой.
Класс [Notes]RichTextItem представляет в документе одно поле типа «произвольный
текст» (RichText). Этот класс является производным от класса [Notesjltem, т.е. он наследует
все свойства и методы базового класса, но дополнительно имеет и свои собственные
специфические свойства и методы для работы с произвольным текстом. Класс
[Notes]RichTextStyle служит для определения стиля текста в поле типа RichText, а классы
[Notes]RichTextParagraphStyle и [Notes]RichTextTab - стиля абзаца и положений
табуляционных меток в абзаце поля типа RichText.
Класс [NotesjEmbeddedObect представляет внедренный объект, связанный объект или
присоединенный файл, содержащийся в объекте класса [Notes]RichTextltem, а с точки зрения
пользователя - в поле типа RichText.
Класс [NotesJLog позволяет протоколировать выполняемые при работе приложения
действия и возникающие при этом ошибки. Результат протоколирования может быть
помещен в базу, почтовое сообщение, файл (если выполнение происходит локально) или в
протокол агента.
Класс [Notes]NewsLetter позволяет создавать документы, содержащие информацию из
других документов, или документы, содержащие ссылки (DocLink-и) на многие другие
документы.
Класс jNotesJRegistration применяется при создании и администрировании ID-файлов и
«связанных» с ними документов в адресной книге сервера (с версии 5.0 она называется
Domino Directory). Методы класса позволяют выпускать взаимные сертификаты,
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
353
ресертифицировать существующие ID-файлы, регистрировать новых пользователей,
сертификаторов и серверы, включая создание ID-файлов, соответствующих документов в
адресной книге сервера, и, для пользователей, создание почтовых баз. Класс также содержит
методы, позволяющие извлекать или удалять присоединенные ID-файлы из документов в
адресной книге сервера, «переключаться» на другой ID-файл, получать или изменять
информацию в документах адресной книги сервера.
Класс [Notes]DateTime служит для преобразования значений типа «дата-время» между
форматами LotusScript/Java и Domino, а класс [NotesjDateRange представляет «отрезок
времени».
">
Класс [NotesjName предназначен для работы с именами или адресами пользователей или
серверов.
Класс [Notesjlnternational позволяет получить доступ к характеристикам среды
(платформы), в (на) которой происходит выполнение приложения.
Классы интерфейса пользователя
Классы «заднего плана» (back-end)
На Рис. 3.1 дается так называемая «контейнерная иерархия» встроенных классов. При
этом объекты классов, находящихся на более высоких уровнях дерева, являются
контейнерами для объектов, расположенных на более низких уровнях дерева. Речь идет
вовсе не о наследовании классов. Каждый класс содержит члены (members): свойства
(properties) и методы (methods). Отношение «является контейнером» (содержит)
подразумевает, что находящийся «выше по дереву» класс имеет свойства и методы для
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript u Java
354
создания новых объектов или доступа к существующим объектам находящихся «ниже по
дереву» классов. Следует только отметить, что приведенное на рисунке дерево не является
совершенно «полным». «Полное» дерево выглядит сложнее и запутаннее, поэтому мы не
приводим его целиком, но в описании каждого класса даем полную таблицу-поддерево «в
окрестностях» рассматриваемого класса.
«Контейнерная иерархия» находит свое прямое отражение при создании и использовании
объектов. Рассмотрим следующий скрипт.
1.
2.
3.
4.
5.
6.
7.
8.
9.
Dim
Dim
Dim
Dim
Dim
Set
Set
Set
Set
session As New NotesSession
db As NotesDatabase
view As NotesView
doc As NotesDocument
item As Notesltem
db = session.CurrentDatabase
view = db.GetView("Main View")
doc = view.GetFirstDocument
item - doc.GetFirstItern
..
-
•
1. Переменная session объявлена как переменная типа NotesSession. Метод New создает
новый объект класса NotesSession и присваивает переменной session ссылку на него. Этот
объект представляет текущий сеанс пользователя.
2,3,4,5. Переменные db, view, doc и item объявлены соответственно как переменные
классов NotesDatabase, NotesView, NotesDocument и Notesltem. Этим переменным пока не
присвоены значения - они пока не связаны ни с какими объектами.
6. Переменной db присваивается ссылка на объект1 класса NotesDatabase, возвращаемая
свойством CurrentDatabase объекта session. Этот объект «содержится» в объекте класса
NotesSession, он представляет текущую базу в сеансе пользователя.
7. Переменной view присваивается ссылка на объект класса NotesView. возвращаемая
методом getView объекта db. У объекта db - базы данных - может быть несколько видов, и
метод getView имеет параметр - строку с названием вида. Здесь метод getView создает и
возвращает ссылку на объект, представляющий вид с названием "Main View".
8. Переменной doc присваивается ссылка
представляющий первый документ в виде view.
па
объект
класса
NotesDocument,
9. Переменной item класса Notesltem присваивается ссылка на объект класса Notesltem,
представляющий первое поле в документе doc.
Из рассмотренного примера становится очевидной следующая «контейнерная иерархия»
классов: NotesSession —> NotesDatabase -> NotesView —> NotesDocument —» Notesltem.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @гформулы, LotusScript, встроенные классы LotusScript и Java
355
3.2. Основы разработки Java-приложений, использующих
;
встроенные классы Domino
Пакет lotus.domino
В любом Java-приложении, использующем классы Domino (программе, апплете, агенте
или сервлете), должен быть «импортирован» пакет lotus.domino. Для обеспечения
совместимости с Domino версии 4.6 пакет lotus.domino содержит те же классы и методы, что
и «старый» пакет lotus.notes, а так же новые классы, методы и другие расширения.
Пакет lotus.domino допускает как «локальные», так и «удаленные» (ПОР) вызовы к
объектам Domino.
* Локальные вызовы (local calls) используют исполняемый код с локального компьютера,
поэтому на локальном компьютере должен быть установлен Domino. Подробнее это
означает следующее. Когда вы «вызываете» в своем Java-приложении какой-либо метод
встроенного класса, например, Database db = DbDir.openDatabase("myDbFile.nsf"), то для
объекта DbDir происходит вызов метода openDatabase класса DbDirectory. Байт-код
метода openDatabase находится в пакете lotus.domino. Однако в самом байт-коде метода
для выполнения необходимой операции производится т.н. native-вызов С-функции из
библиотеки динамической компоновки, входящей в состав установленного на локальном
компьютере Domino. Эта С-функция или «полностью самостоятельно» реализует
«запрошенную» вами операцию, или, если это необходимо, обращается к серверу
Domino, используя при этом Notes RFC (Remote Procedure Call).
Рис. 3.2 Общая схема «локальных» вызовов
•
Удаленные (ПОР) вызовы (remote calls) используют исполняемый код с сервера Domino,
так что в этом случае на локальной машине нет необходимости устанавливать Domino.
DommoHCORBA-.••.•..•••;,••••:•••::.•• • . . . :. : .-. •..•,-•..,.••,..; • .. . . .....-.••• .....
CORBA (Common Object Request Broker Architecture) - архитектура брокера запросов
объектов - спецификация, принадлежащая некоммерческой группе Object Management Group
(OMG). OMG - консорциум промышленных корпораций, членами которой являются Lotus,
IBM, Netscape и более 700 других компаний, имеет Web-сайт http://www.omg.org.
CORBA специфицирует базовые механизмы для вызова с компьютера клиента методов
объектов, которые находятся на компьютере сервера. ORB (Object Request Broker) - брокер
запросов к объектам. Это распределенное приложение, функцией которого является
© InterTrust Co. Тел. (095) 9567928
356
Встроенные классы LotusScript и Java
предоставление механизма выполнения запроса, сделанного клиентом, на вызов метода
объекта, находящегося на сервере. Для связи между брокером запросов клиента и брокером
запросов сервера (а более широко, между разными брокерами запросов), разработан
протокол GIOP (General Inter-ORB Protocol), стандартизующий множество форматов
сообщений и низкоуровневое представление передаваемых данных. Реализация GIOP
«поверх» протокола TCP/IP - ПОР (Internet Inter-ORB Protocol) - протокол связи между двумя
компьютерами, обеспечивающий передачу параметров для вызываемого метода, его вызов и
возврат значения метода клиенту.
.. ;
,
Программное обеспечение брокеров запросов клиента и сервера могут быть написаны на
разных языках программирования и разными производителями, но, являясь
CORBA-совместимыми, «общаются» между собой по протоколу ПОР. Чтобы было
возможным формально описывать методы объектов независимо от языка программирования,
на котором эти объекты действительно реализованы, в CORBA предусмотрен IDL (Interface
Definition Language) - язык определения интерфейсов. Описание объекта (класса) на IDL
содержит лишь имена методов и их сигнатуры (имена и типы параметров, типы
возвращаемых значений), но никак не затрагивает вопросов реализации методов. Имеются
трансляторы с языка IDL на разные языки программирования для различных платформ.
Результат работы таких трансляторов дает две компоненты: «скелетную» реализацию классов
для «стороны» сервера (skeletons, «скелетоны») и «полную» реализацию этих классов для
«стороны» клиента (stubs, «стабы»).
Разработчик объектов (в нашем случае Lotus) должен обеспечить «реальный» код для
сервера, «дополняя» код «скелетонов», сгенерированный IDL-транслятором. Для
«клиентской стороны» ничего разрабатывать не нужно, за исключением, разумеется, самого
приложения или апплета, осуществляющего вызовы необходимых клиенту методов. Байт-код
«стабов» и клиентского брокера запросов обычно загружаются в броузер клиента «как
JAR-файл». «Стабы» сами формируют пакеты из входных параметров для каждого
вызываемого клиентом метода в ПОР-совместимом буфере и посылают эти пакеты через
клиентский брокер запросов брокеру запросов сервера. Затем «стабы» ожидают заполнения
буфера ответов сервером и, если метод определен с возвращаемым значением, распаковывают
это значение из буфера и возвращает его.
Рис. 3.3 Обгцая схема «удаленных» вызовов объектов Domino
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: (ф-формуды, LotusScript, встроенные классы LotusScript и Java
357
Требования к серверу
Удаленные (ПОР) вызовы требуют установки «на серверной стороне» сервера Domino
только версий 5.x. На сервере должны быть запущены задачи HTTP (она так же известна как
Domino Web Server) и DJIOP (Domino Internet Inter-Object request broker Protocol).
В документе Server применительно к задаче ОПОР обратите внимание на заполнение
следующих полей.
,
• Internet Protocols - ПОР - в поле Number of threads задается количество подпроцессов
задачи ОПОР для обработки удаленных вызовов. SERVER'
N<rtesSrv40b/lnterTnntOorp/Sl!
Puc. 3.4 Количество подпроцессов задачи DIIOP
Ports - Internet Ports - HOP - номера портов (TCP/IP port number), статус портов (TCP/IP
port status), анонимный доступ и разрешенные способы аутентификации (Authentication
options) для доступа к DIIOP по «обычному» порту TCP/IP и порту TCP/IP с поддержкой
SSL.
SERVER:
NotesSrv400/tn,torTrustCorp/
SLJ
Basics Security Ports Server Tasks
Internet Protocol: j Mi/'w I Miici
)
Notes Network Ports
Internet Ports
Proxies
SSL key We name:
" keyfile.kyrj
SSL protocol version (for use
with all protocols except
HTTP):
Accept SSL site certificates:
r*Negotiated_i_»j
О Yes <?< No
Accept expired SSL
Щ' Yes О No
certificates:
Web j Directory ] News ] Mail j HOP ]
TCP/IP port number:
:
TCP/IP port status:
Authentication options:
Name & password:
Anonymous:
SSL port number:
SSL port status:
Authentication options:
Client certificate:
Name & password:
Anonymous:
63148 ±
Enabled _»j
Yes
^j
' Ye s j j
63149*
'Enabled jj
N/A
'"Yes _,-jJ
' Yes -,^
Puc. 3.5 Используемые порты и способы аутентификации для задачи DIIOP
1
*
1
InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
358
Security - Server Access - поля Access server. Not access server. Create new databases и
Create replica databases содержат списки имен, шаблонов имен и групп, кому разрешается
или не разрешается обращаться к серверу Domino, создавать на нем новые базы или
реплики баз. Если кто-то не имеет доступа к серверу, или имеет, но, например, не может
создавать на нем новые базы, то он не сможет этого сделать ни из клиента Domino, ни
«через задачу» DIIOP.
Security - ПОР Restrictions - в этой группе два поля, содержащие списки имен,
шаблонов имен или групп тех, кому разрешается выполнять «удаленные» приложения на
Java или Javascript с «ограниченными» или «неограниченными» функциональными
возможностями. В ходе процесса аутентификации, происходящего при получении
удаленным приложением объекта Session, задача DIIOP проверяет вхождение имени
клиента в списки из этих полей. Чтобы к задаче DIIOP был возможен и анонимный
доступ, необходимо поместить имя "Anonymous" в одно или оба поля.
SERVER Notes8rv40GiJn1er1iutitCofplS.
Basics I Security
Ports
Smf-i li: 1 -- | Internet Pn
>
Puc. 3.6 Поля, определяющие возможность доступа к задаче DIIOP
Задача DIIOP автоматически обновляет информацию из документа Server, касающуюся
доступа, в своем кэше приблизительно раз в полчаса. Команда консоли сервера Tell DIIOP
Refresh «обязывает» задачу DIIOP осуществить внеплановое обновление информации в
кэше.
Требования к компьютеру, на котором выполняется разработка приложений
Компиляция Java-приложений, использующих классы Domino, должна выполняться на
компьютере с установленным Domino Designer версий 5.x. Убедитесь, что в файле
NOTES.INI этого компьютера имеется строка
ALLOW NOTES PACKAGE APPLETS=1
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: (tv-формулы, LotusScript, встроенные классы LotusScript и Java
359
Кроме того, переменная окружения CLASSPATH должна содержать путь на JAR-файлы
пакета lotus.domino:
set
CLASSPATH=<other>;c:\notes\domino\java\NCSO.jar;с\notes\Notes.jar
Архив Notes.jar содержит «высокоуровневый» пакет lotus.domino, пакет lotus.domino.local
для локальных вызовов и «старый» пакет lotus.notes. Архив NCSO.jar (NCSO - Notes Client
Side Objects - объекты Notes для «стороны» клиента) содержит «высокоуровневый» пакет
lotus.domino и пакет lotus.domino.corba для удаленных вызовов. Строго говоря, если вы
компилируете только удаленные вызовы, то необходим только NCSO.jar. а если вы
компилируете только локальные или «старые» обращения, необходим только Notes.jar.
Код вашего класса должен «импортировать» пакет lotus.domino
import lotus.domino.*;
Требования к компьютеру, на котором выполняется Java-приложение
На компьютере, выполняющем Java-приложение, осуществляющее «локальные» вызовы
свойств и методов классов Domino, должен быть установлен Domino версий 5.x (Client,
Designer или Server), а переменная окружения CLASSPATH должна содержать путь к архиву
Notes.jar. Кроме того, в переменную окружения PATH необходимо добавить каталог
программ Domino (например, c:\notes), чтобы виртуальная машина Java могла находить и
загружать библиотеки динамической компоновки, которые необходимы Java-классам.
Естественно, необходим и ID-файл, поскольку доступ к серверу в этом случае
осуществляется «по каналам Notes» (т.е. посредством Notes RFC) под текущим (указанным в
файле NOTES.IN! в переменной KeyFilenarne) ID-файлом.
На компьютере, выполняющем Java-приложение, осуществляющее «удаленные» вызовы
свойств и методов классов Domino, нет необходимости устанавливать Domino. Однако на
этом компьютере должен присутствовать архив NCSO.jar, а переменная окружения
CLASSPATH должна содержать путь к архиву NCSO.jar.
Domino-агент, написанный на Java, может выполняться только на компьютере с
установленным Domino версий 5.x (Client, Designer или Server), Переменная окружения
CLASSPATH на этом компьютере должна содержать путь к архиву Notes.jar.
На компьютере, выполняющем апплет, осуществляющий «удаленные» вызовы свойств и
методов классов Domino, нет необходимости ни в программном обеспечении Domino, ни в
каких-либо специальных назначениях в CLASSPATH.
3.2.1. Класс NotesThread
Класс NotesThread «расширяет» класс Java.lang.Thread (является наследником). Класс был
создан разработчиками Domino для того, чтобы обеспечить и гарантировать выполнение для
каждого потока необходимого кода инициализации и завершения Domino.
Если вам приходилось разрабатывать программы на языке С, использующие функции NotesAPI,
вспомните, что в однопоточной программе перед вызовом функций NotesAPI вы должны были
вызывать функцию NotesInitExtendedQ, основные действия которой сводились к нахождению каталога
данных Notes, загрузке файла NOTES.INI и поиску ID-файла пользователя, а по завершении
использования функций NotesAPI вызвать функцию NotesTermQ. В случае же многопоточной
программы в каждом потоке (thread) перед вызовом функций NotesAPI требовалось вызывать функцию
NotesInitThreadQ, а по завершении использования функций NotesAPI - функцию NotesTermThreadQ.
Java-программы и сервлеты, выполняющие «локальные» вызовы свойств и методов
классов Domino, должны явно использовать класс NotesThread. Напротив, Java-приложения,
выполняющие «удаленные» вызовы, не должны использовать класс NotesThread.
Java-приложения, которые выполняют как локальные, так и удаленные вызовы, «должны сами
динамически определять», когда должны выполняться локальные вызовы, и в этом случае
© InterTrust Со. Тел. (095) 9567928
360
Встроенные классы LotusScript и Java
«пользоваться» статическими методами sinitThread и stermThread класса NotesThread.
Потоки, активизированные AWT и использующие локальные вызовы к объектам Domino,
«должны пользоваться» статическими методами sinitThread и stermThread класса
NotesThread.
Агенты «расширяют» класс AgentBase, который в свою очередь расширяет класс
NotesThteacl. В агентах "применяются только локальные вызовы классов Domino, но при их
разработке не требуется явное использование класса NotesThtead, поскольку все
необходимые операции инициализации и завершения реализованы в самом классе AgentBase.
Апплеты, выполняющие вызовы классов Domino, расширяют класс AppletBase, который
«прозрачно для разработчика» выполняет локальные вызовы объектов Domino, если апплет
выполняется в среде клиента Domino, и удаленные вызовы, если апплет выполняется в
броузере.
Для завершения работы Java-приложения, использующего класс NotesThread, никогда не
должен применяться метод System.exit. Это относится и к агентам, расширяющим класс
AgentBase, который в свою очередь является наследником класса NotesThread. Но если в
агенте вызов System.exit генерирует исключение SecurityException, то в других
Java-приложениях вызов System.exit может повлечь гораздо более серьезные проблемы.
Спецификация класса NotesThread
public class NotesThread extends Java.lang.Thread 1
// Конструкторы
public NotesThread( ) ;
public NotesThread(Runnable t ) ;
public NotesThread(String name);
public NotesThread(Runnable t, String name);
public NotesThread(ThreadGroup group, String name);
public NotesThread(ThreadGroup group, Runnable t, String name);
public NotesThread(ThreadGroup group, Runnable t ) ;
// Инициализация и завершение потока Domino
public void initThread();
public void termThread();
// Статические: инициализация и завершение потока Domino
public static void sinitThread ( ) ;
•
public static void stermThread!);
// Метод run не может быть переопределен в производном классе
public final void run();
// Метод run вызывает метод runNotes,
// который вы обычно переопределяете в производном классе
public void runNotes() throws NotesException;
// Деструктор
public void finalize!);
•»
public static void load(boolean debug) throws NotesException;
Выполнение кодов инициализации и завершения Domino для потока путем
наследования
Класс Java-программы должен «явно расширять» класс NotesThread и содержать
реализацию метода runNotes, в котором и осуществляются локальные обращения к классам
Domino.
Программа создает новый экземпляр своего класса и вызывает для него метод start.
Поскольку в классе NotesThread метод start не переопределен, вызывается метод start класса
© InterTrust Со. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
361
Java.lang.Thread. Он создает новый поток и «в нем» вызывает для объекта, метод run. Вы не
можете переопределить метод run в своем классе, поскольку он объявлен в базовом классе
NotesThread с модификатором final. Следовательно, всегда происходит вызов метода
NotesThread.run, который сначала выполняет код инициализации Domino, а затем вызывает
метод runNotes, который вы переопределили в своем классе. По завершении метода runNotes в
методе NotesThread.run выполняется необходимый для Domino код завершения. Наконец, по
завершении метода NotesThread.run выполнение потока завершается.
Пример-шаблон I. Программа, обеспечивающая выполнение кодов инициализации и завершения
Domino для потока путем наследования класса NotesThread, выполняет «локальный» вызов.
import lotus.domino.*;
public class Appl extends NotesThread {
public static void main(String argv[]) {
Appl t = new Appl(); t.
start (}; }
public void runNotes()
{ try {
Session s - NotesFactory.createSession ( ) ;
Storing p - s.getPlatform ();
String u = s . get.UserName () ;
System, out. println ("Local session for user ." + u +
" on platform " + p); } catch (Exception
e) { e.printStackTrace(); } '
}
}
-•.••-...•
Результат выполнения этой программы может выглядеть следующим образом.
D: \JavaEx\BookExamples \Templat es> Java Appl
Local session for user CN=Nikolay N. Iontsev/0=InterTrustCorp/C=SU on
platform Windows /32
Выполнение кодов инициализации и завершения Domino для потока
реализацией интерфейса КшшаЫе
Класс Java-программы должен реализовывать интерфейс Runnable и, как требует этот
интерфейс, содержать реализацию метода run, в котором и осуществляются локальные
обращения к объектам Domino. Применяется этот вариант обычно в тех случаях, когда ваш
класс должен быть наследником другого класса (не NotesThread).
Программа создает новый объект своего класса, затем новый объект класса NotesThread,
передавая его конструктору в качестве параметра ссылку на объект своего класса. В
конструкторе NotesThread происходит сохранение ссылки на объект вашего класса для
использования в дальнейшем. Затем программа вызывает метод start для объекта
NotesThread. Поскольку в классе NotesThread метод start не переопределен, вызывается метод
start класса java.lang.Thread. Он создает новый поток и «в нем» вызывает для объекта
NotesThread метод run, который сначала выполняет код инициализации Domino, а затем
вызывает метод run (а не runNotes) вашего объекта, ссылку на который конструктор
NotesThread «предусмотрительно сохранил» в объекте NotesThread. По завершении вашего
метода run в методе NotesThread.run выполняется необходимый для Domino код завершения.
Наконец, по завершении метода NotesThread.run выполнение потока завершается.
©InterTrust Со. Тел. (095) 9567928
Встроенные классы LotusScript u Java
362
Пример-шаблон 2. Программа, обеспечивающая выполнение кодов инициализации и завершения
Domino для потока путем реализации интерфейса Runnable, выполняет «локальный» вызов.
import lotus.domino. * ;
public class App2 implements Runnable
{
public static void main(String argvf]) {
App2 t = new App2();
NotesThread nt — new NotesThread((Runnable)t); rit.
start (} ; }
public void run()
try {
Session s = NotesFactory. creaf.eSession ();
String p = s.getPlatform();
String u = s.getUserName();
System.out.println("Local session for user " + u +
" on platform. " + p) ; }
catch
(Exception e)
{
e.printStackTrace ();
} }}
Результат выполнения этой программы может выглядеть следующим образом.
D:\JavaEx\BookExamples\Templates>java Арр2
Local session for user CN=Nikolay N. Iontsev/O=InterTrustCorp/C=SU on
p1 a t f orm Wi n dow s/3 2
Выполнение кодов инициализации и завершения Domino «явным»
использованием статических методов
Класс Java-программы перед выполнением локальных обращений к объектам Domino
должен «явно» вызвать статический метод sinitThread, а по завершении обращений к
объектам Domino «явно» вызвать статический метод stermThread (обычно в блоке finally).
Пример-шаблон 3. Программа, обеспечивающая явный вызов «кодов» инициализации и
завершения Domino для «основного» потока, выполняет «локальный» вызов.
import lotus.domino.*;
public class АррЗ
{
. . .
public static void main(String argv[])
{
try {
NotesThread. sinitThread() ;
••
Session s = NotesFactory.createSession();
String p = s.getPlatform(); String u =
s.getUserName();
System, out. .println ("Local session for user " + u + " on
platform " + p);
!
. . , ' - •
catch(Exception e) { e.printStackTrace(); }
finally { NotesThread.stermlhread(); }
} }
Результат выполнения этой программы может выглядеть следующим образом. ©
InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: ^-формулы, LotusScript, встроенные классы LotusScript и Java
363
D:\JavaEx\BookExamples\Templates>java АррЗ
• •
Local session for user CN=Nikolay N. lontsev/O=InterTrustCorp/C=SU on
platform Windows/32
3.2.2. Класс AgentBase
Java-агенты Domino должны расширять класс AgentBase и реализовывать метод
NotesMainQ «как точку входа в их функциональный код». Сам же класс AgentBase
«расширяет» класс NotesThread (является наследником). Для получения объекта класса
Session в агентах должен использоваться метод AgentBase.getSession.
Спецификация класса AgentBase
public class AgentBase extends NotesThread 1
protected Session m_session;
public AgentBase(};
// Эти методы не могут быть перекрыты
public final void startup(Agentlnf о info);
public final void runNot.es () throws NotesException;
// Метод NotesMain перекрывается в вашем классе.
// Он должен содержать «функциональный код» агента.
// Его вызов выполняется из AgentBase.runNotes, причем к этому моменту
// -не только уже; выполнена инициализация для Domino,
// но и фактически получен объект класса Session
public void NotesMain( } ;
public Session getSession( ) ;
public boolean isRestricted();
public PrintWriter getAgentOutput();
public void setDebug(boolean debug);
public void setTrace(boolean trace);
public void dbgMsg (String msg, Print-Stream ps);
public void dbgMsg(String msg, PrintWriter pw);
public void dbgMsg(String msg); }
Пример-шаблон 4. При создании Java-агента в интерфейсе Domino Designer автоматически
генерируется шаблон его кода. Необходимый «функциональный код» агента должен быть вставлен
вами «за строкой» // (Your code goes here). Таким же образом «должны оформляться» и агенты,
создаваемые в других средах разработки.
import lotus.domino.*;
public class JavaAgent extends AgentBase
{
,".,•-..
public void NotesMain()
{
try { Session session = getSession ();
AgentContext agentCont&xt — session.getAgentContext(); //
(Your code goes here)
// Начало функционального кода агента
String p = session . getPlatform () ;
String u - session.getUserName(} ;
System. out .printIn (".Session for user " + u +
" on platform " + p);
// Конец функционального кода агента }
catch(Exception e) { e.printStackTrace(); } } }
' InterTrust Co. Тел. (095) 9567928
364
Встроенные кчассы LotusScript u Java
Поскольку большинство примеров использования свойств и методов встроенных классов
Domino, рассматриваемых далее в этой книге, выглядят именно таким образом, в этих
примерах дается только добавленный «за строкой» // (Your code goes here) «функциональный
код» агента. При этом так же предполагается, что переменные с именами session и
agentContext «уже определены» точно так же, как и в этом шаблоне.
В агентах, выполняющихся в клиенте Domino «на переднем плане», вывод в System.out и
System.err «направляется в окно» Java debug console. В агентах, запускаемых на выполнение по
расписанию или событию, вывод в System.out и System «направляется» в базу Log.nsf (Domino
log).
Агенты, выполняющие вывод HTML-кода «в броузер», должны создавать объект
java.io.PrintWriter методом getAgentOutputQ класса AgentBase, Вывод, выполняемый в этот
объект, например, методом println, «направляется в броузер». Этот же прием будет работать и
при выполнении агента в среде клиента Domino, однако вывод, осуществляемый в объект,
«направляется в окно» Java debug console.
Пример-шаблон 5. Java-агент создает объект PrintWriter методом getAgentOutput и выполняет
вывод HTML-кода «в броузер». Если «запустить» этот агент из броузера по URL наподобие
http://domino500.inttrust.i'u:8080/Education/JavaLSExs.nsf/Java-PrintWriter?OpenAgent, в броузер будет
передана строка "Session for user CN=Domino500/O=lnterTrustCorp/C=SU on platform Windows/32", где
DominoSOO - имя сервера. При запуске в клиенте Domino этот же агент выведет в окно Java debug
console строку "Session for user CN=Nikolay N. iontsev/O=InterTrustCorp/C=SU on platform Windows/32",
где Nikolay N. lontsev - имя пользователя.
import lotus.domino.*;
impor-t Java . io . PrintWriter;
public class JavaAgent extends AgentBase
{
public void NotesMain'J
{
try {
Session session = qetSession();
PrintWriter pw = getAgentOutput();
String p = session.get Plat form{);
String u = session.getUserName(};
pw.println{"Session for user " + u + " on platform " + p); }
catch (Exception e) { e,printStackTrace(); } } }
3.2.3. Класс NotesFactory
Хотя «корнем» в контейнерной иерархии back-end классов Domino считается класс
Session, для получения объекта этого класса в Java-приложениях используются методы
класса NotesFactory. Все методы класса NotesFactory являются статическими.
Спецификация класса NotesFactory
public class NotesFactory
{
// «Локальная» сессия - должен быть установлен Domino static public Session
createSession() throws NotesException; /'/ «Удаленная» (ПОР) сессия с хостом
как Anonymous или с аутентификацией static public Session createSession(String
host) throws NotesException; static public Session createSession(String host,
String user, String passwd) throws NotesException;
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: (а)-формулы, LotusScript, встроенные классы LotusScript и Java
365
static public Session createSession(String host, String argsf ],
String user, String passwd) throws NotesException; //
«Удаленная» (ПОР) сессия с применением TOR static public
Session createSessionWithlOR(String IOR)
throws NotesException; static public Session
createSessionWithlOR(String IOR, String user,
String passwd) throws NotesException; static public Session
createSessionWithlOR(String IOR, String args [ ],
String user, String passwd) throws NotesException; // «Удаленная» (ПОР)
сессия для апплета static public Session createSession(Java.applet.Applet app,
String user,
String passwd) throws NotesException; static public
Session createSession(Java.applet.Applet app,
org.omg.CORBA.ORB orb, String user, String passwd)
throws NotesException; // Возвращает
IOR для заданного хоста
static public String getIOR(String host) throws Exception; }
В приложениях, выполняющих «локальные» вызовы, для получения объекта класса
Session должен использоваться метод NotesFactory.createSessionQ без параметров.
Соответствующие примеры использования этого метода были рассмотрены в подразделе
3.2.1.
В приложениях, выполняющих «удаленные» (НОР) вызовы, для получения объекта
класса Session рекомендуется использовать методы NotesFactory.createSession(String host)
или NotesFactory.createSession(String host, String user, String pwd). Параметр host обоих
методов - «строковое представление» имени хоста сервера Domino. Параметр user - строка с
именем пользователя - должен позволять серверу «обнаружить» в его адресных книгах
соответствующий документ Person, а параметр pwd - пароль пользователя - должен быть
таким же, как и пароль, содержащийся в поле Internet password этого документа Person. Если
имя и пароль не были заданы, т.е. был использован NotesFactory.createSession(String host),
приложению будет предоставлен анонимный доступ, если только анонимный доступ к
серверу по портам ПОР не запрещен вовсе.
В приложениях, выполняющих «удаленные» (ПОР) вызовы по порту задачи ОПОР с
поддержкой SSL (Secure Socket Layer), для получения объекта класса Session должен
использоваться метод NotesFactory.createSession(String host, String args[], String user, String
pwd). Второй параметр метода - «массив строк» args[] - должен содержать первым элементом
строку "-ORBEnableSSLSecurity".
Пример-шаблон 6. Java-программа осуществляет «удаленные» вызовы к объектам на сервере
Domino. При запуске программы в качестве первого параметра должно задаваться имя хоста, на
котором находится сервер Domino. По выбору могут даваться третий и четвертый параметры - имя
пользователя и его пароль. Если имя и пароль отсутствуют, к серверу возможен только анонимный
доступ. Присутствие четвертого параметра требует «открытия сессии» по порту с поддержкой SSL и
аутентификацией по имени и паролю.
import lotus.domino.*;
public class App4 implements Runnable
{
.
-
-
"
:
•
String host~null, user="", pwd-"", ssl=null;
public static void main(String argv[])
• :
i
• • • . • ' •
.
if(argv.length < 1)
.
{
• - • - .
System.out.println("Need to supply Domino server host name");
return;
}
© InterTrust Co. Тел. (095) 9567928
366
Встроенные классы LotusScript и Java
Арр4 t = new App4(argv); Thread nt = new
Thread((Runnable)t); nt.start(); }
public App4 (String argvt]) // Конструктор {
host = argv[0];
i f (argv. length >•- 2) user = argv[l];
if(argv.length >= 3) pwd = argv[2];
if (argv. length >= 4) ssl •— argv[3]; }
public void run() {
tгу{
Session s = null;
String args[] = new String[1];
args[0] = "-ORBEnableSSLSecurity";
if (ssl == null)
//Вез SSL
{ s = NotesFactory,createSession(host, user, pwd); )
else
// SSL
{ s = NotesFactory,createSession(host, args, user, pwd); }
String p = s.getPlatform();
String u = s.getUserName();
System.out.println("Remote session for user " + u + " on
platform " -t p) ;
}
.
.
.
catch(NotesException e)
{
System.out.println(e.id + " " + e.text);
e .printStackT.race ( ) ;
}
catch (Exception e)
{ e.printStackTrace(); } } . . . . . .
t
Результат выполнения этой программы может выглядеть следующим образом.
D: \JavaEx\BookExamples\Templates>java App4 dominoSOO NIontsev password
Remote session for user CN=Nikolay N. Iontsev/0=InterTrustCorp/C=SU on
plat form Windows/32
Заметим, что для получения объекта класга Session в агентах используется метод
AgentBase.getSessionQ. В апплетах же для получения объекта класса Session применяются
методы AppletBase.openSessionQ или AppletBase.openSession(String user. String pwd), а для
«закрытия сессии» метод AppletBase.closeSession(Session session).
3.2.4. Классы AppletBase и JAppIetBase
Апплет, осуществляющий обращения к объектам Domino, должен «расширять» класс
AppletBase или JAppIetBase и замещать в своем базовом классе все или только необходимые
методы notesAppletlnitQ, notesAppIetStartQ, notesAppletStopQ и notesAppletDestroyQ. Эти
методы подобны методам initQ, start(), stop() и destroyQ «обычных» апплетов. Другие методы
«обычных» апплетов, в частности getAppletlnfoQ, getParameterlnfoQ, а так же
унаследованные от суперклассов класса Applet методы paintQ, printQ, getParameter(),
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @гформулы, LotusScript, встроенные классы LotusScript и Java
getCodeBaseQ, getDocumentBaseQ, showStatus(), getAppletContext() и др.,
AppletBase или JAppletBase «не перекрыты».
367
в классах
Метод notesApplet!nit() (аналог init()) вызывается при первой загрузке апплета в броузер.
Обычно содержит код инициализации апплета.
Метод notesAppletStartQ (аналог startQ) вызывается, когда апплет становится «видимым»
и должен приступить к выполнению своей работы.
Метод paintQ вызывается, когда апплет «должен отобразить себя на экране».
Метод notesAppletStopO (аналог stopQ) вызывается, когда апплет становится
«невидимым» (например, пользователь «прокрутил» изображение апплета за пределы окна
броузера.) и «должен приостановить» выполнение апплетом своей работы.
Метод notesAppletDestroyO (аналог destroyQ) вызывается перед выгрузкой апплета из
броузера и должен освободить все ресурсы, захваченные апплетом, за исключением ресурсов
памяти.
Для разработчика апплета, расширяющего класс AppletBase или JAppletBase, в основном
нет никаких различий между «локальными» и «удаленными» вызовами. Сами классы
AppletBase или JAppletBase автоматически выполняют «локальные» вызовы, если апплет
выполняется в среде клиента Domino, и «удаленные» вызовы, когда апплет выполняется в
броузере.
Спецификация класса AppletBase
public class AgentBase extends Applet: implements DominoAppletBase {
public AppletBase();
,// Методы getSession и openSession возвращают объект класса Session.
// В варианте с параметрами апплет получает доступ к серверу под именем
// user с паролем pwd, в варианте без параметров - как Anonumous.
// Метод closeSession закрывает открытую сессию.
public Session getSession () throws N'otesException;
public Session getSession(String user, String pwd)
throws NotesException;
public Session openSession() throws NotesException;
public Session openSession(String user, String pwd)
throws NotesException;
public void clcseSession(Session session)
throws NotesException;
,/,/ Выполняет инициализацию апплета
public final void init();
public void notesAppletlnit();
// Выполняет запуск апплета
public final void start{);
public void notesAppletStart();
// Выполняет останов апплета
public final void stop();
•
* public void notesAppletStop { } ;
..•
// Выполняет завершение апплета
public final void destroy();
public void notesAppletDestroyO;
// Возвращает true, если апплет может выполнять локальные обращения или
// false, если не может
public boolean isNotesLocal() ; }
Спецификация класса JAppletBase отличается от приведенной лишь тем, что класс
JAppletBase «расширяет» класс JApplet и «импортирует» пакет com.sun.java.swing.
© InterTrust Co. Тел. (095)9567928
Встроенные классы LotusScript и Java
368
Для создания объекта класса Session, обеспечивающего доступ к классам Domino, такой
апплет должен использовать методы getSessionQ или getSession(String user, String pwd) или
аналогичные им методы openSessionQ или openSession(String user, String pwd), а для
«закрытия сессии» метод closeSessioii(Sessior) session).
Шаблон-пример 7. Простейший апплет, осуществляющий обращения к объектам Domino, может
выглядеть следующим образом.
.;•-..
import lotus.domino.*;
public class DIlOFAppletl extends AppletBase {
Java.awt.TextArea ta;
Session s;
public void notesAppletlnit{)
{
set-Layout (null) ; setSize (600, 50} ; t
a r= new j ava . awt. Text Area () ;
ta.setBounds(0,0,599,49); add(ta); ta.setEditable(false);
setVisible(true); }
public void notesAppletStartО {
try {
// Can also do
// s = this.openSession("NIontsev","Password");
s = this.openSession();
if (s == null)
{ //not able to make the connection, warn user
ta.append("Unable to create a session with the server"); return; }
String p = s . getPlatform (} ; String u -• s . getLIserName ( } ;
ta.append("Session for user "+ ц + " on platform " + p); }
catch (Exception e) { e .printStackT'race (} ; } i
public void notesAppletStopO
{
try { this.closeSession(s); }
catch (Exception e) { e , printStackT'race ( ) ;
}} }
Пример 8. Этот апплет выполняет обращения к объектам на сервере Domino не только из метода
notesAppletStart, но и в обработчике события нажатия кнопки - action. Поскольку обработчик события
выполняется в отдельном потоке, в случае выполнения апплета в среде клиента Dornino («локальные»
вызовы) должен выполняться код инициализации и завершения Domino. Однако при «удаленных»
вызовах такое, напротив, не должно происходить.
i m p o r t l o tu s . do m i no .* ;
import j ava.awt.*;
i mp о r t: j a v a . a pp 1 e t. App let;
public class DlIOPApplet.2 extends AppletBase
{
© InterTrust Co. Тел. (095) 9567928
Lotus Domino К, 5: (^-формулы, LotusScript, встроенные кшссы LotusScript и Java
private Button Ь2; '
_
private String text = "";
Graphics gl;
int j = 0, k = 0;
Dimension dScreen;
public Java.awt.TextArea ta;
public Session s;
.
..
• ;•
369
•• . ..
public void notesAppletlnit () ' = • ' -''V-">K- "."••^"^ •-,'<*"<: X>> • •"• •'•"-••-.:-• .... .
{
gl = getGraphics();
dScreen - this.getToolkit().getScreenSize();
b2 = new Button("b2 Java Notes Classes");
add(b2);
я.-.
••
b2.requestFocus();
ta - new Java.awt.TextArea(15,30);
add(ta);
}
public void paint(Graphics g)
;
т
b2.move(0, 0); ta.move(200,0);
}
.
' '
public void notesAppletStart()
i
.
•
try
-•. . . .
..
{
s = this.openSession();
ta.append("User " + s.getCommonUserName()+ "\n"); }
catch (NotesException e) { text :=; e. id + " " + e.text; }
catch(Exception e){ e.printStackTrace (); }
}•
.
, / ' . . . . .
public boolean action(Event e, Object o) •
f
:
if(e.target instanceof Button)
_
{
^
"
text = "";
if(e.target.equals(b2) ) { this.b2Test (); }
ta.append(text + "\n");
}
' . ' . . .
return true;
}
;
.
;
• .
// Jjiva Notes Classes
public void b2Test()
{
try
{
,
' '
., . .-
:
.
if (isNotesLocal() == true) NotesThread.sinitThread();
text = "User " + s.getCommonUserName();
}
' " ' • ' '
'
catch(NotesException e) { text - e.id + " " + e.text; } catch(Exception
e) { e.printStackTrace(); } finally { if (isNotesLocal() == true)
NotesThread.stermThread(); }
}
......... - - •- - } // end of Applet
•
... ,
.
© InterTrust Co. Тел. (095) 9567928
370
Встроенные классы LotusScript u Java
3.2.5. Размещение CORBA-анплетов на сервере Domino
Процесс помещения апплета из примера 7 в базу данных на сервере Domino может быть
приблизительно следующим.
В документе в поле типа RichText (и аналогично в форме или на странице) выбором в
меню Create-Java Applet создается новый апплет.
Рис. 3. 7 Окно Create Java Applet
Кнопкой Locate «вызывается» окно, в котором выбираются дополнительные файлы,
загружаемые вместе с апплетом. В данном случае архив NSCO.jar, хотя рациональнее
использовать его «сжатую» версию NSCOC.jar.
Рис. 3.8 Окно Locate Java Applet Files
В окне свойств апплета выбирается опция Applet uses Notes CORBA classes.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5; @гформулы, LotusScript, встроенные классы LotusScript и Java
PMC. 3.9
371
Свойства апплета
В клиенте Domino или броузере этот апплет выглядит приблизительно следующим
образом.
"
•02. DHOP Applet Template
Рис, 3.10 «Внешний вид» апплета из примера 7
.
.
Рассмотрим тег <APPLET>, автоматически генерируемый задачей HTTP для данного
апплета.
<APPLET WIDTH="600" HEIGHT="50"
CODEBASE^"/OursDBs/WorkDatabases/Education/JavaLSExs.nsf/79866f57dc2229d4с
32567480043cf8e/8a4ddf721bf778c7c32567700058fda3/$FILE"
CODE="DIIOPAppletl.class" ALT="Loading..." ARCHIVE="NCSO.jar,NCSOC.jar">
<PARAM NAME="NOI__IOR"
VALUE-"TOR:010000002900000049444c3a6c6f7475732f646f6d696e6f2f636f7262612f4
94f626a6563745365727665723а312е3000000000010000000000000054000000010101000
dOO00003139352e3230382e36382e380000acf6310000000438353235363531612d6563363
82d313036632d656565302d303037653264323233336235004c6f7475734e4f49010001000
00000000000">
<PARAM NAME="NOI_COOKIE_URL"
VALUE="/OursDBs/WorkDatabases/Education/JavaLSExs .nsf'PGetOrbCookie">
</APPLET>
, .
'
,
• ,
В нем нет ничего необычного, за исключением лишь двух параметров NOI__IOR и
NOI_COOKIE_URL, автоматически генерируемых задачей HTTP, если в свойствах апплета
была выбрана опция Applet uses Notes CORBA classes.
Для уяснения смысла параметра NOMOR придется обсудить еще одно заимствованное
из CORBA понятие - IOR (Interoperable Object Reference). Это ссылка на объект, по которой
клиентский брокер запросов может «найти» компьютер, на котором находится объект, и
передавать этому компьютеру запрос на вызов необходимого метода. В частности, IOR
включает TCP/IP-адрес компьютера и номер порта, на котором брокер запросов сервера
ожидает запросы, некоторый уникальный идентификатор для процесса сервера и ссылку на
) InterTrust Co. Тел. (095) 9567928
372
Встроенные классы LotusScript и Java
запрашиваемый объект. Когда брокер запросов сервера получает ПОР-запрос, содержащий
1OR необходимого клиенту объекта, он «загружает» этот объект в свою виртуальную память
или создает его экземпляр и возвращает клиенту ссылку на этот объект. После этого клиент
может посылать запрос на вызов метода «непосредственно объекту».
Параметр NOIJOR содержит ни что иное, как строку 1OR (Interoperable Object Reference)
для задачи DIIOP данного сервера, позволяющую открыть с ней сессию. В своем методе
notesAppletStartQ для получения объекта класса Session апплет вызывает метод
AppletBase.getSession(). Этот метод сам реализуется посредством вызова
NotesFactory.createSession(String IOR), которому необходима строка 1OR. Конечно, строку
IOR можно было бы получить вызовом NotesFactory.getIOR(String host), но последнее будет
означать «пусть небольшой, но все же» HTTP-запрос типа GET на HTTP-сервер. Чтобы по
возможности не выполнять такого запроса, в реализации AppletBase.getSessionQ сначала
проверяется, не передана ли строка 1OR апплету в качестве значения параметра NOIJOR, и,
если передана, ее значение «сразу» используется в методе NotesFactory.createSession(String
IOR).
Параметр NO1_ COOKIEjURL не менее важен - он позволяет апплету сообщать задаче
ОПОР, какой пользователь «находится» на клиентском компьютере. Предположим, что в
списке управления доступом базы данных, содержащей апплет, для -Default- выбрано No
Access (нет доступа). Введя URL в окне броузера, клиент получает от задачи HTTP запрос на
ввод имени пользователя и пароля, чтобы сервер мог его аутентифицировать и затем
проверить, имеет ли данный пользователь доступ к базе. Предположим, что задача ОПОР не
имела бы никакого автоматического опознавательного механизма. Когда апплет, теперь уже
разгруженный в виртуальную машину броузера, попытался бы открыть сессию с задачей
ОПОР, его «пользователя» пришлось бы вновь аутентифицировать, возможно, повторным
вводом имени и пароля. Поэтому, генерируя по запросу броузера HTML-код страницы с
CORBA-апплетом, задача HTTP добавляет в тег <APPLET> параметр NOI_COOKIE_URL,
содержащий ссылку на аутентифицированное имя пользователя и IP-адрес компьютера, на
который передан этот HTML-код. Затем, когда этот апплет обращается к задаче ОПОР на
этом сервере, метод AppletBase.getSessionQ передает значение параметра NOI_COOKIE_JJRL
задаче ОПОР, и по нему задача ОПОР «узнает», какой пользователь «находится» на
клиентском компьютере.
3.2.6. Сервлеты, использующие объекты Domino
Сервлет (servlet) представляет собой специальное приложение, написанное на языке Java и
выполняющееся на Web-сервере, обеспечивающем поддержку сервлетов. Когда
Web-сервер принимает от клиента запрос, IJRL которого «указывает на» сервлет, сервер
выполняет сервлет, и вывод сервлета отправляется клиенту. Поведение сервлета во многом
подобно поведению CGl-программы. Одно из основных отличий состоит в том, что сервлет
не нуждается в загрузке при каждом обращении к нему - загрузка сервлета выполняется
только один раз, обычно при первом обращении к нему.
Domino, точнее серверная задача HTTP, может загружать и выполнять сервлеты,
удовлетворяющие Java Servlet API Specification Version 2.0 от Sun Microsystems, Inc. Для
разработки сервлетов необходимо получить копию Java Servlet Development Kit с сайта
JavaSoft (http://www.javasoft.com/products/servlet/index.html).
Краткое введение в сервлеты
Сервлеты должны реализовывать интерфейс javax.servlet.Servlet. Обычно этого
досчитают,
создавая
класс-потомок
javax.servlet.GenericServlet
или
javax.servlet.HttpServIet. Оба эти базовых класса реализуют интерфейс Servlet, причем
HttpServlet сам является потомком GenericServiet.
© InterTrust Со. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные массы LotusScript и Java
373
Когда сервлет загружается сервером, в сервлете происходит вызов метода initQ. Метод
initQ вызывается только один раз. После того, как сервер загрузит и «инициализирует»
сервлет, последний становится способен обрабатывать запросы клиентов.
Каждый запрос клиента приводит к вызову в сервлете метода serviceQ. Метод serviceQ
должен быть написан с учетом параллельного выполнения потоков (thread-safe manner),
поскольку каждый новый запрос порождает новый поток, выполняющий в себе метод
serviceQ. Например, если метод serviceQ изменяет значение некоторого поля в объекте
сервлета, доступ к этому полю должен быть синхронизирован. Если же по каким -то
соображениям метод serviceQ не должен выполняться в разных потоках, то сервлет должен
реализовать интерфейс SingleThreadModel.
import javax.servlet.*
import j ava.io . *
public class MyServletl extends HttpServlet
{ /* метод service!) будет вызываться из многих потоков */ }
import; ~j avax . servlet . *
import j ava.io.*
public class MyServlet2 extends HttpServlet implements SingleThreadModel
{ /* метод service{) может вызываться только в одном потоке */ }
Сервлет обычно функционирует на сервере до тех пор, пока функционирует сервер или
пока его не выгрузят. В этом случае в сервлете вызывается метод destroyQ. Метод destroyQ
вызывается только один раз, и должен «дождаться» завершения или принудительно
завершить все потоки, выполняющие метод serviceQ, и освободить все выделенные сервлету
ресурсы. Только после этого сервлет может быть вновь загружен и инициализирован.
Еще одним стандартным методом сервлета является getServletlnfoQ. Он должен
возвращать строку (String), содержащую описание сервлета. Возвращаемый текст обычно
используется средствами управления сервлетами на сервере. «Не перегруженный» метод
getServletlnfoQ возвращает пустую строку.
Если сервлет является наследником класса HttpServlet, часто перегружают не сам метод
serviceQ, а другие методы, вызываемые «родным» методом serviceQ в зависимости от
запросов клиента:
* doGetQ - вызывается для обработки запросов GET, условный GET и HEAD (клиент
запрашивает необходимые ему данные, а сервер (сервлет) возвращает клиенту
запрошенную им информацию);
» getLastModifiedQ - вызывается при обработке запросов GET, условный GET и HEAD и
возвращает время последней модификации запрошенного клиентом ресурса; ;'
» doPostQ - вызывается для обработки запроса POST (клиент заполняет форму и передает
введенные данные на сервер, сервер (сервлет) принимает и обрабатывает данные и
обычно отвечает клиенту подтверждением приеме данных).
«Не перегруженные» методы doGetQ и doPostQ возвращают код ошибки 400
(BAD_REQUEST - «Плохой» запрос от клиента), а «не перегруженный» getLastModifiedQ
-отрицательное число, означающее, что время последней модификации неизвестно, а потому
не должно применяться в запросе условный GET и при кэшировании.
Методы serviceQ, doGetQ и doPostQ получают два параметра: объекты классов
HttpServletRequest и HttpServletResponse, метод getLastModifiedQ - один параметр: объект
класса HttpServletRequest. Эти объекты поддерживают соответственно интерфейсы
javax.servlet.http.HttpServletRequest и javax.servlet.http.HttpServletResponse, которые в
свою очередь «расширяют базовые» интерфейсы javax.servlet.ServietRequest и
javax.servlet.ServletResponse.
i InterTrust Co. Тел. (095) 9567928
374
Встроенные классы LotusScript и Java
Класс HttpServletRequest инкапсулирует передачу информации от клиента к сервлету.
Методы и свойства ServletRequest позволяет сервлету получать такую информацию, как
имена параметров, переданных клиентом серверу, схему, использованную клиентом, имена
хостов клиента и сервера, а также входной поток ServletlnputStream, «из которого» сервлет
получает данные, переданные клиентом при использовании метода POST.
Класс HttpServletResponse инкапсулирует передачу информации от сервлета к клиенту.
Методы и свойства ServletResponse позволяет сервлету «отвечать» клиенту: задать М1МЕ-тип
«ответа» и длину содержимого (content length), а так же получить выходной поток
ServletOutputStream, в который сервлет должен записывать передаваемые клиенту данные.
Пример 9. Самый простой сервлет из Java Servlet Development Kit.
/*
* @(#)HelloWorldServlet.Java 1.9 97/05/22
* Copyright (c) 1995-1997 Sun Microsystems, Inc. All Rights Reserved.
+/
import java.io.*; import
javax.servlet.*; import
javax,servlet.http.*;
public class HelloWorldServlet extends HttpServlet
{
.'
public void doGet (HttpServletRequest req, HttpServletResponse res)
throws ServletException, lOException {
res.setContentType("text/html");
ServletOutputStream out = res.getOutputStream();
out.println("<html>");
out .printIn ("<head><title>Hello World</titlex/head>") ;
out.println("<body>");
out .println ("<hl> -- Hello World -- </.hl>") ;
out.println("</body></html>"};
}
public String getServletInfо() {
return "Create a page that says <i>Hello World</i> and send it back";
}
}
© InterTrust Co. Тел. (095) 9567928
•
Lotus Domino R, 5: (ад-формулы, LotusScript, встроенные классы LotusScript и Java
375
Настройка поддержки сервлетов задачей HTTP
К вопросу поддержки сервлетов задачей HTTP имеет отношение группа полей Java
Servlets, находящихся на закладке Internet Protocols - Domino Web Engine документа Server.
SERVER NotesScv4GQ/JrHe» Гг-л',»<"
Basics I Security j Ports
Serve-T^ks | Internet Protoi
i
1 Miscellaneous
Ttansacdonal Logging j Administrate,i ,
HTTP J Domino Web Engine | HOP ] LDAP ] NN7P
Session authentication
I die session timeout:
i ikibird ,_»j
*' 10.. r minutes
Pitc. 3.12 Фрагмент документа Server - группа полей Java Servlets
Java servlet support - три варианта поддержки сервлетов задачей HTTP:
* None (по умолчанию) - отсутствует, задача HTTP не загружает виртуальную машину
Java (JVM) и Servlet Manager;
* Domino Servlet Manager - стандартная, задача HTTP загружает JVM и Domino Servlet
Manager;
* Third Party Servlet Support - используется Servlet Manager от другого
производителя, например, IBM's WebSphere; задача HTTP загружает JVM, но не
загружает Domino Servlet Manager.
Servlet URL path - префикс «пути» в URL, «сигнализирующий» задаче HTTP, что URL
указывает на сервлет. По умолчанию /servlet.
Class path - список, содержащий относительные (относительно каталога данных Domino)
или абсолютные пути к каталогам или файлам архивов, в которых Servlet Manager
должен осуществлять поиск классов самих сервлетов и необходимых им классов. По
умолчанию domino\servlet.
Servlet file extensions - список, содержащий «расширения», «сигнализирующие» задаче
HTTP, что URL указывает на сервлет. Каждое «расширение» в этом списке должно быть
определено в файле servlets.properties в директиве extension и должно однозначно
«указывать» на единственный сервлет. Подробнее рассматривается ниже.
Session state tracking - относится только к сервлетам, реализующим интерфейс
HttpSession. Выбор Enabled (значение по умолчанию) требует, чтобы Servlet Manager
«отслеживал» объекты класса HttpSession, которые «были неактивны» в течении
заданного интервала времени. Как только Servlet Manager обнаруживает такую
«продолжительно неактивную сессию», он вызыва ет для ее объекта метод
HttpSession.invalidateQ, «сообщая» тем самым сервлету, что сессия завершается. Выбор
Disabled запрещает Servlet Manager контролировать «продолжительность неактивности»
этих объектов.
Idle session timeout - относится только к сервлетам, реализующим интерфейс HttpSession,
и задает продолжительность «интервала неактивности» в минутах (по умолчанию 30).
Maximum active sessions - применимо только к сервлетам, реализующим интерфейс
HttpSession, и задает максимально допустимое количество «конкурирующих сессий»
-объектов класса HttpSession. По умолчанию 1000. Когда количество «конкурирующих
© InterTrust Со, Тел. (095) 9567928
376
#
Встроенные классы LotusScript и Java
сессий» превышает заданное, Servlet Manager начинает «закрывать сессии», имеющие
наибольший «интервал неактивности».
Sessions persistence - применимо только к сервлетам, реализующим интерфейс
HttpSession. Выбор Enabled означает, что перед завершением задачи HTTP Servlet
Manager должен сохранить состояние объектов класса HttpSession в файле sessdata.ser в
каталоге данных Domino, а при очередном запуске задачи HTTP вновь создать эти
объекты класса HttpSession с восстановлением их состояния из файла sessdata.ser
(сериализация объектов, реализующих интерфейс java.io.Serializable). Выбор Disabled (по
умолчанию) запрещает сериализацию объекты класса HttpSession.
Файл servlets.properties представляет собой текстовый файл, расположенный в каталоге
данных Domino, и содержащий набор директив четырех типов. Директивы «чувствительны к
регистру». В файле допустимы строки комментариев - они должны начинаться символом #.
Директива servlet.<alias-name>.code=<class-name> определяет алиас alias-name (в нем не
должна встречаться «точка») для сервлета class-name. Например, директива
servlet.SQLQuery.code=sql.database.query.Servlet
назначает сервлету sql.database.query.Servlet алиас SQLQuery. В результате этот сервлет
становится доступен по URL http://<hostname>/servlet/SQLQuery?month=june. Заметим, что
Domino Servlet Manager по соображениям безопасности не загружает сервлеты, в именах
которых содержится «точка» - для таких всегда должен быть назначен алиас.
Директива servJet.<a!ias or class name>.extension=<extension> <extension> ... задает
список «расширений» для сервлета. «Расширения» в директиве отделяются друг от друга
пробелами. Например, директива
servlet.SQLQuery.extension=sql sq
обязывает Servlet Manager вызывать сервлет SQLQuery по любому URL, содержащему
«расширения» "sql" или "sq", в частности, http://<hostiiarne>/query.sql?month=june. Все
«расширения», встречающиеся в файле servlets.properties, должны однозначно определять
сервлеты и должны быть дополнительно перечислены в поле Servlet file extensions документа
Server.
Директива servlet.<alias or class name>.initArgs=<namel>=<valuel>,<name2>=<value2>...
позволяет сообщить сервлету значения «инициализационных» параметров. Сервлет обычно
получает эти значения методом ServletConfig.getlnitParameterQ в своем методе init().
Например,
servlet.SQLQuery.initArgs=target=db2,user=Domino,cacheSize=30
Директива servlets.startup=<alias or class> <alias or class> ... требует, чтобы загрузка
перечисленных в ней сервлетов выполнялась при запуске задачи HTTP, а не при первом
обращении к сервлету. как происходит по умолчанию. Имена алиасов (или классов)
разделяются в директиве пробелами.
Например, файл servlets.properties может выглядеть следующим образом.
# Properties for the sql servlet
servlet,SQLQuery.code=sql.database.query.Servlet
servlet.SQLQuery.extension=sql servlet. SQLQuery .
init.Args=cache=30
# Properties for the mail servlet
servlet. MailServlet. initArgs-mime-enabled, sm.ime=disabled tt
Both servlets should be loaded at startup
servlets.startup=SQLQuery MailServlet
# end of file
Domino Servlet Manager не выполняет загрузку классов, которые используют внешний
код на Си (native code), создают собственные загрузчики классов или выполняют другие
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R, 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
377
«ограниченные» операции. Если ваш сервлет использует класс, который не может быть
загружен Domino Servlet Manager, можно попытаться загрузить его загрузчиком классов
виртуальной машины Java, используемой задачей HTTP (Domino JVM). Загрузчик классов
Domino JVM обычно осуществляет загрузку классов из стандартных Java-архивов, входящих
в состав Domino, в частности, из пакетов Java.* и lotus.* . Вы можете «форсировать» загрузку
своих классов, переместив их «из путей» Domino Servlet Manager «в пути» Domino JVM,
которые задаются в переменной JavaUserClasses файла NOTES.INI сервера.
Команда консоли сервера Tell HTTP Restart «реинициализирует» загруженные
сервлеты: Domino Servlet Manager вызывает для каждого загруженного им сервлета метод
destroy(), а затем, обычно при «первом последующем» обращении-к сервлету, метод init().
Выгрузки и повторной загрузки класса сервлета при этом не происходит. Выгрузка и
повторная загрузка классов сервлетов происходит при перезапуске задачи HTTP (команды
консоли Tell HTTP Quit, затем Load HTTP). Именно это должно выполняться, когда в код
сервлета (файл .class) были внесены изменения.
Сервлет, осуществляющий локальные обращения к объектам Domino
Поскольку класс сервлета обычно «расширяет» класс HttpServlet. а обращения сервлета к
объектам Domino «локальны», в коде такого сервлета вы должны или реализовывать
интерфейс Runnable и создавать объект класса NotesThread (подобно примеру-шаблону 2),
или пользоваться статическими методами sinitThread и stermThread.
Выполнение такого сервлета происходит «под ID-файлом» сервера Domino, что, говоря
вообще, может расцениваться как нарушение безопасности сервера.
Шаблон-пример 10. Простейший сервлет, осуществляющий локальные обращения к объектам
Domino «техникой» sinitThread и stermThread, может выглядеть следующим образом,
import
java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import lotus.domino.*;
'
'
'
•
public class Servlet1 extends HttpServlet
{
''""•'
public void doGet(HttpServletRequest req,
HttpServletResponse resp) ' ' { '
try
{
-
. ••
: '
•-••••
• • - - ' • -
NotesThread.sinitThread();
- >
:-•resp. setContentType ( "text/html" )/
Session s = NotesFactory.createSession();
ServletOutputStream out = resp.qetOutputStream();
out.printIn{"<html>");
out. print In ( "< headxt it 1 e>UserN ame &Plat form</title ></head>" ) ;
out.println("<body>");
out.print In("Session for " + s.getUserName() +
...-.
" on platform " + s . getPlatf orm () ) ;
out .println ("</bodyx/html>") ;
'...•}-.
- . , . . . .
catch(Exception e) { e.printStackTrace(); }
finally { NotesThread.stermThread(); }
"•) •
" . . • . - • . . . . . . ' .
public String getServletlnfо()
"'{'
' • :. -••-
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
378
return
"Servlet to display server name & platform";
}
,
:
}
Рис, 3.13 «Отклик» этого сервлета в броузере
3.2.7. Класс Base - общие методы для встроенных классов Domino
Все рассматриваемые далее встроенные классы Domino для Java являются производными
(наследуются) от класса Base, В классе Base имеются методы, «общие» для встроенных
классов Domino.
Метод recycle - «освободить память, занимаемую СРР-объектом в кеше»
void Object.recycleQ
void Session. recycle(/ava. util. Vector objects)
Большинство классов Domino, находящихся в «контейнерной иерархии от Session и
ниже», имеют метод recycle. Кроме того, класс Session имеет вариант метода recycle,
аргументом которого является вектор объектов - он наиболее эффективен при «удаленных
вызовах».
Метод recycle освобождает память, занимаемую в кеше Domino СРР-объектом,
соответствующим объекту Domino. Появился метод в Domino с версии 4.61 для
предотвращения ситуации переполнения кеша СРР-обьектов. Все дело в том, что свойства и
методы классов «внутри» Domino реально реализованы на языке C++, а их вызов из
Java-приложения (как, впрочем, и из скрипта), влечет вызов соответствующего метода на
языке C++ (native call, см. Рис. 3.2 и Рис. 3.1). Создание нового объекта в приложении на
Java влечет создание СРР-объекта, память для которого выделяется не Java-машиной, а
соответствующим конструктором из реализации класса на языке C++ в специальном кеше
Domino. При этом Domino (при локальных вызовах как сервер, так и клиент, при удаленных
-сервер) сохраняет СРР-объекты в кеше, чтобы было возможным повторно использовать их
при последующих обращениях, не создавая заново. В большинстве случаев, как в
однопоточных, так и в многопоточных агентах и приложениях, такое поведение позволяет
ускорить обработку.
Но размер кеша Domino для СРР-объектов не безграничен, и в агентах и приложениях с
большим количеством объектов иногда возникает ситуация нехватки памяти. Наиболее часто
такое встречается при обработке в цикле большого количества (несколько тысяч) документов
из коллекции или вида или при создании в цикле большого количества новых документов.
Сборщик мусора Java не может освобождать память, занимаемую СРР-объектами - она
находится «вне его области компетенции». Чтобы освобождать память, занимаемую
СРР-объектами Domino, в Java используют метод recycle. Аналогичная ситуация может
возникать и в LotusScript, где «для борьбы с нею» применяют явные вызовы деструктора
delete для
© InterTrust Со. Тел. (095) 9567928
Lotus Domino R, 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
379
«ненужных» объектов, однако полной аналогии между явным вызовом деструктора в
LotusScript и метода recycle в Java нет.
Перечислим основные принципы использования метода recycle.
•
•
•
•
•
•
•
•
•
•
Не следует применять recycle, если не возникает проблем с нехваткой памяти.
Типичные «места кода», где целесообразно применять recycle - циклы по коллекциям
документов или по документам из вида.
Вы должны быть уверены, что ни к самому объекту, ни к содержащимся в нем объектам
не происходит обращений после того, как для объекта был выполнен recycle.
Метод recycle для объекта вызывает «серию вызовов recycle» для содержащихся в нем
объектов.
Не применяйте recycle для объектов, которые существуют, но создавались «не вами» например, которые были получили из «контекста агента», в частности для объекта текущей базы данных, полученной методом CurrentDatabase.
Будьте крайне аккуратны при использовании recycle в случае многопоточного
приложения с «локальными» вызовами или агента. Вызывать метод нужно обязательно в
том же потоке, в котором этот объект был создан, и только тогда, когда этот объект
гарантированно не будет более использоваться другим потоком. Вызывать метод recycle
для объекта Session следует не только в том же потоке, где объект был создан, но и после
завершении всех остальных потоков. В случае «удаленных» вызовов таких ограничений
нет.
В многопоточном приложении с «локальными» вызовами или агенте безопасно
применять метод recycle к объекту класса Database (представляет базу данных) или
содержащимся в нем объектам лишь тогда, когда с этим объектом Database работают
только из одного потока. В противном случае recycle, вызванный из одного потока,
«грубо удалит» СРР-объект, в результате чего при попытке использовать объект в другом
потоке, скорее всего, возникнут исключения наподобие обращения по нулевому
указателю (null pointer).
Однако в многопоточном приложении с «локальными» вызовами или агенте можно
«взять за правило» получать в каждом потоке свой объект класса Session, а от него - свой
объект класса Database. Это позволит безопасно применять метод recycle к объекту
класса Database или содержащимся в нем объектам в каждом потоке, даже если объекты
Database разных потоков связаны с одной и той же базой данных.
Если ваш Java-агент должен выполняться как асинхронный Web-агент (в NOTES.INI
сервера имеется переменная DOMINOASYNCHRONIZEAGENTS=1), методы recycle
рекомендуется применяться всякий раз, когда это возможно. Это минимизирует набор
рабочих СРР-объектов агента, который совместно использует ресурсы с другими
выполняющимися агентами.
Все СРР-объекты автоматически освобождаются по завершении агента или приложения
(но не потока).
Метод toString - «текстовое представление объекта»
String text = OZy<?e?.toString()
Метод toString, наследуемый всеми классами от java.lang.Object, «перекрыт» в
следующих классах Domino: ACLEntry (как gefName), Agent (как getName), AgentContext
(как getEffectiveUserName), Database (как getFilePath), DateRange (как getText), DateTime (как
getLocalTime), DbDirectory (как getName), Document (как getUniversallD), EmbeddedObject
(как getName), Form (как getName), Item (как getName), Log (как getProgramName), Name (как
getCanonical), Session (как getUserName), View (как getName), ViewColumn (как getTitle).
© InterTrust Co. Тел. (095) 9567928
380
Встроенные классы LotusScript и Java
Метод getURL - «получить URL объекта»
•;..•..- •
String ml = Ofyect.getURLO
Метод возвращает URL объекта. Определен для объектов классов Agent, Database,
Document, Form, Session (при локальных вызовах «пустая строка») и View.
Пример. Этот Java-агент выведет на консоль следующее.
Database db=agent.Context . getCurrentDatabase {) ;
Agent ag = agentContext.getCurrentAgent(); System.,
out . print In ("Session " + session . toString {) +
"\n\t URL "+session,getURL();;
System.out.println("Database "+db.toString ()+"\n\t URL "+db.getURb());
System, out. .println ( "Agent "+ag. toString {) + "\n\t URL "+ag.getURL() ) ;
Session CN=Nikolay N. lontsev/O=InterTrustCorp/C=SL)
URL Database WorkDatabases\Educatioo\JavaLSExs.nsf
URLnotes://CN=NotcsSrv400/O=lnterTrustCorp/C=SU/_C32S6714004F334B.nsf?OpenDatabase
Agent Java-getUrl
URLnotes://CN=NotesSrv400/O=lnterTrustCorp/C=SU/_C3256714004F334B.nsf/
ODOC732D91A01605C32567A100259555?OpenAgent
Интерфейс java.beans.Visibiiity
Все классы Domino реализуют интерфейс java.beans.Visibiiity, но «сконфигурированы как
невидимые»: метод needsGuiQ всегда возвращает false, а метод avoidingGUIQ - всегда true.
•j
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулм, LotusScript, встроенные классы LotusScript и Java
381
3.3. «Сессия» и «контекст агента» - классы [Notes]Session и
AgentContext
Класс [NotesJSession является «корневым» в «контейнерной» иерархии встроенных
классов. Объект класса [Notes]Session представляет текущую сессию (сеанс). Он
обеспечивает доступ к переменным среды, адресным книгам, текущей базе данных и
текущему агенту, позволяет получать информацию о текущем пользователе, текущей
платформе и номере реализации Notes, используется для «отметки» обработанных агентом
документов и обеспечивает возможность создания объектов некоторых других классов без
явного создания объектов, являющихся контейнерами для создаваемых.
Класс AgentContext присутствует только в составе встроенных классов Java и
инкапсулирует те свойства и методы, которые присущи только выполняющемуся агенту и не
имеют смысла в иных контекстах. Все свойства и методы класса AgentContext так или иначе
доступны и в LotusScript, чаще всего в составе класса NotesSession и NotesDatabase, но всегда с
четкой оговоркой допустимого контекста применения. Вероятно, последнее и послужило
причиной выделения присущих только выполняющемуся агенту свойств и методов в
отдельных класс в Java.
«Контейнерная иерархия»
LotusScript
New _ >
NotesSession
~> NotesDbDirectory NotesDatabase
NotesAgent NotesDocument NotesDocumentCollection NotesRichTextStyle
NotesRichTextParagraphStyle NotesNewsLetter NotesLog NotesDataTime NotesDateRange
Noteslnternational NotesNarne NotesTimer Java
AgentBase — >
Session
— > AgentContext AppletBase
AgentContext — > Agent
NotesFactory
DbDirectory Database Registration Document
Documented lection RichTextStyle RichTextParagraphStyle News Letter Log DataTime DateRange
International Name
В LotusScript для получения доступа к текущей сессии необходимо методом New создать
объект класса NotesSession.
.
.
Dim variableName As New NotesSession
или
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
382
^
Set notesSession = New NotesSession
Поскольку выполнение любого скрипта всегда происходит в рамках одной сессии,
очередной вызов метода New для NotesSession будет всегда возвращать тот же самый объект.
Пример. Скрипт создает новый объект класса NotesSession и использует его для доступа к текущей
базе (базе, в которой выполняется скрипт). Такая техника позволяет избегать использования
конкретных имен серверов и файлов баз в скриптах.
Dim session As New NotesSession
Dim db As NotesDatabase
Set db = session.CurrentDatabase
If ( db.IsOpen ) Then
Messagebox db.Title
Eise
Call db.Open( "", "" )
Messagebox db.Title
End If
Различные способы создания объекта класса Session в Java были рассмотрены в главе 3.2.
3.3.1. Свойства
Свойство AddressBooks - «доступные адресные книги»
LotusScript:
Java:
... . . . : . . . . ; • • ........ . ...
notesDatabaseArray - notesSession.AiidressBooks
java.util. Vector database Vector -- Sessww.getAddress'BooksQ
Адресные книги, доступные во время выполнения. В LotusScript возвращается массив с
элементами класса NotesDatabase, в Java - объект класса java.util.Vector с элементами класса
Database. Если выполнение происходит на станции, свойством обычно возвращаются как
личная адресная книга, так и общие. Если же выполнение осуществляется на сервере, обычно
возвращаются только общие адресные книги. Чтобы определить, какая из адресных книг
общая, а какая личная, в классе [Notes]Database предусмотрены свойства PublicAddressBook
и PrivateAddressBook.
Исходно все базы в массиве или векторе, полученном свойством AddressBooks, закрыты, и
для них доступны только свойства FileName, FilePath, IsOpen, IsPublicAddressBook,
IsPrivateAddressBook, Parent и Server. Для доступа к остальным свойствам и методам базы ее
необходимо предварительно открыть методом open.
Пример 1. Скрипт выводит типы и заголовки всех возвращаемых свойством AddressBooks
адресных книг. При выполнении на станции будут перечислены все те адресные книги, которые вы
можете выбрать в окне Select Addresses, когда выбираете получателя созданного вами почтового
сообщения.
Dim session As Mew NotesSession
Dim books As Variant
books = session.AddressBooks
Forall b In books
If b.IsPublicAddressBook Then t="Public NAB: "
If b.IsPrivateAddressBook Then t="Private NAB: "
Call b.0pen( "", "" )
Msgbox( t + b.Title ) End
Forall
Пример 2. Java-агент выводит имена файлов, названия серверов и заголовки всех возвращаемых
свойством AddressBooks адресных книг.
import, j ava . ut il . * ;
© InterTrust Co. Ten. (095) 9567928
Lotus Domino R. 5: (а)-формулы, LotusScript, встроенные классы LotusScript и Java
383
// Java-Session/AddressBooks
Database db;
Vector books = session.getAddressBooks();
Enumeration e = books.elements( ) ;
whale (e . hasMoreEierhents () )
{
db ---- (Database)e.nextElement();
String fn = db.get FileName();
String server;
if (db.getServer() != null) server - db.getServer();
else
server ~ "Local";
if (fn !- null) db.open();
String title = db.getTitle ();
System.out .println (server + " " -f fn + " \"" t- title + "\""); i
Свойство AgentContext - «контекст агента»»
Java:
AgeniContext agentContext = Session.getAgentConte\t()
Если свойство вызывается из агента, оно возвращает объект класса AgentContext. Если же
свойство вызывается не из агента, возвращается null. Свойства объекта класса AgentContext
позволяют получить то же самое, что и одноименные свойства объекта класса NotesSession
(LotusScript), имеющие смысл только в контексте агентаСвойство UserName -«полное имя пользователя или сервера»
LotusScript:
Java:
пате$ = notesSession.UserName
Siring name = Session.getVser'NameO
Полное имя текущего пользователя или сервера (тип String), например "CN=Nikolay N.
foiitsev/O=InterTrustCorp/C=SU'!, Когда выполнение происходит на станции, возвращается
имя пользователя. Для агента, выполняющегося на сервере, свойство всегда возвращает
полное имя сервера.
Свойство Common UserName - «общее имя пользователя или сервера»
LotusScript:
commonName$ = tiotesSession.CommonUserNtime
Java:
String commonName ~ &jvw"ow.getCommonUserName()
Возвращается составляющая CN (тип String) из полного имени текущего пользователя,
если выполнение происходит на станции, или сервера, если выполнение осуществляется на
сервере. Например, если полное имя текущего пользователя "CN=Nikolay N.
lontsev/O-InterTrustCorp/C=SU", свойство вернет "Nikolay N. lontsev". Если имя простое
(неиерархическое), то составляющая CN для него совпадает с полным именем.
Свойство EffectiveUserName - «имя пользователя или разработчика агента»
LotusScript:
name$ -•'-= nolesSession.'Effective'UserNume
Java:
String name = lSV5.y/ow.getAgentContext().getEffectiveUserName()
Если выполнение происходит на станции, возвращается полное имя пользователя (тип
String). Если выполнение осуществляется на сервере, возвращается полное имя владельца
агента - разработчика, который создал или последним редактировал этого агента.
© InterTrust Со. Тел. (095) 9567928
Встроенные классы LotusScript и Java
384
Основное назначение свойства состоит в определении лица, отвечающего за результаты
выполнения агента, а область применения свойства - код агента. Поэтому в Java свойство
является членом класса AgentContext, а не Session.
Пример. В первом диалоговом окне может быть возвращено CN-Nikolay N.
lontsev/O=InterTrustCorp/C=SU, во втором - Nikolay N. lontsev, а в третьем, когда скрипт выполняется
на станции, то же, что и в первом.
Dim session As New NotesSession
, Messagebox session.UserName,,"session.UserName" Messagebox session.
ConuaonUserName, , "session. CorninonUserName" Messagebox
session.EffectiveUserName,, ''session.EffectiveOserName"
0 Свойство UserNameList - «список всех имен пользователя»
LotusScript:
Java:
note sNanie Array - m7tes>Sbvv/o«.UserNameList
java.util. Vector names - 5'e,ss/o/7.getUserNameList{)
Возвращаются «массив» всех имен пользователя или сервера (в LotusScript как массив, в
Java - как объект класса java.util,Vector), Элементы «массива» являются объектами класса
[Notes'JName. Первый элемент «массива» соответствует основному имени, остальные
-альтернативным именам пользователя (если они имеются).
Пример. Скрипт выводит составляющую CN и код языка для всех имен текущего пользователя.
Результат выполнения скрипта на станции может вы глядеть следующим образом:
Common name is Nikolay N. iontsev
Language is
(основное имя)
Common name is Николай Н. Ионцев
Language is ru
(первое альтернативное имя)
Dim session As New NotesSession
Dim nameslist As variant nameslist =
session.UserNameList
Forall nnanie in nameslist
print ("Common name is " & nname.common)
print ("Language is " & nname.Language)
end Forall
Свойство UserNameObject - «имя пользователя как объект класса Name» ..
Java:
Name name = ,Ses;«o?7.getUserNameObject()
Возвращает основное имя пользователя или сервера как объект класса Name.
Пример. Выполняясь на станции, этот Java-агент может вывести следующие строки:
User name = CN-Nikolay N. Iontsev/O~-=InterTrustCorp/C=SU
Common user name = Nikolay N. lontsev
Effective user name = CN=Nikolay N. lontsev/O=InterTrustCorp/C~SU
no.getCommonO ~: Nikolay N. iontsev
Common name is Nikolay N. lontsev
Language is
(основное имя)
Common name is Николай Н. Ионцев
Language is ru
(альтернативное имя)
import j ava.util.*;
// Java-Session/Names
String un = session.getUserName();
System.out.println("User name = " + un) ;
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
385
String en = session.getCommonUserName();
System.out.println("Common user name = " + en);
String en = session.getAgentContext().getEffectiveUserName();
System.out.println("Effective user name = " + en);
Name no = session.getUserNameObject{);
System.out.println("no.getCommon() = " + no.getCommon());
Vector nl = session.getUserNameList();
Enumeration e = nl. elements () ; -, •.: . ;: -_.,.
, - • , . . . - while
(e.hasMoreElements ()) {
Name nobj = (Name)e.nextElement();
System.out.println ("
Common name is " + nobj.getCommon());
System.out.println ("
Language is " + nobj.getLanguage()); }
Свойство Platform - «платформа»
LotusScript:
platform$ = notesSession.Platform
Java:
String platform = Session.gGtPlatfarmQ
Платформа, на которой происходит выполнение. Возможные значения: "Macintosh",
"MS-DOS", "Netware", "OS/2vl", "OS/2v2" - версии 16 bit и 32 bit, "Windows/16", "Windows/32",
"UNIX" - UNIX (Sun, SCO, HPUX, A1X).
Свойство Notes Version - «версия Notes»
LotusScript:
version$ = notesSession.NotesVersion
Java:
String version = getNotesVersionQ
Версия Notes (тип String). Например, "Release 5.0(IntI)|30 March 1999".
© Свойство NotesBuildVersion - «номер реализации Notes»
LotusScript:
long = notesSession.NotesJZmld Version
Номер реализации Notes (тип Long). Например, 166.
Пример. Скрипт выводит название платформы и название и номер реализации версии Notes..
Dim session As New NotesSession
Print "Platform = "; session.Platform
Print "NotesVersion = "; session.NotesVersion
Print "NotesBuildVersion = "; session.NotesBuildVersion
Свойство International - «характеристики среды выполнения»
LotusScript:
Java:
Set noteslnternational = notesSession.lnternational
International intl = 5ess/o«.getlnternational()
Возвращает объект класса [Notes]International, представляющий характеристики среды
выполнения.
Свойство IsOnServer - «выполнение на сервере»
LotusScript:
Java:
flag = notesSession.isOnServer
boolean flag = tVe55/on.isOnServer()
.
-•
Возвращает true, если выполнение происходит на сервере, или false, если на станции.
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
386
v «,i,-
@ Свойство ServerName - «имя сервера» ;-•-•-:-..-• '..'•*•'•'•' '•'/ "
Java:
"" ''•'• ''
String serverName = •Sess/o/j.getServerNameQ . • .-- .-•• /:.-•- .-
Возвращает полное имя сервера, на котором открыта сессия и происходит выполнение,
или null, если выполнение происходит не на сервере.
© Свойство ConvertMime - «преобразование TYPE_MIME_PART в Notes Rich
Text» ... ... . •;.. . •••••'..., ;: • ..' .. • ' . : . - . . . .... ; : '.. ...;... ; .• .. .. ',, . . ..
LotusScript:
flag = noiesSession.ConveriMime
notesSession.ConveriMtme-flag
Java:
boolean flag = Skss/cw.isConvertMime()
void Session.setCon\eriMime(boolean flag)
Если значение свойства равно true, то в полях типа Rich Text информация формата
TYPE _M1ME_PART должна преобразовываться в формат Notes Rich Text (CD Records), если
false - не должна. По умолчанию свойство равно false.
Свойство CurrentDatabase - «текущая база»
LotusScript:
Set notesDatabase = notoSkvs/'ow.CurrentDatabase
Java:
Database database = 5k«'zow.getAgentContext().getCurrentDatabase()
Объект класса [NotesJDatabase, представляющий базу, в которой находится данный
скрипт или агент. База может оказаться как открытой, так и нет.
Свойство CurrentAgent - «текущий агент»
'•'•.'-'•'••'"•-. •--^•: ; -'*':
LotusScript:
Set notes-Agent = nolesSession.CurrentAgent
Java:
Agent agent — iS'ei'5/o/7.getAgeiitCoiitext().getCurrentAgeiit()
• --.•'.-••'.•• ;
Имеет смысл только в контексте агента и возвращает объект класса [NotesJAgent,
представляющий выполняющегося в настоящий момент агента.
т*
...
Пример. Скрипт агента «узнает свое собственное имя».
Dim session As New NotesSession
Dim agent As NotesAgent
• •
•
Dim aqentName As String
•• •-••
Set agent = session.CurrentAgent
agentName = agent. Name . . . . . .
._• . . - • . / - • • . - .
. ; . • ' .
..••.<
Свойство LastRun - «время предыдущего запуска»
LotusScript:
daleV= notesSession.L'AsfRun
Java:
DateTime date = 5es5;'o«,getAgentContext().getLastRun()
Имеет смысл только в контексте агента. Возвращает дату и время (в LotusScript тип
Variant of type DATE, в Java - объект класса DateTime), когда предыдущий раз выполнялся
данный агент. Если агент никогда ранее еще не выполнялся, в LotusScript свойство
возвращает 1 1/30/1899, а в Java - null.
. . .
..
Пример. Скрипт агента определяет, когда агент в предыдущий раз запускался. Например, если это
имело место 15 августа 1999 года в 11:09:20 утра, свойство вернет 8/15/99 11:09:20 AM.
© InterTrust Co, Тел. (095) 9567928
Lotus Domino R, 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
387
Dim session As New NotesSession
Dim runDate As Variant runDate =
session.LastRun
Свойство LastExitStatus -«статуе завершения при предыдущем запуске»
LotusScript:
code% = «otes'S'es.s/o/j.LastExitStatus
Java:
int code - 5b;«'cw.getAgentContext().getLastExitStatus()
Имеет смысл только в контексте агента. Возвращает статус завершения (в LotusScript тип
Long, в Java - int), имевший место при предыдущем выполнении этого агента. Статус равен О,
если агент в предыдущий раз завершился без ошибок, и отличен от нуля, если имели место
ошибки.
Пример. Скрипт агента проверяет статус завершения при предыдущем запуске и выводит
соответствующее сообщение в строке состояния.
Dim session As New NotesSession
If ( session.LastExitStatus = 0 ) Then
Print ( "В прошлый раз агент завершился успешно" )
Else
Print ( "В прошлый раз агент завершился с ошибкой" ) End
If
Свойство SavedData - «SavedData-документ агента»
LotusScript:
Set notesDocument = notesSession,S»vedData
Java:
Document document = &s,«'on.getAgentContext().getSavedData()
Возвращает объект класса [NotesjDocument, представляющий документ, используемый
агентом для сохранения информации, необходимой при следующем запуске данного агента.
Свойство имеет смысл только для агента. Во всех иных контекстах оно возвращает
Nothing/null.
Документ для сохранения промежуточной информации агента - SavedData-документ
-создается в базе автоматически в момент сохранения в ней этого агента его разработчиком.
Исходно документ «пуст». При своем выполнении агент может получить объект класса
[NotesjDocument, представляющий этот документ, и добавить в него новые поля с
необходимыми значениями или изменить в нем значения полей. Этот документ, подобно
обычному документу, участвует в репликациях, но он не может быть показан в виде. При
повторном сохранении агента разработчиком после редактирования старый
SavedData-документ агента удаляется, но вместо него создается «пустой» новый. Когда
разработчик удаляет агента, удаляется и связанный с этим агентом SavedData-документ.
«Визуально обнаружить» SavedData-документы в базе данных позволяет общедоступная
программа NotesPeek - такие документы отображаются программой «в категории» Design
ElementsYAgent Data.
Благодаря наличию таких документов могут быть созданы агенты, поведение которых
при очередном запуске зависит от результатов предыдущего запуска.
Пример ]. Предположим, что каждый продавец имеет собственную базу на сервере. Совершая акт
продажи, продавец создает в этой базе документ - ведомость продажи. Каждая ведомость имеет
автоматически генерируемый порядковый номер. В конце каждой недели ведомости за прошедшую
неделю переписываются в общий архив и удаляются из базы продавца. На следующей неделе продавец
опять заполняет ведомости продаж, но нумерация их начинается с единицы.
Этот агент запускается в конце недели, например, в воскресенье, и сравнивает максимальный
номер ведомости, созданной продавцом на текущей неделе, с максимальным номером ведомости,
созданной этим же продавцом на прошлой неделе. Агент проверяет вид, содержащий документы,
© InterTrust Со. Тел. (095) 9567928
388
Встроенные классы LotusScript u Java
заполненные продавцом за текущую неделю. Первый, отсортированный по убыванию, столбец в этом
виде содержит номер последней созданной продавцом ведомости. Поле NumLeads этой ведомости дает
количество продаж за текущую неделю. Эта величина сравнивается с количеством продаж продавца за
предыдущую неделю - оно извлекается из поля MaxLeads в SavedData-документе данного агента.
Результат сравнения заносится в поле Summary последней созданной продавцом на текущей неделе
ведомости. В конце работы агента значение поля MaxLeads в SavedData-документе обновляется. Само
«архивирование» документов за текущую неделю в тексте агента для простоты не приведено.
Sub Initialize
- • '
Dim session As New NotesSession
Dim db As NotesDatabase
Dim view As NotesView
Dim doc, agentDoc As NotesDocument
Dim d As Integer
Set db = session.CurrentDatabase
Set. view = db.GetViewf "Ведомости за текущую неделю" )
' Первый документ в виде имеет наибольший номер
Set doc = view.GetFirstDocument
Set agentDoc = session.SavedData
' При первом запуске агента его SavedData-документ
' не содержит поля MaxLeads - принимаем его равным О
If Not{ agentDoc.Hasltem( "MaxLeads" } ) Then
agentDoc.MaxLeads = 0
Call agentDoc.Save( True, True )
End If
d -" doc. NumLeads ( 0 ) - agentDoc, MaxLeads ( 0 ) If
( d > 0 ) Then
doc.Summary = Abs( d ) & " больше, чем на прошлой неделе."
Elseif ( d < 0 ) Then
doc. Summary =-= Abs ( d ) & " меньше, чем на прошлой неделе."
Else
doc. Summary = "Столько же, как и на. прошлой неделе." End
If
' сохранение макс, номера ведомости за текущую неделю 'в
SavedData-документе
agentDoc.MaxLeads = doc.NumLeads
,
.
Call doc.Save( True, True ) Call
agentDoc.Save( True, True } End Sub
Пример 2. Java-агент использует SavedData-документ для вычисления «рекордной» суммы продаж
за неделю. Каждый документ содержит поля Weeky_ Sales (сумма продаж за неделю) и Name (имя
продавца). Все такие документы содержатся в виде Weeky Sales. SavedData-документ агента имеет поля
MaxSales («рекордная» сумма продаж) и MaxSalesPerson (имя продавца-рекордсмена). Агент заменяет
значение полей MaxSales и MaxSalesPerson в SavedData-документе, если значение Weeky Sales из
документа превышает текущее значение MaxSales.
import j ava.ut il.Vector;
import java.lang.Float;
.// Java-Session/SavedData
Document agentDoc = agentContext.getSavedData();
Database db = agentContext.getCurrentDatabase( ) ; if
(!agentDoc.hasltem("MaxSales"))
{
agentDoc.replaceltemValue("MaxSales", "0");
agentDoc.save(true, true);
agentDoc = agentContext.getSavedData();
}
View view = db.getView("Weeky Sales"); Document doc =
view.getFirstDocument();
.
...
© InterTrust Co. Тел. (095) 9567928
•
Lotus Domino R. 5: @-форму.чы, LotusScript, встроенные классы LotusScript и Java
389
while (doc ! =•- null)
• -{
Vector mvalue = agent Doc.get ItemValue("MaxSales") ;
Vector wvalue = doc.getltemValue("Weekly_Sales");
Float maxSales
= new Float((String) mvalue.firstElement());
Float weeklySales = new Float((String) wvalue.firstElement());
if (weeklySales.floatValue() > maxSales.floatValue())
{
agentDoc.replaceltemValue("MaxSales",
doc.getltemValue("Weekly_Sales"));
agentDoc.replaceltemValue("MaxSalesPerson",
doc.getltemValue("Name"));
/
}
• •' •
doc.replaceltemValue("Weekly_Sales", "0") ;
doc.save(true, true);
doc = view.getNextDocument(doc);
}
.
•
:
agentDoc.save(true, true); System.out.println("Best Sales
person up-to-date is " +
agentDoc.getltemValue("MaxSalesPerson") +
" and sold $" + agentDoc.getltemValue("MaxSales"));
Свойство DocumentContext - «In-inemory-документ агента»
LotusScript:
Set notesDocument — «ofes5'ess/on.DocumentContext
Java:
Document document = &si7O77.getAgentContext().getDocumentContext()
Возвращает объект класса [Notes]Document, представляющий так называемый
«in-memory-документ» для данного агента. Свойство имеет смысл только для агента. Во всех
иных контекстах, а так же при отсутствии in-memory-документа для агента, оно возвращает
Nothing/null. При работе с таким документом в агенте нельзя пользоваться методами encrypt и
remove, а также методом compact для объекта [NotesJDatabase, полученного «от этого
документа» свойством Parent.
Принципиально дело обстоит так, что серверная или иная внешняя программа, пользуясь
средствами Notes API, может создать в виртуальной памяти документ (in-memory-документ),
«ввести» этот документ в контекст агента (вызовом функции AgentSetDocumentContext из
Notes API), а затем запустить агента. Этот агент во время своего выполнения,
воспользовавшись свойством
DocumentContext, получит доступ к данному
in-memory-докумешу и затем к содержащейся в нем информации. Практически же наиболее
часто встречаются два рассматриваемых ниже случая, в которых in-memory-документ для
агента создается программным обеспечением станции или сервера «автоматически».
Во-первых, для агента, запускаемого пользователем станции, «сама станция»
автоматически создает in-memory-документ, представляющий текущий документ в
интерфейсе пользователя.
Во-вторых, значительно более важное применение этого механизма - получение значений
CGI-переменных в агентах, запускаемых на сервере Domino из Web-броузера. Это относится
к ак к аге н та м, за п уск ае м ы м и з бро уз ер а «в р уч н ую п о ко ма нде »
@Command([ToolsRunMacro]) или по URL с операцией ?OpenAgent, так и к агентам,
запускаемым по событиям WebQueryOpen и WebQuerySave. Перед запуском такого агента
Domino Web Server (серверная задача HTTP) автоматически создает для агента
in-memory-документ, содержащий поля, имена которых совпадают с именами
CGI-переменных, а значения равны значениям этих CGI-переменных. Поэтому агент,
получив in-memory-документ свойством DocumentContext, может «добраться до» значений
CGI-переменных.
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
390
Список полей, генерируемых задачей HTTP и соответствующих CGl-переменным, дается в
таблице ниже.
Auth Type
Тип идентификации пользователя, осуществленный
сервером, например: Basic
Content, Length
Количество байт данных в запросе. Используется при
получении и обработке запроса от броузера. Эта и следующая переменные имеются
только для тех видов запросов, которые поддерживают присоединенные к запросу
данные, например, запрос POST
Content JType
Тип данных MIME для присоединенных к запросу POST или
PUT данных
Gateway_Interface
Версия спецификации CG1, например: CG3/1.1
HTTP Accept
Типы данных MIME, которые принимает клиент, как указано
в заголовках HTTP
HTTP__Referer
URL страницы, с которой пользователь «пришел сюда» HTTPS
Показывает, включена ли поддержка SSL на сервере
HTTP__User_Agent
.
Броузер, который используется клиентом, например:
Mozilla/4.0 (compatible; MSIE 4.0 1 ; Windows NT)
Pathjnfo
Путь, указанный пользователем в URL, например: ' ; ;:
:r
""
/Education/JavaLSExs.nsf/Java-Session-Web2
Path Translated
«Оттранслированный» сервером путь Path Info
Query _String
Запрос к агенту (CGI-скрипту). Запрос представляет собой .
текстовую строку, содержащую параметры запроса -соответствующую часть после
символа «?» из URL запроса
Remote_Addr
IP-адрес хоста, с которого пришел запрос
:
Remote_Host
Имя хоста, с которого пришел запрос, например:
niontsey.inttrust.ru
Remote_ldent
Идентификатор пользователя, от которого пришел запрос
Remote User
Имя пользователя, производящего запрос, например:
' "'
CN=Nikolay N. Iontsev/O=InterTrustCorp/C=SU
Request ^Method
Метод запроса к CGI-скрипту: GET, HEAD, POST и т.п.
Request_Content
Данные, передаваемые методом POST
Server_Name
Имя сервера, на котором выполняется CGI-скрипт, или его
IP-адрес
Server _Protoco!
Информация о протоколе, который броузер использует для '
связи с сервером, например: НТТР/1 .1
Server Port
Номер порта, через который броузер связывается с сервером
Server_Sofrware
Информация о программной реализации сервера,
например: Lotus-Domino/Release
Пример I. Агент на LotusScript получает значение из полей Form и Subject текущего документа в и
нтерфейсе пользователя.
© InterTrust Co. Тед. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
Dim doc As NotesDocument
Set doc = session.DocumentContext
If doc Is Nothing Then
Messagebox "Doc Is Nothing!"
Else
Messagebox "Form = " + doc.Form( 0 )
If
391
+ " Subject = " + doc.Subject ( 0 ) End
Пример 2. Java-агент получает значение из поля Subject текущего документа в интерфейсе
пользователя.
import Java.utii.Vector;
// Java-Session/DocumentContext
Document doc = agentContext.getDocumentContext();
if (doc != null)
{
Vector v = doc . get.ItemValue ( "Subject " ) ;
System.out.println("Value of 'Subject' in document
} else System, out . println ( "No document,
context");
is
"+v.toString (});
Пример З. Агент на LotusScript, выполняемый по событию WebQuerySave, выдает в броузер
подтверждающее сообщение при сохранении документа. Для работы с CGl-переменной в документе
должно присутствовать поле Remote User типа Text/Computed for display с формулой RemoteJJser.
Dim session As New NotesSession
Dim doc As NotesDocument
Set doc = session.DocumentContext
.
Dim remote As Variant
remote = doc . Remote___User (0 )
.
Print "Документ был успешно сохранен<ВК>"
Print "<Ь2>Спасибо за участие в нашем форуме,
• •
•
.
.
" + remot:e+"</h2>"
Пример 4. Агент на LotusScript со свойством Run Agent as Web user выводит «в броузер» значения
всех доступных во время его выполнения CGI-переменмых.
Dim session As New NotesSession
•
Set doc = session.DocumentContext
Prin t " < b xf o nt s ize = 5 > D is p la y c o n te x t v aria b le s </f o n tx b x br >" Forall
item In doc.items
Print "<brxb>" & item. Name & ":</b>"
If Isempty(item.Text) Then
Print "EMPTY"
Else
Print item. Text. End If
End Forall
'.
Пример 5. Java-агент со свойством Run Agent as Web user выводит «в броузер» значения всех
доступных во время его выполнения CGI-переменных.
import Java.uti1.*;
import. Java.io.*;
/'/ Java-Session-Web2
Document doc = agentContext.getDocumentContext();
PrintWriter pw = this.getAgentOutput();
if (doc == null) pw.println("No context document");
::
else
.
• ; - ,.
{
Java.util.Vector v = doc.getltems();
pw.println("Found vector with " + v.sizef) + " elements<BR>");
int i;
for (i = 0; i < v.size(); i++)
© InterTrust Co. Тел, (095) 9567928
Встроенные классы LotusScript и Java ->
392
{
.
Item item = (Item)v.elementAt(i);
pw.print("Item " + i r ": ") ;
if (item == null) pw.print("NULL");
else pw.print(item.getName() + " / " + item.getText(});
pw.println("<BR>");
}
}
3.3.2. Методы для работы с файлом NOTES.INI
Метод getEnvironmentString - «значение из NOTES.INI как строка»
LotusScript:
value = ?iotesSession.getEnvironment$trmg( nameS [, system ] )
Java:
String value = Session.getEnvironmentString(Strmg name)
String value = Session.getILn\ironmentString(Slring name, boolean system)
Позволяет получить значение переменной из файла NOTES.INS. Если выполнение
осуществляется па станции, значение извлекается из файла NOTES.INI станции, если на
сервере - из файла NOTES.INI сервера.
Параметр пате (тип String) задает имя переменной, значение которой должно быть
получено.
Параметр system не обязателен. Если задано true, метод использует в точности заданное
первым параметром имя переменной. Если задано false, метод добавляет символ "$" в начало
строки пате$ перед получением значения из файла NOTES.INI. Если параметр system
опущен, он считается равным false.
Возвращаемое значение value (типа Variant в LotusScript или String в Java) содержит
значение этой переменной, «извлеченное» из файла NOTES.INJ.
Пример 1. Скрипт получает значение переменной SIEVersionMajor из файла MOTES.INI.
Например, переменная lEVerMajor получит значение "4", если в файле NOTES.INI пользователя
имеется строка "$IEVersionMajor=~4".
Dim session As New NotesSession
Dim lEVerMajor As String
"
lEVerMajor = session.getEnvironmentStrxng( "lEVersionMajor" )
Msgbox lEVerMajor
Пример 2. Агент получает значение переменной MailServer из файла NOTES.INI. Если в файле
NOTES.INI имеется строка "MaiiServer=CN=NotesSrv400/O:r4nteiTrustCorp/C=SU", агент выведет текст
MailServer is CN=NotesSrv400/O-InterTrtistCorp/C=SU.
// Java-Session/getEnvironmentString
String ms — session.getEnvironmentString("MailServer", true);
if (ms == null) System.out.println("No MailServer");
else
System.out.println("MailServer is " + ms);
Метод getEnvironmentValue-«значение из NOTES.INI как число» . . . . . .
LotusScript:
value - notesikw/oM.getEnvironmentValuet nameS [, system ])
Java:
Object value -- Session.getEnvmmme:ntValtte(String name)
.. .
Object value - &?^/oH.getEnvironmentValue(5ltri'nЈr name, boolean system)
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: (агформулы, LotusScript, встроенные классы LotusScript и Java
393
Аналогичен методу getEnvironmentString, но используется для переменных среды,
значения которых по смыслу являются числами, Возвращается значение типа Variant в
LotusScript или класса Object в Java.
Пример 1. Если в NOTES.INI присутствуют строки "$ENVNum=75" и "TimeZone=5", при
выполнении скрипта переменная latestNumber получит значение 75, а переменная zoneNumber
-значение 5.
Dim session As New NotesSession
" Dim latestNumber As Integer
latestNumber = session.getEnvironmentValue( "ENVNum" )
Dim zoneNumber As Integer
zoneNumber = session.getEnvironmentValue( "TimeZone", True
)
Пример 2. В условиях предыдущего примера аналогичные результаты получит и агент на Java.
//
J a v a -S e s s i o n / g e t E n v i r o n me n t V a l u e
Object envnum == session.getEnvironmentValue("ENVNum", false);
if (envnum == null) System.out.println("No $ENVNum");
else
System, out:. println ( "$ ENVNum = " т envnum);
Object tz = session.getEnvironmentValue("TimeZone", true);
if ( t z == null)
System.out.println("No TimeZone"};
else
System.out.println("TimeZone = " + tz) ;
Метод setEnvironmentVar - «занесение значения в NOTES.INI»-
, .......
LotusScript:
Call n0/ЈsSe.M/on.setEnvironmentVar( name$, value [, system ] )
Java:
void Session,setEnvironmentVar(String name, Object value)
void Session.setEnvironmentVar(String name, Object value,
boolean system)
Позволяет присвоить значение переменной в файле NOTES.INI. Если выполнение
происходит на сервере, информация заносится в файл NOTES.INI сервера, если на станции
-NOTES.INI станции.
Параметр пате (тип String) задает имя переменной в файле NOTES.INI, которой должно
быть присвоено новое значение.
Параметр value (типа Variant в LotusScript или класса Object в Java) задает новое значение
для этой переменной среды. Это значение автоматически преобразуется в строку. Если же
значение не удается преобразовать в строку, метод setEnvironmentVar в LotusScript
генерирует ошибку "Environment variables must be strings, dates, or integers", а в Java
-возбуждает соответствующее исключение.
Параметр system не обязателен. Если задано true, метод использует в точности заданное
первым параметром имя переменной среды. Если задано false, метод автоматически
добавляет символ "$" в начало строки пате перед занесением значения в файл NOTES.INI.
Если параметр system опущен, он считается равным false.
Если переменная с именем пате уже существует в файле NOTES.INI, она получает новое
значение. В противном случае в файл NOTES.INI добавляется новая переменная с именем
пате и ей присваивается значение. Чтобы удалить соответствующую переменной строку из
файла NOTES.INI, достаточно присвоить этой переменной пустую строку ("").
Пример 1. Скрипт присваивает .переменной SHomeTown значение "Moscow". После выполнения
скрипта в файле NOTES.INI можно обнаружить строку "$HomeTowiv=Moscow".
Dim session As New NotesSession
Call session.setEnvironmentVar( "HomeTown", "Moscow" )
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
394
Пример 2. Java-агент присваивает переменной SHomeTown значение "Moscow" и заменяет
значение переменной MailServer на MCN^Dommo500/t>4nterTrustCorp/C=SU".
// Java-Session/setEnvironmentVaiue
session,setEnvironmentVar("HomeTown", "Moscow", false);
session.setEnvironmentVar("MailServer",
"CN=Domxno500/O=InterTrustCorp/C=SU", true)
3.3.3. Методы для создания объектов-потомков
Метод getDbDirectory - «создать объект [NotesJDbDirectory»
LotusScript:
Java:
Set notesDbDirectory = notesSession,geiDb1i)irectory( server$ )
DbDirectory dbDir •= Session,getDbDirectory(String server)
Создает новый объект класса [NotesjDbDirectory, используя при этом заданное
параметром server (тип String) имя сервера, к списку баз на котором необходимо получить
доступ. Если в качестве значения параметра задана пустая строка (""/null), обеспечивается
доступ к списку локальных баз. При ПОРччперациях параметр должен задаваться равным
null. Подробности даются в описании класса [Notes]DbDirectory.
Пример I. Скрипт находит и открывает первый шаблон базы на сервере Domino/Org/RU,
Dim session As New NotesSession
Dim directory As NotesDbDirectory
Dim db As NotesDatabase
Set directory = session.getDbDirectory{ "Domino/Org/RU"
Set db = directory.getFirstDatabase( TEMPLATE )
Call db.open( "", "" }
-. >
:' .
)
Пример 2. Java-агент выводит список имен всех расположенных локально баз.
/'/ Java-Session/getDbDirectory
DbDirectory dir = session.getDbDirectory("");
--•
String Server = dir.getName();
if (Server == null) Server = "Local";
System.out.println("Database directory list on server " + Server + "\n"};
Database db = Dir.getFirstDatabase(DbDirectory.DATABASE);
while (db != null)
i
-.
String fn = db.getFileName();
String title = db.getTitle();
System.out.println(fn.toUpperCase() + " - " + title);
db — Dir.getNextDatabase() ;
'
}
М.етод getDatabase - «создать объект [Notes] Database»
LotusScript:
Java:
:
,
• ...........
Set notesDatabase ~ notesSes'sion.geiDatabase( server$, db/ileS )
Database db = Session.getDatabase(Sfring server, String dbfile)
Database db = Session,getDatabase(String server, String dbfile,
boolean createonfail)
Создает объект класса [NotesJDatabase, используя при этом заданное параметром server
(тип String) имя сервера и заданное параметром dbfile (тип String) имя файла базы, и, если это
удается, открывает базу. Если в качестве значения параметра server задана пустая строка
(""/null), предполагается, что база расположена локально на компьютере - сервере или
станции. При ПОР-операциях параметр server должен задаваться равным null. Если в
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: (^-формулы, LotusScript, встроенные классы LotusScript и Java
395
качестве значений обоих параметров server и dbfile заданы пустые строки (""/null),
предполагается, что база будет открыта позже. Если указанная параметрами база существует,
возвращаемый объект класса [Notes]Database будет открыт. Если же база не существует,
возвращаемый объект в LotusScript будет закрыт, а в Java вообще не будет создан
-возвращается null. Однако, если в Java использовать метод с параметром createonfail, равным
true, то объект класса Database создается, даже если указанная база не существует или ее не
удалось открыть. Сам метод getDatabase новой базы не создает - для создания новой базы
необходимо нужно воспользоваться одним из методов класса [Notes]Database,
Дополнительные подробности даются в описании класса [Notes]Database.
Пример 1. Если база plan.nsf существует на сервере Domino/Org/RU и доступна, она будет открыта,
Тогда в диалоговом окне появится название этой базы.
Dim session As New NotesSession
Dim db As NotesDatabase
Set db = session.GetDataba.se ( "Domino/Org/RU", "plan, nsf" )
Messagebox ( db. Title )
Пример 2. Java-агент выведет название базы names.nsf, если эта база существует на сервере
Domino/Org/RU и доступна.
Database db = session.getDatabase("Domino/Org/RU", "names,nsf");
System.out.printin(db.getTitle ()};
Метод getlJRLDatabase - «создать объект Database для Web Navigator»
Java:
Database db = 5e»7o«.getURLDatabase()
Создает объект класса Database, представляющий базу данных Web Navigator. Это может
быть база данных WEB.NSF на сервере, «несущем» серверную задачу WEB, или
«клиентская)) база Web Navigator.
Метод resolve - «создать объект, имеющий заданный URL»
Java:
Base obj - Scssion.resolve(String url)
Возвращает объект Domino классов Database, View, Form, Document или Agent, имеющий
URL, заданный строкой url. Метод имеет смысл только для «удаленной (ПОР) сессии». В
«локальной сессии» будет возбуждено исключение "Not implemented".
Метод createRegistration - «создать объект [NotesJRegistration»
LotusScript:
Set notesRegistration = New NotesRegistration
Java:
Registration variableName — se$sion.crenteRegistration()
В Java создает новый объект класса Registration. В LotusScript объект класса
NotesRegistration получают методом New. Подробности даются в описании класса
|NotesJRegistration.
Метод createRichTextStyle - «создать объект [NotesJRichTextStyle»
LotusScript:
Set notesRichTextStyle = notesSession.cresiteRicliTe\iStyle( )
Java:
RichTextStyle rtsObj = &5,y/o/7.createRichTextStyle()
Создает новый объект класса [NotesJRichTextStyle. Объект этого класса позволяет
управлять -«шрифтовым оформлением» поля типа RichText. Подробности даются в описании
класса [NotesJRichTextStyle.
© InterTrust Со. Тел. (095) 9567928
Встроенные классы LotusScript и Java
396
© Метод createRiehTextParagraphStyle - «создать объект
[NotesJRichTextParagraphStyle»
LotusScript:
Set notesRichTextParagraphStyle =
w0/e.SiS'eASK»7.createRichTextParagraphStyle()
Java:
^~'
RichTextParagraphStyle psObj =:- ,Skw70w.createRichTextParagraphStyIe()
Создает новый объект класса [NotesJRichTextParagraphStyle. Объект этого класса
позволяет управлять «оформлением» абзацев в поле типа RichText. Подробности даются в
описании класса [NotesJRichTextParagraphStyle.
Метод createNewsietter - «создать объект [NotesJNewsletter»
LotusScript:
Set notesNewsletter = notesSession.createNewsletter(
notesDocumentCoUection )
Java:
Newsletter nl = Ses'sion,crea.teNewsletter(DocumentCoIfection collection)
Создает новый объект класса [NotesJNewsletter, содержащий заданную в качестве
параметра коллекцию документов (объект класса [NotesjDocumentCoilection), Подробности
даются в описании класса [NotesJNewsletter.
Метод createLog - «создать объект [NotesJLog»
,
••.•.
LotusScript:
Set notesLog ~ notesSession.ereateLog( name$ )
Java:
Log log - Session.createLiOg(String name)
Создает новый протокол - объект класса [NotesJLog с именем, заданным параметром
пате (тип String). Подробности даются в описании класса [NotesJLog.
Пример I. Скрипт создает протокол с именем "Checkup Agent".
Dim session As New NotesSession
Dim log As NotesLog
Set log = session. createLog ( "Checkup Agent," )
Call log.openMailLog ( "Nikolay N. lontsev", "Log for Checkup Agent" ) Call
log.close
Пример 2. Java-агент создает протокол с именем ''Checkup Agent".
// Java-Sess.ion/createLog
Log log — session.createLog("Checkup Agent");
log.openMailLog("Nikolay N. lontsev", "Log for checkup agent");
log.close(};
© Метод createName - «создать объект [NotesJName»
LotusScript:
Set notesName ~ notesSession.crcuteName( nameS )
Java:
Name nameObj -= Session.cre'AteName(String name)
• • •. . . .
.. ,
Name nameObj = Session,createName(String name, String Jang)
Создает новый объект класса [NotesJName, используя при этом заданное строкой пате
имя пользователя или сервера. Строка long задает язык, ассоциированный с именем
пользователя. Подробности даются в описании класса [NotesJName.
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
398
3.3.4. Прочие методы
Метод updateProcessedDoc - «отметка документа об обработке агентом»
LotusScript:
Java:
Call notesSession.apdateProcess&dDuc( notesDocument)
. vo/^.9eM/o«.getAgentContext().update.ProcessedDoc(Z)0CMmew/ doc)
Отмечает документ, заданный параметром метода, как «обработанный этим агентом».
Метод используется лишь в агентах, которые обрабатывают только созданные или
модифицированные после времени предыдущего выполнения данного агента документы. Во
всех иных случаях данный метод не выполняет никакого действия.
В агенте, обрабатывающем только созданные или модифицированные после времени
предыдущего выполнения данного агента документы, для отбора таких документов должны
использоваться свойство UnprocessedDocuments или методы unprocessedFTSearch или
unprocessedSearch. Эти свойство и методы аналогичны в LotusScript и Java, но в LotusScript
они являются членами класса NotesDatabase, тогда как в Java - членами класса AgentContext.
Все они рассматриваются в 3.5. Однако для того, чтобы эти свойство и методы могли
находить еще необработанные данным агентом документы, после завершения обработки
каждого документа агент «должен отметить документ как обработанный», вызвав метод
updateProcessedDoc. Если же агент не вызывает метод updateProcessedDoc для отметки
документов как уже обработанных, свойство UnprocessedDocuments будет возвращать
коллекцию всех документов из базы, а методы unprocessedFTSearch и unprocessedSearch
будут возвращать все удовлетворяющие заданному критерию отбора документы, не учитывая
при этом, что некоторые из этих документов уже были обработаны при предыдущем запуске
агента.
Для каждого из агентов, использующих метод updateProcessedDoc, в документе создается
уникальная отметка об обработке агентом. Иными словами, если агент А отмечает документ
как обработанный, то для агента В эта отметка (что документ был обработан агентом А) не
доступна, а потому не имеет никакого значения. Для агента В доступна и имеет значение
только отметка об обработке этого документа агентом В.
Пример 1. Агент на LotusScript при очередном запуске обрабатывает только те документы, которые
были созданы или модифицированы после предыдущего запуска этого агента. Свойство
UnprocessedDocuments возвращает коллекцию таких документов. Коллекция просматривается агентом
в цикле. Каждый документ из коллекции методом updateProcessedDoc отмечается как «уже
обработанный агентом». Собственно сама обработка документа в этом примере не приведена,
поскольку требует привлечения ещё не рассмотренных нами методов классов NotesDocument и
Notesltem.
Sub Initialize
Dim session As New NotesSession
Dim db As NotesDatabase
Dim collection As NotesDocumentCollection
Dim doc As NotesDocument
Set db = session.curreritDataba.se
Set. collection = db. UnprocessedDocuments
For j = 1 To collection. Count-Set doc = collection.
getNtliDocument ( j ) Call
session.updateProcessedDoc( doc )
Next-En
d Sub
;
Пример 2. Java-агент реализует те же действия, что и агент на LotusScript из предыдущего примера.
// Java-Session/updateProcessedDoc
Document-Collection collection ~ agentContext. getUnprocessedDocuments () ;
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: ®-формулы, LotusScript, встроенные классы LotusScript и Java
399
Document doc;
int size = collection.getCount();
for (int i = 1; i <= size; i++)
{
.
doc = collection.getNthDocument{i);
agentContext.updateProcessedDoc(doc);
}
;
-.
•
'
Метод evaluate- «вычислить @-формулу» LotusScript:
evaluate (formula$ [ , notesDocument ] )
Variant = evaluate (formulas [, notesDocument ] )
Java:
java.util. Vector v = session.e\'alunte(String formula)
java.util. Vector v = aession.evaluate(Slring formula, Document doc)
Метод имеется только в Java - в LotusScript аналогичное действие выполняется
оператором или функцией Evaluate самого языка.
Метод выполняет @-формулу Notes, заданную строкой formula. Если формула имеет
смысл только «в контексте документа» (например, она использует информацию из полей
документа, определяет дату создания или модификации документа и пр.), следует
использовать метод с двумя параметрами, где doc является объектом класса Document,
представляющим необходимый документ. Возвращаемое значение является объектом класса
java.util.Vector, содержащим результат вычисления формулы. В случае, если формула
возвращает скалярное значение, результат содержится в первом элементе объекта
java.util. Vector.
@-формула не должна «предпринимать попыток» изменить обрабатываемый ею
документ - допустимо только извлечение информации из документа. @~функции,
выполнение которых возможно только в интерфейсе пользователя (@Command,
@DbManager, @DbName, @DbTitle, @DDEExecute, @DDEInitiate, @DDEPoke,
@DDETerminate, @DialogBox, @PickList, @PostedCommand, @Prompt и @ViewTitle) не
выполняются методом evaluate.
Пример. В документах имеется поле Amount, которое может содержать список числовых значений.
Java-агент выводит для каждого документа сумму всех элементов из его поля Amount.
import j ava.ut i1.*;
// Java-Session/evaluate
Database db = agentContext.getCurrentDatabase();
DocuinentCollection dc = db. getAHDocuments () ;
Document doc;
System, out .println ( "Count - " + dc.getCount ());
for (int j = 0; j < dc.getCount{); j++)
{
doc ~ dc.getNthDocument(j);
Vector v = session.evaluate("@Sum(Amount)", doc);
System.out.println(v.firstElement()+" 'M-doc.getltemValue("Subject"));
}
Метод freeTimeSearch - «поиск отрезка свободного времени»
LotusScript:
Set notesDateRange = notesSession.freeTimeSe%rch( window,
duration, names [, firstfit])
Java:
/ava. utiL Vector dr Session.fi"eeTimeSea,rch(DateRange window,
int duration, Object names, boolean firstfit)
©InterTrustCo. Тел. (095) 9567928
400
'
Встроенные классы LotusScript и Java
Выполняет поиск отрезка свободного времени заданной продолжительности для
указанных пользователей в заданном «окне поиска». Параметр window (объект класса
[Notes] Date Range) задает отрезок времени, на котором выполняется поиск отрезков
свободного времени необходимой продолжительности duration (тип Integer/int) минут для
пользователей или групп, чьи имена заданы параметром names (в LotusScript строка или
массив строк, в Java - объект класса String или объект класса java.util.Vector с элементами
класса String). Возвращается «массив» возможных отрезков свободного времени (в
LotusScript массив объектов класса NotesDateRange, в Java - java.util.Vector с элементами
класса DateRange). Если найти отрезок свободного времени не представляется возможным, в
Java будет возвращен null, а в LotusScript - массив, первый элемент которого является
«пустым объектом» (Nothing). Если параметр firstfit равен true, метод возвращает «в массиве»
только первый возможный отрезок свободного времени, если false (в LotusScript это значение
по умолчанию) - все возможные отрезки свободного времени.
Пример. Скрипт выполняет поиск «в окне» продолжительности в одни сутки 60-минутного отрезка
свободного времени для возможной встречи трех пользователей. Когда последний параметр метода
задан равным False, результат может быть следующим:
1:
2:
3:
4:
5:
[09.03.99
[09.03.99
[10.03.99
[10.03.99
[10.03.99
10:00:00
13:00:00
09:00:00
13:00:00
16:00:00
ZE3,
ZE3,
ZE3,
ZE3,
ZE3,
09.03.99
09.03.99
10.03.99
10.03.99
10.03.99
12:00:00
17:00:00
12:00:00
15:00:00
17:00:00
ZE3]
ZE3]
ZE3]
ZE3]
ZE3]
Если в тех же условиях последний параметр метода выбран равным True, то из предыдущего
останется только первый вариант.
Dim session As New NotesSession
Dim window As NotesDateRange
Set window i: session. CreateDateRange ()
Dim startDateTime As New NotesDateTime("Today")
Set. window. StartDateTime = startDateTime
Dim endDateTime As New NotesDateTime("Tomorrow")
Set window.EndDateTime = endDateTime
Dire names(1 To 3} As String
names(1) = "Andre A. Linev/InterTrustCorp/Su"
names(2) = "Nikolay N. lontsev/InterTrustCorp/SU"
names(3) = "Vladimir A. Panov/InterTrustCorp/SU"
Dim freeTime As Variant
freeTime = session.FreeTimeSearch(window, 60, names, False)
If (freeTime(0) Is Nothing) Then
Messagebox "Нет свободного времени"
Else
i-1
Dim b As New NotesDateTime("")
Dim e As New NotesDateTime("")
E'orall x In freeTime
Set b = x.StartDateTime
Set e = x.EndDateTime
Messagebox Str(i) & " [" & b.LocalTime & ", " & e.LocalTime & "]"
i = i+1
End Forali
End If
"
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: (а^-формулы, LotusScript, встроенные классы LotusScript и Java
401
3.4. «Множество баз» - класс [Notes] DbDirectory
Представляет множество баз данных на сервере Domino или станции Notes. Это базы
данных, находящихся в каталоге данных, рекурсивно в его подкаталогах, всех доступных
Directory Link's и рекурсивно их подкаталогах. Directory Link - текстовый файл с
расширением .DIR в каталоге данных или его подкаталоге, который содержит в первой
строке полное название каталога с базами, иного, чем каталог данных, а в остальных строках
может содержать список пользователей и групп, имеющих доступ к базам в этом каталоге.
Такая возможность удобна в случае, когда диск, на котором находится каталог данных
сервера, «переполнен», но имеется другой свободный диск, или когда просто необходимо
разграничить доступ пользователей сразу к целым семействам баз.
Методы [NotesJDbDirectory позволяют «просматривать в цикле» представленное
объектом множество баз и получать из него любую нужную базу - объект класса
[NotesJDatabase. Кроме того, в классе DbDirectory (Java) имеются методы для создания новых и
«открытия» существующих баз. Аналоги этих методов для LotusScript «располагаются» в
классе NotesDatabase.
«Контейнерная иерархия»
Как в LotusScript, так и в Java для получения объекта класса [NotesJDbDirectory обычно
используется метод getDbDirectory класса [NotesJSession.
LotusScript:
Set notesDbDirectory = «0/esYSew/ow.getDbDirectory( serverNameS )
Java:
DbDireclory DbDir = Session.gefDbDirectory(String serverName)
Кроме того, в LotusScript для создания объекта класса NotesDbDirectory можно
использовать метод New.
Dim variableName as New NotesDbDirectory( serverName$ )
или Set
notesDbDirectory — New NotesDbDirectory( serverNameS )
Параметр serverName (тип String) задает имя сервера, к множеству баз на котором
необходимо получить доступ. Пустая строка (""/null) обозначает множество баз на локальном
компьютере. Однако при ТЮР-обращениях параметр serverName должен задаваться равным
null.
Пример. Скрипт получает доступ к множеству баз на сервере NotesSrv400/InterTrustCorp/SU,
находит там первый шаблон базы и открывает его.
Dim directory Аз NotesDbDirectory
Dim db As NotesDatabase
Set directory = New NotesDbDirectory( "NotesSrv400/InterTrustCorp/SU" )
Set db = directory.GetFirstDatabase( TEMPLATE )
Call db.Open( " " , " " )
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
402
3.4.1. Свойства
@ Свойство Parent-«родитель»
Java:
Session session = Z)/?/)/reetory.getParent()
Возвращает «своего родителя» - объект класса Session, содержащий данный объект
класса DbDirectory.
Свойство Name - «имя сервера»
.
LotusScript:
serverNameS ~ notesDbDirectory.Name
Java:
String serverName - DbDirectory.geiNameQ
••••••- . . .
• • . •••.•. .
Возвращает имя сервера (тип String), на котором находится множество баз,
представляемое объектом - т.е. то значение, которое было задано при создании объекта
методом New или getDbDirectory. Если объект представляет множество баз на локальном
компьютере, возвращается пустая строка.
3.4.2. Методы для навигации по множеству баз
Метод getFirstDatabase - «первая база из множества» .......... '
'
LotusScript:
Set notesDatabase - wofesD6.D/rectory.getFirstDatabase( dbType% )
Java:
Database db = DbDirectory.geiFir$tDutabase(int dbType)
.'..
:
1}озвращает объект класса [Notes]Database, представляющий первую базу указанного
параметром dbType типа из множества баз, к которому применяется метод. Параметр dbType
(константа типа Integer/int) может быть одним из следующих:
*
DATABASE/DbDirectory.DATABASE - любая база Notes (.nsf, .nsg, .nsh);
*
TEMPLATE/DbDirectory.TEMPLATE - любой шаблон базы "Notes (.ntf);
*
REPLlCA_CANDIDATE/DbDirectory.REPLICA..CAMDIDATE - любая база Notes или
шаблон базы, для которых не запрещены репликации;
*
TEMPLATE_CANDIDATE/DbDirectory.TEMPLATE_CANDIDATE - любая база, которая
может быть шаблоном.
Возвращаемый объект класса [NotesjDatabase будет закрыт. В случае, если множество баз
пустое, возвращается Nothing/null.
Учтите, что каждый вызов метода заново выполняет относительно продолжительный
процесс сканирования содержимого каталогов.
Метод getNextDatabase - «следующая база .из множества». ,.:.- •;•; ••;••'• '•••'/ •:": ~ :
LotusScript:
Set notesDatabase - notesDbDirectory.geiNe\tDataba$e
Java:
Database db - /J&D/rectory.getNextDatabaseO
Возвращает следующий объект класса [NotesjDatabase заданного при предшествующем
вызове метода getFirstDatabase типа из множества баз, к которому применяется метод.
Возвращаемый объект класса [NotesjDatabase, как и в предыдущем методе, будет закрыт.
Когда все базы «уже просмотрены», возвращается Nothing/null.
© InterTrust Со, Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
403
Пример 1. Скрипт выводит в окне полные имена файлов всех имеющихся на сервере баз.
Dim directory As NotesDbDirectory
Dim db As NotesDatabase
server$ = "NotesSrv400/InterTrustCorp/SU"
Set directory - New NotesDbDirectcry( server$ )
dbType% = DATABASE
Set db = directory.GetFirstDatabase ( dbType% )
counter* =0
While Not ( db is Nothing }
counter% = counter% + 1
Messagebox Cstr (counterl;) + " : " + db . FilePath, , server-?
S et d b = dire ctor y .G etN e xtD ata base
Wend
•Messagebox "Обнаружено " + Cstr(counterl) + " баз",,servers
Пример 2. Java-агент выводит список имен файлов, названий и времен модификации для всех
имеющихся на локальном компьютере шаблонов.
// Java-- DbDi г ее tor у/ get. FirstNext Database
DbDirectory Dir = session . getDbDirectory (null) ;
System.out.println("Local templates\n"};
Database db = Dir.getFirstDatabase(DbDirectory.TEMPLATE);
while (db != null)
r
i
System.out.println(db.getFileName()+" "+db.getTemplateName());
db.open(};
•
System.out.println(" LastModifled: " t
db.getLastModified().getLocalTime());
'
db = Dir.getNextDatabase();
.
..
.
3.4.3. Методы для создания и «открытия» баз в Java
Метод ereateDatabase - «создать новую базу»
.
.
•-•••.-:• .-.';.-..•.
•:/.-. .
LotusScript:
Call notesDatabase.creatc( server$, dbfileS, openFlag )
Java:
Database db = DbDirectory.cre'AteDatabase(String dbfile}
Database db - D^Ј>/rectory.createDatabase(5?r/ng dbfile, boolean open)
Метод createDatabase создает на диске сервера или станции (смотря по тому, что
представляет объект DbDirectory) файл новой базы данных с именем dbfile. Возвращается
объект класса Database, представляющий созданную базу данных, или null, если ее не
удалось создать. Поскольку новая база создается без выбора шаблона - по «шаблону -Blank-» она не будет содержать элементов дизайна, кроме одного «безымянного» вида. Если
использован вариант метода с одним параметром или параметр open равен false,
возвращаемый объект класса Database будет закрыт. Если параметр open равен true, метод
дополнительно предпринимает попытку открыть базу.
Метод openDatabase - «открыть базу»
LotusScript:
flog — notesDatabase.open( server$, dbflle$ )
Java:
Database db = DbDirectory,openD&tab'Ase(String dbfile)
Database db = DbDirectory.openDatabuse(String dbfile, boolean failover)
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
404
Метод openDatabase открывает существующую на сервере или станции (смотря по тому,
что представляет объект DbDirectory) базу данных с именем dbfile. Возвращается объект
класса Database, представляющий эту базу данных, или null, если файл базы не существует
или открыть его не удалось. Для открытой базы данных доступны все свойства и методы.
Вариант метода с двумя параметрами ориентирован на применение в кластере. Если
параметр failover равен true, и базу не удалось открыть на том сервере-члене кластера,
который представлен объектом DbDirectory, предпринимается попытка открыть реплику этой
базы на другом сервере-члене кластера. Если все удалось, то свойства Server и FilePath
объекта Database будут содержать информацию о сервере и имени файла той реплики базы,
которая была действительно открыта.
Пример. Java-агент открывает локальную базу names.nsf и выводит ее название.
// Java-DbDirectory/openDatabase
DbDirectory Dir = session.getDbDirectory("");
Database db = Dir.openDatabase("names.nsf");
System.out.println(db.getTitle()) ;
—-—--.
Метод openDatabaseByReplkalD - «открыть базу по идентификатору
реплики»
. .
;.':/;'•'.•'":.•"'
LotusScript:
flag = w/es'Z>rfa/>ase.openByRep!icaID( server$ , replicaID$ )
Java:
Database db = Z)^D/rectorv.openDatabaseByRepIicaID(Sr/«g replicalD)
Метод openDatabaseByReplicalD открывает существующую на сервере или станции
(смотря по тому, что представляет объект DbDirectory) базу данных с заданным параметром
replicalD идентификатором реплики. Возвращается объект класса Database, представляющий
эту базу данных, или null, если файл базы с таким идентификатором реплики не существует
или открыть его не удалось. Для открытой базы данных доступны все свойства и методы.
Пример. Java-агент открывает локальную базу по идентификатору реплики.
// Java-DbDirectory/openDatabaseByReplicalD
DbDirectory Dir= session.getDbDirectory(null);
String rid = "8b2564D2000B5144";
Database db = Dir. OpenDatabaseByReplicalD(rid) ;
if (db ! --- null)
System.out.println("HELP was located and opened");
else
System.out.println("HELP was not found");
. . .
•>
Метод openDatabaselfModified - «открыть базу, если была модифицирована»
LotusScript:
flag = notesDatabase.openlfModitied( serverS, dbfileS, notesDateTime )
Java:
Database db ~ DbDirectory,openJ)atabiiselfModiued(String dbfile,
Date Time date)
Метод openDatabaselfModified открывает существующую на сервере или станции (смотря
по тому, что представляет объект DbDirectory) базу данных с именем dbfile, если время
последней модификации этой базы не ранее заданного параметром date времени (объект
класса DateTime). Возвращается объект класса Database, представляющий эту базу данных,
или null, если файл базы не существует, ее не удалось открыть или она не была открыта,
поскольку не была модифицирована после заданного времени. Для открытой базы данных
доступны все свойства и методы.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: (a^f-формулы, LotusScript, встроенные классы LotusScript и Java
405
Пример. Java-агент определяет, была ли общая адресная книга модифицирована за последние 3
часа.
// Java-DbDirectorу/openDatabaseIfModified
DbDirectory Dir = session.getDbDirectory("Domino500/InterTrust.Corp/SU");
DateTime dt = session . createDateTirne ( "Today" } ;
dt.setN.ow() ; dt. adjust.Hour (-3) ;
Database db = Dir . openDatabaselffModif iecl( "names . rxsf" , dt) ;
if (db != null)
System.out.println("Database has been modified in the past 3 hours"); else
System,out.println("Database hasn't been modified in the past 3 hours");
Метод openMailDatabase - «открыть почтовый ящик»
LotusScript:
Call notesDatabaae.openMail
Java:
Database db - D&D/m'/ory.openMailDatabaseQ
Метод openMailDatabase открывает «почтовый ящик» текущего пользователя.
Возвращается объект класса Database, представляющий эту базу данных, или null, если файл
базы не существует или ее не удалось открыть.
Метод может вызываться, во-первых, из агента или приложения, работающего на
станции пользователя, во-вторых, из агента, работающего на почтовом сервере
пользователя-«владельца агента», и в третьих, из приложения или апплета, выполняющего
ПОР-вызовы к почтовому серверу пользователя. Если метод вызван на станции, то почтовый
сервер пользователя и имя файла его почтового ящика устанавливается по информации из
локального файла NOTES.INI. Если же метод вызван из агента, выполняющегося на сервере, то
«владельцем агента» считается тот, кто последним модифицировал агента, а почтовый сервер
и файл почтового ящика этого субъекта определяется по информации из общей адресной
книги, расположенной на этом сервере. При использовании ИОР-операций текущим
пользователем считается тот, кто «открыл сессию», а местоположение его почтового ящика
устанавливается по информации из общей адресной книги, расположенной на этом сервере.
Если оказывается, что почтовый ящик находится на друго м сервере, возбуждается
исключение, поскольку сервер не может открыть базу данных на другом сервере.
Пример. Java-агент выводит информацию о почтовом ящике текущего пользователя.
// Java-DbDirectory/openMailDatabase DbDirectory
Dir = session.getDbDirectory(null); Database db =
Dir.openMailDatabase( ) ;
DocumentCollection dc -- db.getAllDocuments();
System.out.println("Mail database : " + db.getTitle() + " is " +
,(db. getSize () /1024) + "KB long arid has " + dc. getCount () + " documents");
/
© InterTrust Co. Тел. (095) 9567928
406
Встроенные классы LotusScript и Java
3.5. «База данных» и «контекст агента» - классы [NotesfDatabase и
Agen (Context
Объект этого класса представляет базу данных Notes. Свойства объекта класса
[Notes]Database позволяют получать доступ к содержащимся в базе объектам: списку
управления доступом (ACL), агентам, коллекции из всех документов, видам,
необработанным агентами документам, а также контролировать свойства самой базы:
идентификатор реплики, сервер размещения, путь и имя файла, размер базы, максимальный
размер и величину неиспользуемого пространства, название базы, категории, название
дизайн-шаблона (если база сама является шаблоном или наследует дизайн с другого
шаблона), дату-время создания и модификации, наличие индекса полнотекстового поиска и
дату-время последнего изменения этого индекса, текущий уровень доступа пользователя,
список менеджеров, и, наконец, является ли база общей или личной адресной книгой и
открыта ли она. Методы объекта класса [Notes]Database позволяют открывать базу
несколькими способами, создавать новую базу (пустую или по нужному дизайн-шаблону),
создавать новую копию или реплику базы, инициировать репликацию базы с заданным
сервером, удалять базу, уплотнять базу, обновлять индекс полнотекстового поиска,
выполнять запрос полнотекстового поиска или запрос с формулой отбора и получать
коллекцию удовлетворяющих запросу документов (включая или не включая ранее
обработанные агентом документы), находить документ по идентификатору документа или, в
базе Web Navigator, по универсальному указателю ресурса, создавать в базе новый документ,
получать доступ к виду по его имени, определять или изменять уровень доступа к базе
любого субъекта.
«Контейнерная иерархия»
LotusScript
NotesSession ~>
NotesDatabase
— > NotesACL NotesDbDirectory
NotesAgent
NotesU [Database
NotesView New
NotesForm NotesOutline NotesDocument NotesDocumentCollection NotesReplication
NotesDatabase NotesSession Java
1
Session _>
Database
— > ACL
AgentContext
Agent DbDirectory
View
Form Outline Document Documented lection Replication DataTime Database 1
Session
Для создания нового или получения доступа к существующему объекту класса
[Notes']Database возможны следующие пути:
• для доступа к существующей базе, если известны имена сервера и файла базы,
используют метод New или метод! getDatabase класса [NotesjSession
€> InterTrust Co, Тел. (095) 9567928
Lotus Domino R. 5: (al-формулы, LotusScript, встроенные классы LotusScript и Java
•
•
•
•
•
•
•
•
•
•
407
для доступа к базе, в которой выполняется скрипт или Java-агент, не указывая явно имен
сервера и файла базы, удобно использовать свойство CurrentDatabase класса
NotesSession/AgentContext
для доступа к существующей базе, когда известен ее идентификатор реплики,
используют
метод
openByReplicalD
класса
NotesDatabase
или
метод
openDatabaseByReplicalD класса DbDirectory
для доступа к существующей базе, когда известен только «несущий» её сервер, но не
известно имя файла, используют методы класса [TMotesJDbDirectory
для доступа к почтовому ящику текущего пользователя используют метод openMail
класса NotesDatabase или метод openMailDatabase класса DbDirectory
чтобы открыть базу Web Navigator, применяют метод openURLDb класса NotesDatabase
или openURLDatabase класса Session
для доступа к адресным книгам рациональнее использовать свойство AddressBooks
класса [Notes]Session
для проверки существования базы на заданном сервере можно воспользоваться
свойством IsOpen или методами open или openlfModified класса NotesDatabase или
openDatabase или openDatabaselfModified класса DbDirectory
для создания новой базы на основе существующей базы предназначены методы
createCopy, createFromTemplate, createReplica класса [Notes]Database
для создания новой пустой базы служит метод create класса NotesDatabase или метод
createDatabase класса DbDirectory
для доступа к базе из объектов классов [Notes] View, [Notes] Document,
[Notes]DocumentCollection, [NotesjACL или [Notes]Agent используют свойство Parent или
ParentDatabase.
Метод New создает в виртуальной памяти новый объект класса NotesDatabase,
представляющий базу данных на указанном сервере и в указанном файле (а не новую базу!), и,
если это возможно, открывает эту базу.
Dim variableName As New NotesDatabase( server$, dbfde$ )
или Set
notesDatabase — New NotesDatabase( server$, dbflleS )
Параметр serverS (тип String) - имя сервера или пусто (""), если база находится на том же
компьютере, на котором выполняется скрипт. Параметр dbfileS (тип String) задает путь и имя
файла базы. Если база расположена не в каталоге данных Notes, нужно указывать полный
путь. Если оба параметра dbfileS и server$ заданы пустыми, предполагается, что они будут
заданы позже, при открытии базы. Возвращаемое значение notesDatabase - объект класса
NotesDatabase. Если база на сервере serverS в указанном файле dbfileS существует, метод
открывает объект класса NotesDatabase, и вам будут доступны все свойства и методы класса.
Если же база в указанном месте не существует, объект класса NotesDatabase закрыт, и вам
будут доступны лишь немногие свойства и методы класса.
Все свойства и методы класса [NotesJDatabase доступны только после того, как объект
[NotesJDatabase будет открыт. В большинстве случаев это происходит автоматически.
Открытие объекта не произойдет лишь в следующих случаях:
•
•
Агент выполняется на сервере и пытается открыть базу на другом сервере. Возникает
ошибка или возбуждается исключение.
Скрипт или Java-приложение пытаются открыть базу, к которой они не имеют
необходимого уровня доступа. Возникает ошибка или возбуждается исключение.
Необходимо иметь по крайней мере доступ читателя к открываемой базе.
© InterTrust Co. Тел. (095) 9567928
408
Встроенные классы LotusScript и Java
•
Объект [NotesjDatabase, полученный из объекта ["NotesJDbDirectory, исходно закрыт. Для
полученного таким способом закрытого объекта [Notes]Database доступны только его
свойства Categories, Delay-Updates, DesignTemplateName, FileName, FilePath. IsOpen,
Parent, ReplicalD, Server, SizeQuota, TemplateNatne, Title. Чтобы пользоваться всеми
свойствами и методами, нужно явно открыть базу.
•
Объект [Notes] Data base, полученный свойством AddressBooks из объекта класса
[Notes]Session, исходно закрыт. Для полученного таким способом объекта доступны
только свойства FileName, FilePath, IsOpen, IsPrivateAddressBook, IsPublicAddressBook,
Parent, Server. Чтобы пользоваться всеми свойствами и методами, нужно явно открыть
базу.
•
Объект NotesDatabase, полученный методом New, будет закрыт, если базы нет в
указанном параметрами server^ и dbfileS местоположении. Для такого объекта доступны
лишь свойства FileName, FilePath, IsOpen, Parent и Server.
Под уровнем доступа скрипта или Java-приложения к базе понимается возможность
открыть базу и читать документы, создавать документы, модифицировать или удалить
документы, изменить ACL и т.п. Под уровнем доступа агента к серверу понимается его
возможность выполняться на сервере - она регламентируется в документе Server из общей
адресной книги.
Когда скрипт или Java-приложение выполняются на станции пользователя, их уровень
доступа к базе совпадает с уровнем доступа к этой базе пользователя, под ID-файлом
которого работает станция, а при «удаленных» (НОР) обращениях к серверу - совпадает с
уровнем доступа к этой базе аутентифицированного сервером пользователя. Если делается
попытка выполнить операцию с базой, не имея к ней необходимого уровня доступа,
возникает ошибка или генерируется исключение.
Если агент выполняется на сервере (например, по расписанию или событию получения
почты), уровень доступа агента к серверу определяется в соответствии с правами создателя
этого агента (того, кто последним модифицировал агента) в документе Server из общей
адресной книги, а уровень доступа этого агента к базе совпадает с уровнем доступа создателя
агента к этой базе. Агент не будет выполнен на сервере, если он не имеет необходимого
доступа к серверу - соответствующее сообщение появится на консоли сервера. Если агент
может выполняться на сервере, но не имеет необходимого уровня доступа к базе, в ходе его
выполнения возникает ошибка или генерируется исключение.
Пример 1. Скрипт создает новый объект класса NotesDatabase для доступа к базе plan.nsf на
сервере Server 1/Acme/RU. Если база существует, объект будет открыт.
Dim db As NotesDatabase
Set db = New NotesDatabase{ "Serverl/Acme/RU", "plan.nsf" )
Messagebox( db.Title )
Пример 2. Скрипт делает то же самое, но он короче.
Dim db As New NotesDatabase(
Messagebox( db.Title )
"Serverl/Acme/RU",
"plan.nsf"
)
Пример 3. Java-агент создает новый объект класса Database для доступа к базе plan.nsf на сервере
Serverl/Acme/RU. Если база существует, объект будет открыт.
,' / Java-Database/Databasel
Datab ase d b = sess ion. getDa ta base("Serv e rl/A cme/RU" ,
System, out. print In ( db . get Т it. le () ) ;
"p lan. nsf");
Пример 4. Скрипт использует свойство IsOpen для проверки, существует ли база QUACK.NSF в
каталоге birds на компьютере, выполняющем скрипт. Если база не существует, скрипт создает новую
методом Create.
Dim db As New NotesDatabase( "",
InterTrust Co. Тел. (095) 9567928
"birdsXquaak.nsf" ) ©
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
409
•...-..:•
If db.IsOpen Then
Messagebox( "База уже существует" )
Else
Messagebox( "Создание новой базы... " )
Call db.Create( "", "", True )
db.Title = "Ducks of North America"
End If
Пример 5. Java-агент использует свойство isOpen для проверки, существует ли база QUACK.NSF в
каталоге birds на компьютере, выполняющем скрипт. Если база не существует, агент создает новую
методом createFromTemplate no шаблону discswSO.ntf.
/7 Java-Database/Database2
'
. - • - Database? db, template;
db = session.getDatabase(null, "birds\\quack");
if (db.isOpen())
S уs t em.out.pri nt1n(db.ge t Т i11e() ) ; " .
else
{
" ' '
System, out.. print In ( "Creating new database ..."); template
= session. getDatabase (null , "disc.sw50.ntf"); if
(template.isOpen()) {
db = template.createFromTemplate(null, "birds\\quack", true); db.
setT.it le ( "Ducks of North America"); System, out. print In (db . get-Title ()); }
else
System.out.println("Template discswSO.ntf does not exist");
}
.<:•
,
,
-
,
-
,
-
'
.'
%
"
-
-
•
-
-
•
•
Пример 6. Скрипт предоставляет пользователю Brian Flokka/Acme/US доступ редактора к текущей
базе. Текущая база - база, в которой находится и выполняется этот скрипт. Использование свойства
CurrentDatabase класса NotesSession способствует разработке универсальных скриптов, «не
привязанных» к конкретным именам баз.
Dim session As New NotesSession
Dim db As NotesDatabase
Set db = session.CurrentDatabase
Call db.GrantAccess( "Brian Flokka/Acme/US", ACLLEVEL EDITOR )
Пример 7. To же самое делает Java-агент.
// Java-Database/DatabaseS
Database db = agentContext.getCurrentDatabase{);
db.grantAccess("Brian Flokka/Acme/US", ACL.LEVEL EDITOR);
Пример 8. Скрипт использует метод Open для проверки существования базы salesdocs.nsf на
сервере Server 1/Acme/RU. Если база существует, скрипт добавляет группу Supervisors в ее ACL.
Dim db As New NotesDatabase( "", "" )
If db.Open( "Serverl/Acme/RU", "salesdocs.nsf" ) Then
Call db.GrantAccess ( "Supervisors", ACL-LEVEL_EDITOR )
End If
'
Пример 9. Скрипт демонстрирует методы New и OpenlfModified для открытия базы только в том
случае, если она была модифицирована после указанной даты. Если база SALESDOCS.NSF на сервере
Serverl/Acme/RU была модифицирована в течении суток, скрипт открывает базу и уплотняет ее.
Dim db As New NotesDatabase( " " , » " )
Dim dateTime As New NotesDateTime( "Today" )
Call dateTime.AdjustDay( -I }
If db.Open!fModified( "Serverl/Acme/RU",, "salesdocs.nsf",
Call db.Compact End
If
dateTime
)
Then
© InterTrust Co. Тел. (095)9567928
Встроенные классы LotusScript u Java
410
Пример 10, То же самое делает Java-агент.
DbDirectory dir = session.getDbDirectory("Server1/Acrne/RU");
DateTime dt = session.createDateTime("Today");
dt.setNow(); dt .adjustDay (-1};
Database db = dir.openDatabaselfModified("quack", dt) ;
if (db !== null)
{ System, out. println ( "Compacting databases"); db . compact (); } else
System.out.println("Database not modified in past day");
3.5.1. Свойства, доступные из интерфейса клиента или администратора
Свойство Title - «название базы»
LotusScript:
title$ = notesDatabase.Title
notesDatabase.Title = title$
Java;
String title. = Database.getTitleQ
void Data base.setTMe(String title)
Позволяет получить или изменить название базы (тип String). Учтите, что нельзя
изменить название базы, в которой происходит выполнение скрипта или Java-агента.
Свойство FileName - «имя файла»
-.••..
/. • . : - : ..- .'. •-" ' • , . . . . .
LotusScript:
file'Name$ ~ nolesDatabase.fileN-лте
Java:
String fileName = Database.getFileNsimeQ
Имя файла базы, включая расширение (обычно .NSF), но не включая каталоги
относительно каталога данных Notes (тип String).
Пример 1. Строковая переменная file получит значение "Names.nsf'.
Dim db As New NotesDatabase( "Domino/Org/RU",
file As String file = db.FileName
"Names.nsf" ) Dim
Пример 2. Строковая переменная file получит значение "ReadMe.nsf".
Dim db As New NotesDatabase( "Domino/Org/RU",
file As String file = db.FileName
"doc\ReadMe.nsf" ) Dim
Пример 3- Если Java-агент выполняется в базе "WDb\Education\JavaLotusScriptEx.nsf", им будет
выведено сообщение «Database "Java&LScript Classes - примеры" has the file name
JavaLotusScriptEx.nsf».
// Java-Database/FileName
Database db = agentContext.getCurrentDatabase();
String title = db.getTitleO ;
String name = db.getFileName();
System.out.println("Database \"" + title +
"\" has the file name " + name);
СвойствоFilePath - «путь и имя файла» . '.••.••".-•••. v •'•'•••'• * ' :"• • ; ;••:••• '-'-.••• :
LotusScript:
pathS - notesDatabase.FilePatb
Java:
Stringpath = Database.geiFilePntbQ
. ::.
Имя файла базы (тип String), включая каталоги и расширение (обычно .NSF). Если база
данных находится на станции, возвращаемый «путь» начинается с буквы диска и включает
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: ©-формулы, LotusScript, встроенные классы LotusScript и Java
411
все каталоги, например, C:\Lotus\Notes\data\dir\subdir\db.nsf. Если база данных находится на
сервере, возвращается путь относительно каталога данных Notes, например, dir\subdir\db.nsf.
Пример 1. Строковая переменная path! получит значение "Names.nsf (база находится на сервере), а
переменная path2 - "D:\Notes50\Data\Narnes.nsf" (база «локальна»).
Dim dbl As New NotesDatabase( "Domino/Org/RU", "Names.nsf" ) Dim
db2 As New NotesDatabase( "", "Names.nsf" ) Dim pathl, path2 As
String pathl = dbl.FilePath path2 = db2.FilePath
Пример 2. Строковая переменная pathl получит значение "doc\ReadMe.nsf" (база на сервере), а
переменная path2 - "D:\Notes50\Data\doc\ReadMe.nsf (база «локальна»).
Dim dbl As New NotesDatabase( "Domino/Org/RU", "doc\ReadMe.nsf" } Dim
db2 As New NotesDatabase( "", "docAReadMe.nsf" ) Dim pathl, pat.h2 As
String pathl = dbl.FilePath path2 = db2.FilePath
Пример З. Агент LSDatabaseFilePath, находящийся в расположенной на сервере базе
OursDBs\WDb\Education\JavaLotusScriptEx.nsf
и
запускаемый
из
броузера
по
URL
http://domino500/OursDBs/WDb/Education/JavaLotusScriptEx.nsf/LSDatabaseFilePath?OpenAgent, вернет
в броузер страницу с текстом «FilePath=OursDBs\WDb\Education\JavaLotusScriptEx.nsf» .
Sub Initialize
Dim s As New NotesSession
Dim db As NotesDatabase
.
Set db ~ s.CurrentDatabase
Print "<b>FilePath=";db.FilePath;"<7b>"
End Sub
. . ' - , - .
- '
Пример 4. Если Java-агент выполняется в базе "OursDBs\WDb\Eiducation\JavaLotusScriptEx.nsf', им
будет выведено сообщение «Database "Java&LScript Classes - примеры" has the file path
OursDBs\WDb\Education\JavaLotusScriptEx.nsf».
// Java-Database/FilePath
Database db = aqentContext,getCurrentDatabase();
String title = db,getTitle();
String path = db.getFilePath();
System.out.println("Database \"" + title + "\"
has the file path " + path);
Свойство Server - «сервер»
LotusScript:
serverName$ - notesDatabase.Server
Java:
String serverName ~ Database.getServerQ
Имя сервера (тип String), на котором размещается база, или пустая строка (""/null), если
база расположена локально.
Пример. Скрипт определяет, находится ли текущая база на сервере или на станции.
Dim session As New NotesSession
Dim db As NotesDatabase
Set db = session.CurrentDatabase
'
If ( db.Server - "" ) Then
Messagebox( "Это локальная база" ) Else
Messagebox( "Это база на сервере " & db.Server ) End
If
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript u Java
412
Свойство ReplicalD - «идентификатор реплики»
LotusScript:
id$ = notesDatabaseJR.epli.caID
Java:
String id = Databose.geiReplicalDQ
16-и символьная комбинация букв и цифр (тип String), представляющая идентификатор
реплики этой базы. Все реплики этой базы имеют такой же идентификатор реплики, а копии
-разные идентификаторы.
Пример. Скрипт выводит в окне ID реплики текущей базы. Например, нечто подобное
"852561C1004D958F".
Dim session As New NotesSession
Dim db As NotesDatabase Set db =
sessi.on.CurrentDataba.se
Messagebox( db.ReplicalD )
Свойство Created - «время создания базы»
LotusScript:
date V - notesDatabase.Created
Java:
Date Time date = Z)ara/>a$e.getCreated()
Дата-время создания базы (в LotusScript тип Variant of type DATE, в Java - объект класса
DateTime).
Свойство LastModified - «время последней модификации базы»
LotusScript:
date V ~ notesDatabaseJLasiM.odified
Java:
DateTime date = Z)ata/>ase.getLastModified()
Дата-время (в LotusScript тип Variant of type DATE, в Java - объект класса DateTime)
последней модификации базы.
Свойство Size - «размер в байтах». .
:.
...
LotusScript:
size# = notes Database.Size
Java:
double size — Database.getSizeQ
. : . . . : . . . . . . . -..: •" ' -- ..
;
• .:
Размер (тип double) базы в байтах. Свойством можно пользоваться для неоткрытой базы.
Пример. Скрипт определяет размер текущей базы.
Dim
Dim
Set
Dim
size
session As New NotesSession
db As NotesDatabase
db = session.CurrentDatabase
size As Double
•
.
•-• db. Size
Свойство SizeQuota - «квота на размер базы в Кбайтах»
LotusScript:
quota& = notesDatabase.SizeQuota
noiesDatabase.Si'i.eQiiQt'A ~ quota&
Java:
int quota - Database,getSizeQuotaQ
void Databose.setSizeQuota(int quota)
© InterTrust Co. Тел. (095) 9567928
.
-
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
413
Позволяет определять ранее установленное или устанавливать новое ограничение на
размер базы («квоту») в Кб (в LotusScript тип Long, в Java - int). Если ограничение для базы не
было установлено, свойство возвращает 0. Для установки свойства владелец агента или
приложения должен иметь доступ администратора к серверу, на котором находится база.
@ Свойство MaxSize - «максимально возможный размер базы в Кбайтах»
LotusScript:
size# - notes Database.MaxSize
Java:
long .size ~ Database.getMaxSizeQ
Выбранный при создании базы ее максимально возможный размер (тип Double/Long)
базы в Кб.
Пример. Скрипт для текущей базы выводит размер, ограничение на размер («квоту») и
максимально возможный размер.
Dim session As New NotesSession
Dim db As NotesDatabase
Set. db = session. CurrentDatabase
Print "Database size is: ", db.Size
Print "Database Quota is: ", db.SizeQuota, "K"
Print "Database Maximum Size is: ", db.MaxSize,
"K"
Свойство PercentUsed - «% использования дискового пространства базы»
LotusScript:
used# = notesDatabase.Percentllsed
Java:
double used = Database.getPercentUsed()
Процентное отношение (тип Double) общего размера базы к размеру пространства в базе,
действительно занятого данными. Операция уплотнения базы (Compact) устраняет из базы
свободное (не занятое данными) пространство и «доводит» данное отношение почти до
100%.
Свойство Categories - «категории в каталоге баз»
LotusScript:
categoryList$ — notesDalaba.se.Categories
notes Database.Categories ~ categoryList$
Java:
String categoryList =- Z)atoЈdwe.getCategQries()
void Database.setC№tegaries(String categoryList)
Категории, в форме строки, «в которых» база появляется в каталоге баз (CATALOG.NSF)
или базе типа Database Library, Если категорий несколько, они должны разделяться в строке
запятыми или точками с запятой. Свойство не требует, чтобы база данных была открыта.
В окне свойств базы можно видеть поле с меткой "Categories:" , в котором и задаются
категории для базы.
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
414
Puc. 3.14 Категории для базы
В следующем окне дан фрагмент вида Databases by Category базы данных
CATALOG. NSF,
|Ы »
/^нс. 3. / Категории в виде Databases by Category базы CATALOG.NSF
Пример 1. Скрипт выводит в диалоговом окне все категории текущей базы.
Dim session As; New NotesSession Dim
db As NotesDatabase Set db =
session.CurrentDatabase
Messagebox( db.Categori.es )
Пример 2. Java-агент выводит категорию текущей базы.
./,/
Java -Database /Categories
© InterTrust Co, Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
415
Database db -= agentContext.getCurrentDatabase{);
String title - db.getTitle(}; String cat =
db.getCategories (); if (cat != null)
System.out.println("Database \"" +
title + "\" has the categories: " + cat); e
1s e
System . out; .println ( "Database V" r
title + "\" has no categories"};
Пример З. Скрипт «присваивает» категорию "Application Template" текущей базе.
Dim session As New NotesSession
Dim db As NotesDatabase
Set db = sess.ion.CurrentDatabase
db.Categories = "Application Template"
Свойство DesignTempIateName - «имя шаблона, с которого базой наследуется
дизайн».....: ''.'.-•.-'.• •.-•'•'••. • -•-. ,'"..•'.••'••'••''••"•.''.;•.....:.•••' " . •- • • •'.-.-.;.. .
LotusScript:
пате$ — ?zofesData6ase.DesignTemplateName
Java:
String name ~ Z)a/a6ase.geffiesignTemplateName()
Имя шаблона (тип String), из которого база наследует дизайн. Это текст из поля с меткой
Template Name под «выбранной» опцией Inherit design from template в окне свойств базы (Рис.
3.14). Если база не наследует дизайн, возвращается ""/null. Если база наследует только
отдельные элементы дизайна, например, только некоторые формы, но не весь дизайн
целиком, также возвращается ""/null.
Пример 1. Скрипт определяет имя шаблона, из которого наследует дизайн база MAIL\Dlvanov.NSF.
Судя по имени файла базы, вероятно, это «почтовый ящик», и метод может вернуть "StdR46Mail", если
только владелец базы не отказался от наследования дизайна или не использует свой собственный
шаблон.
Dim db As New NotesDatabase( "Domino/Org/RO",
template$ = db.DesignTempIateName
"mail\DIvanov.nsf" )
Пример 2. Java-агент выводит имя шаблона, с которого наследует дизайн текущая база.
// Java-Database/DesignTempIateName
Database db = agentContext.getCurrentDatabase( ) ;
String title = db.getTitle();
String template = db.getDesignTemplateName();
if(template != null)
System.out .println ("Database \"" +
title + "\" inherits its design from " + template); else
System, out .print] n ( "Database V" +
title -t- " \ " did not inherit its design from a template");
Пример З. Подпрограмма отправляет менеджерам всех баз почтовые сообщения с
предупреждением о том, что завтра дизайн-шаблон их баз будет изменен. Параметрами подпрограммы
являются имя сервера и имя файла базы, являющейся шаблоном (например, MAIL46.NTF для шаблона
"StdR46Mail"). Скрипт сначала определяет название шаблона, а затем в цикле перебирает все базы на
сервере, и для тех, у которых название дизайн-шаблона совпадает с данным, отправляет письмо всем ее
менеджерам.
Sub templateNotification( server As String, file As String ) Dim
templateDb As NotesDatabase Dim tempiateName As String Dim db
As NotesDatabase
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript u Java
416
D im d irecto r y A s N o te sD b D ire c to r y
Dim doc As NotesDocument
Set teraplateDb = New NotesDatabase ( server, file )
teinplateName = templateDb. TemplateName
Set directory - New NotesDbDirectory( server )
Set db = directory.GetFirstDatabase( DATABASE )
While Not ( db Is Nothing )
If ( db.DesignTemplateName = template'Name ) Then Call
db.Open( "", "" )
Set doc = New NotesDocument( db )
doc. Form ••= "Memo"
doc. Subject = "Template changes in " & teinplateName
doc.Body = "The template " & templateName & _
" will be modified tomorrow." Call
doc.Send( False, db.Managers ) End If
Set db — directory. GetNextDatabase
Wend
^
End Sub
.
Вызов этой подпрограммы мог бы выглядеть так:
Call templateNotification ( "Doraino/Org/RU",
"mai!46.ntf"
}
Свойство TemplateName - «название шаблона»
LotusScript:
name$ -• notesDatabase.TemplateName
Java:
String name = Z)ate/>os<?.getTemplateName()
Если база является шаблоном, свойство возвращает название шаблона (тип String). Это
текст из поля с меткой Template Name под «выбранной» опцией Database is template в окне
свойств базы (Рис. 3.14). Если база не является шаблоном (например, лишь наследует дизайн
с другого шаблона, наследует дизайн поэлементно или вообще ниоткуда не наследует
дизайн), возвращается пустая строка ("") в LotusScript или null в Java.
Пример 1. Скрипт определяет название шаблона у входящей в поставку Notes базы MA1L50.NTF.
Возвращается "StdR50MaiI".
Dim db As New NotesDatabase( "", "rnailSO . nt f " )
Dim template As String template = db.TemplateName
Messagebox ( template )
Пример 2. Подпрограмма по переданным в качестве параметров имени пользователя, сервера и
файла базы создает новую базу - «почтовый ящик» для этого пользователя, используя при этом шаблон
StdRSOMail. Свойство TemplateName используется для поиска базы, которая является этим самым
шаблоном с названием StdRSOMail.
Sub createMailFile( user As String, server As String, file As String ) Dim
templateDb As NotesDatabase Dim mailDb As NotesDatabase
Dim directory As New NotesDbDirectory( server ) Set
templateDb -- director у. Get FirstDatabase ( TEMPLATE ) While
Not ( templateDb.TemplateName = "StdRSOMail" )
Set templateDb = directory.GetNextDatabase
Wend
Call templateDb.Open( "", "" )
Set mailDb = templateDb.CreateFromTemplate( server, "mail\"+flie, True )
mailDb.Title = user + " Mail"
Call mailDb.GrantAccess( "Administrators", ACLLEVEL_MANAGER } Call
mailDb.GrantAccess( user, ACLLEVEL_EDITOR )
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R, 5: (а)-формулы, LotusScript, встроенные классы LotusScript и Java
417
If ( server <> "" ) Then
Call maiiDb.GrantAccess( server, ACLLEVEL__MANAGER ) End
If End Sub
Пример вызова этой полпрограммы:
Call
createMailFile(
"Denis
Ivanov",
"Domino/Org/RU" ,
"DIvanov.nsf"
)
Свойство IsFTIndexed - «имеется ли индекс полнотекстового поиска»
LotusScript:
Java:
flag = notesDatabase.lsҐ'Tmde-%.tid
boolean flag - Database AsfTlndcxeuQ
Возвращает true, если база имеет индекс полнотекстового поиска, или false, если не
имеет.
Пример 1. Java-агент проверяет, имеет ли база индекс полнотекстового поиска.
// Java-Database/1sFTIndexed
Database db = agentContext.getCurrentDatabase();
String title = db.getTitle();
if(db.isFTIndexed())
System.out.println("Database \"" + title + "\" is full text indexed"); else
System.out.println("Database \""+title+"\" is not full text indexed");
Пример 2. Прежде чем выполнять запрос полнотекстового поиска, скрипт «аккуратно» проверяет,
имеет ли база индекс полнотекстового поиска,
Dim session As New NotesSession
Dim db As NotesDatabase
Dim collection As NotesDocumentCollection
Set db = session.CurrentOatabase
If db.IsFTIndexed Then
Set collection = db.FTSearch( "hook* & *DLL",
End If
.
0 )
Пример З. Скрипт использует свойство IsFTIndexed для определения, какой метод следует
использовать для создания коллекции документов из базы SALES.NSF, содержащих слово "press". Если
база имеет индекс полнотекстового поиска, документы со словом "press" отбираются методом
FTSearch. Иначе для отбора документов, содержащих слово "press" в поле Body, используется метод
search. Полученная коллекция документов используется при создании объекта класса NewsLetler.
Объект класса NewsLetter позволяет создать «обзорный» документ - документ, содержащий в поле
Body ссылки (DocLink-и) на все документы из коллекции. Созданный обзорный документ сохраняется в
базе как документ формы Search Summary.
Dim db As New NotesDatabase( "", "sales.nsf" )
Dim collection As NotesDocumentCollection
Dim newsletter As NotesNewsletter
Dim doc As NotesDocument
Dim dateTime As NotesDateTime
Dim maxDocs As Integer
maxDocs - 10
If db.IsFTIndexed Then
Set collection = db.FTSearch( "press", maxDocs ) Else
Set dateTime = New NotesDateTime( "" )
Set collection = db.Search( "@Contains( Body; ""press"" }",
dateTime, maxDocs ) End If Set
newsletter — New NotesNewsletter( collection )
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript u Java
418
Set doc = newsletter.FormatMsgWithDoclinks( db ) doc.
Form. - "Search Summ.ary" Call doc.Save{ True, True )
Свойство IsMuItiDbSearch - «используется ли база при создании индекса
полнотекстового поиска по многим базам»
LotusScript:
flag = notesDatahase.lsMultiDbSem'ch
Java:
boolean flag = Database.isMnltiDbSearchQ
Возвращает true, если база имеет свойство MultiDbSearch, или false, если не имеет.
Свойство означает, что по текстовой информации из данной базы создается индекс
полнотекстового поиска для многих баз. Свойство «не запрещает» базе может иметь и
собственный индекс полнотекстового поиска, хотя последнее обычно считают излишеством.
Свойство LastFTIndexed - «время последнего обновления индекса
полно текстового поиска»
LotusScript:
date V - notesDatabaseJL&siF'TIndexcd
Java:
DateTime date - Z)a/aia,ve.getLastFTindexed()
Дата-время (в LotusScript - Variant of type DATE, в Java - объект класса DateTime)
последнего изменения индекса полнотекстового поиска у базы, или 12/30/1899 в LotusScript
или null в Java, если база не имеет индекса полнотекстового поиска.
3.5.2, Свойства, касающиеся уровня доступа к ба*е
Свойство Managers-«массив менеджеров базы»
LotusScript:
stringArrayMgrs - notesDatabase.'Managers
Java:
Java. util. Vector mgrs = Z)otoЈa$(?.getManagers0
Список пользователей, серверов и групп (в LotusScript - Array of Strings, в Java Java.util.Vector с элементами типа String), имеющих к базе доступ менеджера.
т
Пример 1. Скрипт последовательно выводит в окне имя каждого менеджера базы.
Dim session As New NotesSession Dim
db As NotesDatabase Set db •= session.
CurrentDatabase Forall m In
db.Managers
Messageboxf m }
End Forall
Пример 2. Java-агент выводит список имен всех менеджеров базы.
import т ava.util.Vector;
// Java-Database/Managers
Database db = agentContext.getCurrentDatabase ();
String title = db.getTitle{);
Vector managers = db.getManagers();
int. size = managers . size (};
if (size == 1) System.out.println("Database \"" +
title + "\" has 1 manager"); else
System.out.println("Database \"" +
title + "\" has " + size + " managers"); for
(int i=0; i<size; i++)
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
419
{
String name = (String)managers.elementAt(i); System.out.print
In("Manager # " + (i + 1) + ": " + name); }
Пример З. Скрипт кнопки (событие Click) предлагает пользователю отправить письмо со своими
предложениями по данной базе всем менеджерам этой базы.
Sub Click(Source As Button)
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Set db = session.. CurrentDatabase
Set doc = New MotesDocument( db )
doc.Form = "Memo"
doc.Subject = "Предложения по базе "+ db.Title
doc.Body = InputboxS( "Введите ваши предложения:
Call doc.Send( False, db.Managers )
End Sub
", db.Title )
Пример 4. Приложение состоит из двух баз, которые работают совместно. Необходимо обеспечить,
чтобы в ACL у обоих баз был одинаковый список менеджеров. Скрипт выбирает всех менеджеров из
одной базы и каждому из них обеспечивает доступ менеджера к другой базе. Учтите, что для
выполнения своей работы скрипт «сам» должен иметь доступ менеджера во второй базе.
Dim dbl As New NotesDatabase ( "Key West", "cserv \datadict.nsf" )
Dim db2 As New NotesDatabase ( "Key West", "cserv\calltrak.nsf" )
Forall mgr In dbl.Managers
Call db2.GrantAccess( mgr, ACLLEVEL_MANAGER )
End Forall
Свойство CurrentAccessLevel - «текущий уровень доступа к базе»
LotusScript:
Java:
lcvel% = notes Database.Cur rentAccessLevel
inl level = Database.getCurrentAccessLevel()
Константа типа Integer/int, позволяющая узнать, каков текущий уровень доступа к базе.
Возможные значения:
*
ACLLEVELJNOACCESS / ACL.LEVEL JNOACCESS - нет доступа,
*
ACLLEVEL DEPOSITOR / ACL.LEVEL ^DEPOSITOR - депозитор,
*
ACLLEVEL_READER / ACL.LEVEL READER - читатель,
*
ACLLEVEL_AUTHOR/ACL.LEVEL_AUTHOR-автор,
*
ACLLEVEL_ EDITOR / ACL.LEVEL EDITOR - редактор,
*
ACLLEVEL DESIGNER / ACL.LEVEL ^DESIGNER - дизайнер,
ACLLEVEL MANAGER / ACL.LEVEL JV1ANAGER - менеджер.
Если выполнение происходит на станции или «удаленно» (ПОР) на сервере, значение
свойства CurrentAccessLevel определяется как уровень доступа к базе текущего пользователя.
Если выполнение осуществляется на сервере, значение свойства определяется как уровень
доступа к базе «владельца агента» (лица, последним модифицировавшего агента), а не
сервера.
*
Пример 1. Скрипт определяет уровень доступа пользователя к текущей базе. Например, если
пользователь, под ID-файлом которого работает станция, имеет к базе доступ автора, свойство вернет
константу ACLLEVEL_AUTHOR.
Dim session As New NotesSession
Dim db As NotesDatabase
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
420
Dim level As Integer-Set db =
session.CurrentDatabase level =
db.CurrentAccessLevel
Пример 2. Java-агент выводит уровень доступа пользователя к текущей базе.
./'/ Java -Database /CurrentAccessLevel
db = agentContext.getCurrentDatabase();
String title = db.getTitle ();
•.
int level = db.getCurrentAccessLevel();
System.out.print("For database \"" + title + "\" you have ");
switch(level)
/
i
case(ACL.LEVEL_NOACCESS):
System.out.print("No access"); break;
case(ACL.LEVEL DEPOSITOR): System.out.print("Depositor"); break;
case (ACL . LEVEL_READER) :
System, out.. print ( "Reader" ) ;
break;
case(ACL.LEVEL_AUTHOR):
System.out.print("Author");
break;
case(ACL.LEVEL EDITOR):
System.out.print("Editor");
break;
case(ACL.LEVEL_DESIGNER):
System.out,print("Designer");
break;
case(ACL.LEVEL MANAGER):
System.out.print("Manager");
break;
default:
System.out.print("Unknown");
break;
}
System.out.print(" accessXn");
3.5.3, Свойства для получения объектов-потомков
Свойство Replicationlnfo - «объект Replicationlnfo для базы»
LotusScript:
NotesReplication ~ notesDatabase.Replicationlnfo
Java:
Replication ri = Database.getReplicationlnfoQ
Возвращает ссылку на объект класса [NotesjReplication. Подробности в описании класса
[Notes (Replication.
Свойство ACL - «список управления доступом базы»
LotusScript:
Set notesACL =• notesDatabase.AClj
t
Java:
:
ACL ad = Database.getACL()
Список управления доступом (ACL) базы как объект класса [Notes] ACL.
Пример 1. Скрипт получает ACL базы и, используя метод getFirstEntry класса NotesACL, получает
доступ к первому элементу в ACL.
Dim
Dim
Dim
Set
Set
db As New NotesDatabca.se ( "Domino/Org/RU", "mail\user01. risf" )
acl As NotesACL
entry As NotesACLEntry
acl = db.ACL
>
entry = acl.getFirstEntry
Пример 2. Скрипт получает ACL текущей базы и, используя метод getEntry класса NotesACL,
получает доступ к элементу в ACL для группы Administrators.
Dim
Dim
Dim
Dim
Set
Set
session As New NotesSession
db As NotesDatabase
acl As NotesACL
entry As NotesACLEntry
db = session.current Database
acl = db.ACL
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
Set
entry —
acl.getEntry(
"Administrators"
421
)
Пример 3. Java-агент получает ACL текущей базы и, используя методы getFirstEntry и getNextEntry
класса ACL, выводит имена всех содержащихся в ACL элементов.
// Java-Database/ACL
db = ag ent Conte xt.g etCurre ntD atabas e {);
ACL acl = db.getACL();
ACLEntry entry = acl.getFirstEntry( ) ;
do {
System.out.println(entry.getName());
} while ((entry = acl.getNextEntry(entry))
null);
!=
Свойство Agents - «массив агентов базы»
LotusScript:
Java:
notesAgentArray — notesDatabase.Agents
Java. util. Vector agents -• DataЈa5e.getAgents()
Массив агентов, имеющихся в базе (в LotusScript тип Array of NotesAgents, в Java
-java.util.Vector с элементами класса Agent). Если выполнение происходит на станции или
«удаленно» (ПОР) на сервере, в массиве присутствуют как общие агенты, так и личные
агенты текущего пользователя. Если выполнение осуществляется на сервере, в массиве
содержатся только общие агенты.
Пример 1. Скрипт определяет имя первого агента в текущей базе.
Dim session As New NotesSession
Dim. db As NotesDatabase
Dim agent as NotesAgent
•
Set db =• session. Current-Database Set
agent = db.Agents( 0 ) Messagebox
agent,Name
Пример 2. Java-агент выводит имена всех агентов из текущей базы.
import java.util.Vector;
// Java-Database/Aqents
Database db = agentContext.getCurrentDatabase( } ;
Vector agents = db.getAgents();
System.out.println("Agents in database:");
for (int i = 0; i < agents.size( ) ; i++)
{
Agent agent = (Agent.} agents . elementAt (i) ; System,
out.. print In ( " " + agent. get.Naine ( ) ) ;
\
Свойство Views -«массив видов и папок базы»
LotusScript:
Java:
notesViewArray = notesDatabase.\iews
java.util. Vector views = Database.getViewsQ
Для базы, расположенной на сервере, возвращается «массив» общих видов и папок в базе.
Для локальной базы в «массиве» присутствуют также личные виды и папки пользователя. В
LotusScript это действительно массив типа Array of NotesViews, в Java - объект класса
Java.util.Vector. Каждый элемент массива или «вектора» - объект класса [Motes]View,
представляющий конкретный вид или папку.
Пример 1. Скрипт последовательно выводит в окнах имена всех видов и папок из текущей базы.
Определяется также вид, являющийся видом по умолчанию (default view).
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
422
Dim session As New NotesSession
Dim cib As NotesDatabase Set db=
session.CurrentDatabase For a 1 i v 11\
db. Vi ews
If v.IsDefaultView Then
Messagebox(v.Name &
" - default view")
Else
Messagebox(v.Name)
End If End
Forall
Пример 2. Подобно предыдущему, Java-агент выводит количество и имена всех видов и папок из
текущей базы.
import java.util.Vector;
/'/ Java-Database/Views
Database db = agentContext . get.CurrentDatabase ( ) ;
Strinq title = db.getTitle ( ) ;
Vector views = db.getViews();
int.- size — views . size ( ) ;
System, out.. println ("Database \ " " + title + "\" has " + size + " views"};
for (int i = 0; i < size; i + 4-)
{
String name = ( (View) views , element At ! i )). get.Name {);
System.out.println("View #" + (i + 1) + ": " + name); }
Свойство Forms - «массив форм и субформ базы»
LotusScript:
Java:
notesFormArray = notef>Database.Ґorms
Java. util. Vector forms = Database.getFormsQ
Массив форм и субформ, имеющихся в базе (в LotusScript тип Array объектов класса
NotesForm, в Java -Java.util. Vector с элементами класса Form).
Пример 1. Скрипт выводит список названий всех имеющихся в текущей базе форм.
Dim session Аз New NotesSession
Dim db As NotesDatabase
Set db = session.CurrentDatabase
Forall form In db.Forms
Messagebox form.Name
End Forall
'
,
Пример 2. Java-агент выводит список названий всех имеющихся в текущей базе форм.
import j ava.util.Vector;
// Java-Database/Forms
Database db = agentContext.getCurrentDatabase(};
String title = db.getTitle();
Vector forms = db.getForms();
inc. size = forms, size () ;
System.out.println("Database \"" + title + "\" has " + size
for (int i =-• 0; i < size; i + +)
{
String name = {(Form)forms.elementAt(i)).getName();
System.out.println("Form #" + (i+1) + "; " + name); }
© Inter Trust Co. Тел. (095) 9567928
+ " forms");
Lotus Domino R. 5: (шгформулы, LotusScript, встроенные классы LotusScript и Java
423
Свойство AHDocumcnts - «коллекция всех документов базы»
LotusScript:
Java:
Set notesDocwnentCollection — nolesDatabase.AllDocaments
DocwnentCollection collection ~ Database.getAllDocumentsQ
Коллекция (объект класса [Notes]DocumentCollection) из всех документов в базе.
Пользоваться этим свойством для поиска нужных документов следует осмотрительно,
поскольку при большом количестве документов их последовательный просмотр часто
занимает много времени. Для поиска документов более эффективны методы FTSearch или
search, возвращающие коллекцию документов, удовлетворяющих заданному критерию
поиска - обычно такие коллекции бывают относительно меньшего размера. В то же время
использование свойства AllDocuments оказывается эффективнее применения метода search с
формулой отбора @АП.
Пример 1. Скрипт определяет количество документов в базе свойством Count класса
NotesDocumentCollection.
Dim
Dim
Dim
Dim
Set
Set
n =
session As New NotesSessiori
db As NotesDatabase
collection As NotesDocumentCollection
n As Long
db -- session. CurrentDatabase
collection = db.AllDocuments
collect ion.Count
Пример 2. Скрипт события Click отсоединяет все присоединенные файлы из поля Body всех
документов базы в каталог c:\newfiles и удаляет их из поля Body. Для этого скрипт проверяет каждый
документ в коллекции из всех документов базы, и, если в документе содержатся встроенные
OLE-объекты или присоединенные файлы, вызывает подпрограмму detachFiles, которая более детально
проверяет наличие присоединенных файлов и отсоединяет их в заданный каталог.
Sub Click (Source As Button)
•.
f
Dim session As New NotesSession Dim
db As NotesDatabase
Dim collection As NotesDocumentCollection Dim
doc As NotesDocument Set db session.CurrentDatabase Set collection =
db.AllDocuments For i = 1 To collection.Count
Set doc = collection.GetNthDocument( i )
If doc.HasEmbedded Then
Call detachFiles{ doc )
End If
Next
;:
End Sub
'.-.-.
• . . • - • :
'
'
Sub detachFiles( doc As NotesDocument )
•
• '
Dim rtitem As Variant
- ' • '
Set rtitem = doc.GetFirstltem( "Body" )
•
.
Forall о In rtitem. EmbeddedObjects
-•-.-.
If o.Type - EMBED^ATTACHMENT Then
Call o.ExtractFile( "c:\newfiles\" & o.Source ) Call
о.Remove
Call doc.Save( True, True )
End If
•
.. •
End Foraii
•' .-.."•-•;
End Sub
'
'
•
.
© InterTrust Co, Тел. (095) 9567928
•
424
Встроенные классы LotusScript и Java
Пример 3. Java-агент получает коллекцию из всех документов текущей базы, а затем в цикле для
каждого документа выводит строку, содержащую номер документа в коллекции и содержимое поля
Subject из документа.
// Java-Database/AllDocuments
Database db = agentContext.qetCurrentDatabase ();
String title = db.getTitle {);
DocumentCollection collection = db. getAUDocuments () ;
System, out .print.ln ("Database \"" -t- title + "\" has " +
collection.getCount() + " documents");
Document doc; for (int. i ~ 1; i <— dc. getCount
() ; i + +)
i;
doc = collect ion.getNthDocument (i);
// «Первый» документ в DocumentCollection имеет индекс 1
System, out. print In ( "Document #" + i + " : " +-doc . getltemValue ( "Subject. " ) ) ;
Свойство UnprocessedDocuments - «коллекция необработанных документов»LotusScript:
Java:
Set notesDocumentCoUection ~~ woteA'Azta^ase.UnprocessedDocuments
DocumentCollection coll = AgentContext.getUnprocessedDocmnentsQ
Возвращает коллекцию документов (объект класса [Notes]DocumentCollection) из данной
базы, которые текущий агент «рассматривает» как «необработанные» ("unprocessed").
Свойство имеет смысл только для агента (или действия по виду). Во всех иных контекстах
свойство возвращает пустую коллекцию документов. В LotusScript свойство может
применяться только к объекту класса NotesDatabase, полученному свойством CurrentDatabase
объекта класса NotesSession. Если же объект класса NotesDatabase был получен не свойством
CurrentDatabase, возникает ошибка. Вероятно, во избежание недоразумений с контекстом
применимости в Java свойство UnprocessedDocuments являются членом класса AgentContext, а
не класса Database.
Это очень часто используемое свойство - ведь первый вопрос, с которым вы
сталкиваетесь при разработке агента или акции по виду, заключается в определении
множества (коллекции) документов, которые следует обработать.
Множество документов, включаемых свойством в коллекцию, зависит от типа агента.
Кроме того, если в «построителе агентов» был задан дополнительный поисковый критерий,
включаемые в коллекцию документы должны удовлетворять еще и этому критерию.
Последнее для простоты не оговаривается, но подразумевается в нижеследующем.
*
Если агент определен как работающий по новым или модифицированным с момента его
предыдущего запуска документам (All new and modified documents since last run),
свойство UnprocessedDocuments возвращает все документы, которые «не отмечены»
агентом «как обработанные». Дело в том, что вы должны использовать метод
updateProcessedDoc класса NotesSession/AgentContext для «отметки» каждого документа,
обработанного агентом такого типа. Из этого следует, что свойство
UnprocessedDocuments просто возвращает те документы, у которых нет отметки об
обработке, «ранее созданной» этим же агентом.
•
Если агент определен как работающий по выбранным в виде документам (Selected
documents), свойство UnprocessedDocuments возвращает все выбранные (отмеченные
пользователем «галочкой» или текущий документ, когда ничего не отмечено «галочкой»)
документы. Использование updateProcessedDoc в такой ситуации не имеет смысла и
эффекта.
© InterTrust Со. Тел. (095) 9567928
Lotus Domino R, 5: (Sf-формулы, LotusScript, встроенные массы LotusScript и Java
*
•
*
425
Если агент определен как работающий по всем документам н виде (All documents in
view), свойство UnprocessedDocuments возвращает все документы из текущего вида.
Использование updateProcessedDoc в этой ситуации не имеет смысла и эффекта.
Если агент определен как работающий по всем документам в базе (A1J documents in
database), свойство UnprocessedDocuments возвращает все документы из текущей базы.
Использование updateProcessedDoc в этой ситуации не имеет смысла и эффекта,
Если агент определен как работающий по всем непрочитанным пользователем
документам из вида (All unread documents in view), свойство UnprocessedDocuments
возвращает все непрочитанные текущим пользователем документы из текущего вида.
Использование updateProcessedDoc в этой ситуации не имеет смысла и эффекта.
•
Если агент определен как работающий только по текущему документу в виде (Run once),
UnprocessedDocuments возвращает коллекцию из одного этого документа. Для такого
агента отсутствует дополнительный поисковый критерий, а использование
updateProcessedDoc не имеет смысла и эффекта.
•
Если агент определен как работающий по поступающим почтой документам (Newly
received mail documents), no созданным новым или модифицированным в базе
документам (Newly modified documents) или по документам, добавленным в базу из
буфера обмена (Pasted documents), свойство UnprocessedDocuments возвращает только
поступившие почтой документы, созданные новые или модифицированные документы
или документы, добавленные в базу из буфера обмена, но только при условии, что они
ещё «не отмечены» агентом «как обработанные». И вы после обработки каждого
документа
должны
использовать
метод
updateProcessedDoc
из
класса
NotesSession/AgentContext для «отметки» этого документа, «как уже обработанного»
агентом.
Если скрипт или агент является частью действия по виду (View action), свойство
UnprocessedDocuments возвращает все выбранные в виде документы.
*
Пример 1. Скрипт действия по виду (view action) позволяет пользователю одобрить
(«положительно завизировать») сразу все выбранные Б виде документы. Коллекция выбранных
пользователем документов просматривается в цикле, и, если документ «требует одобрения» данным
пользователем, т.е. в его поле Approver содержится имя этого пользователя, то полю Approved
присваивается значение "Yes".
Dim session As New NotesSession
Dim db As NotesDatabase
Dim collection As NotesDocumentCollect.ion
Dim doc As NotesDocument
Set. db = session. C'urrentDatabase
Set collection = db.UnprocessedDocuments
For i -= 1 To col lection. Count
Set doc = collection. GetNthDocumer.it ( i )
Set item = doc.GetFirstItem( "Approver" )
If item,Contains ( session.UserName ) Then
doc.Approved = "Yes" Call doc.Save( False,
True )
End If
K'ext
Пример 2. Java-агент, запускаемый действием по виду (view action), выводи! количество
выбранных пользователем в виде документов и текст их поля Subject.
/./ Java- agent Con text /UnprocessedDocuments
DoauatentCollection dc = agentContext. getUnprocessedOocuments () /
System, out.print-In ( "Count = " + dc.get Count( ) ) ;
Document doc = dc.getFirstDocument(); while (doc I—
null) {
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
426
}
System.out.printIn(doc .getItemValueString ("Subject")); doc
= dc.getNextDocument();
'
3.5,4. Прочие свойства
Свойство Parent - «родитель»
LotusScript:
Set notesSession - notesDatabase.Parent ..
Java:
Session session =- Database.geiParentQ
Объект класса [NotesJSession, являющийся «родителем» данного объекта [NotesjDatabase.
Свойство IsOpen - «открыта ли база»
LotusScript:
Java:
flag ~ notesDatabase.lsOpen
boolean flag - Database.isOpenQ
Возвращает true, если объект класса [Notes]Database открыт, иначе false.
Если объект [NotesjDatabase открыт, доступны все его свойства и методы. Если же
объект не открыт, для чтения доступны лишь немногие из его свойств, в частности
Categories, DelayUpdates, DesignTemplateName, FileName, FilePath, IsOpen,
IsPrivateAddressBook, IsPublicAddressBook, Parent, ReplicalD, Server, SizeQuota,
TempIateName, Title. Методы getFirstDatabase и getNextDatabase класса [Notes]DbDirectory и
getAddressBooks класса [NotesJSession возвращают «закрытые базы». Чтобы открыть базу,
можно воспользоваться методом open класса [NotesjDatabase,
Свойство IsPrivateAddressBook - «личная ли адресная книга»
LotusScript:
flag - «ofcsDa?aЈave.IsPrivateAddressBook
Java:
boolean flag = Z)a/aia5e.isPrivateAddressBook()
. . .; ..: ............ .
Возвращает true, если данная база является личной адресной книгой, иначе false.
Свойство имеет смысл только тогда, когда объект класса [NotesjDatabase был получен
свойством AddressBooks объекта класса [NotesJSession. При других способах получения
объекта класса [Notes]Database это свойство вообще не имеет никакого смысла, но
возвращает false.
Свойство IsPublicAddressBook - «общая ли адресная книга»
LotusScript:
Java:
flag = «o/es.DatoAase.IsPubHcAddressBook
boolean flag = Ј>ata6ase,isPublicAddressBook()
Возвращает true, если данная база является общей адресной книгой, иначе false, В
остальном аналогично свойству IsPrivateAddressBook.
© Свойство IsDirectoryCatalog - «типа ли Directory Catalog»
LotusScript:
flag - /2o/esDataЈa$'e.IsDirectoryCatalog
Возвращает true, если данная база является адресной книгой типа Directory Catalog, иначе
false. Имеется в виду база типа Light Address Book, обычно созданная по шаблону с именем
Lightweight Directory (файл DIRCAT.NTF с именем базы Directory Catalog).
© InterTrust Co, Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
427
Свойство имеет смысл только тогда, когда объект класса NotesDatabase был получен
свойством AddressBooks объекта класса NotesSession, а затем был явно открыт. При других
способах получения объекта класса NotesDatabase это свойство вообще не имеет никакого
смысла, но возвращает false.
Пример. Скрипт получает «список» всех адресных книг и для каждой адресной книги «сообщает»,
является ли она адресной книгой типа Directory Catalog и где расположена.
Dim session As New NotesSession Dim
books As Variant books =
session.addressbooks Forall b In
books
If b.IsPrivateAddressBook = True Then Call
b.open("","") If b. IsDirectoryCatalog •=
True Then
Messagebox b.Title+" Directory Catalog on Local"
Else
Messagebox b.Title+" NAB on Local" End
If Else
Call b.open("", "">
If b. IsDirectoryCatalog - True Then
Messagebox b.TitIe+" Directory Catalog on Server"
Else
Messagebox b. Title-)-" NAB on Server" End If
End If End Forall
© Свойство FolderRefereneesEnabled - «поддерживаются ли базой ссылки на
ПаПКИ»
'
LotusScript:
•'
'.
•
:'•
:
•
. • - . ' • . - ; • . . ' • • • '".' -:' : '.- ••'. •
•• ' " ' " . ' . ''' •
flag = notcsDatabase.VolderRcferencesEnabled
notesDatabase.'FolderReferencesE.nabled =flag
Java:
boolean flag ------ /)<3toAa$e.getFoIderReferencesEnabled()
void DataЈaye.setFoIderReferencesEnabled(Јoofean flag)
He все базы поддерживают ссылки на папки (folder references). Поэтому прежде чем для
конкретного документа из базы пытаться получить 4- свойством FolderReferences класса
[NotesJDocument названия содержащих этот документ папок (чтобы «узнать, в каких папках
этот документ находится»), необходимо проверить, поддерживает ли вообще база такую
возможность. Эта проверка осуществляется свойством FolderReferencesEnabled. True
означает, что ссылки на папки поддерживаются базой, a false - что не поддерживаются.
Реализуется же данная возможность посредством скрытых видов с названиями
SFolderlnto и $FolderReflnfo. Эти виды, как элементы дизайна, необходимо предварительно
скопировать в вашу базу данных из шаблона почтового ящика версии 5.0 - «простого
включения» свойства FolderReferencesEnabled недостаточно. Естественно, при этом и ваша
база данных должна быть формата R5 (ODS version 41).
Пример. Скрипт создает в базе новый документ, помещает его в папки с именами "viewl", "view2"
H"view3", а затем для каждого документа этой базы выводит названия содержащих его папок и их
количество.
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
.
:
.
.
. . .
.
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
428
Set db = session.CurrentDataba.se
If (db. FolderReferencesEnabled) Then.
Messagebox ("Folder References enabled") Else
Messagebox ("Folder References are not enabled")
Messagebox ("Enabling Folder References")
db.FolderReferencesEnabled = True
End If
Set doc = db.CreateDocument If
Not (doc Is Nothing) Then
Call doc.AppendltemValue("Name", "Test Document Name")
Call doc.AppendltemValue("Topic", "Test Document Topic")
Call doc:. Save (True, True)
Messagebox ("Adding document to views")
doc.PutlnFolder("viewl")
doc.PutlnFolder("view2")
doc.PutlnFolder("view3")
Call doc.Save(True, True)
End If
Dim doccoll As NotesDocumentCollection
Set doccoll = db.AllDocuments
Set, doc = doccoll. GetF'irstDocument
While Not (doc Is Nothing)
Л
i=0
J
Fora.ll FolderRef erence In doc. FolderReferences
i-i + 1
Print doc.noteid, " ", i, " ", FolderReference
End Fora11
Set doc = doccoll.GetNextDocument(doc) Wend
.'.••
Свойство DelayUpdates/IsDelayUpdates - «отложенные'изменения» " : • • • - . . • . ..LotusScript:
flag ~ notesDatabtise.DelayUpu&tes
notesDatabase.DelayUpdates ~flag
Java:
boolean flag = Database,isT)elayVpd&tes()
void Database.seiDelnyVpdsites(boolean flag)
Определяет способ передачи на сервер выполняемых клиентом операций по изменению
(сохранению или удалению) документов в базе, находящейся на сервере.
Если свойство равно false (значение по умолчанию), изменения документов будут
передаваться на сервер синхронно, т.е. приложение (агент, скрипт, апплет...) на клиенте,
изменив, например, объект [NotesJDocument и вызвав для него метод save, будет
«дожидаться» завершения передачи связанной с этим изменением информации на сервер,
прежде чем «в цикле» перейти к обработке следующего документа. Такой вариант
увеличивает время выполнения приложения на клиенте, однако гарантирует внесение в базу
всех выполненных клиентом изменений до момента его краха, если такое случится.
Если свойство равно true, изменения документов будут передаваться на сервер
асинхронно («отложенно»), т.е. приложение на клиенте, изменив, например, объект
[NotesJDocument и вызвав для него метод save, не будет «дожидаться» завершения передачи
связанной с этим изменением информации на сервер, а сразу перейдет к обработке
следующего «в цикле» документа. «Заказы на изменения» будут кэшироваться клиентом, а их
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @~формулы, LotusScript, встроенные классы LotusScript и Java
429
передача на сервер будет происходить «пакетом» лишь спустя некоторое время. Этот вариант
уменьшает время выполнения приложения и способствует улучшению производительности
клиента, однако в случае краха клиента «заказы на изменения», находящиеся в его кэше,
могут быть потеряны.
Значение свойства не сохраняется в самой базе - его необходимо устанавливать всякий
раз после открытия базы перед внесением в нее изменений.
Пример I. Скрипт устанавливает свойство Delay Updates.
Dim session As New NotesSession Dim
db As NotesDatabase Set db session.CurrentDatabase db.
Delay-Updates = True
Пример 2. Java-агент, начиная свою работу, устанавливает свойство DeiayUpdates в значение true,
если разработчик «написал DelayUpdat.es» в поле комментариев агента.
/ / Ja va - Dat. aba s e / De 1 ayUpdat es
Agent agent. -• agentContext . getCurrentAgent () ;
Database db = agentContext.getCurrentDatabase( ) ; if
(agent.getComment() != null)
if (agent.getComment() .equals{"DeiayUpdates") )
db,set Del a yUpdat es ( t r ue ); System.out.println("Delay
is " + db.isDelayUpdates());
- '
updates
3.5.5. Методы для создания новых баз, копий и реплик баз
Метод create - «создать пустую базу»
LotusScript:
Call notesDatabase.create( xerverS, dbftle$, openflag [, maxSize% ] )
Java:
Database db = DbDirectory.createDntabase(String dbfile)
Database db = (DbDireclory.createDatabase(String dbfile, boolean open)
Метод create создает новую «пустую» (точнее, с одним «безымянным» видом, как и при
создании новой базы без выбора шаблона, т.е. по «шаблону -Blank-») базу на указанном
сервере в указанном файле. Параметр server (тип String) - имя сервера или пустая строка (""),
если нужно создать локальную базу. Параметр dbfile (тип String) - имя файла создаваемой
базы. Если параметр openflag равен true, то метод должен открыть созданную базу
(объект-класса [NotesJDatabase), если false - открывать объект не требуется. Параметр
maxSize добавлен в версии 5.0 и задает максимально допустимый размер базы в Гбайтах
(допустимые значения 1, 2, 3, 4), когда база создается на сервере версии 4.x.
Если объект notesDatabase перед применением метода уже был связан с базой на сервере
или станции (например, если объект notesDalabase был получен методом New с непустыми
параметрами), то оба параметра server и dbfile метода create должны быть пустыми строками
("")•
Если файл базы с указанным именем на указанном сервере уже существует, в LotusScript
возникает ошибка "File already exists".
Агент, выполняющийся на сервере, может создать базу только на этом сервере, но не на
других серверах. Такое поведение, возможно, вызовет у читателя некоторое недоумение в
ситуации, когда оба сервера работают в пределах одной высокоскоростной локальной сети.
Но оно представляется логичным, если серверы связаны друг с другом по коммутируемому
соединению с использованием модемов, и, согласно документу 7 Connection, должны
связываться только раз в неделю ночью по воскресеньям для выполнения репликаций.
Справедливо «более широкое» высказывание: агент, выполняющийся на сервере, может
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
430
иметь доступ только к базам на этом сервере и не может иметь доступ к омам на других
серверах.
Если же скрипт выполняется на станции, он может создать базу на любом из серверов, к
которым пользователь имеет соответствующий доступ/
При создании скриптов, выполняющихся на сервере, самый надежный способ - указывать
имя сервера в виде пустой строки, что означает создание базы на этом же компьютере.
Пример, Скрипт создает новую базу на сервере Domirio/Org/RU в файле inventry.nsf, открывает ее и
присваивает ей название "Inventory Tracking".
Dim db As New NotesDatabase( "", "" )
Call db.create( "Domino/Org/RU", "inventry.nsf", True )
db. Title -^-- "Inventory Tracking"
Метод CreateFromTemplate - «создать базу по шаблону»
LotusScript:
Set notesDatabase — notesDatabase.createFromJ'emplstef serverS,
cib/ileS, inheritFlag [, maxSize% } )
Java:
Database db ~- Database.createFrom'Templa.te(String server, String dbfile,
boolean inherit)
База, к которой применяется метод, рассматривается как шаблон. По этому шаблону на
сервере server в файле dbfile создается новая база - возвращаемое значение метода. Эта новая
база будет содержать все элементы дизайна (формы, субформы, виды, навигаторы, поля,
агенты...) и документы из шаблона. Если флаг inherit равен true, в свойствах созданной базы
устанавливается наследование дизайна с шаблона, если false - не устанавливается.
В ситуации, когда база, к которой применяется метод, шаблоном не является, в
LotusScript новая база все равно создается посредством копирования элементов дизайна и
документов из существующей. Однако в этой же ситуации в Java новая база будет создана
«шаблону -Blank-», т.е. не будет содержать никаких элементов дизайна, кроме одного
«безымянного» вида.
Синтаксис и семантика параметров метода аналогичны параметрам метода create, и все
замечания к методу create имеют силу и для этого метода.
т
Пример I. Скрипт создает базу по шаблону «Дискуссии». Поскольку шаблон и создаваемая база
находятся на разных серверах, такой скрипт будет работоспособен только на станции.
Dim template As New NotesDatabase( "Dominol/Org/RU", "discswSO.ntf" ) Dim
db As NotesDatabase
Set db = template.CreateFromTemplate( "Domino2/Org/RU", "suggest.nsf", _
True )
db.Title = "Suggestions for Giving Campaign"
Пример 2. Java-агент создает базу по шаблону «Дискуссии». Поскольку шаблон и создаваемая база
находятся на «локальном компьютере», агент будет работоспособен как на станции, так и на сервере.
//
J a v a -D a t a b a s e / c r e a t e Fr o mT e mp l a t e
Database template - session.getDatabase(null, "discswSO.ntf");
Database db = template.CreateFromTemplate(null, "suggest", true);
db.setTitle("Suggestions for Giving Campaign");
System, out. .println ( "V'Suggest ions for Giving CampagnV created");
Метод createCopy - «создать копию базы»
LotusScript:
. '.:.-. :
.........
...
Set notesDatabase - notesDatabase.crenteCQpy( serverS, dbfileS
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
.-...Java:
431
[, maxSize% J )
Database db = Database.createCopy(Stri}ig server, String dbfile)
Создает копию (но без документов) базы, к которой применяется метод. Копия получает
из оригинала элементы дизайна, название базы и список управления доступом (ACL). Копия
будет иметь другой по сравнению с оригиналом идентификатор реплики.
Синтаксис и семантика параметров метода аналогичны соответствующим параметрам
методов create и createFromTempiate. Замечания к методу create имеют силу и для этого
метода.
ACL оригинала копируется в новую базу, но если требуется изменить ACL копии, можно
воспользоваться методами grantAccess и removeAccess.
.,
Пример 1. Скрипт создает копию (без документов) базы PURCHASE.NSF на сервере.
Dim db, archiveDb As NotesDatabase
Set db ;= New NotesDatabase ( "Domino/Org/RU" , "purchase . risf" )
Set archiveDb = db.createCopy( "Domino/Org/RU","archive\purchase.nsf"
)
Пример 2. Скрипт переносит все документы, имеющие в поле age значение "old", в архивную базу.
Если архивная база еще не создана, она создается методом createCopy.
Dim session As New NotesSession
Dim db As NotesDatabase
Dim archiveDb As NotesDatabase
Dim collection As NotesDocumentCollection
Dim doc As NotesDocument
Dim date'Time As New NotesDateTime ( "1/1/98" )
Set db = session.CurrentDatabase
Set archiveDb = New NotesDatabase( "", "" )
archiveServer$ = ""
archiveFile$ = "archiveV" + db.FileName
If (Not(archiveDb.Open(archiveServer$, archiveFile$ ))) Then
Set archiveDb = db. createCopy ( archiveServer$ , a.rchiveFile$ ) End
If
Set collection = db. search ( "age --- ""old"" ",
dateTime, 0 ) For
i = 1 To collection.Count
Set doc = collection.getNthDocument( i )
Call doc.copyToDatabase( archiveDb )
Call doc.remove( False )
Next
Пример 3. Java-агент создает «локальную» копию адресной книги. Этот агент работоспособен как
на станции, так и на сервере.
// Java-Database/createCopy
Database db = session.getDatabase(null, "names"};
String title =• db . getTitie () ;
Database db2 = db.createCopy(null, "names2");
db2.setTitle("Copy of names");
~ '
System, out .pr.intln ("Database \"" + title + "\" copied locally");
Метод createReplica - «создать реплику базы»
LotusScript:
Set notesDatabase — notesDatabase.createRcp\ica( server$, dbfileS )
Java:
Database db = Database.createRef>\Ka(String server, String dbfile)
Создает новую реплику базы, к которой применяется метод, в новом местоположении.
Новая реплика получает такую же ACL, как и оригинал.
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
432
Синтаксис и семантика параметров метода аналогичны двум первым параметрам метода
create и параметрам метода createCopy. Замечания к методам create и createCopy имеют силу и
для этого метода.
/
Пример 1. Скрипт создает реплику текущей базы на сервере, '
Dim session As New NotesSession
Dim db As Notes Database
_ ., •.
Dim replica As NotesDatabase
Set db = session.currentDatabase
Set replica = db.createReplica( "Domino/Org/RU",
.
"sales.nsf"
.
.
)
Пример 2, Java-агент, выполняющийся на станции, создает реплику базы DOMLOG.NSF
(«Протокол обращений к Web-серверу Domino») с сервера на станцию.
// Java-Database/createReplica
Database db = session.getDatabase("Dornino/Orq./RU", "Dorolog");
String title = db.getTitle();
Database replica = db.createReplica(null, "Domlog");
System.out.println("Database \"" + title ' "\" has a. new local replica");
3.5.6. Методы для «открытая» баз
Метод open - «открыть базу»
•
• ' . . ' ' ' • . : . . - . . - • • • : ................
LotusScript:
flag -~ notesDatabase.open( server$, db file $ )
Java:
boolean flag — Database,opcnQ
Database db ~-'-: DbDirectory,openDatsibase(S(rmg dbfile)
Database db -~ DbDirecto?'y.openDatabase(Slring dbfile, boolean fauover)
Открывает базу (более строго, объект класса NotesDatabase). Когда база открыта,
доступны все ее свойства и методы.
Параметр server$ (тип String) задает имя сервера, на котором находится база.
Использование пустой строки ("") либо означает, что база размещена локально, либо что
объект класса NotesDatabase уже связан с конкретной базой, а «сейчас» только открывается.
Параметр dbfile$ (тип String) задает имя файла базы. Использование пустой строки означает,
что объект класса NotesDatabase уже связан с конкретной базой, а «сейчас» только
открывается.
Возвращается true, если база существует и объект открылся, или false, если базы в данном
местоположении нет.
В LotusScript возможны два случая использования метода open.
•
•
Объект класса NotesDatabase создан и уже связан с существующей базой. В этом случае
вы должны либо задать оба параметра метода пустыми строками, например db.Open("",
""), либо указать их в точности такими, как они уже установлены в объекте класса
NotesDatabase. Если же вы попытаетесь «переназначить» уже установленные в объекте
сервер или файл, то получите сообщение об ошибке.
Объект класса NotesDatabase создан, но еще не связан с существующей базой. В этом
случае вы должны указать имя сервера (пустая строка вместо имени сервера теперь
означает, что база расположена локально), и имя базы (оно не может быть в этом случае
пустой строкой).
В Java метод open класса Database не имеет параметров, что соответствует «первому
случаю» - объект класса Database создан и уже связан с существующей базой. Однако
© InterTrust Со. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
433
имеется подобный метод класса DbDirectory, при использовании которого имя сервера «уже
было сообщено» при создании объекта DbDirectory, имя файла базы задается параметром
dbfile (тип String), а параметр failover, если он равен true, требует предпринять попытку
открыть базу на другом сервере-члене кластера, если ее не удалось открыть на
первоначальном. Этот метод возвращает открытый объект класса Database или null, если
реплику найти не удалось или она не открылась.
Выполняемый код (скрипт, Java-агент, Java-приложение или апплет) должен иметь
доступ к серверу, если база находится на сервере, и. доступ не ниже депозитора к
открываемой базе. В противном случае возникает ошибка или генерируется исключение в
связи с отсутствием доступа. Если код выполняется на станции, его доступ к базе совпадает с
доступом пользователя, под ID-файлом которого работает станция. Доступ апплета зависит
от того, как был аутентифицирован сервером клиент броузера. Если же код выполняется на
сервере, его доступ обычно определяется как доступ лица, сохранившего последним данный
код. Исключение из этого правила составляет выполняющийся на сервере агент с опцией
«Run agent as Web user» - его доступ зависит от того, как был аутентифицирован сервером
клиент броузера.
Пример 1. Скрипт открывает первую базу, найденную на текущем компьютере (сервере или
станции).
Dim directory As New NotesDbDirectory( "" )
Dim db As NotesDataba.se
Set db ^ directory.getFirstDatabase( DATABASE ) Call
db.Open( "", "" )
Пример 2. Подобно предыдущему примеру Java-агент открывает первую базу, найденную на
текущем компьютере. Текст агента приведен полностью, чтобы дополнительно продемонстрировать
читателям, которые только начинают освоение Java, создание собственных методов в классе.
import lotus.domino.*;
public class JavaAgent extends AgentBase
{
•
.
public void isitopen(Database db) throws NotesException {
if (db.isOpen{))
System.out.println("\"" + db.getTitle() + "\" is open"); else
System.out .println ("\"" + db. getTitle () -t "\" is not: open"); }
,
public void NotesMain()
\
}
try {
Session session = getSession();
AgentContext agentCcntext = session.getAgentContext(); /,/
Java-Database/open
DbDirectory Dir = session.getDbDirectory(null); Database db =
Dir.getFirstDatabase(DbDirectory.DATABASE); isitopen(db);
db.open();
isitopen(db);
'
} catch(Exception e) { e.printStackTrace{) ; }
. . . . . .
}
Пример З. Скрипт открывает базу SALES.NSF на сервере.
Dim db As New NotesDatabase( "", "" )
Call db.Open( "Domino/Org/RU", "sales.nsf" )
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
434
Пример 4. Скрипт пытается открыть на текущем компьютере базу archive\product.nsf. Если это не
удается, он создает базу archive\product.nsf как копию базы product.nsf, и обеспечивает к ней доступ
менеджера для Ivan Sidorov/Org/RU.
Dim archiveDb As New NotesDatabase ( "", "" )
Dim originalDb As New NotesDatabase( "", "product.nsf" )
Dim collection As NotesDocumentCollection
Dim doc As NotesDocumerit
If ( Not ( archiveDb.Open( "", "archive\" & originalDb.FileName ) ) ) Then
Set archiveDb = originalDb.CreateCopy( "", "archiveV &
originalDb.FileName }
Call archiveDb.GrantAccess{ "Ivan Sidorov/Org/RU", ACL_MANAGER )
End If
.
.
- -
Метод openWithFailover - «открыть базу на доступном члене кластера»
LotusScript:
flag - notesDatabase.openWMiFuilover( serverS, dbfileS }
Java:
Database db - DbDirectory.openfiatabase(Strmg dbfile, boolean failover)
Метод openWithFailover аналогичен методу open, но предпринимает попытку открыть
базу на другом сервере-члене кластера, если ее не удалось открыть на первоначальном в
связи с неработоспособностью сервера, уменьшением индекса доступности сервера ниже
заданного порога доступности или превышением допустимого количества работающих с
сервером пользователей. Аналогом этого в Java выступает метод openDatabase класса
Db Directory с параметром failover.
Метод openByReplicalD - «открыть базу по идентификатору реплики»
LotusScript:
flag = notes'.Database.openByReplicaID( serverS , replicaID$ )
Java:
Database db =- DbDirectory.openDatab&$<iByReplic'dlD(Strmg replicalD)
Открывает на заданном сервере базу, имеющую заданный ID реплики, если она
существует. Параметр serverS (тип String) - имя сервера или пустая строка (""), означающая,
что база находится на текущем компьютере. Параметр replicalD (тип String) - идентификатор
реплики базы.
В LotusScript возвращаемое значение равно true, если реплика найдена и объект
открылся, или false, если реплика не найдена или объект не открылся. В Java аналогичный
метод имеется в классе DbDirectory и возвращает открытый объект класса Database или null,
если реплику найти не удалось или она не открылась.
Пример. Java-агент предпринимает попытку открыть базу по идентификатору реплики.
// Java-Database/openDatabaseByReplicalD
,--.
DbDirectory dir = session.getDbDirectory(null};
String rid = "852565D2000B5144";
Database db = dir.openDatabaseByReplicalD(rid);
if (db !— null) System.out.println("help located and opened");
else
System.out.println("help not found");
Метод openlfModffied - «открыть базу, если она была модифицирована»
LotusScript;
Java:
flag = notesDatabase.openIfModiued( serverS, dbfileS, notesDateTime )
Database db - Z)/7D/rector>'.openDatabaseItModified(5/r/ng dbfile,
Date Time date)
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
435
Открывает указанную базу, только если она была модифицирована после заданного
момента времени.
,
В LotusScript параметр serverS (тип String) задает имя сервера, dhfileS (тип String) - имя
файла базы, a notesDateTime (объект класса NotesDateTime) - «момент отсечки» (cutoff date)
-если с этого момента времени в базе был изменен хотя бы один документ, база открывается,
иначе нет. Возвращается true, если объект открылся, или false, если нет.
В Java подобный метод имеется в классе DbDirectory и возвращает открытый объект
класса Database, если хотя бы один документ в базе подвергался модификации после
указанного момента времени, или null, если не подвергался, базу найти не удалось или она не
открылась.
Метод openMail - «открыть почтовый ящик»
LotusScript:
Call notesDatabase,openMail
Java:
Database db = jDM^iVectory.openMailDatabaseQ
В LotusScript открывает объект класса NotesDatabase, связанный с почтовым ящиком
пользователя.
..
,
' ' ' " - . ' ' .- .
В Java подобный метод применяется к объекту класса DbDirectory и возвращает
открытый объект класса Database, связанный с почтовым ящиком пользователя, или null,
если это не удапось.
Использование обоих методов имеет смысл либо со станции пользователя (скрипт или
Java-агент, выполняющийся на станции, может открыть базу на доступном сервере), либо на
почтовом сервере владельца агента (поскольку агент,, выполняющийся на сервере, все равно
не сможет открыть базу на другом сервере).
.
... .
*
Если выполнение происходит на станции, местоположение
пользователя устанавливается по информации из файла NOTES.INI.
почтового
ящика
•
Если выполнение осуществляется сервером, владельцем агента считается лицо,
последним модифицировавшее данный агент. Местоположение почтового ящика
владельца устанавливается поиском в общей адресной книге по имени владельца.
Пример. Скрипт определяет и выводит в диалоговом окне название базы и имя сервера для
почтового ящика пользователя, на станции которого происходит выполнение.
Dim db As New NotesDatabase( » " , " » )
Call db.OpenMail
Call db. Open { "", "" )
Messagebox ( db. Title & " on server " & db. Server )
..
• . • - • -
.....
Метод openURLDb - «открыть базу Web Navigator» . ,.-...;;,:..:; :.:::... . • .... ; .. :.-;..->-.•:.-..:;:..
LotusScript:
flag = notesDatabase.openVKLDb
Java:
Database db = Sesi'/on.getURLDatabaseQ
Открывает объект класса [NotesJDatabase, связанный с базой Web Navigator.
В LotusScript, если объект уже был связан с другой базой, та база сначала закрывается.
Возвращает true, если операция завершилась успешно, или false иначе.
.
В Java подобный метод имеется в классе Session и возвращает открытый объект класса
Database, связанный с базой Web Navigator, или null, если это не удалось.
©InterTrust Co. Тел. (095)9567928
Встроенные классы LotusScript и Java
436
3.5.7. Методы для получения документов
Метод createDocuraent - «создать новый документ»
LotusScript:
Java:
Set notesDocument = notesDatabase.createDocuniKiit
Document doc = Database.createDocnmentQ
Создает в базе, к которой применяется метод, новый документ, и возвращает объект
класса [NotesJDocument, представляющий этот документ. Чтобы созданный документ
сохранился в базе, не забудьте применить к нему метод save.
Для получения дополнительной информации смотрите класс [Notes]Document.
Метод getDocumentByID - «получить документ по Note ID»
LotusScript:
Set notesDocument = notesDatabase.geiDocumentBylD( notelDS )
Java:
Document doc = Database.getDocumentBylD(String notelD)
По заданному параметром notelD (тип String) идентификатору документа (Note ID)
находит документ в базе и возвращает объект класса [NotesJDocument, представляющий этот
документ. Идентификатор документа может быть получен свойством NotelD объекта класса
[NotesjDocument. Он представляется 8-и символьной строкой наподобие "000020FA".
Идентификатор документа, возвращаемый @-функцией @NoteID, содержит префикс "NT",
т.е. выглядит наподобие "NT000020FA".
Метод getDocumentByUNID - «получить документ по UNID»
LotusScript:
Java:
Set notesDocument = notesDatabase,geiDocumeniByUNTD( unid$ )
Document doc = Database.ge{DQCumeniByUNIJ)(Strmg unid)
По заданному параметром unid (тип String) универсальному идентификатору (UNID)
документа находит документ в базе и возвращает объект класса [Notes]Document,
представляющий этот документ. Универсальный идентификатор документа может быть
получен свойством UniversallD или ParentDocumentUNID объекта класса [Notes]Document.
Он одинаков для документа во всех репликах базы и представляется 32 -х символьной
строкой наподобие "CE44267695A4F344C32562CA005C80DB".
Пример 1. Скрипт демонстрирует два варианта получения документа-родителя по ответному
документу (response): по содержимому его поля $REF (оно содержит UNID документа-родителя) или
свойством ParentDocumentUNID.
?
Dim response As NotesDocument
Dim parent As NotesDocument
'...set value of response...
Set parent = db.GetDocumentByUNID( response.GetltemValue( "$REF" )( 0 ) )
' или
Set parent = db. GetDocumentByUNID ( response. ParentDocumentUNID )
Пример 2. Java-агент для каждого ответного документа в базе находит родительский документ и
выводит содержимое полей Subject обоих документов. Но обратите внимание, что как Java-агенты, так
и скрипты, написанные в подобной манере - «коллекции документов и прямой выбор документов»
-при большом количестве документов в базе характеризуются значительным временем исполнения.
// Java-Database/getDocumentByUNID Database db =
agent-Context. getCurrentDatabase ( ) ; DocumentCollection
dc = db . getAHDocuments () ; Document doc, pdoc;
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: ©-формулы, LotusScript, встроенные классы LotusScript и Java
String docSubj, pdocSubj;
for (int. i = 0; i < dc. getCount () ; i + f)
{
doc = dc.getNthDocument(i+1);
if (doc.isResponse()}
{
pdoc = db . getDocumentByUNID (doc . getParentDocument.UNTD () ) ;
docSubj = doc.getltemValueString("Subject");
pdocSubj = pdoc.getltemValueString("Subject");
System, out .println ( "V" + pdocSubj +
"\" has the response \"" + docSubj + "\>r") • } }
437
.
Метод getDocumentByURL - «получить документ по URL из базы Web
Navigator»
.
•
....•'..•'
LotusScript:
Set notesDocument ~ m>/esDa/aЈ>a.ve.getDocumentBylJRL( url$ [, reload ] [,
urllist ] [, charsetS ] [, webuser$ ] [, \vebpasswd$ ] [ ,proxyuser$ ] [,
proxypasswd$ ] [, nowait} )
Java:
Document doc — Database.geiDocumeniByU'RL(String url, boolean reload)
Document doc = Database.getDocumeniByURl^String url, boolean reload,
boolean relifmod, boolean urllist, String charset, String webuser. String
webpasswd, String proxymer, Stringproxypasswd, boolean nowait)
Объект класса [Notes]Database, к которому применяется метод, должен представлять
«серверную» или персональную базу Web Navigator. Метод возвращает объект класса
[NotesjDocument, представляющий документ из этой базы и соответствующий указанному
вами универсальному указателю ресурса (URL).
Параметр url (тип String) - универсальный указатель ресурса (URL), например,
"http://www.iotus.com". Длина строки не должна превышать 15 Кб.
В LotusScript необязательный параметр reload имеет тип Integer. Значение 1 указывает на то,
что необходимо «перезагрузить» гипертекстовую страницу с Web-сервера. Это «заставит»
серверную задачу WEB или станцию соединиться с тем Web-сервером, на котором находится
запрошенная страница, получить страницу, преобразовать ее в формат документа Notes, т.е.
создать документ-образ, поместить документ-образ в базу Web Navigator, и только после
этого создать объект класса NotesDocument, представляющий соответствующий странице
документ из базы. Значение 2 «требует перезагружать» страницу с Web-сервера только тогда,
когда она была модифицирована на Web-сервере по отношению к уже имеющемуся в базе
Web Navigator ее документу-образу, или когда документа-образа еще нет в базе. Значение О
или отсутствие параметра указывает на то, что не требуется выполнять перезагрузку
страницы с Web-сервера. Если образ этой страницы уже имеется в базе Web Navigator, для
него будет создан объект класса NotesDocument. Если же образа запрошенной страницы в
базе Web Navigator нет, страница будет получена с Web-сервера, в базе Web Navigator будет
создан ее документ-образ и возвращен представляющий его объект класса NotesDocument.
В Java аналогичный эффект достигается двумя параметрами типа boolean. Если параметр
reload равен true, то необходимо всегда перезагружать страницу с Web-сервера, если false
-загружать страницу с Web-сервера нужно только тогда, когда ее документа-образа еще нет в
базе. Однако параметр relifmod позволяет уточнить поведение, когда reload = false. Если
relifmod -- true, то страницу требуется загружать, когда ее документа-образа нет в базе, а так же
перезагружать тогда, когда она была модифицирована па Web-сервере по отношению к
© InterTrust Со. Тел, (095) 9567928
Встроенные классы LotusScript u Java
438
уже имеющемуся в базе ее документу-образу. Если же relifmod = false, то страницу требуется
загружать только тогда, когда ее документа-образа нет в базе.
Запрошенная вами HTML-страница обычно содержит ссылки (URL) на другие страницы.
Можно получить список всех ссылок страницы в отдельном поле документа-образа этой
страницы. Естественно, выбор возможности ухудшает производительность, но любителям
создавать «роботов» («пауков», «странников»...) - приложения, автоматически, обычно
рекурсивно, получающих HTML-страницы с Web-серверов - эта возможность может
пригодиться. Параметр urllist имеет в LotusScript тип Integer (по умолчанию 0), а в Java - тип
boolean (в методе с двумя параметрами предполагается false). Значение I/true указывает на
то, что все URL-ссылки (если есть) с этой страницы должны сохраняться в документе-образе
страницы в текстовых полях с именами URLLinksn, а О/false - что не должны. Если
возможность выбрана, «первое» поле со списком ссылок имеет имя URLLinksl. Если ссылок
много, и их общий размер превышает 64 Кб, автоматически создается поле с именем
URLLinks2, содержащее логическое продолжение списка, и т.д.
Параметр char.set (тип String) за/дает кодировку, использованную на странице. Значение
по умолчанию ""/null - задача WEB или клиент автоматически распознает кодировку
страницы по ее MIME-атрибутам, а при их отсутствии в соответствии со своими
настройками. Указывать кодировку явно, например, "ISO-8859-5", имеет смысл только тогда,
когда кодировка неправильно опознается автоматически.
Web-сервер, с которого должна быть получена страница, может требовать вашей
аутентификации. Параметры webuser и webpasswd (оба типа String, по умолчанию ""/null)
позволяют сообщить имя и пароль для доступа к Web-серверу.
Задача WEB или станция клиента может иметь доступ в Internet через proxy-сервер,
требующий аутентификации вводом имени и пароля. Параметры proxyuser и proxypasswd
(оба типа String, по умолчанию ""/null) позволяют сообщить имя и пароль для доступа к
proxy-серверу.
.
Последний параметр nowait, если задать его равным true, обеспечит «асинхронный
возврат» из метода еще до того, как операция «скачивания страницы» завершится. Однако в
этом случае вы не получите объекта [NotesJDocument - будет возвращено null. Значение же
по умолчанию равно false - метод завершается «синхронно» и возвращает объект
[NotesJDocument.
Метод getURLHeadeflhfo - «получить HTTP/1.0 header fields для страницы»
LotusScript: header$ = notc'sDatabase.geiUWLMenderlnfo(url$ , headername$
.
Java:
..
[, webuser$ ] [, webpasswd$ ] [ ,proxyuser$ } [, proxypass\vd$ ] )
String header = Database.getUKLHeaderInfQ(Strmg url, String headername,
String webuser, String webpasswd, Siring proxyuser, String proxypasswd)
Объект класса [NotesJDatabase, к которому применяется метод, должен представлять
«серверную» базу Web Navigator. Метод позволяет получить значения полей (HTTP/1.0
header fields) страницы, заданной универсальным указателем ресурса url Имеются в виду
значения полей, упомянутых в разделе 10 документа RFC 1945 «Hypertext Transfer Protocol HTTP/1.0», например, Content-Encoding, Content-Type, Content-Length, Date, Last-Modified,
Server и др. Чтобы получить значение header, нужно указать название поля - headername.
Символы «тире» в названиях полей должны быть предварительно заменены на символы
подчеркивания, но с версии 5.0 это выполняется автоматически. Все параметры метода и
возвращаемое значение типа String. Параметры, за исключением headername, точно такие же,
как в методе getDocumentByURL. Если название поля или URL не найдены, возвращается
""/null.
,
. . . . . .
© InterTrust Со. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
439
Пример. Скорее некоторая «загадочность», чем практическая ценность метода вынуждают
привести пример его использования. Так, приведенный ниже скрипт вывел в диалоговых окнах
следующее:
Content-Encoding =
Content-Type = text/html;charset=WlNDOWS-1251
Content-Length = 5969
Date= 18.12.98 13:57:59 GMT (текущий момент времени)
Last-Modified = (действительно отсутствовал для этой страницы)
Server = Lotus-Domino/Release-4.6.2
Dim db As NotesDataba.se
•
Set db = New NotesDatabase("","")
Dim URL, hn As String
. '••
URL = "http://www.inttrust.ru"
.
If db.openURLDb() Then
Print db.Title
hn = "Content Encoding"
MsgBox (hn & " ' = " & db.getURLHeade.rInfo{tTRL,hn) )
hn = "Content_Type"
MsgBox (hn & " --= " & db. getURLHeaderlnfо (URL,hn) )
hn — "Content_Length"
MsgBox (hn & " =- " & db. getURLHeaderlnf о (URL, hn) )
hn = "Date"
MsgBox <hn & " - " & db.getURLHeaderlnfо(URL, hn) }
hn = "Last Modified"
MsgBox (hn & " = " & db.getURLHeaderlnfо(URL,hn)}
hn = "Server"
MsgBox (hn & " = " & db.getURLHeaderlnfо(URL,hn)) End
If
Метод getP^offleDocument - «создать или получить профильный документ»
LotusScript:
Set notesDocument = notesDatabase,geiProuleBocument( profileName$
[, userName$ ] )
Java:
Document profileDoc = Database,getProfi\eDocument(StringprqfileName,
String userName)
«Профильные» документы (profile documents) предоставляют быстрый, простой и
эффективный способ сохранения в базе и последующего извлечения из нее всевозможных
данных, относящихся как ко многим пользователям, так и к конкретному пользователю. В
отличие от обычных документов, профильные документы не отображаются в видах базы и не
учитываются при подсчете количества документов в базе. Профильный документ всегда имеет
имя и может быть извлечен из базы по этому имени. Для более удобного доступа к такому
документу может быть изготовлена форма, имя или алиас которой должны в точности
совпадать с именем профильного документа. Тогда «по команде» @Command([EditPro(ile} ;
formName) можно «перевести» этот документ в режим редактирования. Имя профильного
документа можно рассматривать как «первичный ключ» для доступа к нему. Профильные
документы только с «первичным ключом» обычно используются для хранения данных,
относящихся ко многим пользователям. При необходимости обеспечить для каждого
пользователя свой уникальный профильный документ в качестве «вторичного ключа»
используется имя пользователя в «каноническом» формате. К такому документу возможен
доступ «командой» @Cornmand([EditProfile] ; formName ; userName), где formName задает
имя профильного документа и одновременно является именем или алиасом формы,
используемой для доступа к такому документу, a userName - имя пользователя, задающее
конкретный документ.
© InterTrust Со. Тел. (095) 9567928
440
Встроенные классы LotusScript и Java
Отметим, что в профильном документе всегда присутствует поле с предопределенным
именем $Name, содержащее, как показывают эксперименты, информацию либо вида
«$profile_NNN__/brwA'a/K&_» (например, "Sprofile 008protllel_"), если это «не привязанный к
пользователю» документ, или информацию вида «Sprofile NNN_formName_userName»
(например, "$profile_008profilel_cn=nikolay n. ipntsev/o=intertrustcorp/c=su"), если документ
«привязан к пользователю», а так же поле SNoPurge, означающее, что этот документ не
подлежит удалению.
Рассматриваемый метод возвращает объект класса [Notes]Document, представляющий
профильный документ с именем profileName (тип String) и относящийся к пользователю
userName (тип String). Если профильный документ с именем profileName для пользователя
userName существует, возвращаемый объект класса [Notes]Document представляет этот
документ, и вам становится доступна информация из его полей. Если же такой документ
отсутствует, то метод создает объект класса [Notes]Document для «нового» документа, и вы
можете создать в нем необходимые поля, а затем сохранить этот документ, применив к нему
метод save. Когда вы указываете в качестве параметра userName пустую строку, имеется в
виду профильный документ, не относящийся ни к какому пользователю».
Пример 1. Скрипт получает доступ к профильному документу с именем "Interest Profile" для
текущего пользователя, а затем получает и выводит информацию из полей этого документа.
Предполагается, что поля документа содержат списки значений, поэтому значительная часть кода
относится в извлечению и форматированию выводимой информации.
Dim session As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim profileAuthors As Notesltem
Dim. profileStrings As Notesltem
Dim stringAuthors As String
Dim stringStrings As String
Set db = session.CurrentDatabase
Set doc = db.GetProfileDocument{"Interest Profile", session.UserName)
Set profileAuthors = doc.GetFirstltem("ProfileAuthors"}
Set profileStrings - doc.GetFirstltem("ProfileStrings")
stringAuthors - ""
stringStrings =•• ""
Forall profileAuthor In profileAuthors.Values
stringAuthors = stringAuthors & Chr(lO) SprofileAuthor End
Forall Forall profileString In profileStrings.Values
stringStrings -- stringStrings & Chr(lO) &profileString End
Forall If stringAuthors = "" Then
stringAuthors = "None"
•;
Else
•
"
stringAuthors -- Right(stringAuthors, Len(stringAuthors) - 1) End
If If stringStrings = "" Then
stringAuthors r= "None"
Else
stringStrings = Right(stringStrings, Len(stringStrings) - 1) End
If
Messagebox stringAuthors,, "Profile authors"
Messagebox stringStrings,, "Profile strings"
Пример 2. Java-агент получает доступ к профильному документу с именем "Author Profile" для
текущего пользователя, а затем получает и выводит информацию из полей этого документа.
// Java-Database/getProfileDocument ©
InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
441
Database db = agentContext.getCurrentDatabase(};
Document doc = db.getProfileDocument("Author Profile",
session.getUserNameО);
String who =: doc . getItemValueString ( "Who" } ; String
email - doc.getltemValueString("Email"); String
phone = doc.getItemValueString ( "Phone");
System.out.println("Who:
" + who);
System.out.println("Email: " + email);
System.out.println("Phone: " + phone);
© Метод getProfileDocColIection - «получить коллекцию профильных
документовбазы». . " : . . ' .' .:. ..: : . . . . . . . . . . ' . ' . . . . . ••.'...." :
LotusScript:
:
Set notesDocumentCollection = notesDatabase.getProTilcDocCottection(
[proftleName$] )
Java:
DocumenlCollection dc - Da/a^as't'-getProfileDocColiectionC
Siring profileName)
Возвращает объект класса [NotesJDocumentCoIlection, представляющий коллекцию
(возможно, пустую) из профильных документов с именем profileName (тип String), т.е.
«созданных по форме» profileName. Если параметр profileName опущен в LotusScript или
задан равным null в Java, возвращается коллекция из всех профильных документов базы.
Пример. Java-агент демонстрирует цикл для получения всех профильных документов с именем
"Author Profile".
/ / J av a - Da t ab as e /g e tP ro fil e Do cCo l l ec t ion
Database db = agentContext.getCurrentDatabase( } ;
DocumentCollection dc = db.getProfileDocColIection("Author
Profile");
Document: doc - dc . getFirstDocument (} ;
while (doc !- null)
{
System.out.println(doc.getItemValueString("Who"));
doc = dc.getNextDocument(}; }
3.5.8. Методы для получения элементов дизайна
Метод getAgent - «получить агента»
LotusScript:
Set notesAgent = notes Database.get Agent( agentName$ )
Java:
Agent agent = Database.getAgent(String agentName)
По заданному имени агента возвращает объект, представляющий этот агент из базы, к
которой применяется метод.
Пример 1. Скрипт выводит в окне список имен агентов базы, получает от пользователя имя агента
для запуска и запускает этого агента.
Dim session As New NotesSession
Dim db As NotesDatabase
Dim theAgent As NotesAgent
Dim agentString As String
Set db = session.CurrentDatabase
Forall agent In db.Agents
agentString = agentString & Chr(lO) &
End Forall
agent.Name
' .
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
442
Messagebox agent-String,, "Agents"
Set theAgent = db.GetAgent(Inputbox("Which agent do you want to run?"))
If Not(theAgent Is Nothing) Then
Call theAgent.. Run
Else
Messagebox "No existing agent selected" End
If
Пример 2, Java-агент получает агента с именем My Agent и выводит некоторые его свойства.
/ / J a va -D at a ba s e / g etA g e nt
Database db ™ agentContext.getCurrentDatabase ( ) ;
Agent agent
= db.getAgent("My Agent");
System.out.printIn("Agent:\t" + agent.getName());
System.out.println("Owner:\t" + agent.getOwner( ) ) ;
System.out.println("Last run:\t" + agent.getLastRun( } ) ;
System, out .print .In ( "Query: \t" + agent. getQuery ( ) ) ;
Метод getView - «получить вид или панку»
.
.
.
.
LotusScript:
Set notesView ~ notesDatabase.getVie\v( viewName$ )
Java:
View view ~ Database*getVK\v(Sl:ring viewNanie)
По заданному имени вида или папки возвращает объект, представляющий этот вид или
папку из базы, к которой применяется метод.
Параметр viewName (тип String) - имя вида или папки в базе - не чувствителен к регистру.
Это должно быть или полное имя вида или папки (включая обратный слеш для «каскадных»
имен) или алиас (синоним), но не оба вместе. Например, для вида "MaimBy Author |
AuthorView" можно указать либо "MainVBy Author", либо "AuthorView". Символ
подчеркивания в именах видов или папок, используемый для выбора клавиши-акселератора,
можно как включать в задаваемое имя, так и не включать. Если он включен в имя, метод
работает немного быстрее. Возвращаемое значение - объект класса [NotesJView,
представляющий вид или папку.
Если база расположена на сервере, метод может вернуть только общий вид или папку.
Если же база локальна, метод может вернуть как общий, так и личный вид или папку,
который хранится не в базе, а в файле DESKTOP.DSK на компьютере пользователя.
Пример 1. Скрипт получает вид Main View в текущей базе и выводит в окне имя вица.
Dim session As New NotesSession
Dim db As NotesDatabase
Dim view As NotesView
Set db - session.CurrentDatabase
Set view = db.GetView( "Main View"
Messagebox{ view.Name }
,,
.
)
Пример 2. Java-агент получает вид ($А11) в текущей базе и выводит и выводит количество колонок
в нем.
// Java-Database/getDocumentByUNID
Database db = agentContext.getCurrentDatabase ( ) ;
View view = db.getView("($A11)" ) ;
System.out.println("($A11) has " +
view.getColumns( ) . size() + " columns");
Метод getForm - «получить форму»
LotusScript:
Set notesForm = notesDatabase.geiForm(formName$ )
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
Java:
443
Form form - Database.getForm(StringformName)
По заданному имени формы возвращает объект, представляющий эту форму из базы, к
которой применяется метод. Параметр formName (тип String) - или полное имя формы
(включая обратный слеш для «каскадных» имен) или алиас (синоним), но не оба вместе.
Возвращаемое значение - объект класса [Notes]Form, представляющий форму.
Пример. Скрипт проверяет, существует ли в текущей базе форма, имя или алиас которой вводятся в
диалоговом окне.
Dun session As New NotesSession
Dim db As NotesDatabase
Dim form As NotesForm
On Error Goto processError
Set. db --= session. CurrentDatabase
formNameln = Inputbox ("Name of form1?")
Set form = db.GetForm(formNameln)
Messagebox "The form """ & form.Name & """ exists"
Exit Sub
processError:
REM If Err () = ErrObjectVariableNotSet Then
If
Err() =• 91 Then
Messagebox "The form """ & formNameln & """ does not exist" Else
Messagebox "Error " & Err() & ": " & Error()
End If
.
Exit Sub
© Метод getOutline - «получить существующую Outline»
LotusScript:
Set notesOiitline = notesDatabase.getOutlme(outlinename$)
Java:
Outline outline = Database.getQutlim(String outlineName)
Возвращает объект класса [NotesjOutline, представляющий существующую в базе Outline
(как элемент дизайна) с именем outlineName (тип String).
@ Метод createOutliiie - «создать новую Outline»
LotusScript:
Set notesOutline ~ notesDatabase.createOuUme(outlinename$
[, defaultOutline})
Java:
Outline outline — Database,ci*eateQutline(Slririg outlineName)
Outline outline = Database.createOutline(String outlineName,
boolean defaultOutline)
Создает в базе новую Outline (как элемент дизайна) и возвращает объект класса
[NotesjOutline, представляющий этот элемент дизайна. Параметр outlineName (тип String)
задает название для создаваемой Outline. Однако если в базе уже существует Outline с таким
названием, то объект [NotesjOutline будет представлять этот существующий элемент
дизайна. Если параметр defaultOutline равен false (по умолчанию), то создается «пустая»
Outline, если true - создается Outline с элементами по умолчанию.
Остальные подробности даются в описании классов [NotesjOutline и [NotesjOutlineEntry.
Встроенные классы LotusScript и Java
444
@ Метод enabkFoIder - «создать папку, если ее нет»
LotusScript:
Call notesDatabase.enahleҐolder(folderName$ )
Java:
void Database.eaableFolder(String folderName)
Проверяет, существует ли в базе папка с именем folder Name. При отсутствии создает
новую папку с таким именем.
3.5.9. Методы для управления доступом к базе
Метод query Access - «получить уровень доступа»
LotusScript:
Java:
/eve/% = notesDatabase.queryA,cce$s( nameS )
int level = Datcjbase.queryAccess(String name)
Возвращает уровень доступа субъекта с именем пате (тип String) к данной базе. Субъект
может быть пользователем, группой или сервером. Имя субъекта может как присутствовать,
так и отсутствовать в списке управления доступом (ACL) базы. Возвращаемое значение level
* константа типа Integer/int, ее возможные значения:
« ACLLEVEL _NOACCESS / ACL.LEVEL_NOACCESS - нет доступа,
* ACLLEVEL DEPOSITOR / ACL.LEVEL_DEPOSITOR - депозитор,
* ACLLEVEL_READER / ACL.LEVEL_READER - читатель,
* ACLLEVEL, AUTHOR / ACL.LEVEL_AUTHOR - автор,
» ACLLEVEL EDITOR / ACL.LEVEL_EDITOR - редактор,
* ACLLEVEL DESIGNER / ACL.LEVEL_DESIGNER - дизайнер,
* ACLLEVEL^ MANAGER / ACL.LEVEL ^MANAGER - менеджер.
Если имя субъекта иерархическое, должно быть указано полное имя в формате
[Canonicalize], например "CN=Vladimir A. Panov/O=InterTrustCorp/C=SU", или [Abbreviate],
например "Vladimir A. Panov/lnterTrustCorp/SU",
Если указанное имя субъекта явно присутствует в ACL базы, возвращается уровень
доступа субъекта. Если указанное имя субъекта отсутствует в ACL базы явным образом,
метод выполняет следующее:
*
*
*
если субъект является членом группы, а название этой группы присутствует в АСЕ базы,
метод возвращает уровень доступа группы;
если субъект является членом нескольких групп из ACL базы, метод возвращает
наибольший уровень доступа среди этих групп;
если субъект не является членом ни одной из групп в ACL базы, метод возвращает
уровень доступа «любого прочего» (-Default-) к этой базе.
Состав групп всегда определяется методом по основной адресной книге компьютера, на
котором происходит выполнение.
Пример 1. Скрипт определяет уровень доступа пользователя с именем Vladimir A.
Panov/lnterTrustCorp/SU к базе CHECK.NSF.
Dim db As NotesDatabase
Dim level. As Integer
Set db = New NotesDatabase( "NotesSrv400/InterTrustCorp/SU", "check.nsf"~ )
level = db.QueryAccess( "Vladimir A. Panov/lnterTrustCorp/SU" )
Если в ACL базы явно указано, что Vladimir A. Panov/lnterTrustCorp/SU имеет доступ автора,
независимо от того, в какие группы он входит, возвращается ACLLEVEL AUTHOR.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
445
Если Vladimir A. Panov/InterTrustCorp/SU член группы, которая имеет доступ дизайнера к базе, но
сам Vladimir A. Panov/InterTrustCorp/SU не указан явно в ACL базы, возвращается
ACLLEVEL_DESIGNER.
Если Vladimir A. Panov/lnterTrustCorp/SU член одной группы, имеющей доступ редактора к базе, и
одновременно член другой группы, имеющей доступ дизайнера к базе, но сам Vladimir A.
Panov/InterTrustCorp/SU не указан явно в ACL базы, возвращается ACLLEVEL_DESIGNER.
Если Vladimir A. Panov/lnterTrustCorp/SU не указан явно в ACL базы и не является членом ни
одной группы в ACL базы, а для -Default- в ACL базы указан доступ читателя, возвращается
ACLLEVEL READER.
Пример 2. Java-агент определяет уровень доступа текущего пользователя к текущей базе.
// Java-Database/queryAccess
Database db = agentContext.getCurrentDatabase();
String title = db.getTitle();
int accLevel = db,queryAccess(session.getUserName( ) ) ;
System, out .print {"E'or database \ " " + title + "\" you have " ) ;
switch (accLevel)
i
case(ACL.LEVEL_NOACCESS}
case(ACL.LEVEL_DEPOSITOR)
case(ACL.LEVEL_READER)
case(ACL.LEVEL^AUTHOR)
case(ACL.LEVEL_EDITOR)
case(ACL.LEVEL_DESIGNER)
case(ACL.LEVEL_MANAGER)
default
}
System.out.println ("
System.out.print("no");
System.out.print("depositor");
System.out.print("reader");
System.out.print("author");
System.out.print("editor");
System.out.print("designer");
S y s te m . o u t . p r in t ( " m a n a g e r " };
System.out.print("unknown");
break ;
break;
break ;
break;
break ;
break ;
break;
break;
access");
Метод grantAccess - «предоставить уровень доступа»
LotusScript:
Call notesDatabase.grantA.ccess( name$ , /eve/% )
Java:
void Database,grantAcce$s(String name, int level)
-
Изменяет список управления доступом (ACL) базы так, что заданному имени пате
(пользователю, серверу или группе) предоставляется заданный уровень доступа level. Если
заданное имя уже присутствует в ACL базы, изменяется только уровень доступа, иначе
заданное имя добавляется в ACL базы с заданным уровнем доступа,
Параметр пате типа String, a level - константа типа Integer/int, возможные значения
которой такие же, как в методе queryAccess.
Пример 1. Скрипт предоставляет к базе всем из группы Sales Supervisors доступ автора, a Sam
Sidorov/Acme/RU - доступ менеджера.
Dim db As New NotesDatabase{ "Serverl/Acme/RU", "profits.nsf"
db.GrantAccess( "Sales Supervisors", ACLLEVEL_AUTHOR ) Call
db.GrantAccess{ "Sam Sidorov/Acme/RU", ACLLEVEL_MANAGER )
) Call
Пример 2. Java-агент предоставляет к базе доступ менеджера всем серверам данного домена и
доступ читателя всем серверам из других доменов,
//' Java-Database/queryAccess
Database db = agentContext.getCurrentDatabase();
db.grantAccess("LocalDomainServers", ACL.LEVEL__MANAGER);
db.grantAccess("OtherDomainServers", ACL.LEVEL_JREADER);
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
446
Метод revokeAccess - «удалить из ACL базы»
. .•••
LotusScript:
Call notesDa(abase.revokeA.ccess( name.$ )
Java:
void Database.revokeAcces$(Strmg name)
Удаляет имя пользователя, группы или сервера, заданное параметром пате (тип String) из
списка управления доступом (ACL) базы.
Применение метода revoke отличается от присвоения методом grantAccess доступа
ACLLEVEL NOACCESS / ACL.LEVEL NOACCESS. Метод revoke просто удаляет имя
субъекта из ACL, но этот субъект eaie может иметь к базе доступ как -Default- или как член
группы. Когда лее метод grantAccess «явно» присваивает имени субъекта уровень доступа
NOACCESS, субъект безусловно не будет иметь доступа к базе, независимо от установок для
-Default- и его «вхождения» в группы.
Если имя пате отсутствует в ACL, в LotusScript возникает ошибка, а в Java генерируется
исключение "The name is not in the list".
Пример. Скрипт лишает Willi Hacker/Acme права пользования базой. Сначала скрипт удаляет имя
Willi Hacker/Acme из ACL, «стремясь не засорять АС1. лишними именами». Но затем проверяет,
сохранил ли после этого Willi Hacker/Acme какой-нибудь доступ к базе. Если все-таки сохранил (как
-Default- или член группы), то скрипт вновь обеспечивает явное присутствие в ACL имени Willi
Hacker/Acme с уровнем доступа No Access.
Dim user As String
user = "Willi Hacker/Acme"
Him db As New NotesDatabase( "Serverl/Acme/RU", "profits.nsf" )
Call db.RevokeAccess( user )
If ( db.QueryAccess( user ) <> ACLLEVEL_NOACCESS ) Then
Call db.GrantAccess( user , ACLLEVEL_NOACCESS } End
If
3.5.10. Методы полнотекстового поиска и «обычного» поиска документов
Метод FTSearch - «полнотекстовый поиск по базе»
LotusScript:
Set notesDocumentCollection ~ notesDatabase.ҐTSearch( queryS,
moxDocs% I, sortoptions [, otheroptions}})
Java:
.
DocumentCollection dc -••- Databose.ҐTSearcb(String query)
DocumenlCollection dc — Dalabasc.FTSearch(Sfring query, bit maxDocs)
DocumentCollection dc = Database.FTSe&rch(String query, inf maxDocs, in!
sortoptions, int otheroptions)
Выполняет запрос полнотекстового поиска по всем документам в базе. Параметр query
(тип String) задает запрос полнотекстового поиска. Параметр maxDocs (тип Integer/int)
сообщает, что в качестве ответа на запрос должно возвращаться не более чем maxDocs
документов. Чтобы возвращались все удовлетворяющие запросу документы, задайте 0.
Параметр sortoptions (тип Integer/int) сообщает порядок, в котором должна быть
отсортирована полученная коллекция документов: F1 SCORES/Database.FT_SCORES (по
умолчанию)
- по
убыванию
показателя
соответствия
поисковому запросу,
FT_DATE_DES/Database.FT_DATE_DES - по убыванию времени создания документов
(«более свежие в начале»), FT_DATE ASC/Database.FT DATE_ASC - по возрастанию
времени создания документов («более свежие в конце»).
© InterTrust Со. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
447
Параметр otheroptions (тип Integer/int) задает дополнительные опции поиска:
FT_STEMS/Database.FT_STEMS - выполнять поиск так же по синонимам слов из запроса,
FT_FUZZY/Database.FT FUZZY - выполнять поиск так же по «однокоренным» словам из
запроса, FT_DATABASE/Database.FT_DATABASE - выполнять поиск в базах Domino,
FT_FILESYSTEM/Database.FT_FILESYSTEM - выполнять поиск в файлах, не являющихся
базами Domino. Возможен выбор нескольких опций, например, FT STEMS + FT FUZZY, a
значение 0 трактуется как отсутствие дополнительных опций.
Возвращаемое значение представляет собой коллекцию документов (объект класса
[Notes]DocumentCollection), удовлетворяющих запросу. Если ничего не найдено, в
возвращаемой коллекции будет 0 элементов. Коллекция соответствующим образом
отсортирована. Если она отсортирована по убыванию значения показателя соответствия
поисковому запросу, то получить значение показателя для любого документа из коллекции
можно свойством FTSearchScore класса [Notes]Document.
Метод работает, даже если база не имеет индекса полнотекстового поиска, однако
значительно менее эффективно. Для проверки наличия индекса полнотекстового поиска
используют свойство IsFTIndexed, а для создания индекса - метод updateFTIndex. Для поиска не
по всем документам в базе, а только по документам из заданного вида используют
одноименный метод класса [NotesJView. Для поиска же по предварительно отобранной
коллекции документов используют метод FTSearch класса [Notes]DocumentCollection.
Если база, к которой применяется метод, имеет индекс полнотекстового поиска по
многим базам (имеется в виду база типа Multi DB Search, а не база, имеющая
«установленное» свойство MultiDbSearch), то в коллекции найденных документов могут
содержаться документы из разных баз.
Пример. Скрипт присылает Joann Smera/Medical обзорный документ, содержащий ссылки
(DocLink-и) на все документы из базы invntion.nsf на сервере Berlin/Medical, которые были обнаружены
полнотекстовым поиском. Запрос полнотекстового поиска требует, чтобы документ содержал слово
"vaccine" (вакцина). Отбирается не более 10 документов. Если база не имеет индекса полнотекстового
поиска, запрос не выполняется.
Dim db As New NotesDatabase( "Berlin/Medical", "invntion.nsf" ) Dim
collection As NotesDocumentCollection Dim newsletter As
NotesNewsletter Dim doc As NotesDocument If db.IsFTIndexed Then
Set collection = db. FTSearch { "vaccine-", 10 )
Set newsletter = New NotesNewsletter( collection )
Set doc = newsletter.FormatMsgWithDoclinks( db )
'
doc.Form = "Memo"
doc.Subject = "Here's the newsletter you requested."
Call doc.Send( False, "Joann Smera/Medical" )
End If
. , . . ; . .
Пример 2. Java-агент выполняет запрос полнотекстового поиска по текущей базе и выводит
количество обнаруженных документов.
//
J a va -D a ta b a se / FT S e a rch
Database db = agentContext.getCurrentDatabase();
String title -= db . getTitle ( ) ;
String qry = "";
if (db.isFTIndexed())
{
// He более .10 документов со словом "vaccine"
/I qry = "vaccine";
// DocumentCollection dc = db.FTSearch(qry, 10);
// He более 100 документов со словами "red" и "blue"
// qry = "red & blue";
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
448
I/ DocumentCollection dc = db.FTSearch("red & blue", 100);
//' He более 100 документов со словами "red" и "blue" и сортировкой
// найденных документов по убыванию даты создания
qry = "red & blue";
DocumentCollection dc = db.FTSearch(qry, 100,' Database.FT_DATE_DES, 0);
int matches = dc.getCount ();
System.out.println("FTSearch of \"" + title + "\" found " +
matches + " document, (s) with " + qry); } e
1se
Syst em. out .pr int ln ( " Data bas e V " + ti tle +
"\" is not full text indexed");
Метод unprocessedFTSearch - «полнотекстовый поиск по необработанным
агентом документам»
.
.. . . . . . . . . . ...^
LotusScript:
Set notesDocitmentCollection = notesDataha$e.nnprocesse<lҐTSearcli(
queryS, maxDocs% [, sortoptions [, otheroptions\\)
Java:
DocumentCollection dc = AgentContext.unprocessedFTSearcb(
String query, int maxDocs)
DocumentCollection dc = AgentContext.nnprocessedҐTSeai
ch( String query, int maxDocs, int sortoptions, int otheroptions)
Для заданного запроса полнотекстового поиска возвращает коллекцию документов,
которые еще не обработаны текущим агентом (unprocessed) и удовлетворяют запросу
полнотекстового поиска. Все параметры и возвращаемое значение такие же, как в методе
FTSearch.
В LotusScript этот метод может применяться только в скриптах агентов и действий по
виду (view actions), и только при условии, что объект класса NotesDatabase получен
свойством CurrentDatabase из объекта класса NotesSession. Если метод пытаются применять в
ином контексте, получают пустую коллекцию. Если метод пытаются применять к объекту,
полученному не свойством CurrentDatabase из объекта класса NotesSession, получают
сообщение об ошибке. Вероятно, именно в целях более четкого определения контекста
применения подобных методов в Java введен класс AgentContext, членом которого и является
одноименный метод в Java.
Метод работает в два приема:
•
•
Во-первых, находит коллекцию документов, еще не обработанных данным агентом. Эта
коллекция зависит от типа агента. Она идентична коллекции, получаемой свойст вом
UnprocessedDocuments класса NotesDatabase/AgentContext.
Во-вторых, выполняет запрос полнотекстового поиска по коллекции необработанных
документов и возвращает полученную в результате коллекцию удовлетворяющих
запросу.
Если база не имев! индекса полнотекстового поиска, метод работает, но значительно
менее эффективно.
Пример. В Agent Builder выбрано, что Java-агент обрабатывает все или только «отмеченные»
документы в виде. Агент отбирает документы со словом "botany" и помещает их в папку "Botanist's
Delight".
// Java-Database/unprocessedFTSearch
DocumentCollection dc = agentContext.unprocessedFTSearch("botany",
Database.FT_SCORES, Database.FT__STEMS+Database.FT_THESAURUS);
© InterTrust Co. Тел- (095) 9567928
0,
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
449
Document doc;
.
int. size = dc . getCount () ;
System, out. println { "Count =- " + size);
for (int i = 1; i <= size; i++)
i
doc = dc.getNthDocument( i ) ;
doc.putInFolder("Botanist's Delight");
System.out.println(i + " *** " + doc.getltemValue("Subject" } ) ; }
Метод search - «поиск с формулой отбора по документам базы»
LotusScript:
Set notesDocumentCollection = notesDatabase.searcb( formula^,
notesDateTime, maxDocs% )
Java:
DocumentCollection dc =-- Database.se&rch(Slring formula)
DocumentCollection dc =- Database.search(String formula, DateTime df)
DocumentCollection dc ~ Database.se&rch(String formula, DateTime dt, int
maxDocs)
Возвращает коллекцию документов, удовлетворяющих заданному формулой критерию
отбора. Параметр formula (тип String) - @-формула Notes с применением @функций,
определяющая критерий отбора документов. Параметр notesDateTime/dt - объект класса
[Notes]DateTime, задающий «момент отсечки» (cutoff date) - тогда метод просматривает в
базе только документы, созданные или модифицированные не ранее данного момента
времени. Чтобы «момент отсечки» вообще не принимался во внимание, задайте параметр
равным Nothing/null. Параметр maxDocs (тип Integer/int) - максимальное количество
документов, которое вы хотите получить в коллекции. Чтобы получать все отобранные
документы, задайте 0.
Возвращаемое значение - объект класса [NotesjDocumentCoilection - несортированная
коллекция документов, удовлетворяющих заданному критерию.
Формула отбора вычисляется для каждого документа в базе, созданного или
модифицированного не ранее указанного «момента отсечки». Если формула возвращает
@Тше, считается, что документ удовлетворяет критерию отбора.
Пример 1. Скрипт отбирает в базе все ответные документы (формула отбора - @lsResponseDoc),
созданные или модифицированные после 1 декабря 1998 года.
Dim db As New NotesDatabase( "Serverl/Acme", "somedocs.nsf" )
Dim collection As NotesDocumentCollection
Dim dateTime As New NotesDateTime( "12/01/98" )
Set collection = db.Search( "@IsResponseDoc", dateTime, 0 )
Пример 2. Java-агент отбирает в базе все документы, в поле Subject которых содержится текст,
который агент выбирает из своего коля комментариев,
// Java-Database/unprocessedFTSearch Agent, agent =
agentContext.getCurrentAgent( ) ; Database db =
agentContext.getCurrentDatabase( ) ; S t ri n g t i t l e =
db.getTitle();
DocuznentCollection dc = db.search("Subject= \""+agent.getComment ()+"\""); int
matches = dc . getCount. ( } ;
System.out.println("Search of \"" + title + "\" found " + matches + "
document( s ) with Subject = \"" + agent.getComment(} + " \ " " ) ;
Пример З. Поле ReminderDate («дата напоминания») в каждом документе формы Project служит
для хранения даты, когда «напоминание» должно быть отправлено. Агент на LotusScript, используя
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Javd
450
метод search, отбирает документы формы Project, в которых «дата напоминания» равна
отправляет напоминание почтой и «сдвигает дату» в поле ReminderDate на неделю вперед.
текущей,
Dim db As New NotesDatabase ( "", "reminder:. nsf" )
Dim collection As NotesDocumentCollection
Dim doc As NotesDocument
Dim dateTime As New NotesDateTime( "12/01/98" )
Dim nextDateTime As NotesDateTime
searchFormula$ = "Form = ""Project"" & ReminderDate = @Today"
Set collection = db.Search( searchFormula$, dateTime, 0 )
' Create a date that's one week from today.
' That's when the project participants get their next reminder.
Set nextDateTime = New NotesDateTime( "Today" }
Call nextDateTime.AdjustDay( 7 )
' E'or each document with reminder date today, send document, to
' project participants.
' Then update the Reminder-Date field with a date
' one week from today.
For i = 1 To collection.Count
Set: doc - collection. GetNthDocument ( i )
Call doc.Send( True )
Call doc.ReplaceltemValue( "ReminderDate",
nextDateTime.LSLocalTime )
Call doc.Save( True, False ) Next
Метод unprocessedSearch - «поиск с формулой отбора по необработанным
агентом документам» .
. .....
. : . / . . . : , ' . • . ••;•• ::.: • ::
• -'••'.
LotusScript:
Set notesDocumentCollection = notesDatabase,unprocessedScarch(
formiila$, notes DateTime, maxDocs% )
Java:
DocumentCoUection dc L= AgentContext.u.nprocessedSearch(
String for mulct) DateTime dt, int maxDocs)
Для заданных формулы отбора и момента отсечки возвращает коллекцию документов из
базы, которые еще не обработаны данным агентом (unprocessed), удовлетворяют формуле
отбора и созданы или модифицированы после момента отсечки (cutoff date). Все параметры и
возвращаемое значение такие же, как в методе search.
Метод работает в два приема:
*
*
Во-первых, находит коллекцию документов, еще не обработанных данным агентом. Эта
коллекция зависит от типа агента. Она идентична коллекции, получаемой свойством
UnprocessedDocuments класса NotesDatabase/AgentContext.
Во-вторых, он выполняет по коллекции необработанных документов отбор документов,
созданных или модифицированных после момента отсечки и удовлетворяющих формуле
отбора, и возвращает полученную в результате коллекцию.
Метод unprocessedSearch класса NotesDatabase может применяться только в агентах и
действиях по виду (view actions), и при условии, что объект класса NotesDatabase получен
свойством CurrentDatabase из объекта NotesSession. Если метод пытаются применять не в
агентах, получают пустую коллекцию. Если метод пытаются применять к объекту,
полученному не свойством CurrentDatabase из объекта NotesSession, возникает ошибка.
Вероятно, именно в целях более четкого определения контекста применения этого и ему
подобных методов в Java и был введен класс AgentContext.
© InterTrust Со. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
451
Пример. Пусть в «построителе агентов» выбрано, что данный Java-агент обрабатывает только
выбранные пользователем документы в виде. В этом случае свойство UnprocessedDoeuments
возвращает коллекцию этих (выбранных пользователем) документов. Агент отбирает из них
документы, созданные после 1 января 1998 года и содержащие слово "botany" в поле Subject.
Отобранные документы помешаются в папку "Botanist's Delight".
//
Java-Database/unprocessedSearch
DateTime date = session.createDateTime("01/01/98");
DocumentColleetion dc =
agentContext.unprocessedSearch( "SContains(Subject;
\"botany\")", date, 0);
Document doc;
int size = dc.getCount();
System.out.println("Count = " + size);
for (int i = 1; i <= size; i+4)
{
doc = dc.getNthDocament(i);
doc.putlnFolder("Botanist's Delight");
System.out.println(i + " *** " + doc.getltemValue("Subject")!;
i
© Метод FTDomainSearch - «иолнетекстовый поиск по базам домена»
LotusScript:
Set notesDocument = note5Dcrra&ave.FTDomainSearch(
query , maxDocs% [, sortoption% ] [, otheroptions% ] [,
start& j [, count% ] , entryForm )
Java:
Document searchResDoc - Dfltoftoi re.FTDomainSearch(^rwg query,
int maxDocs, int sortoptions, int oiheroptions, int
start, int count, String entryForm)
Объект класса [Notes]Database, к которому применяется метод, должен представлять базу
Domain Catalog. Метод осуществляет полнотекстовый поиск документов по всем базам
домена, которые перечислены в базе Domain Catalog и имеют свойство MultiDbSearch.
Параметр query (тип String) задает запрос полнотекстового поиска. Параметр maxDocs
(тип Integer/int) сообщает, что в качестве ответа на запрос должно возвращаться не более чем
maxDocs документов. Чтобы возвращались все удовлетворяющие запросу докумен ты,
задайте 0. Параметр start (тип Long/int) сообщает номер первой возвращаемой страницы, а
параметр count (тип Integer/int) - количество возвращаемых страниц. Параметр entryForm
(тип String) дает имя поисковой формы в базе Domain Catalog, например, "Search Form" или
"DomainQuery". Остальные параметры - sortoptions и otheroptions - такие же, как в методе
FTSearch.
Возвращается объект класса [Notes]Document, представляющий документ с результатами
выполнения поискового запроса - «ссылками» на найденные по запросу документы в базах
домена.
3.5.11. Методы для выполнения административных действий с базами
Метод compact - «уплотнить локальную базу»
LotusScript: sizeDelta& ~ notesDatabase.compact
Java:
int sizeDelta - Database.compactQ
«Уплотняет» локальную базу. Возвращает разницу в байтах (тип Long/int) размеров базы
до и после уплотнения. Для баз, находящихся на сервере, выдает ошибку или генерирует
© InterTrust Со. Тел. (095) 9567928
Встроенные классы LotusScript и Java
452
исключение. Не может использоваться и для уплотнения текущей базы (которая содержит
этот скрипт или Java-агент, использующий метод compact).
Пример. Java-агент уплотняет базу данных, имя файла которой он получает из своего поля
комментариев, если в этой базе реально используется менее 75% пространства.
// Java-Database/сompact
Agent agent = agentContext.getCurrentAgent();
String dbNarne = agent . get Comment ( ) ;
Database db = session.getDatabase(null, dbName);
String title = db.getTitle ( );
double percentUsed = db.getPercentUsed();
if (percentUsed < 75)
{
System, out. println ( "Compacting database \"" + title -f " \ " " ) ;
int saved == db. compact () ; }
System.out.println("Database \"" + title + "\" is " +
(int}percentUsed + " percent used");
i
Метод updateFTIndex - «обновить индекс полнотекстового поиска»
LotusScript:
Call notesDatabase,upda.teVTInde\( createf'lag )
Java:
void Database.updateҐTlnden(boolean createFlag)
Обновляет индекс полнотекстового поиска базы. Параметр createf'lag можно задать
равным true только для локальных баз - это означает, что когда индекс полнотекстового
поиска у базы не существует, метод должен создавать этот индекс. В противном случае
задавайте false, поскольку при попытке создать индекс полнотекстового поиска в базе на
сервере возникает' ошибка или генерируется исключение.
Метод replicate - «выполнить репликацию локальной базы» •LotusScript:
Java:
, ....
flag ~- notes Database,replicate( serverName$ )
boolean flag ~ Database.replicate(String serverName)
Выполняет репликацию локальной базы, к которой применяется метод, с ее
ренликой(ами) на сервере, имя которого задано параметром serverName. В репликации
примут участие все реплики данной базы на указанном сервере. Если в процессе репликации
не возникло ошибок, возвращается true, иначе false. Если на сервере нет реплики данной
базы или база, к которой применяется метод, не локальна, возникает ошибка или
генерируется исключениеМетод remove - «удалить базу» ; . . ;
• ... • . :• •... ... • . . . . . . - .
LotusScript:
Call notesDatabase.remove
Java:
void Database.remo\eQ
.
Удаляет базу, связанную с объектом, с диска.
Пример. Скрипт удаляет базу BYEBYE.NSF, если она не изменялась за последние 100 дней.
Dire db As New NotesDatabase( "", "byebye.nsf" ) If
{ ( Today - db.LastModifled ) > 100 ) Then Call
db.Remove
End If
•
'
•
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
453
3.6. «Репликационные установки» - класс flNotesjReplication
Свойства объекта класса [NotesJReplication позволяют определять и устанавливать ряд
свойств базы данных, касающихся поведения базы данных при репликациях. Методы
объекта этого класса позволяют «считывать» репликационные установки базы данных в
объект, «заносить» репликационные установки из объекта в базу данных, а так же выполнять
«очистку» истории репликаций базы.
Получают ссылку на объект класса [NotesJReplication свойством Replicationlnfo класса
[NotesJDatabase. В каждом объекте [Notes]Database содержится только один объект
[NotesJReplication.
LotusScript:
Java:
.
•- ••.-.
,
.
NolesReplication = notesDatabase*Rep\Kationlnfo
Replication ri — Database.geiReplicatianlnfoQ
3.6.1. Свойства
© Свойство Abstract - «принимать «полные» или «усеченные» документы»
LotusScript:
flagBoolean - NotesReplication,Abstract
NotesRepIication.Abstract -flagBoolean
Java:
boolean flag — ReplicationAsAbstrstctQ
void Replication.setAbstr»ct(boolean flag)
При репликации в данную реплику базы могут приниматься или «полные», или
«усеченные» (truncated) документы. «Усеченный» документ может появиться в реплике базы,
если в ее репликационных установках выбрана возможность Receive summary and 40KB of
rich text only (Рис. 3.15). В «усеченном» документе по сравнению с «полным» сохранена
информация в полях с флагами Summary, но размер информации в полях типа RichText и
полях иных типов с флагами Non-Summary не превышает примерно 40 Кб, а все
присоединенные файлы и OLE-объекты «отброшены».
Если свойство Abstract равно true, в реплику принимаются «усеченные» документы, если
false - «полные».
Рис. 3.15 Окно репликационных установок базы на закладке Space Savers
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
454
© Свойство Cutofflnterva! - «интервал устаревания документов»
LotusScript:
intervalLong — NotesReplication.Cutofnnterval
NofesReplicaliori.Cuiofflnterval = intervalLong
Java:
long interval = Replicatwn.getCutofflntervAlQ
void Replication.setCutofflntervAl(long interval)
Интервал устаревания документов в данной реплике базы. Задается количеством дней
(тип Long/long).
В окне репликационных установок базы интервал устаревания указывается в поле XXX
возможности Remove documents not modified in the last XXX days (Рис. 3.15), причем вне
зависимости or того, выбрана или нет сама эта возможность.
Документы, с момента последней модификации которых уже прошло заданное свойством
количество дней, подлежат автоматическому удалению из данной реплики базы, только если в
ее репликационных установках была выбрана возможность Remove documents not modified in
the last XXX days. При этом удаляемый документ заменяется своим «окурком».
«Окурки», с момента появления (иными словами, последней модификации) которых уже
прошло заданное свойством количество дней, безусловно подлежат «полному» удалению из
данной реплики базы.
© Свойство CutoffDelete - «разрешено ли автоматически удалять устаревшие
: 'документы» " . : . .'.• "•' : :•: :-:'^' .• : • ' " ' • • ' . . ' . л ".
•••' ;
LotusScript:
flagBoolecm = NotesReplication.CutoffDelete
NotesReplication.CutoffDelete = flagBoolean
Java:
boolean flag = Replication.isCutoffDeleteO
void Rep!ication.setCutoffDe\ete(boolean flag)
Свойство соответствует возможности Remove documents not modified in the last XXX days в
репликационных установках базы. Значение true разрешает, a false - запрещает
автоматически удалять из данной реплики базы документы, с момента посл едней
модификации которых уже прошло заданное свойством Cutofflnterval количество дней. _
© Свойство CutoffDate - «порог времени для приема документов при
репликации» ; ''•-. " .-. '••- ' • . . , . ; • .. '-..-.. •'•'::,•....;:":••.- ••:••-.-•"";. :: •••'• -:
LotusScript:
Java:
timeDate Variant = NotesReplication.CutoffD'Ate
DateTime timeDate = RepIication.getCutoffDateQ
Возвращает дата-временное значение: в LotusScript Variant of type DATE, в Java - объект
класса DateTime. Документы, время последней модификации которых меньше CutoffDate,
при репликации в данную реплики базы не принимаются.
В документации Domino версии 5.0 утверждается, что это значение, получаемое
вычитанием из значения текущих даты-времени интервала устаревания документов
(Cutofflnterval). Однако практика показывает, что свойство просто возвращает значение из
поля Only replicate incoming documents saved or modified after в репликационных установках
базы (Рис. 3.17). Значение в этом поле всегда может быть произвольным образом изменено
«вручную», однако затем оно эпизодически подвергается автоматическим корректировкам,
получая при них значения, «достаточно близкие» к тем, которые получаются вычитанием
интервала устаревания документов (Cutofflnterva!) из значения текущих даты-времени.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: (ар-формулы, LotusScript, встроенные классы LotusScript и Java
455
© Свойство Disabled - «участвует ли в репликациях»
LotusScript:
flagBoolean - NotesReplication.Disabled
No(esReplication.Disabled =flagBoolean
Java:
boolean flag - RepIication.isDisabletlQ
void Replication,seil)isabled(boo!ean flag)
Значение true разрешает, a false - запрещает участие данной реплики в репликациях. В
окне репликационных установок базы это свойство соответствует возможности Temporarily
disable replication (Рис. 3.17),
Puc. 3.16 Окно репликационных установок базы на закладке Send
Puc. 3.17 Окно репликационных установок базы на закладке Other
0 Свойство IgnoreDelctes - «передаются ли «окурки» из данной реплики в
другие» .'" -;•; :Г.. •'"".•'.'.: ' •• ''•'•"• : ' ' ' . -; " - '.-... •-:-'•'••:•••';" .'--;';; •'•'../•;•";;./'•:: ;:;..'-. .', ;;-:'::'. '-•:-•
LotusScript:
flag = NotesReplication.IgnoreDeletes
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
456
NotesReplication. Igno reDeletes = flag boolean
flag = Replication.islgnoreDeletesQ void
Java:
Repiication,seiIgnoreDe:letes(boolean flag)
Значение true запрещает, a false разрешает при репликациях передачу «окурков» из
данной реплики в другие реплики. В окне репликационных установок базы это свойство
соответствует возможности Do not send deletions made in this replica to other replicas (Рис.
3.16).
@ Свойство IgnoreDestDeletes - «принимаются ли «окурки» в данную
реплику из других»
LotusScript:
flagBoolean = NotesReplication. IgnoreDestDeletes
NotesReplication.lgnoreDestDeletes -flagBoolean
Java:
boolean flag = Replication.islgooreDesiDeletesQ
void Replication.setIgnoreDestDeietes(&o0/eo77 flag)
Значение true запрещает, a false разрешает при репликациях прием «окурков» в данную
реплику из других реплик. В окне репликационных установок базы это свойство
соответствует возможности Deletions (Рис. 3.18).
ixl
Replication Settings for Глоссарий
Wher»Јomputef:
Receive* trom:
pomino500/lnterTtus(Corp/SLI
I -A nv Server-
Space Saveiv
Send
Other
' Advanced
'
"*
"'1 JSJJ
~
""M*w*
д-п И1П III «if
Г"
^ AIIDociirnents _ 1 Без
описания _ I Все по термину
оригинала __ J По
риссв.пмчтррмину
Replicate
П7 Forms, views etc
P* Acces.,
F? ,4дзп^
P f fieleliotu
ori fotniuio
Г Fjelds
j ^ O K J
Lint
f'nc. 3.18 Окно репликационных установок базы на закладке Advanced
@ Свойство Priority - «приоритетность участия в реплкациях»
LotusScript:
constantLong = NotesReplication.friority
NotesReplication.Priority = constantLong
Java:
int. constant - Replication.geiPriorityQ
void Replica(ion.setPriority(int constant) ! 1риоритетность участия в
репликациях для данной реплики, задается константами:
DB REPLICATION,PRIORITY HIGH/
RepHcation.CNOTES_REPLCONST_PRIORITYHIGH - высокая,
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: (а)-формулы, LotusScript, встроенные классы LotusScript и Java
*
DB_ REPLICATION PRIOR1TY_MED/
Replication.CNOTES_REPLCONST_PRIORITYMED - средняя,
*
DB_REPLICATION_PRIORITY_LOW/
Replication.CNOTES_REPLCONST_PRIORITYLOW - низкая,
DB_REPLICATION_PRIORITY_NOTSET/
Replicalion.CNOTESJREPLCONST JPRIOR1TYNOTSEТ - не выбрана.
*
451
Приоритетность может быть учтена администратором при составлении расписания
репликаций баз.
3.6.2. Методы
© Метод clearHistory - «очистить историю репликаций»
LotusScript:
Call NotesReplication.cle-Arflistory
Java:
int returnValue = Replication.clearVListoryQ
Очищает историю репликаций базы.
© Метод reset - «занести репликационные установки базы в объект»
LotusScript:
Call NotesReplication.reset
Java:
int returnValue = Replication.resetQ
Заносит репликационные установки базы данных в объект [NotesjReplication.
© Метод save - «занести репликационные установки из объекта в базу»
LotusScript:
Call NotesReplication.s«ve
Java:
int returnValue = Replication.saveQ
Записывает репликационные установки из объекта в базу данных. Без вызова этого
метода до закрытия базы свойства, измененные Вами в объекте, не будут записаны в саму
базу данных, и, соответственно, не начнут функционировать.
Пример 1. Следующий скрипт проверяет работоспособность всех свойств и методов класса
NotesReplication.
Dim bt As Long
tot = 36 ' MB_YESNO + MB_ICONQUESTION
Dim IDDK As Integer
IDDK = 6 ' Ok
Dim db As NotesDatabase Dim
rep As NotesReplication
Set db = session.CurrentDatabase Set
rep = db.Replicationlnfo
' Abstract
If Messagebox(rep.Abstract,bt,"Change Abstract?") = IDDK Then
rep.Abstract = Not rep.Abstract
End If
,
' CutOffInterval If Messagebox(rep.CutOffInterval,bt,"Change CutOffInterval?")
= IDDK Then
rep.CutOffInterval = rqp.CutOffInterval + 1 End
If
© InterTrust Co. Тел. (095) 9567928
458
Встроенные классы LotusScript и Java
CutOffDate
Msgbox rep.CutOffDate,,"CutOffDate"
1 CutoffDelete
If Messagebox(rep.CutoffDelete,bt, "Change CutoffDelete?"} - 1DOK Then
rep.CutoffDelete = Not rep.CutoffDelete
' . End If ' Disabled
If Messagebox(rep.Disabled,bt,"Change Disabled?") = IDOK Then
rep.Disabled = Not rep.Disabled End
If
' IgnoreDeletes If Messagebox(rep.IgnoreDeletes,bt,"Change IgnoreDeletes?")
= IDOK Then
rep.Ign.oreDelet.es == Not rep. IgnoreDeletes
End If ' Priority Select Case rep.Priority
Case DB_REPLICATION PRIORITY HIGH: If
Messagebox("PRIORITY_HIGH",bt,"Change Priority (LOW)?") - IDOK Then
rep.Priority = DB_REPLICATION_PRIORITY LOW
End If
Case DB_REPLICATION_PRIORITY_MED: If
Messagebox("PRIORITY_MED",bt,"Change Priority (HIGH)?") = IDOK Then
rep.Priority = DB REPLICATION^PRIORITY_HIGH End
If
Case DB_REPLICATION_PRIORITY_LOW: If
Messagebox("PRIORITY_LOW",bt,"Change Priority(MED)?") - IDOK Then
rep. Priority = DB_REPLICATION_PRIORITY__MED
End If
Case DB REPLICATION^PRIORITY NOT/SET: If
Messagebox("PRIORITY_NOTSET",bt,"Change Priority?") = IDOK Then
rep.Priority = DB_REPLICATION_PRIORITY_LOW End If End Select '
IgnoreDestDelet.es If Messagebox(rep.IgnoreDestDeletes,bt,"Change
IgnDestDel?") = IDOK Then
rep.IgnoreDestDeletes = Not rep.IgnoreDestDeletes End
If
1 clearHistory ()
•,
If Messagebox("",bt,"clearHistory()?") = IDOK Then
Call rep.clearHistoryО
End If
' reset() OR save() If
Messagebox("",bt,"save()?") = IDOK Then
Call rep.save{)
Else
Call rep.reset()
End If
1
Пример 2. Java-агент, подобно скрипту из предыдущего примера, демонстрирует работу свойств и
методов класса Replication.
// Java-Replication-All
Database db =; agentContext.getCurrentDatabase();
Replication rep = db.getReplicationlnfо();
// Abstract
rep.setAbstract(!rep.isAbstract());
System, out. println ( "Abstract. = " + rep.isAbstract ());
// Cutofflnterval
rep.setCutoffInterval(rep.getCutoffInterval() + 1);
© InterTrust Co, Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
459
System.out.println("CutoffInterval = " + rep,getCutoffInterval());
// CutoffDate
System.out.println{"CutoffDate = " + rep.getCutoffDate());
// CutoffDelete
rep.setCutoffDelete(!rep.isCutoffDelete());
System.out.println("CutoffDelete - " + rep.isCutoffDelete());
// Disabled
rep.setDisabled(!rep.isDisabled());
System.out.println("Disabled = " + rep.isDisabled());
// IgnoreDeletes
rep.setlgnoreDeletes(!rep,isIgnoreDeletes());
System, out . pr.int.ln ( "IgnoreDeletes = " 4 rep . isIgnoreDeletes ());
// Priority
switch (rep. getPriority () ) .• /,-. ,.-..••-- .,-., ..•;,•>• •,-,-..;•'•"*•:;.--, . .• :- ' : ;.
{
case Replication.CNOTES REPLCONST_PRIORITYHIGH:
// В 5.0 нет Replication.DB REPLICATION PRIORITY_HIGH . . .
rep.setPriority(Replication.CNOTESJREPLCONSTJPRIORITYLOW) ;
System.out.println("Priority ~ HIGH->LOW");
break; c a s e R e p l i ca t i o n .C N O T E S
R E PL C O N S T_ P R 1 0 RI T Y M E D :
r e p. s e t P ri o r i t y( R e p l i c at i o n . CN O T E S __ R E P L C O NS T _ P R IO R I T Y HI G H ) ;
System.out.println("Priority = MED->HIGH");
break; c a s e
R e pl i c a t io n . C N OT E S _ R E P LC O N S T _P R I O R IT Y L O W :
rep.setPriority(Replica tion.CNOTES_REPLCONST PRIORITYMED) ;
System.out.println("Priority = LOW->MED");
break; c a s e R e p l i ca t i o n .C N O T E S R E P L CO N S T
P R IO R I T Y NO T S E T :
rep.setPriority(Replication.CNOTES_REPLCONST_PRIORITYLOW) ;
System.out.println("Priority = NOTSET->LOW");
break; i
/'/ IgnoreDestDeletes
rep.setlgnoreDestDeletes(!rep.isIgnoreDestDeletes());
System.out.println("IgnoreDestDeletes = " + rep.isIgnoreDestDeletes());
// clearHistory()
rep.clearHistory();
System.out.println("clearHistory!"};
// reset () OR save ()
System.out.print In("reset () OR save() !");
rep.save();
// rep.reset();
При своем выполнении агент выводит приблизительно следующее.
Первое выполнение
Второе выполнение
Abstract = true
Abstract = false
Cutofflnterval = 127
CutoffInterval = 128
CutoffDate = 20.01.9802:34:22 ZE3
CutoffDate = 20.01.98 02:34:22 ZE3
CutoffDelete = true
CutoffDelete = false
Disabled -= true
Disabled = false
IgnoreDeletes = false
IgnoreDeletes = true
Priority - HIGH->LOW
Priority = LOW->MED
IgnoreDestDeletes = false
IgnoreDestDeletes = true
clearHistory!
clearHistory!
reset () OR save()!
reset () OR save ( } !
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
460
3.7. «Список управления доступом» - класс [NotesJACL
Объект этого класса представляет список управления доступом (ACL) базы. ACL
включает две компоненты:
•
список элементов ACL, каждый из которых содержит имя владельца элемента ACL
(пользователя, сервера или группы), его тип и уровень доступа к базе, а так же
дополнительные свойства;
список ролей вместе с назначением владельцев элементов ACL на роли.
*
•
Access Control List
PeopI?, Sewras, flumps- Show AH
\sf* 4
, Щ|
•»] User type:
-Default-
&eeess
Unspecified
И
ReaJei
^|
A Nuolay N Iontsev.5nterTrustCorp/SU >— _ j^
NotesSrHOMnteiTnistCorpCl)
r ' 3U OtheiDonainServ«rc
'_ Авторы
' Иван И Иванов/ЛсмЯШ
Г"
С иак wtuivjij.ia^-s agents Редакторы
Г* ' Сидор
Г Сидаров/ACME/RU
Г" gnte раЫас dacijeants Roles
[Mam Developer]
»J [Очень дп]
1 Remmf j ^ [Роль!]
Rales
— — - — — • — ™— __«___. — i
-_
kd
...
Last cbuvp • Kikol «fN Iotttsevun2909P3
Accoittagto Intel TnistCarpjOSU
Us
.
i Add.
| genare,
—J
K
jp^,^ jj
^j
f
f
QK
1
Cancel I
i ---- S",, ,., t ------- !L, — i
..
!
.J
Рис. 3.19 Список управления доступом базы, закчадка Basics
Свойства и методы этого класса позволяют получать «общие свойства ACL»:
максимальный уровень доступа к базе через Internet, поддержку в одинаковом состоянии
ACL во всех репликах базы, а так же список ролей из ACL, переименовывать, добавлять
новые или удалять роли, получать доступ к существующим элементам ACL (по имени
владельца или последовательным просмотром всех элементов) и создавать новые и удалять
существующие элементы ACL.
«Контейнерная иерархия»
LotusScript
Java
NotesDatabase
— >,
Database
>
NotesACL — > NotesACLEntry
NotesDatabase
ACL -» ACLEntry
Database
Для получения объекта класса [NotesJACL используют свойство ACL класса
[NotesjDataba.se. Кроме того, в классе [NotesJDatabase имеются три метода - queryAccess,
grantAccess и revokeAccess - которыми можно осуществлять доступ к ACL базы, не создавая
при этом явно объекта класса [Notes]ACL. Работа же с элементами ACL осуществляется
методами и свойствами класса [NotesJACLEntry.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: (аи-формулы, LotusScript, встроенные классы LotusScript и Java
461
Пример 1. Скрипт получает доступ к ACL базы, а затем к ее первому элементу.
Dim
Dim
Dim
Set
Set
db As New NotesDatabase( "", "names.nsf" )
acl As NotesACL
entry As NotesACLEntry
acl = db.ACL
entry =
acl.GetFirstEntry
Пример 2. Java-агент получает доступ к ACL текущей базы, а затем к первому элементу ACL.
// Java-ACL/getACL
Database db ™ aqentContext.getCurrentDatabase();
ACL acl = db.getACLC);
.,.,
ACLEntry entry •= acl. getFirst.Entry () ;
3.7.1. Свойства
Свойство Parent- «родитель»
• : . . . , . -•• ... . . . . . • : : • . • , . -v.;: . ........... .-•...
LotusScript:
Set notesDatabase — notesACL.Psurent
Java:
Database db = ACL.getParentQ
База данных, ACL которой представляет объект класса [NotesjACL.
Пример 1. Скрипт в обоих окнах выведет одно и тоже название локальной базы N AMES.NSF.
Dim db As New NotesDatabase( " ",
Dim parentDb As NotesDatabase
Dim acl As NotesACL
Set acl = db.ACL
"names.nsf" )
Set parentDb - acl.Parent
Messagebox ( db.Title }
Messagebox{ parentDb.Title )
Пример 2. Подобно предыдущему примеру, Java-агент дважды выведет название текущей базы.
// Java-ACL/ParentAgent
Database db = agentContext.getCurrentDatabase();
ACL acl = db.getACL();
Database parent = acl.getParent();
System.out .println ("Database is \"" +• db. getTitle () •+ "\"");
System.out.println ("Parent database is \"" + parent.getTitle (} + "\"");
Свойство Roles-«роли»•'-•" "•'••;"•'v;"::::.':••'••/.:."':;;'::::;••;"'.-:•'•'' ""-•'-":• -•-::"':,>:"; "::•.:-.•••-' ••:;:'".".'
LotusScript:
stringArray = notesACLRtA&s
Java:
java.util Vector roles ;= /JCZ/.getRolesQ
Возвращает «массив» названий ролей (в LotusScript тип Array of strings, в Java
-java.util.Vector с элементами типа String), определенных в ACL. Каждый элемент массива
-название роли, заключенное в квадратные скобки, например, "[Supervisor]". Но для чего
здесь квадратные скобки? Чтобы было возможным отличить роли от привилегий
(анахронизм Notes версии 2.0) - названия привилегий заключались в круглые скобки.
Пример 1. Скрипт выводит все роли, определенные в ACL, текущей базы. Например, он мог бы
вывести "[HR Contact]", "[Supervisor]" и "[Project Leader]".
Dim session As New NotesSession
Dim db As NotesDatabase
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
462
Dim aci As NotesACL
Set db = session.CurrentDatabase
Set acl =• db.ACL
Forall r In acl.Roles
Messagebox( r } End
Forall
Puc. 3.20 Список управления доступом базы, закладка Roles
Пример 2. Агент выводит все роли, определенные в ACL текущей базы.
i m po rt J ava .u ti l . Ve ct o r ;
// Java-ACL/RolesAgent
Database db = agentCoritext. getCurreritDatabase () ;
ACL acl = db.getACLO ;
Vector roles = acl.getRoles(};
for (int i=0; i < roles.size( ) ; i++)
System.out.printIn(roles.elementAt(i});
@ Свойство InternetLevel - «максимальный доступ к базе по протоколам :
Internet прикладного уровня при аутентификации вводом имени и пароля»
LotusScript:
levellnteger = notesACL. InternetLevel
notesACL. InternetLevel = levellnteger
Java:
int level = /JCL.getlnternetLevelQ
void /lCL.setInternetL.evel(mt level)
Максимальный уровень доступа к базе по протоколам Internet прикладного уровня
(HTTP, РОРЗ, ШАР, NNTP) при аутентификации вводом имени и пароля (задается в поле
Maximum Internet name & password, см. Рис. 3.2).
Возможные уровни доступа задаются константами:
ACLLEVEL_NOACCESS / ACL. LEVELING ACCESS - нет доступа,
ACLLEVEL_DEPOSITOR/ ACL.LEVELlDEPOSITOR - депозитор,
© InterTrust Co. Тел, (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
463
ACLLEVEL_READER / ACL.LEVEL READER - читатель,
ACLLEVEL_AUTHOR / ACL.LEVELj\UTHOR - автор,
ACLLEVEL_ED1TOR / ACL.LEVEL_EDITOR - редактор,
ACLLEVEL_DESIGNER / ACL.LEVEL DESIGNER - дизайнер,
ACLLEVELJMANAGER / ACL. LEVEL" MAN ACER - менеджер.
Чтобы выполненные в объекте [Notes]ACL изменения были «записаны» в базу, для
объекта необходимо вызвать метод save.
•
Рис. 3.2 Список управления доступом базы, закладка Advanced
Пример 1. Скрипт выводит заданный в ACL текущей базы максимальный уровень доступа к этой
базе по протоколам прикладного уровня Internet при аутентификации вводом имени и пароля, а затем
изменяет его на ACLLEVEL READER.
Dim session As New NotesSession
Dim db As NotesDatabase
Dim acl As NotesACL
Dim lev As Integer
Set db = session.CurrentDatabase
Set acl = db.ACL
lev = acl.InternetLevel
If lev = ACLLEVEL_NOACCESS Then Print
If lev = ACLLEVEL_DEPOSITOR Then Print
If lev - ACLLEVEL_READER
Then Print
If lev = ACLLEVEL_AUTHOR
Then Print
If lev = ACLLEVEL_EDITOR
Then Print
If lev = ACLLEVEL^DESIGNER Then Print
If lev - ACLLEVEL MANAGER
Then Print
acl. InternetLevel "= ACLLEVEL_READER
Call acl.save
lev;
lev;
lev;
lev;
lev;
lev;
lev;
"
"
"
"
"
"
"
NOACCESS"
DEPOSITOR"
READER"
AUTHOR"
EDITOR"
DESIGNER"
MANAGER"
Пример 2. Агент выводит заданный в ACL текущей базы максимальный уровень доступа к этой
базе по протоколам прикладного уровня Internet при аутентификации вводом имени и пароля, а затем
изменяет его на ACL.LEVEL MANAGER.
//Java-ACL/InternetLevelAgent
Database db =• agentContext. getCurrentDatabase () ;
^InterTrustCo. Ten. (095) 9567928
Встроенные классы LotusScript и Java
464
ACL acl = db.get.ACL () ;
int level =-• acl.getlnternetLevel();
String strLevel = "UNDEE'INED" ;
if (level == ACL.LEVEL_NOACCESS) strLevel = "NOACCESS";
if (level == ACL.LEVEL_DEPOSTTOR) strLevel = "DEPOSITOR";
if (level == ACL.LEVEL^READER)
strLevel - "READER";
if (level == ACL.LEVEL_AUTHOR)
strLevel = "AUTHOR";
if (level == ACL.LEVEL_EDITOR)
strLevel, = "EDITOR";
if (level == ACL.LEVEL_DESIGNER) strLevel = "DESIGNER";
if (.level == ACL.LEVEL^MANAGER)
strLevel -•= "MANAGER";
System, out. println ( "Maximum InternetLevel is-, " + level + " .-;.-- ; • ••
("+strLevel+")");
'
.
acl.setlnternetLevel(ACL.LEVEL_MANAGER);
acl.save();
Свойство UniformAccess - «должен яи поддерживаться одинаковый список
управления доступом во всех репликах»
.....
. .•-
I
LotusScript:
flag - notes ACL, Uniform Access
HotoJCZ.UniformAccess -flag
Java:
boolean flag = ^CX.isUniformAccessO
voidyiCjL.setUniform\.cces$(boolean flag)
Свойство определяет, должен ли список управления доступом поддерживаться в
одинаковом состоянии во всех репликах этой базы и «функционировать» даже при
локальном доступе к базе (задается в поле Enforce a consistent Access Control List across all
replicas of this database, см. Рис. 3.2). Как в Java, так и в LotusScript true означает, что
свойство установлено, a false - нет. Чтобы выполненные в объекте [Notes]ACL изменения
были «записаны» в базу, для объекта необходимо вызвать метод save.
Пример 1. Скрипт выдает в диалоговом окне текущее значение свойства UniformAccess и, если
нажата кнопка Yes, изменяет значение свойства на «обратное».
Const MB YESNO = 4
Const MB_ICONQUESTION = 32
Const IDYES - 6
Dim
Dim
Dim
Set
Set.
' Yes and No buttons
' Warning query
' Yes button pressed
session As New NocesSession
db As NotesDatabase
acl As NotesACL
db =- session. CurrentDatabase
acl = db.ACL
If acl.UniformAccess Then
If Messagebox("Do you want to toggle?", MB YESNO + MB_ICONQUESTION, "Uniform
access is in effect") = TDYES Then acl.UniformAccess = False Call acl.Save End
If E1 я е
If Messagebox("Do you want to toggle?", MB_YESNO + MB ICONQUESTION, "Uniform
access is not in effect") - IDYES Then acl.UniformAccess = True Call acl.Save
End If End If
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
465
Пример 2. Агент изменяет значение свойства Uniform Access на "обратное".
// Java-ACL/UniforrnAccessAgent
•
Database db = agentContext.getCurrentDatabase();
ACL acl = db.getACLf);
System.out.println("Uniform access is " + acl.isUniformAccess());
if(acl.isUniformAccess()) acl.setUniformAccess(false);
eJ.se
acl. setUnif ormAccess (true) ;
acl.save();
System, out .println ( "Uniform access is " + acl. isUnif ormAccess ());
'
3.7.2. Методы
Метод addRole - «добавить роль»
LotusScript:
Call notes ACL.&ddRole( name$ )
Java:
void ACL.^ddRole(String name)
Добавляет в ACL роль с заданным названием (тип String). Название роли не нужно
«заключать в квадратные скобки». Если указанная роль уже существует в ACL, в LotusScript
произойдет ошибка, а в Java будет возбуждено исключение "The role name already exists".
Чтобы изменения, выполненные в объекте, были «записаны» в саму базу, для объекта
необходимо вызвать метод save.
Пример 1. Скрипт добавляет в ACL роль Developer.
Dim session As New NotesSession
Dim db As NotesDa.taba.se
Dim acl As NotesACL
Set db == session. CurrentDatabase
Set acl - db.ACL
Call acl.AddRole( "Developer" )
Ca11 а с1,S a ve
Пример 2, Агент добавляет в ACL роль, название которой записано в поле комментариев этого
агента.
// Java-ACL/AddRoleAgent
Agent agent = agentContext.getCurrentAgent( ) ;
Database db = agentContext. get.CurrentDatabase ( ) ;
ACT, acl = db.getACL 0;
acl.addRole(agent.getComment());
acl.save();
- Метод deleteRole - «удалить роль».... ,:. -; ,:.:. • -: •:...•;.:• . ...... •:•••,.•:•:. .... ,: :-•':::••'•:•
LotusScript:
Call notesACL.deleteRo\e( name$ )
Java:
void ACL.deleteRolf:(Strmg name)
Удаляет из ACL роль с заданным названием (тип String). Название роли не нужно
«заключать в квадратные скобки». Если указанная роль отсутствует в ACL, в LotusScript
произойдет ошибка, а в Java будет возбуждено исключение "Role name not found". Чтобы
изменения, выполненные в объекте, были «записаны» в саму базу, для объекта необходимо
вызвать метод save.
© InterTrust Со. Тел. (095) 9567928
Встроенные классы LotusScript и Java
466
Mei од renameRole - «переименовать роль»
LotusScript:
Call notesAi X.renameRoIe( oldNameS, newNameS)
Java:
void ACL.renameRole(String oldName, Siring newName')
Переименовывает роль oldName в newName (оба параметра типа String). Названия ролей
не нужно «заключать в квадратные скобки». Все элементы ACL, ранее назначенные на роль
oldName, станут назначенными на роль newName. Если старое название роли отсутствует в
ACL, ничего не происходит. Чтобы изменения, выполненные в объекте, были «записаны» в
саму базу, для объекта необходимо вызвать метод save.
Пример 1. Скрипт переименовывает роль "Developer" в "Main Developer".
Dim session As New NotesSession
Dim db As NotesDatabase
Dim acl As NotesACL
Set db = session.CurrentDatabase
Set acl = db.ACL
Call acl.RenameRole( "Developer", "Main Developer" )
Caii aci.Save
Пример 2. Агент добавляет суффикс "Role" к названию каждой имеющейся в ACL роли. Например,
[Supervisor] будет заменено на [SupervisorRole]. Каждая строка из вектора ролей содержит название
роли «в квадратных скобках». Названия ролей передается методу renameRole «без квадратных скобок».
import j ava.util.Vector;
// Java-ACL/RenameRoleAgent
Database db = agentContext.getCurrentDatabase();
ACL acl = db.getACL();
Vector roles = acl.getRoles(};
String role;
for (int. i = 0; i < roles. size (); i+-+)
{
role =• (String) roles . elementAt (i );
role = role.substring (1, role.length()-1);
acl.renameRole((String)roles.elementAt(i), role + "Role"); }
acl.save();
Метод getEntry - «получить элемент ACL но его имени» .•:,:•• • -..• ..LotusScript:
Set notesACLEntry - notesACL.geiEntry( nameS )
Java:
ACLEntry entry =ACL.getEntry(String name)
: .. .... ...
По имени элемента ACL (пользователя, сервера или группы), заданному параметром
пате (тип String), возвращает объект класса [NotesjACLEntry, представляющий этот элемент
ACL. Должно быть указано полное имя в формате [Canonicalize] или [Abbreviate], причем с
учетом регистра. Если элемент пате не найден в ACL, в LotusScript возвращается Nothing, а в
Java - null.
Если вам требуется определить уровень доступа к базе некоторого субъекта, который не
указан в ACL явно, но имеет к базе доступ как член группы, метод getEntry не поможет
-используйте для этого метод queryAccess класса [Notes]Database.
О InterTrust Co. Тел. (095) 9567'92'8
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
467
Пример 1. Скрипт получает элемент для Nikoiay N. lontsev/InterTrustCorp/SU из ACL текущей базы.
Dim session As New NotesSession
Dim db As NotesDatabase
Set db = session.CurrentDatabase
Dim acl As NotesACL
Dim entry As NotesACLEntry
Set acl = db.ACL
Dim ename As String
ename = "CN=Nikolay N. lontsev/O=InterTrustCorp/C=SU" '[Canonicalize]
ename = "Nikoiay N. lontsev/InterTrustCorp/SU"
'[Abbreviate]
Set entry = acl.GetEntry(ename)
If entry Is Nothing Then
Print: ename & " not found"
Else
Print entry.Name & " found"
End If
Пример 2. Если агент находит в ACL текущей базы элемент с именем, которое указано в поле
комментариев этого агента, он выводит сообщение о способности владельца элемента ACL удалять
документы. Если не находит, то выводит сообщение об отсутствии элемента ACL для заданного имени.
//
Java-ACL/GetEntryAgent
Agent agent = agentContext.getCurrentAgent( ) ;
Database db = agentContext.getCurrentDatabase();
ACL acl = db.getACL( ) ;
ACLEntry entry = acl.getEntry(agent.getComment());
if (entry != null)
{
if (entry.isCanDeleteDocuments())
System, out .println (entry. getNarne () + " can delete documents"}; else
System.out.println (entry.getName() + " cannot delete documents"); }
else System.out.println ("No entry for " + agent.getComment());
Метод getFirstEntry - «получить первый элемент ACL».:• • - :•.••;....•..::. . •••• . . ......
LotusScript:
Set notesACLEntry = notesACL.geiFirstEntry
Java:
ACLEntry entry = ACLEntry /4CLgetFirstEntry()
Возвращает объект класса [NotesJACLEntry, представляющий первый элемент в ACL
базы. Обычно это элемент для "-Default-".
Метод getNextEntry - «получить следующий за указанным элемент ACL»
LotusScript:
Set notesACLEntry - notes ACL.geiNextEntry (notesACLEntry)
Java:
ACLEntry entry = /ICX.getNexiEntryO
ACLEntry entry = ACL.gGtNen.tEntry(ACLEntrypreventry)
Возвращает объект класса [NotesJACLEntry, представляющий элемент из ACL ба:^ы,
следующий за элементом, заданным параметром метода, или, если в Java был применен
метод без параметров, ранее извлеченным из объекта ACL элементом. Если следующего
элемента нет, в LotusScript возвращается Nothing, а в Java - null.
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
468
Пример 1. Скрипт выводит имена всех элементов из ACL текущей базы.
Dim session As New NotesSession
Dim db As NotesDatabase
Set db = session.CurrentDatabase
Dim acl As NotesACL
...
Dim entry As NotesACLEntry
Sot aci ~ db.ACL
Set entry = acl.GetFirstEntry
While Not entry Is Nothing
P r in t e ntry.N ame
Set entry = acl.GetNextEntry(entry)
Wend
Пример 2. Агент проверяет, содержится ли имя, указанное в поле комментариев этого агента, в
ACL текущей базы. Имя должно задаваться в формате [Caninicalize], но без учета регистра.
// Java-ACL/GetFirstEntryAgent
•'
Agent agent = agentContext.getCurrentAgent();
Database db = agentContext.getCurrentDatabase();
ACL acl = db.getACL();
boolean gotlt = false;
ACLEntry entry = acl.getFirstEntry();
do
{
if ( entry . get Name () . equals IgnoreCase (agent. . get Comment ( ) ) )
{
gotlt = true;
break;
} } while ( (entry = acl.getNextEntry(entry)) != null);
if (gotlt) System., out .print In (entry . getName () -h " is in the ACL");
else
System.out.print In(agent,getComment() + " is not in the ACL");
1
Метод create ACLEntry - «создать элемент ACL» . "•' . ••.•:...,..;.. • ............. . .... ••• . .
LotusScript:
Java:
Set notesACLEntry — «0to/4CZ,.createACLEntry( name$, level% )
ACLEntry entry = ACL,createACljE,ntry(String name, int level)
Создает в ACL новый элемент с именем пате (тип String) и уровнем доступа level.
Уровень доступа задается одной из следующих констант:
ACLLEVELJMOACCESS / ACL.LEVEL_NOACCESS - нет доступа, '
ACLLEVEL!DEPOSITOR / ACL.LEVEL DEPOSITOR - депозитор,
ACLLEVEL READER / ACL.LEVELJIEADER - читатель,
ACL.LEVEL_ AUTHOR / ACL.LEVEL_AUTHOR - автор,
ACLLEVEL EDITOR / ACL.LEVEL_EDITOR - редактор,
ACLLEVEL~DES1GNER / ACL.LEVELJDES1GNER - дизайнер,
ACLLEVELlMANAGER / ACL.LEVEL_MANAGER - менеджер.
Метод возвращает объект класса [Notes] ACLEntry, представляющий созданный элемент.
Не забывайте вызывать метод save для сохранения модифицированной ACL в базе.
© InterTrust Со. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
469
Пример !. Скрипт добавляет группу Редакторы с доступом редактора в ACL текущей базы.
Dim session As New NotesSession . .
Dim db As NotesDatabase
Set db = session.CurrentDatabase
Dim acl As NotesACL
Dim entry As NotesACLEntry
Set acl = db.ACL
.
.
Set entry = acl.CreateACLEntry { "Редакторы", ACLLEVEL_EDITOR )
Call acl.Save
Пример 2. Агент добавляет имя, указанное в поле комментариев этого агента, в ACL текущей базы с
доступом автора.
// Java-ACL/CreateACLEntryAgent
Agent agent = aqentContext.getCurrentAgent();
Database db = agentContext.getCurrentDatabase () ;
ACL acl - db.get.ACLO ;
acl. CreateACLEntry (agent. getComment. () , ACL. LEVEL_AUTHOR) ;
acl.save();
© Метод removeACLEntry - «удалить элемент ACL»' . : •..•.-••••••••Java:
.......::;:'
void ACL.remove\CLEntry(String name}
Удаляет из ACL элемент с именем пате (тип String). He забывайте вызывать метод save
для сохранения модифицированной ACL в базе.
Пример 1. Агент удаляет имя. указанное в поле комментариев этого агента, из ACL текущей базы.
// ACL/RemoveAclEntry
Agent agent = agentContext.getCurrentAgent ( ) ;
Database db = agentContext.getCurrentDatabase( ) ;
ACL acl = db.getACL();
acl.removeACLEntry(agent.getComment());
acl.save() ;
Метод save - «сохранить информацию из объекта ACL в базе»
LotusScript:
Call notesACL.$a\e
Java:
public void ACL.saveQ
Сохраняет выполненные в объекте класса [NotesjACLEntry изменения в базе (в файле
базы на диске). Без вызова этого метода до закрытия базы все выполненные в объекте
изменения будут утеряны.
Встроенные классы LotusScript и Java
470
3.8. «Элемент из списка управления доступом» - класс
[NotesJACLEntry
Представляет один элемент (для пользователя, сервера или группы) из списка управления
доступом (ACL) базы. Свойства и методы этого класса позволяют определять и изменять имя
владельца элемента ACL, его уровень доступа, тип и дополнительные возможности (может ли
удалять документы, создавать новые документы, папки, агентов и пр.), а также управлять
назначением владельца на роли.
«Контейнерная иерархия»
LotusScript
Java
NotesACL
->
NotesACLEntry
->
NotesACL
ACL
_>
ACLEntry
_>
ACL
Для создания объекта класса [NotesjACLEntry обычно используют метод createACLEntry
класса [Notes]ACL.
• В LotusScript для этого может также использоваться метод New. Метод New создает в
объекте notesACL, представляющем ACL, новый элемент с именем пате$ (тип String) и
уровнем доступа /eve/%.
Dim variableName As New NotesACLEntry( notesACL, name$, level% )
или Set
notes ACLEntry - New NotesACLEntry( notesACL, name$, /eve/% ) Константа,
/eve/% может быть одной из следующих:
•
•
•
•
•
•
•
ACLLEVEL NOACCESS - нет доступа,
ACLLEVEL_DEPOSITOR-депозитор,
ACLLEVELJREADER - читатель,
ACLLEVEL_AUTHOR - автор,
ACLLEVEL_EDITOR - редактор,
ACLLEVEL_DESIGNER - дизайнер,
ACLLEVELJMANAGER - менеджер.
Для доступа к существующему элементу ACL из объекта класса [NotesjACL имеются два
способа:
'
• если известно имя владельца элемента ACL, его элемент можно получить методом
getEntry;
•
если имя владельца неизвестно, можно «просмотреть» все элементы методами
getFirstEntry и getNextEntry.
Не забывайте вызывать метод save для объекта [NotesjACL, чтобы сохранить в ACL базы
изменения, произведенные вами как в объекте [NotesjACL, так и в содержащихся в нем
объектах [NotesjACLEntry.
Пример. Скрипт методом New создает в ACL элемент для группы Terminations, которая, как
общепринято, содержит список субъектов, которым никуда нет доступа.
Dim session As New NotesSession
Dim db As NotesDataba.se
Dim acl As NotesACL
Dim entry As NotesACLEntry
Set db - session.CurrentDatabase
If Not. ( db.IsOpen ) Then
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
Call db.Open( "", "" }
End If
Set acl = db.ACL Set entry = New NotesACLEntry( acl,
ACLLEVEL_NOACCESS )
Call acl.Save
471
"Terminations",
3.8.1. Свойства
Свойство Parent-«родитель»
LotusScript:
Set notes ACL - notesACLEntry.Parent
Java:
ACL ad = ACLEntry.getPurentQ
Объект класса [NotesJACL, содержащий данный элемент ACL.
Свойство Level -«уровень доступа»
-:-..'-'"'. :;...
LotusScript:
:•."..':•
•':•'•''•
level% = notesACLEntry.Lev el
notesACLEntry.Level - level%
Java:
int level = ACLEntry.getLe\elQ
void ACLEnlry.seiLe\el(int level)
Уровень доступа к базе владельца этого элемента ACL. Возможные уровни доступа
задаются константами:
ACLLEVELJNOACCESS / ACL.LEVEL_NOACCESS - нет доступа,
ACLLEVEL DEPOSITOR / ACL.LEVEL_DEPOS1TOR - депозитор,
ACLLEVEL "READER / ACL.LEVEL_READER - читатель,
ACLLEVEL ^AUTHOR / ACL.LEVEL_AUTHOR - автор,
ACLLEVEL_ED1TOR / ACL.LEVEL_EDITOR - редактор,
ACLLEVEL_DES1GNER / ACLiLEVEL_DESIGNER - дизайнер,
ACLLEVELJV1ANAGER / ACL.LEVEL_MANAGER - менеджер.
Пример 1. Скрипт находит в ACL- текущей базы элемент для группы LocalDomainServers и, если
группа имеет к базе доступ менеджера, предоставляет ей доступ дизайнера.
Dim session As New NotesSessiori
Dim db As NotesDatabase
Dim acl As NotesACL
Dim entry As NotesACLEntry
Set db = session.CurrentDatabase
Set acl = db.ACL
Set entry •- acl. GetEntry ( "LocalDomainServers" )
If Not ( entry Is Nothing ) Then
If entry.Level = ACLLEVEL_MANAGER Then
entry.Level = ACLLEVEL_DESIGNER Call
acl.Save
End If
.
End If
-
Пример 2. Java-агент выводит уровни доступа всех элементов ACL текущей базы.
// Java-ACLEntry/LevelAgent
Database db = agentContext.getCurrentDatabase{);
ACL acl = db.getACL();
ACLEntry entry = acl.getFirstEntry();
String lev = null;
do {
switch(entry.getLevel())
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript u Java
472
{
case ACL.LEVEL_NOACCESS: lev = "no";
break ;
case ACL.LEVEL_DEPOSITOR: lev = "depositor"; break;
case ACL.LEVEL_READER:
lev = "reader";
b r e a k;
case ACL,LEVEL^AUTHOR:
lev = "author";
-break;
case ACL.LEVEL_EDITOR:
lev = "editor";
break;
case ACL.LEVEL__DESIGNER:
lev = "designer";
break;
case ACL.LEVELJMANAGER:
lev = "manager";
break; }
System.out.println(entry.getName( ) + " has "+lev+" access"); }
while ( (entry = acl.getNextEntry(entry)) != null);
Свойство Name - «имя владельца элемента ACL»
LotusScript:
.
•. ,
name$ ~ notesACLEntry.Nsane
notesACLEntry.Nstme = nameS
Java:
String name = ACLEntry.geiNnmeQ
void ACLEntry.seiName(String name)
void ACLEntry.setName(Name name)
Имя владельца элемента ACL. Тип String или, в Java при установке свойства, объект
класса Name, содержащий это имя. Когда вы изменяете имя, все прочие атрибуты этого
элемента, например, уровень доступа и тип, сохраняются.
Пример. Скрипт кнопки в форме «просит» пользователя ввести уровень доступа, а затем выбирает us
ACL текущей базы список элементов, имеющих этот уровень доступа, и помещает этот список в поле
Comment текущего документа. Функция GetLevelConstant служи! для преобразования введенной
пользователем строки, например, "Designer", в соответствующую константу - ACLLEVEL_ DESIGNER.
Sub Click(Source As Button)
Dim workspace As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Dim session As New NotesSession
Dim db As NotesDatabase
Dim acl As NotesACL
Dim entry As NotesACLEntry
Dim LevelString As String
Dim .levelConstant As Integer
Set uidoc = workspace.Current Document
Set db = session.CurrentDatabase
Set acl = db.ACL
levelString = Inputbox$( "Какой уровень доступа вас интересует?" }
' преобразуем строку в константу ACLLEVEL
levelConstant = GetLevelConstant( levelString )
' просматриваем все элементы ACL
Set entry =•- acl. GetFirstEntry
While Not ( entry Is Nothing )
' если у элемента нужный уровень доступа,
If ( entry.Level - levelConstant ) Then 1 добавляем имя элемента
в поле People. Call uidoc.FieldAppendText( "Comment",
entry.Name & "; " )
End If
Set entry - acl.GetNextEntry( entry ) Wend
' Обновляем текущий документ, чтобы текстовый список '
отображался «красиво» Call uidoc.Refresh
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
473
End Sub
Function GetLevelConstant ( desired.Level As String ) Dim
levelConstant As Integer LevelConstant = 9999 Select
Case Lease(desiredLevel) Case "manager":
levelConstant = ACLLEVEL MANAGER
Case "designer":
levelConstant = ACLLEVEL_DESIGNER
Case "editor":
levelConstant -= ACLLEVEL EDITOR
Case "author":
levelConstant =• ACLLEVEL_ AUTHOR
Case "reader":
levelConstant = ACLLEVEL READER
Case "no access":
levelConstant = ACLLEVEL NOACCESS End
Select
GetLevelConstant = levelConstant.
End Function
- -
Свойство NameObject - «объект [NotesjName для владельца элемента ACL»
LotusScript:
Java:
Set notesName = New NotesName(notesACLEntry.Name)
Name nameOhj = ^CZ.&;frv.getNameObject()
В Java этот метод возвращает объект класса Name, представляющий имя владельца
элемента ACL. В LotusScript аналогичного эффекта можно достичь созданием нового
объекта класса NotesName, указав в качестве параметра его конструктора значение свойства
Name элемента ACL.
Свойства объекта [NotesjName позволяют легко извлекать из имени его различные
составляющие.
® Свойства UserType, IsGroup, IsPerson, IsServer - «тип элемента ACL»
LotusScript:
usertype% = notesACLEntry. UserType
notesACLEntry.Vsei'Type = usertype%
flag
~
notesACLEn
try.IsGroup
notesACLEntry.lsGroup -flag flag notesACLEntry.lsPerson
notesACLEntry.lsPerson —flag flag notesACLEntry.lsServer
notesACLEntry.lsServer —flag
Java:
int user type =^CLЈw/r>'.getUserType()
void A CLEntry.setlherType(int usertype)
boolean flag = ACLEntry.isGroupQ void
ACLEntry.$etGroup(boo!ean flag)
boolean flag ~ ACLEntry.isPerson() void
AC'LEntry.setPerson(boolean flag)
© InterTrust Co. Тел. (095)9567928
Встроенные классы LotusScript и Java
474
boolean flag = ACLEntry.isServerQ
void ACLEntry.$etServer(boolean flag)
Свойство UserType позволяет определить или изменить тип элемента ACL. Тип задается
константой:
* ACLTYPE_Unspecified(= 0)/ACLEntry.TYPE_UNSPECIFIED - не указан,
* ACLTYPEJPerson(= l)/ACLEntry.TYPE_PERSON - пользователь,
* ACLTYPE_Server(= 2)/ACLEntry.TYPE SERVER - сервер,
» ACLTYPE_MixedGroup(= 3)/ACLEntry.TYPE_MIXED_GROUP - «смешанная» группа,
* ACI. TYPE_PersonGroup(= 4)/ACLEntry.TYPE_PERSON_GROUP - группа пользователей,
» ACLTYPE_ServerGroup(= 5)/ACLEntry.TYPEJSERVER_GROUP - группа серверов.
Свойства IsGroup, IsServer и IsPerson имеют значение true, если элемент ACL является
группой (пользователей, серверов или «смешанной»), сервером (собственно сервером,
группой серверов или «смешанной» группой) или пользователем (собственно пользователем,
группой пользователей или «смешанной» группой).
',
Свойство CanCreateDocuments - «может ли создавать документы»
LotusScript:
flog ~ notesACLEntry.CanCresteDocuments
notesACLEntry.Ca.nCre&teDocnments = flag
Java:
boolean flag = ACLEntry.isCanCreateDocumentsQ
void ACLEntry.setCanCreateDocuments(boolean flag)
Для элемента с доступом автора проверяет или устанавливает признак, может ли его
владелец создавать новые документы (Create documents). Если flag =: true, то может, а если
false - нет.
Установка свойства для элементов с иным, чем автор, доступом, не вызывает никакого
эффекта. Для элементов с доступом редактора, дизайнера и менеджера свойство всегда
возвращает true, а для элементов с доступом читателя, депозитора и «нет доступа» - всегда
false. Для вновь созданного элемента ACL с доступом автора свойство по умолчанию
устанавливается в false.
^
Свойство CanDeleteDocuments - «может ли удалять документы»
LotusScript:
flag~ notesACLEntrv.CanDeleteDocuments
notesACLEntry.CanDeleteDocuments —flag
Java:
boolean flag =^CL&tfry.isCanDeIeteDocuments()
void ACLEntry.setCanDeleteDovuments(boolean flag)
Для элемента с доступом автора и выше проверяет или устанавливает признак, может ли
его владелец удалять документы (Delete documents). Если flag == true, то может, а если false
-нет.
Установка свойства для элементов с меньшим, чем автор, доступом, не вызывает
никакого эффекта. Для элементов с доступом читателя, депозитора и «нет доступа» свойство
всегда возвращает false. Для вновь созданного элемента ACL с доступом автора и выше
свойство по умолчанию устанавливается в false.
Пример 1. Скрипт добавляет в ACL текущей базы имя Иван И. Иванов/Acme/RU с доступом автора
и правом создавать новые документы, но без права удалять документы.
Dim session As New NotesSession
Dim db As NotesDatabase
© InterTrust Co. Тел. (095) 9567923 _
Lotus Domino R. 5: {(^-формулы, LotusScript, встроенные классы LotusScript и Java
475
Dim
Dim
Set
Set
Set
acl As NotesACL
...-•..
entry As NotesACLEntry
db = session.Current Database
acl = db.ACL
entry = New NotesACLEntry(acl,"Иван И. Иванов/Acme/RU",
ACLLEVEL AUTHOR )
entry,CanCreateDocuments = True
entry.CanDeleteDocuments = False Call acl.Save
Пример 2. Java-агент выполняет то же, что и скрипт в предыдущем примере. Единственное отличие
- имя добавляемого элемента ACL выбирается из поля комментариев этого агента.
.// Java-ACLEnt r у /CanCr Del Document sAgent
Agent agent = agentContext.getCurrentAgent();
Database db = agentContext.getCurrentDatabase();
ACL acl = db.getACL();.
ACLEntry entry - acl . createACLEnt. ry (agent. get.Comment () , ACL . LEVEL_ AUTHOR) ;
entry.setCanCreateDocuments(true);
entry.setCanDeleteDoeuments(false);
acl.save{);
Свойство CanCreatePersonalFolder - «может ли создавать личные виды или
папки» '•'•'•'•• : •' ' . . - ' . : . - • " • ''::.:-'";.'•••:"".";•-V:"'.'.•••. '"'"'••'•-::.:'•..-.' -•'.•"''V.'..'•-:-...':;-'.-;••
LotusScript:
flag — notesACLEntry.CanCresntcPersanaWolder
notesACLEntry.CanCreatePersonmlFa\der —flag
Java:
boolean flag ~ ACLEntry.isC'dnCreatePcrsonalFolderQ
void ACLEntry.setCa.nCreatePersonalFo\der(boolean flag)
Признак, может или нет владелец элемента с доступом редактора, автора или читателя к
базе создавать в этой базе личные папки (Create personal folders/views). Если flag ~ true, то
может, а если false - нет.
Для элементов ACL с доступом дизайнера и менеджера свойство всегда возвращает
значение true, а для элементов с доступом депозитор и «нет доступа» - всегда false. Установка
свойства для элементов с доступом, отличным от редактора, автора или читателя, не
вызывает никакого эффекта. Для вновь созданного элемента ACL с доступом редактора,
автора или читателя свойство по умолчанию устанавливается в false.
© Свойство CanCreateSharedFolder - «может ли создавать общие виды или
папки»
LotusScript:
flag ~ no/es^CZJi/z/ry.CanCreateSharedFolder
notesACLEntry.C&nCreateSliaredFolder=flag
Java:
boolean flag = ^CLEnfry.isCanCreateSharedFolderQ
void ACLEntry.setCanCreateSharedFolder(boo!ean flag)
Признак, может или нет владелец элемента с доступом редактора к базе создавать в этой
базе общие папки (Create shared folders/views). Если flag = true, то может, а если false - нет.
Для элементов ACL с доступом дизайнера и менеджера свойство всегда возвращает
значение true, а для элементов с доступом автора, читателя, депозитора и «нет доступа»
-всегда false. Установка свойства для элементов с доступом, отличным от редактора, не
вызывает никакого эффекта. Для вновь созданного элемента ACL с доступом редактора
свойство по умолчанию устанавливается в false.
© InterTrust Со. Тел. (095) 9567928
Встроенные классы LotusScript и Java
476
Свойство CanCreatePersonalAgent - «может ли создавать личных агентов»
LotusScript:
flag - woto^CZJ<r«/ry.CanCreatePersonalAgeot
wotei^CLEw/ry.CanCreatePersoiialAgent = flag
Java:
public boolean isCanCreatePersonaiAgent () throws NotesException
public void setCanCreatePersonaiAgent (boolean flag)
throws NotesException
Признак, может или нет владелец элемента с доступом редактора, автора или читателя к
базе создавать в этой базе личных агентов (Create personal agents). Если flag = true, то может, а
если false - нет.
Для элементов ACL с доступом дизайнера и менеджера свойство всегда возвращает
значение true, а для элементов с доступом депозитор и «нет доступа» - всегда false. Установка
свойства для элементов с доступом, отличным от редактора, автора или читателя, не
вызывает никакого эффекта. Для вновь созданного элемента ACL с доступом редактора,
автора или читателя свойство по умолчанию устанавливается в false.
© Свойство CanCreateLSOrJavaAgent - «может ли создавать агентов на
LotusScript или Java». . ..
.. . . ... .. ..-"•:.-:.•• ...... . . • • . . : . • . . • - • '
LotusScript:
flag ~ «0/e&4CЈ.E«fry.CanCreateLSOrJavaAgent
woto/4CLЈ»/rv.CanCreateLSOrJavaAgent -flag
Java:
boolean flag = ^CZj&tfry.isCanCreateLSOrJavaAgentQ
void ,^CiЈ^ry.setCanCreateLSOrJavaAgent(Z>oo/<?a« flag)
Признак, может или нет владелец элемента с доступом читателя, автора, редактора, или
дизайнера к базе создавать в этой базе агенты на LotusScript или Java (Create LotusScript/Java
agents). Если flag = true, то может, а если false - нет.
Для элементов ACL с доступом менеджера свойство всегда возвращает значение true, a
для элементов с доступом депозитор и «нет доступа.» - всегда false. Установка свойства для
элементов с доступом, отличным от дизайнера, редактора, автора или читателя, не вызывает
никакого эффекта. Для вновь созданного элемента ACL с доступом дизайнера, редактора,
автора или читателя свойство по умолчанию устанавливается в false.
Свойство IsPublicReader - «может ли читать общедоступные документы»
LotusScript:
flag = notesACLEntry.IsPablicReader
notesACLEntry.lsPvib}ieReader=flag
Java:
boolean flag ~- ACLEntry.isPublicRe&derQ
void ACLEtitry.setPublicR.eader(boolean flag)
Признак, может или нет владелец элемента, имеющий к базе доступ депозитор или «нет
доступа», читать в этой базе общедоступные документы (Read public documents). Если flag =
true, то может, а если false - нет.
Для элементов ACL с доступом выше депозитора свойство всегда возвращает значение
true. Установка свойства для элементов с доступом выше депозитора не вызывает никакого
эффекта. Для вновь созданного элемента ACL с доступом депозитор и «нет доступа»
свойство по умолчанию устанавливается в false.
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
477
Свойство IsPublic Writer - «может ли создавать общедоступные документы»
LotusScript:
flag = notesACLEntry.IsPublicWnter
notesACLEntry,ls,Public\Vriter = flag
Java:
boolean flag ~ ACLEntry.isPublicWriterQ
voidACLEntry.setPu.blicWriter(boelean flag)
Признак, может или нет владелец элемента, имеющий к базе доступ автора, читателя,
депозитора или «нет доступа», создавать в этой базе общедоступные документы (Write public
documents). Если flag - true, то может, а если false - нет.
Для элементов ACL с доступом выше автора свойство всегда возвращает значение true.
Установка свойства для элементов с доступом выше автора не вызывает никакого эффекта.
Для вновь созданного элемента ACL с доступом автора и ниже свойство по умолчанию
устанавливается в false.
© Свойство IsAdminServer- «является ли сервером администрирования
базы»
:
. . .
.... . .... .
. .."."
LotusScript:
flag = notesACLEntry.lsAdmmServer
notesACLEntry.IsAdmmServcr = flag
Java:
boolean flag = ACLEntry.isAdminServerQ
void ACLEntry.setAdminServer(boolean flag)
Признак, является ли данный элемент ACL сервером администрирования этой базы. Если
flag = true, то является, а если false - нет.
© Свойство IsAdminReaderAuthor - «разрешается ли серверу
администрирования базы изменять в ней поля типа Readers и Authors»
LotusScript:
flag ~ notesACLEntry.lsAdminReauerAuthor
notcsACLEntry.lsAdminReaderAuthor -flag
Java:
boolean flag = ACLEntry.isAdminReaderA.uihor()
void ACLEntry.setAdminRe-MlerAutbor(boolean flag)
Признак, разрешается ли данному элементу ACL, представляющему сервер
администрирования базы, изменять в базе поля типа Readers и Authors при выполнении
запросов по изменению имен или удалению пользователей или серверов. Если flag = true, то
разрешается, а если false - нет.
Пример. Java-агент запускается с рабочей станции администратора и проверяет наличие на
заданном сервере баз, для которых не был назначен сервер администрирования. Если это возможно,
этот сервер назначается сервером администрирования такой базы.
//Java-ACLEntry/SetAdminServer
String server = "Domino500/InterTrustCorp/SU";
DbDirectory Dir = session.getDbDirectory(server);
Database db = Dir . get.FirstDatabase (DbDirectory. REPLICA_CANDIDATE) ;
if ( db != null )
(
do
'
{
try { db.open(); } catch(Exception e) // нет доступа {
System, out .println ( "Not opened " i- db . getFilePath { ) ) ;
© InterTrust Co. Тел. (095)9567928
478
Встроенные классы LotusScript и Java
db. recycle() ; continue; ..,.,.
,
.•
}
ACL acl « db.getACL{);
'
if {acl. isUnif ormAccess { ) =-- true) // такие трогать опасно {
System, out. println ( "Unif ormAccess for " <- db.getFilePath());
db.recycle(); continue;
}
"''•''" ':';" ":
int. accLevel = db . getCurreritAccess'Levei ( ) ; if
(accLevel != ACL.LEVEL MANAGER)
:
\
Syst em. out .pr int ln ( " Not MAN AGE R f or " + db.g etF ile Fat h () );
db.recycle (); continue; }
boolean got It = true;
AC LEn t г у en t. г у - а с 1. g e t Fir s t En t г у () ; do {
if(entry .isAdminServer () == true) f
g o t l t = f al s e ; // с е р ве р а д м ин и с тр и ро в а ни я у ж е н а зн а ч ен break; }
} while ( (entry = acl.getNextEntry(entry )) != null); if
(gotlt === true) // нет сервера администрирования {
System, out. .println ("* + * Database " -f db. getFilePath ( ) + " ..."); AC LE n t r y
s e n t r y = ac l . ge t E nt ry ( s e r ve r ) ; if (sentry == null)
sentry = acl.createACLEntry(server,ACL.LEVEL J4ANAGER) ; it
(sentry i= null)
.
{
.
.
.
sent ry. set Can Del ete D ocum ent s(t rue ) ;
sentry.setUserType(ACLEntry.TYPE_SERVER) ;
sent ry . set Adm inS erv e r(tr ue) ;
sent ry. set Adm inR ead e rAut hor (fa lse ) ;
acl.save();
System.out.println("... AdminServer") ;
,
}
'
}
db.recycle();
} while ( (db = Dir. get NextDatabase ( ) } ! r= null); }
Свойство Roles - «роли, на которые назначен владелец элемента ACL»
LotusScript:
stringArray — notesACLEntry.Roles
Java:
java.util. Vector roles - ACLEntry.geiRolesQ
Возвращает роли (в LotusScript тип Array of strings, в Java - объект класса java.util. Vector с
элементами класса String), на которые назначен владелец элемента ACL. Каждое имя роли
возвращается в квадратных скобках, например: "[Project Leader]".
Пример 1. Скрипт выводит все роли, на которые назначен Иван И. Иванов/Acme/RU. Например,
скрипт мог бы выдать "[Project Leader]" и "[Writer]".
Dim session As New NotesSession
Dim db As NotesDatabase Dim acl
As NotesACL
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
479
Dim entry As NotesACLEntry
Set db = session.CurrentDatabase
Set acl = db.ACL
Set entry = acl .GetEntry( "Иван И, Иваноа/Acme/RU" )
Forall r In entry,Roles
Messagebox( r }
End Forall
Пример 2. Подобно предыдущему примеру, Java-агент выводит все роли, на которые назначен
субъект, имя которого агент получает из «своего» поля комментариев.
import Java -ut.il .Vector;
// Java-ACLEntry/RolesAgent
Agent agent = agentContext.getCurrentAgent();
Database db = agentContext.getCurrentDatabase ();
ACL acl = db.getACL();
ACLEntry entry -- acl. getEntry (agent. getComment ());
i f ( en t r у ! -- nu .11}
I
Vector roles = entry.getRoles();
if (roles.size() == 0)
System.out.println(entry .getName() + " has no roles");
else
{
System.out.println(entry .getName() +
" has the following role(s ):"); for
(int i = 0; i < roles.size(); i++)
System, out. println (" " +• roles . elementAt (i) ) ; } }
3.8.2. Методы
Метод isRoleEnabled - «назначен ли на роль»
LotusScript:
Java:
flag = no1esACLEntry.isRo}eEnableu(rolename$ )
boolean flag — notesACLEntry.isRoleEnabled(String rolename}
Для имени роли rolename (тип String) возвращает true, если владелец элемента ACL
назначен на эту роль, или false, если нет. Имя роли следует задавать «в квадратных скобках».
Если указанное имя роли отсутствует в ACL, в LotusScript последует ошибка, а в Java будет
возбуждено исключение "Role name not found".
Пример. Скрипт создает в интерфейсе пользователя новый документ. Однако для тех, кто назначен
на роль "[Supervisor]", этот документ создается по форме approval, а для прочих - по форме request.
Dim workspace As New NotesOIWorkspace
Dim session As New NotesSession
Dim uidoc As NotesUIDocument
Dim acl As NotesACL
Dim entry As NotesACLEntry
Set. db = session.Current.Databa.se
Set acl = db.ACL
Set entry = acl.GetEntry( session,CommonUserName )
If entry.IsRoleEnabled( "[Supervisor]" ) Then
Set uidoc = workspace.ComposeDocument( "", "approval" ) E1 s
e
Set uidoc = workspace.ComposeDocument( "", "request" ) End I
f
© InterTrust Co. Ten. (095)9567928
Встроенные классы LotusScript и Java
480
Метод EnableRole - «назначить на роль»
LotusScript:
Call notesACLEntry,^nst\3\eVio\e(rolename$)
Java:
voidACLEnlry.enableRole(String rolename)
Назначает владельца элемента ACL на роль, имя которой задано параметром rolename.
Имя роли следует задавать «без квадратных скобок». Если указанное имя роли отсутствует в
ACL, в LotusScript последует ошибка, а в Java будет возбуждено исключение "Role name not
found". Если роль существует, но владелец элемента уже назначен на эту роль, нечего не
изменится. Выполненные назначения вступят в силу только после сохранения ACL методом
save.
Пример I. Скрипт кнопки вызывает подпрограмму enablePeople, которая в ACL текущей базы
назначает на роль [Роль 1] всех субъектов, перечисленных в списке names.
Sub Click(Source As Button)
Dim session. As New NotesSession
Dim db As NotesDatabase
Dim acl As NotesACL
Dim entry As NotesACLEntry
Set db = session.CurrentDatabase
Set acl - db.ACL
Dim names List As Variant
names("1") = "Nikolay N. lontsev/InterTrustCorp/SU"
names("2") = "LocalDomainServers"
names("3") = "Иван И, Иванов/Acme/RU"
names("4") = "John П. Иванов/Acme/RU"
Dim role As String
role = "Роль 1"
Call enablePeople(acl, role, names) End
Sub
Sub enablePeople ( acl As NotesACL, role; As String, names As Variant ) Dim
person As NotesACLEntry Forall ri In names
Set person ^ acl. Get.Entry ( n ) If
person Is Nothing Then
Set person = New NotesACLEntry( acl, n, ACLLEVEL_READER ) End
If
Call person.EnableRole( role )
Print n; " enabled the role ["; role; " ] "
End Forall
Call acl.Save
End Sub
'
Пример 2. Java-агент назначает все элементы ACL текущей базы на роль, имя которой выбирается из
моля комментариев агента. Предварительная проверка, что элемент уже назначен на роль, не
является необходимой, но приведена, чтобы продемонстрировать применение метода isRoleEnabled.
/' / Ja va - AC LEn try /Enable Role Agent
Agent agent - agentContext.getCurrentAgent();
Database db = agentContext.getCurrentDatabase ( ) ;
ACL acl = db.getACL();
ACLEntry entry = acl.getFirstEntry{) ;
do {
if (entry.isRoleEnabled(agent.getComment()))
{
System.out.println(agent.getComment() +
" is already enabled for " + entry. getName ());
}
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
481
else
{
entry.enableRole(agent.getComment( ) ) ;
System.out.println(agent.getCoiranent(} +
" enabled for " + entry.getName( ) ) ; }
} while { (entry = acl.getNextEntry(entry)) ' = null);
acl.save ();
Метод disableRole - «ликвидировать назначение на роль»
LotusScript:
Call notesACLEntryMs»bleRolK(roIenameS)
Java:
voidACLEnlry.<\isable:Ro\e(String rolename)
Ликвидирует назначение владельца элемента ACL на роль, имя которой задано
параметром rolename. Имя роли следует задавать «без квадратных скобок». Если указанное
имя роли отсутствует в ACL, в LotusScript последует ошибка, а в Java будет возбуждено
исключение "Role name not found". Если роль существует, но владелец элемента не назначен
на эту роль, нечего не изменится. Выполненные назначения вступят в силу только после
сохранения ACL методом save.
Метод remove - «удалить элемент из ACL»
LotusScript:
Call notesACLEntry.i'eniQ've
Jav я:
vo id A CLEntry. rem ove()
',.. ::.. :... ..: ' : . . • ; . . . . .
•
.; :;. ,:
Удаляет элемент из ACL. Изменения вступят в силу после сохранения ACL. Учтите, что
субъект, элемент которого вы удалили из ACL, возможно, сможет получить доступ к базе как
член группы или -Default-.
Пример I. Скрипт находит сервер Development/InterTrustCorp/SU в ACL текущей базы и удаляет
его из ACL.
Dim session As New NotesSession
Dim db As NotesDatabase
Dim acl As NotesACL
Dim entry As NotesACLEntry
Set db = session.CurrentDatabase
Set acl = db.ACL
Set entry = acl.GetEntry( "Development/InterTrustCorp/SU" )
If Not (entry Is Nothing) Then
Call entry.Remove
Call acl.Save
,
. '
,
End If
Пример 2. Java-агент находит элемент ACL, имя которого указано в поле комментариев агента, и
удаляет этот элемент из ACL.
/7 Java-ACLEntry/RemoveAgent
Agent agent = agentContext.getCurrentAgent();
Database db = agentContext.getCurrentDatabase( ) ;
ACL acl = db.getACL(};
ACLEntry entry = acl.getEntry(agent.getComment( ) ) ;
if (entry != null)
{
entry.remove();
acl.save();
}
'
© InterTrust Co. Тел, (095)9567928
Встроенные классы LotusScript и Java
482
3.9. «Иерархическая навигационная схема» - класс [Notes]Outline
Новый класс в Domino версии 5 - [Notes]Outline - предназначен для работы с элементом
дизайна Outline - «иерархической навигационной схемой». Навигационная схема в свою
очередь состоит из набора иерархически («древовидно») упорядоченных элементов, выбор
которых пользователем влечет выполнение некоторого действия или перехода по ссылке.
Каждый элемент схемы характеризуется своим положением и уровнем в схеме и может
иметь «родителя» и «потомков». Уровень элемента в схеме исчисляется с нуля. Для работы с
элементом схемы в LotusScript или Java используется объект класса [Notes]OutlineEntry.
Рис. 3.21 Внешний вид Outline как элемента дизайна (в окне Domino Designer)
«Контейнерная иерархия»
LotusScript
Java
NotesDatabase
_»
NotesOutline
Database
—»
Outline
->
—>
NotesOutlineEntry
OutlineEntry
Свойства объекта [NotesjOutline «немногочисленны» - название, алиас и комментарий.
Методы объекта [Notes]Outline позволяют осуществлять навигацию по элементам, входяешм в
схему, создавать новые элементы, добавлять их в необходимое место в схеме, перемещать
существующие элементы в схеме и удалять их. Для того, чтобы все модификации,
выполненные «программно» в объекте [Notes(Outline, были сохранены в базе, необходимо
вызвать метод save.
Рис. 3.22 Окно свойств Outline как элемента дизайна
Для создания новой иерархической навигационной схемы используется метод
createOutline класса [NotesJDatabase - он создает в базе новый элемент дизайна и возвращает
ссылку на представляющий его объект класса [NotesJOutline. Для доступа к существующей
навигационной схеме можно использовать метод getOutline класса [NotesJDatabase, однако и
© InterTrust Co. Тел. (095) 9567928
Lotus. Domino R. 5: (<£м$<чшулы,. LotusScript, встроенные классы LotusScript и Java
483
метод createOutline в случае, когда схема уже существует в базе, будет возвращать тот же
самый объект.
3.9.1. Свойства
© Свойство Name - «название схемы»
LotusScript:
пате$ — notesOutline.'Name
по1езОиШпе.1$яте = пате$
Java:
String name - OM//w<?.getNameQ
void Ou(line.seiName(String name)
Имя иерархической навигационной схемы как элемента дизайна.
® Свойство Alias - «алиас схемы»
LotusScript:
Java:
пате$ = notesOutline.A\ia.$
String пате - Oz////ne.getAHasQ
notesOutline.Alias ~ пате$
void Outline.setAli&s(String пате)
Алиас (альтернативное название) иерархической навигационной схемы как элемент;
дизайна.
© Свойство Comment - «комментарий к схеме»
LotusScript:
пате$ = notesOutline.Comment
:
S
notesOuiIine.Comment = пате$
Java:
String пате — 0M///>?e.getComment()
void Outline.setComment(String пате) Комментарий к
иерархической навигационной схеме как элементу дизайна.
3.9.2. Методы для навигации по элементам схемы
© Метод getFirst - «получить первый элемент из схемы»
LotusScript:
SetnotesOutlineEntry — notesOutline.getҐirst()
Java:
OutlineEntry entry - Outline.geiFirstQ
-,
Возвращает первый элемент из объекта [Notes]Outline или Nothing/null, если его нет.
@ Метод getNext - «получить следующий за указанны м элемент» .....-.... .-.:..ч.••:'.:"
LotusScript:
Set nextNotesOutlineEntry —
notesOutline,^,eiNe\t( NotesOutlineEntry)
Java:
OutlineEntry nextEntry = Outline.geiNeTit(OutlineEntry entry)
Возвращает элемент из объекта [NotesJOutline, следующий за элементом, заданнь
параметром метода, или Nothing/null, если его нет.
..
.
©Метод getLast- «получить последний элемент из схемы»
LotusScript:
Set notesOullineEntry = notesOulline.gKtLast( )
Java:
OutlineEntry entry = Outline.geiLast()
. . .... ..:.-:..
Возвращает последний элемент из объекта [NotesjOutline или Nothing/null, если его нет.
Встроенные классы LotusScript и Java
484
@ Метод getPrev - «получить предшествующий указанному элемент»
LotusScript:
Set prevNotesOuiUneEntry =
notesOutline.getPrev( NotesOutlineEntry )
Java:
OutlineEntry prevEntty — Outline.geiPrev^OutlineEntry entry)
Возвращает элемент из объекта [Notes]Outline, предшествующий элементу, заданному
параметром метода, или Nothing/null, если его нет.
© Метод getNextSibiing - «получить следующий за указанным элемент того же
уровня»
LotusScript:
Set nextSibNotes Outline Entry ~
notesOutline.geiNe\tSib\\ng( NotesOutlineEntry)
Java:
OutlineEntry nextSibEntry = Oiitlit-ie.gct'Ne^tSiblhi^OutlineEntry entry)
Возвращает элемент из объекта [NotesJOutline, следующий за элементом, заданным
параметром метода, и имеющий тот же уровень. Например, на Рис. 3.21 для элемента с
именем «Презентация» таким окажется элемент с именем «New Entry4». Ехли такого
элемента не существует, возвращается Nothing/null.
© Метод getPrevSibling - «получить предшествующий указанному элемент ..
тогожеуровня» •' ' . • •' . " •. ' -. ' • ::;'••:...::.'--.-•..'•.. ,^-•••..•-'..-..•.•::-'. • - . . ": ' :. :' ;
LotusScript:
Set prevSibNotesOutlineEntry ~
«o/esOw////2e.getPrevSibImg( NotesOutlineEntry )
Java:
OutlineEntry prevSibEntry ~ Outline.getPrevSib\ing(OutlmeEntry entry)
Возвращает элемент из объекта [NotesJOutline, предшествующий элементу, заданному
параметром метода, и имеющий тот же уровень. Если такого элемента не существует,
возвращается Nothing/null.
© Метод getParent - «получить элемент, являющийся родителем указанного»
LotusScript:
Set parentNotesOutlineEntry =
,
notesOutline,getParent( NotesOutlineEntry )
Java:
OutlineEntry parentEntry = Outline.getParent(OutlineEntry entry)
Возвращает элемент из объекта [NotesJOutline, являющийся «родителем» для элемента,
заданного параметром метода. Например, на Рис. 3.21 для элемента с именем «Пример 2»
таким окажется элемент с именем «Презентация». Если такого элемента не существует,
возвращается Nothing/null.
3.9.3, Прочие методы
© Метод createEntry - «создать для схемы новый элемент»
LotusScript:
Java:
:
• .... . .
- ::
Set notesOutlineEntry - notesOutline.createEntry( entryNameS)
OutlineEntry entry = Outline.createEntry (String entryName)
Создает в схеме новый элемент с именем, заданным параметром entryName (тип String), и
возвращает представляющий его объект класса [Notes]OutlineEntry. Этот элемент «еще не
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: (а)-формулы, LotusScript, встроенные классы LotusScript и Java
485
добавлен в определенное место в схеме», и для осуществления этого необходимо
воспользоваться методом addEntry.
© Метод addEntry - «добавить новый элемент в схему»
LotusScript:
Call note$Outline.mdd'Entry( newEntry [ , re/Entry [, after ] [, asChild ]] )
Java:
void Outline.add'Entry(OutlineEntry newEntry, OutlineEntry re/Entry)
void Outline.addE>ntry(OullineEnlry newEntry, OutlineEntry re/Entry,
boolean after)
void Outline.•AUAE.atry(OutlineEntry newEntry, OutlineEntry refEntry,
boolean after, boolean asChild)
Добавляет в объект [Notes]Outline новый элемент newEntry (объект класса
[NotesjOutlineEntry). Элемент добавляется после или перед элементом, заданным параметром
refEnlry (объект класса [NotesjOutlineEntry). Добавление происходит «после» , если флаг after
опущен или равен true, и «перед», если флаг after равен false. Чтобы добавить первый
элемент в «пустую схему» или «за последним существующим элементом», нужно опустить
параметр refEntry или задать его равным null. Если флаг asChild опущен или равен true,
добавляемый элемент становится потомком элемента refEntry. Если флаг asChild равен false,
добавляемый элемент будет иметь тот же уровень, что и элемент refEnlry. Учтите, что
добавление нового элемента «как потомка перед указанным элементом» не допускается.
© Метод moveEntry - «переместить существующий элемент в схеме»
LotusScript:
Call notesOutline,moveEntry( movedEntry [, refEntry [, after ][, asChild ]])
Java:
void Outline.moveE,ntry(OutlineEntry movedEntry, OutlineEntry refEntry)
void Ontline.moveEntry(OutlineEntry movedEntry, OutlineEntry re/Entry,
boolean after) void Outline.mQve~Entry(OutlineEntry movedEntry,
OutlineEntry refEntry,
boolean after, boolean asChild)
Перемещает в объекте [NotesJOutline существующий элемент movedEntry (объект класса
[NotesjOutlineEntry). Элемент помещается после или перед элементом, заданным параметром
refEntry (объект класса [NotesjOutlineEntry). Перемещение выполняется «в позицию после
элемента», если флаг after опущен или равен true, и «перед», если флаг after равен false. Если
флаг asChild опущен или равен true, перемещаемый элемент становится потомком элемента
refEntry, Если же флаг asChild равен false, перемещаемый элемент будет иметь тот же
уровень, что и элемент refEnlry, Учтите, что «за перемещаемым элементом в новое
местоположение последуют и все его потомки».
© Метод removeEntry - «удалить существующий элемент из схемы»
LotusScript:
Call notesOutline.removeEntry( NotesOutlineEntry)
Java:
void Outlme.rEmoveEntry(OutlineEntry entry)
Удаляет из объекта [NotesJOutline существующий элемент - объект класса
[NotesjOutlineEntry. Учтите, что вместе с удаляемым элементом удаляется и все его потомки.
© Метод save - «сохранить схему» . • . . . .
LotusScript:
• •: . • •••...,. , . : - •••:•••.•••..:•-:':::;:.;..
Call notesOutline.save
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
486
Java:
void Outline.s&\eQ
Для того, чтобы все модификации, выполненные в объекте объекта [NotesJOutline, были
сохранены в элементе дизайна Outline в базе, необходимо вызвать метод save.
Пример 1. Скрипт получает иерархическую навигационную схему с именем Outline! и сначала
выводит информацию о составляющих ее элементах, их количестве и количестве уровней. Затем
скрипт добавляет в схему вслед за ее последним элементом новый элемент «как потомка».
Dim s As New NotesSession
Dim db As notesDataba.se
Set db = s.CurrentDatabase
Dim о As notesOutline
Set о = db.GetOutline( "Outlinel" )
Dim oe As notesOut.lineEn.try
Dim oe.Last As notesOutlineEntry
Л
Set oe — o.GetFirstQ
n = 0
maxLev -~ 0
While Not ( oe Is Nothing )
n = n + 1
If maxLev < oe.Level Then maxLev = oe.Level
Messagebox "OutlineEntry #" & Cstr(n) S " Level" & Cstr(oe.Level) & " :
" & oe.Label
Set oeLast = oe
Set oe = о.GetNext( oe )
Wend
Messagebox "Элементов " & Cstr(n) & " Уровней " & Cstr(maxLev+1) Dim
oeNew As notesOutlineEntry
Set oeNew = о.CreateEntry{"New Entry" & Cstr(rH-l))
Call oeNew.SetURL("http:/'/dominoSOO"} Call o.AddEntry
(oeNew, oeLast} Call о.Save Messagebox "Добавлена
новая OutlineEntry"
Пример 2. Java-агент выполняет те же действия, что и скрипт в предыдущем примере.
//Java-Outline/Exl
Database db =-- agentContext. getCurrentDatabase (} ;
Outline о = db.getOutline{"Outlinel");
OutlineEntry oe = о.getFirst();
OutlineEntry oeLast = null; int
n = 0; int. maxLev = 0; while
( oe != null ) {
n - n + 1; if (maxLev < oe.getLevel()} maxLev = oe.getLevel();
System .out. println ( "OutlineEntry it" + n + " Level" + oe . getLevel () + " :
" + oe.getLabel());
oeLast = oe; oe = o.getNext( oe }; }
System.out.println("Элементов " + n + " Уровней " + (maxLev+1));
OutlineEntry oeNew = о.CreateEntry("New Entry" + (n+1)); oeNew.set
URL("http://dominoSOO") ; о.addEntry (oeNew, oeLast); о.save();
о.recycle(); System.out.println("Добавлена новая OutlineEntry") ;
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R, 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
487
3.10, «Элемент навигационной схемы» - класс [NotesjOutlineEntry
Класс [NotesjOutlineEntry - новый класс в Domino версии 5, позволяющий работать с
элементом, входящим в состав иерархической навигационной схемы (Outline). Каждый
элемент схемы имеет имя и алиас, может иметь пиктограмму, быть «видимым» или
«скрытым», характеризуется типом и классом, и, наконец, имеет или ссылку на ресурс,
который «открывается» при выборе элемента пользователем в текущем окне или заданном
фрейме-«мишени», или действие, заданное @-функцией и выполняемое при выборе элемента
пользователем.
Свойства класса [NotesjOutlineEntry во многом соответствуют возможностям, доступным
в окне свойств элемента навигационной схемы в Domino Designer.
Puc, 3.23 Окна свойств элемента навигационной схемы в Domino Designer
Методы класса [NotesjOutlineEntry позволяют определять для элемента ссылку на ресурс на базу данных Notes, вид или документ в базе, на элемент дизайна в базе (форму, страницу,
набор фреймов, вид, папку, навигатор), на ресурс в Internet - или выполняемое при выборе
элемента действие, которое определяется @-формулой.
«Контейнерная иерархия»
LotusScript
Java
NotesOutline
—>
Outline
—>
NotesOutlineEntry
—>
NotesDatabase
NotesView
NotesDocument
OutlineEntry — > Database View
Document
Для создания объекта класса [NotesjOutlineEntry, представляющего новый элемент
схемы, используют метод createEntry класса [NotesJOutline, а для получения объекта для
существующего элемента схемы - различные методы класса [NotesJOutline.
3.10.1. Свойства
© Свойство Label - «метка элемента»
LotusScript:
text$ - notesOutlineEntry.l&bel
notesOutlineEntry.luabel — texlS
< InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
488
Java:
String text = OutlineEntry.getLabelQ
void OutlineEntry.seiL&be\(String text) Метка
(название) элемента иерархической навигационной схемы.
© Свойство Alias - «алиас элемента»
LotusScript:
textS = notesOtitlineEntry.Alias
notesOutlineEntry.Alias = text$
Java:
String text = OutlineEntry.getAlmsQ
void OutlineEntr)>.setAlias(String text) Алиас (альтернативное
название) элемента иерархической навигационной схемы.
© Свойство IsHidden - «скрытый ли»
LotusScript:
flag = notesOutlineEntry.lsHidden
notesOutlmeEntry.lsHidtlen -flag
Java:
boolean flag - OutlineEntry,isHidden()
void OutlineEntry.seiHidden(booiean flag)
Значение true, если элемент схемы «скрытый», или false, если он «виден» в интерфейсе
пользователя.
© Свойство IsPrivate - «общий или частный» •
:
.
.
':v•
:
:
LotusScript:
flag = notesOutlineEntry.IsPrivate
Java:
boolean flag = OutlineEntry,iPtiv&te()
Возвращает true, если элемент схемы «частный», или false, если он «общий».
© Свойство ImagesText - «файл с изображением пиктограммы для элемента»
LotusScript:
imageS = notesOutlineEntry.Im.agesText
note$OutlineEntry.Imag,es'Te\t:~ image $
Java:
String image = OM///neЈ'«/ry.getImagesText()
voidOutlineEntry.seilm»gesTe\t(String image)
Строка с именем файла, содержащего изображение пиктограммы для этого элемента
схемы. Сам же этот файл должен содержаться в графических ресурсах базы.
© Свойство Level - «уровень в иерархической навигационной схеме»
LotusScript:
level& = notesOutlineEntry.~Level
Java:
int level = OutlineEntry.geiLevelQ
Целое число (тип Long/int), дающее уровень элемента в иерархической навигационной
схеме. Для элемента на самом старшем уровне Level == 0.
© InterTrust Со. Тел. (095) 9567928
Lotus Domino R, 5: @гформулы, LotusScript, встроенные классы LotusScript и Java
489
© Свойство HasChildren - «имеет ли потомков»
LotusScript:
flag - notesOutlineEntry.HasCbildren
Java:
boolean flag = OutlineEntry.hasCbMrenQ
Возвращает true, если элемент схемы имеет потомков, или false, если не имеет.
© Свойство Туре - «тин элемента»
LotusScript:
. , .-....• •....•.-....
;."\'.•'..••'.-..
type& — notesOtttlineEnlry.Type
notesOutlineEntry^ype - type&
Java:
int type = OutlineEntry.getTypeQ
Константа типа Long/int характеризующая тип элемента схемы:
»
OUTLINE_TYPE_NOTELrNK/OutiineEntry.OUTLlNE_TYPE_NOTELTNK - ссылка на базу
Notes (Database Link), вид (View Link) или документ (Document Link);
*
OUTLINE_TYPE_NAMEDELEMENT/OutlineEntry.OUTLlME_TYPE_NAMEDELEMENTссылка на элемент дизайна из базы Notes (форму, страницу, набор фреймов, вид, папку,
навигатор) по его имени;
OUTLINE^TYPEJURL/OutlineEntry.OUTLINEJTYPEJJRL - ссылка на ресурс в Internet
по URL;
OUTLlNE_TYPE_ACTION/OutlineEntry.OUTLlNE_TYPE_ACTION
действие,
описываемое @-формулой;
,
;•••
OUTLINE_OTHER_VlEWS_TYPE/OutlineEntry.OUTLINE_OTHER_VIEWS_TYPE
ссылка на виды других типов;
OUTLINE_OTHER_FOLDERS_TYPE/OutlineEntry.OUTLINE_OTHER_FOLDERS_TYPE ссылка на папки других типов;
OUTLINE_OTHER_UNKNOWN_TYPE/OutlineEntry.OUTL[NE_OTHER_UNKNOWN_TY
РЕ - другой тип.
. ., .
*
«
*
*
*
© Свойство Entry Class - «класс элемента» . •
LotusScript:
Java:
. . . , . ; •;;; - •::': •• ..•.... , ;....:.,. .;:-:•:.; • :•; ...
entryClass% — notesOutlineEntry.'EntryCfass
int entryClass -•=- OutlineEntry.getEntryClassQ
Константа типа Integer/int, характеризующая класс элемента схемы:
*
*
*
*
*
*
OUTLINE_CLASS_DATABASE/OutlineEntry.OUTLINE_CLASS_DATABASE - ссылка на
базу данных Notes (Database Link);
OUTLINE_CLASS_DOCUMENT/OutlineEntr>'.OUTLINE_CL,ASS_DOCUMENT - ссылка
на документ в базе данных Notes (Document Link);
OUTlJNE_CLASS_VIEW/OutlineEntry.OUTLINE_CLASS_VIEW - ссылка на вид в базе
данных Notes;
OUTLINE CLASS FOLDER/OutlineEntry.OUTLlNE CLASS_FOLDER - ссылка на папку
в базе данных Notes;
OUTLI>JE_CLASS_FORM/OutlineEntry.OUTLINE_CLASS_FORM - ссылка на форму в
базе данных Notes;
OUTLlNE_CLASS_PAGE/OutlineEntry.OUTLINE_CLASS__PAGE - ссылка на страницу в
базе данных Notes (Database Link);
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
490
•
OUTLINE_CLASS_FRAMESET/OutlineEntry.OUTLINE_CLASS_FRAMESET - ссылка на
набор фреймов в базе данных Notes;
®
OUTLINE_CLASS_NAVIGATOR/OutlineEntry.OUTLINE_CLASS_NAVIGATOR - ссылка
на навигатор в базе данных Notes;
*
OUTLlNE_CLASS_UNKNOWN/OutlineEntry.OUTLINE_CLASS_UNK"NO\VN
класс.
- другой
© Свойство IsInThisDb - «ссылается ли на ресурс в данной базе»
LotusScript:
flag- notesOutlineEntry.IslnThisDb
Java:
boolean flag = OutlmeEntry.islnthisDbQ
Возвращается true, если элемент схемы «ссылается» на какой-то ресурс из данной базы
(из которой был получен объект [NotesjOutline, «содержащий» объект [NotesjOutlineEntry),
или false, если нет.
© Свойство Database - «база, на которую ссылается элемент схемы»
LotusScript:
Set notesDatabase ~ notesOutlmeEntry.Database
Java:
Database db = OutlineEntry.getDatsibaseQ
Если элемент схемы имеет run OUTL1NE_TYPE_NOTELINK или
OUTL1NE_TYPE NAMEDELEMENT
и
класс
OUTLINE CLASS_DATABASE,
OUTLINE_CLASS_DOCUMENT или OUTLINE_CLASS_VIEW, то "возвращается объект
класса [Notes]Database, представляющий базу, на которую «ссылается» элемент схемы. В
противном случае возвращается Nothing/null.
© Свойство View - «вид, на который ссылается элемент схемы» •-.'••.•• •
LotusScript:
Java:
• ...
Set notesView = notesOutlineEntry.View
View view = OutlineEntry.get\iewQ
Если элемент схемы имеет тип OUTLfNE_TYPE_NOTELINK и класс
OUTLJNE_CLASS_DOCUMENT или OUTLINE CLASS VIEW, то возвращается объект
класса [Notes]View, представляющий вид, на который «ссылается» элемент схемы. В
противном случае возвращается Nothing/null.
© Свойство Document - «документ, на который ссылается элемент схемы»
LotusScript:
Java:
Set notesDocument — notesOutlineEntryJDocument
Document doc — OutlineEntry.geiDocumentQ
Если элемент схемы имеет тип OUTLINE_ TYPE_NOTELINK и класс
OUTLTNE_CLASS_ DOCUMENT, то возвращается объект класса [NotesJDocument,
представляющий документ, на который «ссылается» элемент схемы. В противном случае
возвращается Nothing/null.
© Свойство NamedElement-«название элемента дизайна, на который
ссылается элемент схемы»
:.
.. •" . . ' ; . : .
LotusScript:
name$ = notesOutlineEntry.NaLmedElement
Java:
Siring пате ~ Oz///weЈ'7?/ry.getNamedEIement()
© InterTrust Co. Тел, (095) 9567928
:
Lotus Domino R. 5: @-фармулы, LotusScript, встроенные классы LotusScript и Java
491
Если элемент схемы имеет тип OUTLINE TYPE_NAMEDELEMENT, то возвращается
название или алиас элемента дизайна, на который «ссылается» элемент схемы. В противном
случае возвращается «пустая» строка.
© Свойство URL - «URL ресурса, на который ссылается элемент схемы»
LotusScript:
url$ - notesOittIineEntry.lJRL
Java:
String url - OutlineEntry.getURLQ
Если элемент схемы имеет тип OUTLINE_TYPE_URL, то возвращается URL ресурса в
Internet, на который «ссылается» элемент схемы. В противном случае возвращается «пустая»
строка.
® Свойство Formula - «@-формула, выполняемая при выборе элемента схемы»
' . • .- : .'.•• ••" ••."••> ;•'-"..'-: . ;• • •-: ;•;•;-.-": у V. ': •• • : ' •' ' ;. ••-' •- ; '':\УLotusScript:
formulaS = notesOullineEntry.Formula
Java:
String formula = OutlineEntry.geiFormu\»()
Если элемент схемы имеет тип OUTLINE TYPE ACTION, то возвращается строка,
содержащая текст @-формулы, которая выполняется при выборе пользователем элемента
схемы. В противном случае возвращается «пустая» строка.
© Свойство FrameText - «имя фрейма-мишени»
LotusScript:
frame$ ~ notesOutlineEntry.FramsText
notesOtitlineEntry.'FrumeText ~frame$
Java:
String frame = OutlineEntry.getFrameTextQ
void OutlineEnlry.seiFrameText(_Stri'ng frame)
Строка с именем фрейма (из текущего набора фреймов), в который должен помещаться
ресурс (страница, документ, вид...), на который «ссылается» элемент схемы.
Пример. Java-агент формирует отчет о свойствах всех элементов схемы с именем Outline2. Если
эта схема была сформирована агентом .lava-Outline/ЕхЗ (см. пример в конце подраздела 3.10.2), то этот
отчет будет выглядеть следующим образом,
*** Outline2 ***Alias: ExSComment: Примеры создания элементов cxeMbiNoteLink to Database
Type: Note link Entry class: Database
Level: 0 Does not refer to an element in this db
Entry is publicNarnedElement of VIEW class
Type: Named element
Entry class: View
Level: ! Does not refer to an element in this db
Entry is publicURL www.inttrust.ruType: URL
Entry class: Unknown
Level: 1 Does not refer to an element in this db
Entry
is
publicACTION ToolsRunMacro Type: Action
Entry class: Unknown
Level: 1 Does not refer to an
element in this db Entry is public
// Java-Outline/Ex2
Database db = agentCoritext. getCurrentDatabase ();
Outline о = db.getOutline("Outline2");
System, out .println ("*** " + o.get.Name() + " ***"),System, out. printlri ( "Alias : " + o. get.Alias () ) ;
System.out.println("Comment: " + о.getComment()};
OutlineEntry e = о.getFirst();
while (e != null.)
•
{
•
System.out.println(e.getLabel());
.
© InterTrust Co. Тел. (095) 9567928
492
Встроенные классы LotusScript u Java
if (e.getAlias ().length () > 0)
System, out.. println ( "\tAlias : " + e.getAlias());
String type = null; switch (e.getType())
\
cas e Out l i neE nt ry .OU TLI NE OT HE R F OL DE RS TYP E:
typ e = " Ot her f ol der s"; b rea k; case
OutlineEntry.OUTLINE OTHER_VIEWS TYPE:
type — "Other views"; break; case
OutlineEntry.OUTLINE_OTHER UNKNOWN TYPE:
type = "Other unknown"; break/ case
OutlineEntry.OUTLINE_TYPE_ACTION:
type = "Action"; break; case
OutlineEntry .OUTLINE_TYPE NAMEDELEMENT :
typ e = " Na med e le men t"; b rea k; case
Out].ineEntry.OUTLINE_TYPE_NOTELINK:
type -•• "Note link"; break; case
OutlineEntry.OUTLINE TYPEJJRL:
type = "URL"; break; }
System, out . print In ( "\tType : " + type); String
entryClass = null; switch
(e.getEntryClass ()) {
case OutlineEntry. OUTLINE__CLASS DATABASE:
ent ry Cla ss = "D at aba se" ; bre ak ; case
OutlineEntry.OUTLINE CLASS_DOCUMENT:
ent ry Cla ss - "D oc ume nt" ; bre ak ; case
OutlineEntry.OUTLINE_CLAS S_FORM:
ent ry Cla ss = "F or m"; br ea k; case
OutlineEntry.OUTLINE_CLASS FOLDER:
ent ry Cla ss = "F ol der "; br eak ; case
OutlineEntry.OUTLINE_CLASS FRAMESET:
ent ry Cla ss - "F ra me set "; br ea k; case
OutlineEntry.OUTLINE CLASSENAVIGATOR :
ent ry Cla ss = " Na vi ga tor "; b rea k; case
OutlineEntry.OUTLINE CLASS_PAGE:
entryClass = "Page"; break; case
OutlineEntry, OUTLINE_CLASS__UNKNOWN:
ent ry Cla ss = "U nk now n"; b rea k; case
OutlineEntry.OUTLINE_CLASS_VIEW:
entryClass -= "View"; break; }
System.out.println ("\tEntry class: " + entryCl ass};
Sys te m .o ut .pr in tl n (" \tL ev el : " + e. ge tLe vel () ); if
(e.isInThisDB())
Sys te m.o ut .pr in tl n (" \tR ef ers to an el em e nt i n t h i s d b " ) ; e 1
se
System.out .println (" \tDoes not refer to a n element in this db" ); if
(e.isPrivate<))
System.out .println (" \tEntry is pr ivat e " ) ; e 1
se
System.out.print In("\tEntry is public") ; if
fe.getFrameText() .length() > 0)
System.out.println {"VtFrame text: " 4 e, g etFrameText ()); if
(e.getlnagesText ().length () > 0)
System, out: . print In ( "\tlmages text: " + e . get ImagesText () ) ; e = о.getNext
(e) ; }
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
493
3.10.2. Методы
@ Метод setNoteLink - «определить ссылку на базу, вид или документ»
LotusScript:
flag = notesOullineEntry.seiNoteLink( notesDatabase, nolesView,
notes Document)
Java:
boolean /Jag = OutlineEntry.set'NotelAnk(Database db)
boolean flag = Ot(tlineEntn\setNote'Lmk(Fiew view) boolean
flag - OutlineEntry.seiNoteLink(Document doc)
Устанавливает для элемента схемы в качестве ссылки на ресурс ссылку на базу Notes, вид
или документ в базе, заданный в качестве параметра метода. В LotusScript методу должен
передаваться только один параметр соответствующего класса. Одновременно устанавливает
для элемента тип OUTLINE TYPE_NOTELINK и класс OUTLINE_CLASS DATABASE,
OUTLINE_CLASS_DOCUMENT или" OUTLINE_CLASS_VIEW в зависимости от класса
переданного параметра. Возвращает true, если операция завершилась успешно.
0 Метод setNamedEIement - «определить ссылку на элемент дизайна»
LotusScript:
flag - notesOutlineEntry.seiNamed'Element( notesDatabase,
elernentNameS, entryClass% )
Java:
boolean flag -= OutlineEntry.seiNamedElemeni(Database db,
Siring elementName, int entry-Class)
Устанавливает для элемента схемы в качестве ссылки на .ресурс ссылку на элемент
дизайна из базы Notes (форму, страницу, набор фреймов, вид, папку, навигатор), имя
которого заданно параметром elementName, а класс - параметром entryClass (константа типа
Long/int, определения констант приведены в описании свойства EntryClass). Одновременно
устанавливает для элемента тип OUTL1NE_TYPE NAMEDELEMENT и класс, заданный
параметром entryClass. Возвращает true, если операция завершилась успешно.
0 Метод setURL - «определить ссылку на ресурс в Internet»- . . . : • . : :., •.- ... ,..
LotusScript:
flag = notesOutlineEritry.setURL( urlS )
Java:
boolean flag - OutlmeEr(try.setURL(Slring url)
Устанавливает для элемента схемы в качестве ссылки ссылку на ресурс в Internet с
заданным URL (тип String). Одновременно устанавливает для элемента тип
OUTLINE_TYPE URL. Возвращает true, если операция завершилась успешно.
© Метод setAction - «определить формулу действия»
LotusScript:
flag = notesOutlineEntry.setA.ction( formufaS)
Java:
boolean flag - OittlineEntry.setAction(String formula)
Устанавливает для элемента схемы формулу действия, заданную в строке formula.
Одновременно устанавливает для элемента тип OUTLINE TYPE_ACTION. Возвращает true,
если операция завершилась успешно.
Пример. Java-агент создает новую или добавляет в существующую схему с именем Outline2 четыре
элемента разных типов. Созданная схема в Domino Designer выглядит следующим образом.
© InterTrust Co. Тел. (095) 9567928
494
Встроенные классы LotusScript и Java
// Java-Outline/Ex3
Datcibase db - agentContext. getCurrentDatabase () ;
Outline о = db.createOutline("Outline2") ;
o.setAlias("Ex3") ;
о.setCominent("Примеры создания элементов схемы");
System.out.print In("Creating entry TYPE_NOTELINK. . .") ;
OutlineEntry e = о.createEntry("NoteLink to Database"!;
e.setHidden(false);
e.setlmagesText("abook.gif");
e.setNoteLink(db);
о.addEntry(e, null, true); System.out.println{"Creating
entry TYPE_NAMEDELEMENT...");
e - o. createEntry("MamedElement of VIEW class");
e.setHidden(false);
e . setlmagesText("vwtrash.gif");
e.setNamedElement(cib, "($A11)",OutlineEntry.OUTLINE_CLASS_VIEW)
о.addEntry(e, о.getLast() , true) ;
System.out.println("Creating entry TYPE _URL. . . ") ;
e = о.createEntry("URL www.inttrust.ru");
e.setHidden(false);
e.setlmagesText{"graphic. gif") ;
e.setURL("http://www.inttrust.ru");
о.addEntry(e, o.getLast(), true, false);
System.out.println("Creating entry TYPE ACTION...");
e = o. createEntry ( "ACTION ToolsRunMac.ro");
e.setHidden(false);
e.setlmagesText("vwinbox.gif");
e.setAction("@Coiomand([ToolsRunMacro];\"Java-Outline\\\\Ex3\")"
о.addEntry(e, о.getLast (), true, false);
) InterTrust Co, Тел. (095) 9567928
Lotus Domino R. 5: ((^формулы, LotusScript, встроенные классы LotusScript и Java
495
3.11. «Агент» - класс [NotesJAgent
Объект этого класса представляет агента. Свойства класса [NotesjAgent позволяют
«узнать» название агента, комментарии к нему и имя его владельца (лицо,
модифицировавшее агента последним), определить, общий это агент или личный,
выполняется он в среде Notes или предназначен для запуска из Web-броузера, разрешено или
запрещено его выполнение, на каком сервере он должен выполняться, каков способ его
запуска, какое множество документов им обрабатывается, какой «поисковый» запрос
использует для отбора коллекции обрабатываемых документов, выполнялся ли агент хотя бы
раз и когда он в последний раз выполнялся. Методы класса [Notes]Agent позволяют
сохранить агента в базе (после изменения имени сервера, на котором должен выполняться
агент, или «разрешения на выполнение»), инициировать запуск агента, а также удалить
агента из базы.
«Контейнерная иерархия»
LotusScript
Java
NotesSession _>
NotesDatabase
AgentContext
Database
NotesAgent
-»
Agent
—>
_>
NotesDatabase
Database
DateTime
Получить объект класса [NotesjAgent можно двумя способами. Если необходим объект,
представляющий агента, который выполняется в настоящее время, используют свойство
CurrentAgent класса NotesSession/AgentContext. Если необходим доступ ко всем агентам
базы, используют свойство Agents класса [Notes]Database.
3.11.1. Свойства
Свойство Parent - «родитель»
LotusScript:
Set notesDatabase = notesAgent.Varent
Java:
Database db = Agent.geiParentO
Возвращает объект класса [NotesJDatabase, представляющий базу, в которой определен
агент.
Пример. Скрипт агента получает доступ к базе, в которой он выполняется.
•
Dim session As New NotesSession
Dim db As NotesDatabase
Dim agent As NotesAgent
Set agent = session.CurrentAgent
Set d b = age nt. Pa re n t
Свойство Name - «название агента»
LotusScript:
agentName$ ~ notcsAgent.Name
Java:
String agentName - Agent.getNameQ
Название агента (тип String). Учтите, что в одной базе может существовать несколько
агентов с одинаковым названием.
Пример. Java-агент выводит имена всех агентов, имеющихся в текущей базе.
import j ava.util.Vector;
// Agent/Name
Database db — agentContext.getCurrentDatabase() ;
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
496
Vector agents = db.getAgents();
System.out.println("Agents in database:");
for (int. i=0; i < agents. size (); i + +)
{
Agent agent = (Agent)agents.elementAt(i);
System.out.println(" " + agent.getName()); )
Свойство Comment - «комментарий»
LotusScript:
comments = notesAgent.CQmment
Java:
String comment = Agent.getCommentQ
Возвращает комментарии (тип String), «записанные» по поводу агента его разработчиком.
Пример. Скрипт по текущей базе формирует отчет обо всех общих агентах, выполнение которых
разрешено. Для каждого такого агента дается его название и комментарии. Отчет помещается в поле
Body нового документа, который затем отсылается всем менеджерам текущей базы,
Dim session As New NotesSession
Dim db As NctesDatabase
Dim doc As NotesDocument
,<
Dim rtitem As NotesRichTextltem
Set db = session.CurrentDatabase
Set. doc = New NotesDocument ( db )
Set rtitem = New NotesRichTextltem( doc, "Body" )
Forall a Tn db.Agents
If ( a.IsPublic And a.IsEnabled ) Then
Call rtitem.AppendText( a.Name.)
Call rtitem.AddTab( 2 )
Call rtitem.AppendText( a.Comment )
Call rtitem.AddNewLine( 1 ) End
If End Forall
doc.Subject = "Сводка по общим агентам в базе " & db.Title
Call doc.Send( False, db.Managers )
Свойство Owner - «полное имя владельца агента»
LotusScript:
ownerNameS ~ notesAgent.Owner
Java:
Siring ownerName ~ Agent.getO~wner()
Л
Полное имя владельца агента (тип String).
Владельцем агента считается тот, кто последним модифицировал данного агента. Это
справедливо, ибо если пользователь запустил агента, ожидая при этом, что агент должен
переносить документы с пометкой «Для служебного пользования» в другую базу с
ограниченным доступом, а агент вместо этого переслал документы по адресу в
фирме-конкуренте и удалил их в текущей базе, то ответственность за произошедшее несет
разработчик, модифицировавший агента последним.
Пример. Предположим, что агента создал Yukiko Kitarmura/Tokyo/Production, а последним
модифицировал Mariko Ikebuchi/Tokyo/Production. Строка owner будет содержать "Mariko
Ikebuchi/Tokyo/Production".
' created by Yukiko Kitamura 11/28/98 '
modified by Mariko Ikebuchi 12/17/98 Dim
session As New NotesSession Dim agent As
NotesAgent Dim owner As String
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: @-формулы, LotusScript, встроенные классы LotusScript и Java
497
Set agent = session.CurrentAgent
owner -- agent. Owner
Свойство CommonOwner - «общее имя владельца агента»
LotusScript:
commonOwner$ — notes Agent.CommonQytner
Java:
String commonOwner — Agent.getCommonQwnerQ
Общее имя (составляющая CN= из полного имени) владельца агента (тип String).
Пример. Предположим, что Java-агента создал Yukiko Kitarmura/Tokyo/Production, а последним
модифицировал Mariko Ikebuchi/Tokyo/Production. Последняя строка будет содержать "Common owner:
Mariko Ikebuchi".
// Agent/CommonOwner
// created by Yukiko Kitamura 11/28/98
// modified by Mariko Ikebuchi 12/17/98
Agent agent = agentContext.getCurrentAgent();
System, out. println ( "Current agent is \"" -i agent. getName () + "\"");
System, out .println ( "Common owner: " 4- agent. getCommonOwner ());
Свойство IsPublic - «общий ли агент» -. '."•'•- ' :••. ..,: ..."••. ...-••••••• ... •
LotusScript:
flag = notesAgent.isPublic
Java:
boolean flag-• AgentAsVublic()
Возвращает true, если агент общий (public), или false, если он «личный» (person). Общий
агент доступен всем пользователям базы и физически хранится в базе. Личный агент обычно
доступен только его владельцу, а физически может хранится как в базе, так и в файле
DESKTOP.DSK на станции владельца.
Свойство IsEnabled - «разрешено ли выполнение агента»
LotusScript:
flag = notesAgent.isEnabled
notesAgent.hEnabled -flag
Java:
boolean flag = AgentAsEnabledQ
void Agent.seiE n a bled (boolean flag)
•
Возвращает true, если выполнение агента разрешено, или false, если запрещено. Свойство
имеет смысл только для агентов, выполняемых по расписанию или событию
создания/модификации документа или получения почты (после получения). Для агентов
других типов свойство всегда возвращает true. После изменения значения свойства
необходимо «применить к агенту» метод save.
«Признаком» агентов, выполняемых по расписанию или событию создания/модификации
документа или получения почты (после получения), является наличие «прямоугольника» —*
или ^ в первом столбце списка агентов в Domino Designer (Ошибка! Источник ссылки не
найден.). Если «в прямоугольнике имеется галочка», выполнение такого агента разрешено,
иначе запрещено. Кроме того, для агентов, выполняемых по расписанию или событию
создания/модификации документа, в окне Построителя агентов имеется кнопка Schedule.
Нажатие этой кнопки влечет появление окна Schedule, в котором можно выбрать компьютер
для выполнения такого агента и разрешить или запретить его выполнение. Однако для
агентов, выполняемых по событию получения почты (после получения), компьютером для
выполнения всегда является почтовый сервер владельца агента. Можно только разрешить
или запретить выполнение такого агента, например, «щелчком мыши по соответствующему
прямоугольнику» в списке агентов.
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
498
Рис. 3.24 Список агентов в Domino Designer
.
Пример. Java-агент разрешает выполнение агента с именем Agent To Enable в текущей базе.
import ] ava.util.Vector;
// Agent/Enabled
Database db = agentContext.getCurrentDatabase() ;
Vector agents = db.getAgents();
int count - agents.size();
int i;
for (i = 0; i < count; i++)
.
.
. .
Agent agent — (Agent)agents.elementAt(i};
String name = agent.getName();
if (name == null) name = "No name";
if (name . compareTo ( "Agent To Enable") r== 0)
{
if ( agent. isEnabled{) == false ) {
agent.setEnabled(true);
agent.save(); }
System.out.println("agent found and enabled"}; break; } }
if (i == count) System.out.println("agent not found");
© Свойство IsNotesAgent - «может ли быть выполнен в среде Notes».. - ; .-.-•.- .
LotusScript:
flag - notesAgent.isNoteskgent
Java:
boolean flag = Agent.isNotesAgentQ
Возвращает true, если данный агент может быть выполнен в среде Notes, т.е. в окне
свойств агента на закладке Disign не выбрана опция Hide design element from: Notes 4.6 or
later clients, или false, если эта опция выбрана.
© Свойство IsWebAgent - «может ли быть выполнен в среде Web»
LotusScript:
flag = notesAgent.isWeb&gcnt
© InterTrust Co. Тел. (095) 9567928
Lotus Domino R. 5: (а)-формулы, LotusScript, встроенные классы LotusScript и Java
Java:
499
boolean flag = ,4g<?«/.isWebAgent()
Возвращает true, если запуск данного агента на сервере Domino может быть инициирован
из броузера, т.е. в окне свойств агента на закладке Design не выбрана опция Hide design
element from: Web Browser, или false, если эта опция выбрана.
Пример. Java-агент для каждого агента текущей базы выводит значения свойств isNotesAgent и
isWebAgent.
import java.uti1.Vector;
// Agent/isNotesWebAgent
Database db = agentContext.getCurrentDatabase();
Vector agents =;; db.getAgents();
for (int i = 0; i < agents.size(); i + +)
{
Agent agent. - (Agent) agents . elementAt (i) ;
System.out.print In(agent.getName() );
if (agent.isNotesAgent()} System.out.println(" is a Notes agent");
else
System.out.println(" is not a Notes agent");
if (agent.isWebAgent())
System.out.print In(" is a Web agent");
else
System.out.println(" is not a Web agent");
}
Свойство ServerName - «компьютер, на котором долясен выполняться агент»
LotusScript:
serverS = notesAgent,ServerName
notesAgent.ServerName - serverS
Java:
String server — j4gen/.getServerName()
void Agent.setServerName(String server)
Значение свойства (тип String) определяет компьютер, на котором должен выполняться
агент. Возможны следующие случаи. *
*
*
Если агент выполняется по расписанию или событию создания/модификации документа
в базе на сервере, свойство возвращает имя сервера, на котором должен запускаться
агент. Поскольку обычно такой агент обычно должен работать только в одной реплике
базы, должно быть выбрано имя сервера для выполнения агента (см. окно «кнопки»
Schedule). Поэтому свойство может вернуть как имя сервера, на котором находится ваша
база, так и имя сервера, с которым ваша база реплицируется - в зависимости от того, в
какой из реплик действительно должен работать агент. Однако допустимы и агенты,
которые должны выполняться в каждой реплике базы. Для таких агентов свойство
возвращает строку "*". Соответственно для изменения значения свойства необходимо
задать полное имя сервера или строку "*", а после изменения значения свойства
«применить к агенту» метод save.
Если агент выполняется по событию получения почты (после получения) в базе на
сервере, свойство обычно возвращает имя сервера, являющегося почтовым сервером
владельца агента. Для изменения значения свойства необходимо задать полное имя
нового сервера, а после изменения значения свойства «применить к агенту» метод save.
Однако, если в файле NOTES.INI нового сервера отсутствует переменная
AMgr DisableMailLookup = 1, то сервер не станет выполнять этого агента, когда имя
сервера для выполнения агента не совпадает с именем почтового сервера владельца этого
агента.
Если агент выполняется по расписанию в базе на станции пользователя, свойство
возвращает полное имя пользователя. Для изменения значения свойства необходимо
задать полное имя пользователя, а после изменения значения свойства «применить к
агенту» метод save.
© InterTrust Co. Тел. (095) 9567928
Встроенные классы LotusScript и Java
500
•
Для агентов других типов свойство как в LotusScript, так и в Java, возвращает «пустую
строку» (""). Изменение значения свойства в этом случае не имеет смысла.
© Свойство Trigger - «способ запуска агента»
LotusScript:
trigger% - notesAgent.Trigger
Java:
int trigger = Agent.getTriggerQ
Возвращает целое число, позволяющее определить способ запуска («триггер») агента:
•
•
TRIGGER_MANUAL7Agent.TRIGGERJMANUAL - «вручную» из
пользователя,
TRIGGER_SCHEDULED/Agent.TRIGGER_ SCHEDULED - по расписанию,
интерфейса.
•
TRIGGER_DOC_PASTED/Agent.TRIGGER_DOC_PASTED - по событию копирования
документа в базу из буфера обмена,
• TRIGGER_DOC_UPDATE/Agent.TRlGGER DOC UPDATE - по событию создания или
модификации документа в базе,
• TRlGGER_BEFORE_MAIL_DELIVERY/Agent.TRlGGER_BEFORE_MAIL_DELIVERY- по событию получения почты (перед получением),
® TRIGGER_AFTER_MAIL_DELIVERY/Agent.TRlGGER_AFTER_MAlL_DELlVERY - по
событию получения почты (после получения)
• TRIGGER_NONE/Agent.TRlGGER_NONE - агент не выполняется.
© Свойство Target - «множество документов, обрабатываемых агентом»
LotusScript:
target% - nolesAgenl.Target
Java:
int target = Agent.getTurgetQ
Возвращает целое число, позволяющее определить множество документов,
обрабатываемых агентом (выбирается разработчиком в поле Which document(s) should it act
on? окна Построителя агентов):
»
TARGET__ALL_DOCS/Agent.TARGET_ALL_DOCS - все документы в базе (All documents
in database),
в TARGET_NEW_OR_MODIFIED_DOCS/Agent.TARGET_NEW_OR_MODIFIED_DOCS новые или модифицированные документы (All new or modified documents since last run),
• TARGET UNREAD _DOCSJN_VlEW/Agent.TARGET_UNREAD _DOCS _IN_VIEW
«непрочитанные» пользователем документы из вида (All unread documents in view),
• TARGET^ ALL DOCS IN VIEW/Agent.TARGET ALL DOCS__JN_VIEW - все документы
из вида (All documents in view),
• TARGET SELECTED DOCS/Agent.TARGET SELECTED DOCS
выбранные
пользователем документы (Selected documents),
• TARGET_NEW_DOCS/Agent.TARGET_NEW_DOCS - новые документы,
• TARGET NONE/Agent.TARGET_NO:NE - отсутствует.
Пример. Java-агент для каждого агента из текущей базы выводит значения свойств Target и Trigger.
Заметим, что в Domino версии 5.0а для агентов Run once свойство Target возвращает значение 8, что не
соответствует определению константы Agent.TARGETJNONE = 0.
import Java.util.*;
// Agent/TargetTrigger
Database db = agentContext.getCurrentDatabase(};
Enumeration agents = db.getAgents(),elements(};
© InterTrust Co. Тел. (095) 9567928
Download