Работа системы Greenstone

Эта глава описывает работу системы Greenstone, чтобы вы могли понять, увеличить и расширить ее возможности. Программное обеспечение написано на С ++ и предоставляет большие возможности использования виртуального наследия. Если вы незнакомы с этим языком, вы должны изучить его перед тем, как приступить к работе. Дейтель и Дейтель (1994) предоставили всестороннюю обучающую программу, а Страуструп (1997) - лаконичный справочник.

Мы начинаем рассказ о философии дизайна после описания работы системы, так как он будет напрямую зависеть от этого описания. Теперь приступим к деталям, из которых состоит основная часть главы. Версия Greenstone, описанная здесь - это CGI-версия (Web Library if for Windows users/Web -библиотека для пользователей Windows). Windows Local Library использует ту же самую исходную программу, но имеет встроенный web-сервер. Плюс ко всему, Local Library - постоянно продолжающийся процесс.

Структура процесса

На рисунке ## показано, как несколько пользователей (они представлены в виде компьютерных терминалов наверху диаграммы) обращаяются к трем коллекциям Greenstone. Перед тем, как предстать в режиме on-line, эти коллекции проходят процессы импорта и формирования, которые были описаны в предыдущих главах. Сначала документы, показанные внизу рисунка, импортированы в XML-совместимый Формат Архива Greenstone. Теперь для файлов созданы различные доступные для поиска индексы и информационная база данных коллекции, которая включает иерархические структуры поддержки просмотра. Конечная коллекция готова к работе в режиме on-line и способна предоставлять информацию по запросам.

Два центральных компонента обеспечивают работу системы: "receptionists" (регистраторы) и "collection servers" (серверы коллекции). С точки зрения пользователя, регистраторы - точка контакта с цифровой библиотекой. Они принимают запрос пользователя в форме клавиатурного ввода и щелчков мыши, анализируют их, а затем посылают запрос соответствующему серверу (или серверам) коллекции. Здесь определяется местонахождение требуемой части информации и возвращается регистратору для предоставления пользователю. Серверы коллекции действуют как абстрактный механизм, который обрабатывает содержание коллекции, в то время как регистраторы ответственны за интерфейс пользователя.

Array

Как показано на рисунке ## , регистраторы связываются с серверами коллекции, используя определенный протокол. Выполнение этого протокола зависит от конфигурации компьютера, на котором работает система цифровых библиотек. Наиболее простой и подходящий выбор - это один регистратор и один сервер коллекции, которые оба установлены на одном компьютере. Вы получаете именно такую модификацию, когда устанавливаете систему Greenstone с параметрами по умолчанию. В этом случае оба процесса объединены в один запускаемый файл (называемый library), и следовательно, использование протокола сводится к созданияю функциональных запросов. Мы называем это null protocol (нулевым протоколом). Он формирует основу для стандарта out-of-the-box (из блока) цифровой системы библиотек Greenstone. Ее упрощенная конфигурация представлена на рисунке ## с регистратором, протоколом и сервером совокупности, связанными вместе в один объект программы библиотеки. Цель этой главы состоит в том, чтобы объяснить вам, как все это работает.

Обычно "сервер" - постоянный процесс: единожды запущенный, работает постоянно, отвечая на любые входящие запросы. Несмотря на название, сервер коллекции в конфигурации нулевого протокола не является сервером в привычном смысле слова. Фактически, каждый раз, когда вызывают любую web-страницу Greenstone, запускается программа library (CGI механизмом), которая отвечает на запрос и затем выгружается. Это мы называем "сервером", потому что дополнительно он также предназначен для работы с более общей конфигурацией (см. рисунок ## ).

Удивительно, но цикл запуска, обработки и выхода работает не так медленно, как можно было ожидать. Однако, это абсолютно неэффективно. Существует механизм Fast-CGI (www.fastcgi.com), который обеспечивает средний уровень. Используя его, программа library может остаться в памяти в конце первого выполнения и накапливать последующие наборы параметров CGI, таким образом избегая повторных инициализаций и достигая почти такого же уровня работы, как сервер. Fast-CGI в Greenstone используется как опция, допуская повторную компиляцию исходного текста с соответствующими библиотеками.

Как альтернатива нулевому протоколу, протокол Greenstone был также создан с использованием известной схемы CORBA (Slama et al, 1999). Он использует объединенную объектно-ориентированную парадигму, чтобы разрешить различным процессам, выполняющимся на различных компьютерных платформах и созданных нп различных языках программирования, обращаться к одному и тому же набору распределенных объектов в Internet (или любой другой сети). Тогда сценарии, подобно изображенному на рисунке ## , могут быть полностью осуществлены со всеми регистраторами и серверами коллекции, работающими на различных компьютерах.

Array

Это позволяет устанавливать для работы с теми же самыми цифровыми библиотечными коллекциями намного более сложные интерфейсы. В качестве примера рассмотрим один рисунок (см. рисунок ## ), который показывает графический интерфейс запроса, основанный на диаграммах Венна, позволяющий пользователям непосредственно управлять Булевыми запросами. Написанный на Java, интерфейс запускается локально на собственном компьютере пользователя. Используя CORBA, он обращается к отдаленному серверу коллекции Greenstone, написанному на C++.

Распределенный протокол все еще совершенствуется и готовится для использования, так что в этом руководстве мы более не станем его обсуждать (для получения дополнительной информации см. Bainbridge et al., 2001).

Концептуальная структура

Рисунок ## показывает страницу "about this collection" (о коллекции) специфической коллекции Greenstone (коллекция Проекта Gutenberg). Смотрите URL наверху. Страница сгенерирована в результате выполнения CGI-программы library, которая, как говорилось выше,является выполняемой программой, включающей и регистратор и сервер коллекции, связанный в соответствии с нулевым протоколом. Аргументы library - c=gberg, a=p, и p=about. Они могут интерпретироваться следующим образом:

Для коллекции Проект Gutenberg (c=gberg) действие генерирует страницу (а=р), сгенрированная страница названа "about" (p=about).

Array

Рисунок ## иллюстрирует основные части работы системы Greenstone. Наверху регистратор сначала инициализирует свои компоненты, затем анализирует CGI-аргументы, чтобы решить, какое действие запустить. При запуске действия (которое включает в дальнейшем обработку CGI аргументов), программное обеспечение использует протокол, чтобы обратиться к содержанию коллекции. Ответ используется для генерации web-страницы с помощью компонента формата и макроязыка.

Макроязык, который мы виделив Разделе controlling_the_greenstone_user_interface, используется, чтобы обеспечить цифровую библиотечную систему Greenstone лаконичным стилем и создавать интерфейсы на различных языках. Взаимодействие с библиотекой генерирует скелет web-страниц; макрос в GSDLHOME/macros наращивает на этот скелет плоть.

Объект Macro Language (макроязык) на рисунке ## ответственен за чтение файлов и сохранение результата анализа этих файлов в памяти. Любое действие может использовать этот объект, чтобы развернуть макрокоманду. Оно может даже создать новые макросы и отменить существующие, добавляя динамическое распределение в использовании макросов.

Внешний вид страницы "about this collection" (рисунок ## ) известен до момента запуска и закодирован в макрофайле about.dm. Заголовки, нижние колонтитулы и фоновая заливка даже не упомянуты, потому что они расположены в пакете макрокоманды Global. Однако, определенный "about" текст (текст для страницы "О коллекции") для специфической коллекции не известен заранее, он хранится в информационной базе данных коллекции в течение процесса формирования. Эта информация вызывается использованием протокола и хранится как _collectionextra_ в пакете макрокоманды Global. Обратите внимание на то, что имя макроса - по существу имя, используемое для описания этой информации в файле конфигурации коллекции, описанном в Разделе configuration_file. Чтобы сгенерировать содержание страницы, была расширена макрокоманда _content_ в пакете about (рисунок ## ) . Она в свою очередь запускает _textabout _, который непосредственно обращается к _collectionextra _, только что динамически помещенной туда.

Следующий важный компонент - объект Format. Операторы задания формата в файле конфигурации коллекции затрагивают представление специфических частей информации, как описано в Разделе formatting_greenstone_output. Они обработаны объектом Format (см. рисунок ## ). Основная задача этого объекта состоит в том, чтобы анализировать и оценивать инструкции типа строк формата (рисунок ## ). Как стало ясно из Раздела formatting_greenstone_output, они могут включать ссылки на метаданные в квадратных скобках (например, [Title]), которые должены быть найдены сервером коллекции. Взаимодействие происходит между объектом Format и объектом Macro Language, потому что операторы задания формата могут включать макросы, которые в качестве расширения включают метаданные, которые в качестве расширения включают макросы и так далее.

Внизу рисунка ## , сервер коллекции также проходит процесс инициализации, устанавливая объекты Filter и Source, чтобы ответить на входящие запросы протокола, и объект Search, чтобы облегчить выполнение задачи. В конечном счете они обращаются к индексам и информационной базе данных коллекции, которые сформировались в процессе формирования коллекции.

Игнорируя пустые строки, регистратор содержит 15 000 строк программы. Сервер коллекции содержит только 5 000 строк (75 % которого занимают файлы заголовка). Сервер коллекции более компактен, потому что релевантный поиск проходит через две предоткомпиляционные программы. Для поиска используется полнотекстовая поисковая система MG, а для поддержки информационной базы даннх коллекции используется СУБД GDBM.

Для обеспечения расширяемости и гибкости Greenstone широко использует порядок следования в пределах Action, Filter, Source и Search. Для простой цифровой библиотеки, специализированной на текстовой коллекции, это означает, что вы должны узнать немного больше, чтобы программировать систему. Однако, это также означает, что MG и GDBM могут быть легко заменены, если возникнет потребность. Кроме того, программная архитектура достаточно богата, чтобы поддержать полные возможности мультимедиа, типа управления интерфейсом через устройство речевого ввода или передачи запросов в виде графическх изображений.

Совместимость концептуальной структуры

Разделы collection_server и receptionist объясняют взаимодействие сервера коллекции и регистратора более подробно, останавливаясь на каждом модуле рисунка ## и описывая, как это работает. Полезно сначала разобраться на примере пользователя, взаимодействующего с Greenstone, и описывать то, что происходит. Предполагается, что к настоящему моменту все объекты правильно инициализированы. Инициализация - запутанная процедура, к которой мы вернемся в Разделе initialisation.

Поиск

Array

6: Поиск по запросу Darcy в коллекции Gutenberg

Когда пользователь вводит запрос, нажимая кнопку Begin search на странице поиска, запускается новое действие Greenstone, которое заканчиваясь, генерирует новую HTML-страницу, используя макроязык. На рисунке ## показан результат поиска в коллекции Project Gutenberg для поискового выражения Darcy. В пределах первоначальной HTML -страницы скрыта инструкция поиска a=q. Когда кнопка поиска нажата, эта инструкция активизируется и устанавливает новое действие - queryaction. Запуск queryaction направляет запрос к объекту Filter/Фильтр (c=gberg), определяемый для коллекции через протокол.

Фильтры - важная основная функция серверов коллекции. Приспособленные для действий поиска и просмотра, они обеспечивают способы выбора подмножества информации из коллекции. В этом случае, queryaction устанавливает запрос фильтра:

Запросы к протоколу синхронны. Регистратор эффективно блокируется, пока запрос фильтра не будет обработан сервером коллекции и все сгенерированные данные будут отображены.

Когда запрос протокола типа QueryFilter сделан, объект Filter (см. рисунок ## ) декодирует варианты и запрашивает объект Search, который использует MG для фактического поиска. Роль объекта Search состоит в том, что он должен обеспечить абстрактный интерфейс программы, который поддерживает поиск, независимо от основного используемого средства поиска. Формат, используемый для того, чтобы возвращать результаты, также предписывает абстракцию, требуя от объекта Search транслировать данные, сгенерированные средством поиска в стандартную форму.

Как только результаты поиска возвращены регистратору, дальнейшим действием становится форматирование результатов для отображения, используя объект Format и Макроязык. Как показано на рисунке ## , он выглядит следующим образом: стандартный заголовок Greenstone, нижний колонтитул, навигационная область и фон; повторение основной части страницы запроса только ниже навигационной области; отображение книжного значка, заголовка и автора для каждого найденного документа соответственно. Формат последней части управляется инструкцией format SearchVList в файле конфигурации коллекции. Прежде чем заголовок и метаданные автора будут отображены, они должны быть найдены сервером коллекции. Тут требуется запрос к протоколу, на сей раз используя BrowseFilter.

Retrieving a document

После вышеупомянутого запроса для Darcy, рассмотрим отображаемый документ. Рисунок ## показывает результат щелчка по иконке около The Golf Course Mystery на рисунке ## .

ArrayThe Golf Course Mystery

7:

Исходный текст для коллекции Gutenberg включает один длинный файл книги. Во время компоновки, этот файл разбит на отдельные страницы, каждая по 200 строк или около этого, и необходимая информация для каждой страницы сохранена в индексах и информационной базе данных коллекции. В верхней части рисунка ## указано, что эта книга содержит 104 создаваемых компьютером страницы, и ниже - начало страницы один: кто ввел информацию, заголовок, автор, начало оглавления (это часть табличной формы исходного текста Gutenberg, она не была сгенерирована Greenstone). В верхней левой части находятся кнопки, которые управляют внешним видом документа: только одна страница или целый документ; подсветка термина запроса вкл. или выкл.; действительно ли книга должна быть отображена в ее собственном окне; отделение поисковой части от окна просмотра. В верхней правой части - навигационная помощь, которая обеспечивает прямой доступ к любой странице в книге: просто напечатайте номер страницы и нажмите кнопку "go to page" (перейти к странице). Дополнительно можно использовать для перехода по страницам стрелки next/previous pages (следующая/предыдущая страница).

Действие поиска документов documentaction определено установкой a=d и имеет несколько дополнительных параметров. Наиболее важный - дпоиск документа: это определено через переменную d. На рисунке ## это установлено как d=HASH51e598821ed6cbbdf0942b. 1 найти первую страницу документа с идентификатором HASH51e598821ed6cbbdf0942b, зная более дружественый термин The Golf Course Mystery. Остальные переменные определяют: вкл. или выкл. подсветку термина запроса (hi), отобразить информацию о том, какая страница книги отображена (gt). Эти переменные используются для поддержки действий, предлагаемых кнопками на странице (см. рисунок ## ), описанной выше. Значения по умолчанию используются, если любая из этих переменных опущена.

Действие следует за процедурой queryaction: оценка CGI -аргумента, доступ к серверу коллекции, используя протокол и результат для генерации web-страницы. Варианты, касающиеся документа, декодированы CGI-аргументом и сохранены в объекте для дальнейшей работы. Чтобы отыскать документ на сервере коллекции, необходим только идентификатор документа, чтобы установить запрос протокола к get_document (). Как только текст найден, должно быть произведено значительное форматирование. Для этого программа доступа к documentaction сохраняет аргумент и использует объект Format и Макроязык.

Просмотр иерархического классификатора

На рисунке ## показан пример просмотра, где пользователь выбрал Titles А-Z (Заголовки A-Z) и обратился к гиперсвязи для символа К. Это происходит благодаря действию documentaction, которое задается CGI -аргументом a=d. Однако, до подключения переменной d стоит оговориться, что в данном случае она не была использована. Вместо этого использовался узел в пределах доступной для просмотра иерархии классификации, чтобы отобразить определенную переменную cl. В данном примере она представляет заголовки, сгруппированные символом К. Этот список был сформирован во время компановки и сохранен в информационной базе данных коллекции.

Array

8: Просмотр заголовков коллекции Gutenberg

Записи, которые представляют узлы классификатора в базе данных, используют префикс CL, сопровождаемый числами, отделенными периодами (.), определяющими их нахождение в пределах вложенной структуры. Игнорируя кнопку поиска (левый край в навигационной области), классификаторы пронумерованы последовательно в порядке возрастания, слева направо, начиная с 1. Таким образом, узел классификатора верхнего уровня для заголовков в нашем примере - CL1, а разыскиваемая страница сгенерирована установкой cl=CLl.ll. Вы можете увидеть это в строке URL наверху рисунка ## .

Для обработки запроса документа cl используется объект Filter, который отыскивает узел по протоколу. возвращенных данных, дальнейшие запросы протокола сделаны для того, чтобы отыскать метаданные документа. В данном случае найдены заголовки книг. Однако, если узел был внутренний, дочерние записи которого - самостоятельные узлы, то были бы найдены заголовки дочерних вершин. С точки зрения программирования, это тоже самое и обработано тем же самым механизмом.

Наконец, вся найденная информация связана с использованием макроязыка и отображена на web-странице, показанной на рисунке ## .

Generating the home page

Array

9: Генерация домашней страницы

В качестве последнего примера мы рассмотрим создание домашней страницы Greenstone. Рисунок ## демонстрирует домашнюю страницу Greenstone, установленную со значениями по умолчанию. Ее URL, который вы можете видеть наверху экрана, включает аргументы а=р np=home. Таким образом, подобно странице "about this collection" (об этой коллекции), она была сгенерированара^еасй'ои (а=р), но на сей раз применялось home (p=home). Поэтому макроязык обращается к содержанию home.dm. В данном случае нет никакой набодности определять коллекцию (с переменной с).

Цель главной страница показать, какие коллекции доступны. Щелчок по иконке приведёт пользователя на страницу “о коллекции” для этой коллекции. Меню создаётся динамически каждый раз, как только страница загружена, и базировано на коллекциях, находящихся в файлах в данное время . Каждая новая коллекция автоматически отображается на главной странице, как только страница перезагружается (если предусмотрено, что коллекция “публичная”)

Для этого регистратор использует протокол (конечно). Как часть оценки CGI аргументов, pageaction запрограммирована для обнаружения особого случая когда p=home. Тогда это действие пользуется протокольным запросом get_collection_list(), чтобы установить текущий набор коллекций. Он вызывает get_collectinfo() для получения информации о каждом из них. Эта информация включает: доступность коллекции публично, URL иконки коллекции (если есть какая-нибудь), и полное название коллекции. Эта информация используется, чтобы сгенерировать правильный вход в коллекцию с главной страницы.

Исходный код

<tblcaption table_standalone_programs_included_in_greenstone|Независимые программы, включённые в Гринстоун></tblcaption>

setpasswd/ Поддержка пароля для Windows
getpw/ Поддержка пароля для Юникса
txt2db/ Конвертировать текстовой ASCII формат, подобный XML, в формат базы данных Gnu
db2txt/ Конвертировать формат базы данных Gnu в текстовой ASCII формат, подобный XML.
phind/ Инструмент для просмотра иерархической фразы
hashfile/ Вычислить уникальный опознавательный признак документа, базированый на содержании файла.
mgpp/ Переписанная и обновлённая версия Managing Gigabytes пакета в C++.
w32server/ Локальный сервер библиотеки для Windows.
checkis/ Специфическая поддержка для инсталляции Гринстоун в Windows.

Исходный код для работающей системы находится в GSDLHOME/src. Он занимает две поддиректории, recpt для регистрационного сервера и colservr для коллекционного сервера. Гринстоун работает во всех версиях Windows вплоть до Windows 3.1, и к несчастью это налагает восьмизнаковый лимит на файл и название директории. Это объясняет почему используются такие загодачные сокращение, как recpt и colservr. Остальные директории включают отдельностоящие утилиты, в основном для порддержки процесса построения. Они перечислены в Таблице<tblref table_standalone_programs_included_in_greenstone>.

Другая директория, GSDLHOME/lib, включает подуровневые объекты, которые используются обоими, регистрационным и коллекционным, серверами . Этот код описан в Секции common_greenstone_types.

Greenstone широко использует Standard Template Library (STL)/ Стандартную библиотеку шаблонов С ++,- созданную Silicon Graphics (www.sgi.com), которая является результатом многих лет разработки и развития. Подобно всем библиотекам программирования, она требует некоторого времени на изучение. Приложение А дает краткий обзор ключевых частей, которые используются всюду в программе Greenstone. Для более полного ознакомления обращайтесь к официальному STL справочному руководству, доступному на сайте www.sgi.com, или к одному из многих учебников STL, например Josuttis (1999).

Общие типы Greenstone

Объекты, определенные в GSDLHOME/lib, являются объектами Greenstone нижнего уровня, основываясь на вершине STL, которые входят в исходную программу. Сначала мы детально рассмотрим бъект text_t, который используется для представления текста в формате Unicode. После чего мы сможем кратко изложить цель каждого файла библиотеки.

Объект text_t

Greenstone работает с многими языками и для поддержки коллекции, и пользовательского интерфейса. Для этого исходная программа повсеместно использует Unicode. Основным объектом, который понимает строку Unicode является text_t.

Arraytext_tAPI––

10: %

typedef vector<unsigned short> usvector;
 
class text_t {
protected:
usvector text;
unsigned short encoding; // 0 = unicode, 1 = other
 
public:
   // constructors
   text_t ();
   text_t (int i);
   text_t (char *s); // assumed to be a normal c string
 
   void setencoding (unsigned short theencoding);
   unsigned short getencoding ();
 
   // STL container support
   iterator begin ();
   iterator end ();
 
   void erase(iterator pos);
   void push_back(unsigned short c);
   void pop_back();
 
   void reserve (size_type n);
 
   bool empty () const {return text.empty();}
   size_type size() const {return text.size();}
 
   // added functionality
   void clear ();
   void append (const text_t &t);
 
   // support for integers
   void appendint (int i);
   void setint (int i);
   int getint () const;
 
   // support for arrays of chars
   void appendcarr (char *s, size_type len);
   void setcarr (char *s, size_type len);
};

Unicode использует два байта для хранения каждого символа. На рисунке ## показаны главные особенности text_t Application Program Interface/ Интерфейс прикладной программы (API). Он позволяет выполнить двухбайтовое требование, используя С ++ встроенный тип short, который определен как двухбайтовое целое число. Центральный тип данных объекта text_t - это динамический массив, сформированный short, используя STL описание vector<unsigned short> и полученное сокращенное название usvector.

Функции конструктора (строки 10-12) явно поддерживают три формы инициализации: конструкция без параметров, которая генерирует пустую строку Unicode; конструкция с целочисленным параметром, которая генерирует версию текста Unicode числового обеспеченного значения; конструкция с параметром char*, который обрабатывает аргумент как строку С ++ с нулевым символом в конце и генерирует версию Unicode.

После этого, большинство элементов (строки 17-28), переходят на обслуживание STL векторного контейнера: beginQ, endQ,push_back(), emptyQ и т.д. Здесь имеется поддержка очистки и добавления строки, а также преобразования целочисленного значения в строку текста Unicode, и возвращения соответствующего целочисленного значения текста, который представляет номер.

Arraytext_t––

11: %

class text_t {
   // ...
   public:
   text_t &operator=(const text_t &x);
   text_t &operator+= (const text_t &t);
   reference operator[](size_type n);
 
   text_t &operator=(int i);
   text_t &operator+= (int i);^ \\
   text_t &operator= (char *s);
   text_t &operator+= (char *s);
 
   friend inline bool operator!=(const text_t& x, const text_t& y);
   friend inline bool operator==(const text_t& x, const text_t& y);
   friend inline bool operator< (const text_t& x, const text_t& y);
   friend inline bool operator> (const text_t& x, const text_t& y);
   friend inline bool operator>=(const text_t& x, const text_t& y);
   friend inline bool operator<=(const text_t& x, const text_t& y);
   // ...
};

Существует множество перегруженных операторов , которые не показаны на рисунке ## . Особо значимые операторы представлены на рисунке ## . Строка 4 поддерживает назначение одного объекта text_t другому, а строка 5 перегружает оператор+ = , чтобы обеспечить более естественный способ добавления одного объекта text_t в конец другого. Также возможно через строку 6 обратиться к специфическому символу Unicode (представленному как short), используя знак массива []. Далее необходимо назначить и добавить в конец операторы, предназначенные для строк C++ и целых чисел. Строки 12-18 представляют Булевы операторы для того, чтобы сравнить два объекта text_t: равно, не равно, предшествует в алфавитном порядке и так далее.

Функция-член, которая берет аргумент const вместо не-const, также имеется (но на рисунке не показана). Такое повторение стандартно для объектов C++, делая API более весомым, но не более концептуальным. В действительности, многие из этих функций представлены как отдельные действующие инструкции. Для более подробного изучения обратитесь к исходному файлу GSDLHOME/lib/text_t.h.

Программа библиотеки Greenstone

Файлы заголовка в GSDLHOME/lib включают смесь функций и объектов, что обеспечивает поддержку работы системы Greenstone. Для большей эффективности отношения, функции и функции-члены объявлены как inline. Для большей части подробности выполнения содержатся в копии файла заголовка .срр.

<tblcaption table_table|##HIDDEN##></tblcaption>

cfgread.h Функции для чтения и записи файла конфигурации. Например, read_cfg_line () как аргумент для использования берет входной поток и text_tarray (обработанный для vector<text_t>), чтобы заполнить данными для чтения.
display.h Сложный объект, используемый регистратором для установки, хранения и расширения макроса, плюс поддержки типов. Подробности вы можете найти в Разделе receptionist.
fileutil.h Функция поддержки независимости нескольких файловых утилит в операционной системе. Например, fllename_cat () берет до шести text_t параметров и возвращает textjt, который является результатом связывания элементов, используя соответствующий директивный разделитель для текущей операционной системы.
gsdlconf.h Системно-специфические функции, которые отвечают на вопросы типа: операционная система, используемая для трансляции, должна обратиться к strings.h так же, как string.ht Действительно ли все соответствующие значения для закрытия файла, правильно определенного?
gsdltimes.h Функция поддержки дат и времени. Например, time2text () берет компьютерное время, выраженное в количестве секунд, которые прошли с 1 января 1970, конвертирует их в форму YYYY/MM/DD (ГГГГ/ММ/ДД), hh:mm:ss (чч:мм:сс) и возвращает как тип textjt.
gsdltools.h Различная поддержка работы системы Greenstone: объясняет, если HttleEndian или bigEndian; проверяет, доступен ли Perl; выполняет системную команду (с несколькими ненужными свойствами программы) и избавляет от специальных макросимволов в text_t строке.
gsdlunicode.h Ряд унаследованных объектов, которые поддерживают обработку Unicode text_t строки через потоки Ю, типа Unicode к UTF-8 и наоборот; удаление пространств нулевой ширины. Поддержка тар-файлов обеспечена через объект mapconvert с распределениями, загруженными из GSDLHOME/mappings.
text_t.h Прежде всего это объект текста Unicode, описанный выше. Но также обеспечивает два класса для преобразования потоков: inconvertclass и outconvertclass. Это - базовые классы, используемые в gsdlunicode.h.

Collection server

Теперь детально объясним все объекты в концептуальной структуре рисунка ## . Мы начнем с низа диаграммы, который является также основой системы, и с Search (Поиск), Source (Источник), РШег(Филыр) и продолжим наш путь через уровень протокола к центральным компонентам в регистраторе: Actions (Действия), Format (Формат) и Macro Language (Макроязык). Затем мы сосредоточимся на объектной инициализации, так как это будет проще понять, если уже известна роль различных объектов.

Большинство классов, центральных в концептуальной структуре, выражено с использованием виртуального наследования, чтобы помочь расширяемости. При виртуальном наследовании унаследованные объекты можно передать по кругу, как их базовый класс, но когда вызвана функция-член, ее версия определена в призванном унаследованном объекте. Гарантируя, что исходная программа Greenstone использует базовый класс повсюду, кроме точки объекта конструкции, это означает, что различное выполнение - использование возможно на основе радикально различных технологий - может быть легко размещено на месте.

Например, предположим, что базовый класс по имени BaseCalc обеспечивает основную арифметику: сложение, вычитание, умножение и деление. Если все его функции объявлены виртуальными, а аргументы и возвратные типы все объявлены как строки, мы можем легко осуществить наследование версии объекта. Один из них, названный FixedPrecisionCalc, мог бы использовать библиотечные функции С, чтобы совершать конвертацию между строками и целыми числами и обратно, осуществляя вычисления, используя стандартные арифметические операторы: +, -, *, и /. Другой, названный InfinitePrecisionCalc, мог бы обращаться к строковым аргументам и символам одновременно, осуществляя арифметические операции с бесконечной точностью. Написанная главная программа использует BaseCalc повсюду, параметры ее работы могут регулироваться переключением между установленной точностью и бесконечной точностью, редактируя только одну строку: пункт, где создан объект - калькулятор.

ArrayAPI

12:

class searchclass {
public:
   searchclass ();
   virtual ~searchclass ();
   // the index directory must be set before any searching
   // is done
   virtual void setcollectdir (const text_t &thecollectdir);
   // the search results are returned in queryresults
   // search returns 'true' if it was able to do a search
   virtual bool search(const queryparamclass &queryparams,
                         queryresultsclass &queryresults)=0;
   // the document text for 'docnum' is placed in 'output'
   // docTargetDocument returns 'true' if it was able to
   // try to get a document
   // collection is needed to see if an index from the
   // collection is loaded. If no index has been loaded
   // defaultindex is needed to load one
   virtual bool docTargetDocument(const text_t &defaultindex,
                                               const text_t &defaultsubcollection,
                                               const text_t &defaultlanguage,
                                               const text_t &collection,
                                               int docnum,
                                               text_t &output)=0;
protected:
   querycache *cache;
   text_t collectdir; // the collection directory
};

Рисунок ## демонстрирует листинг базового классф API для объекта Search (см. рисунок ## ). Это определяет две виртуальные функции-члены: search() и docTargetDocument(). Из рисунка видно, что =0, который следует за описанием аргумента, это функция риге, означающая, что класс, который наследует объект, должен осуществить обе функции (иначе компилятор выдаст сообщение).

Класс также включает два защищенных поля данных: collectdir и cache. Объект Search иллюстрируется примерами для специфической коллекции, а поле collectdir используется для хранения системы файлов (и что еще более важно - их файлы индекса) в месте нахождения коллекции. Поле сасйесохраняет результат запроса. Это используется, чтобы ускорить обработку последующих запросов, которые будут дублировать этот запрос (и его параметры). В то время, как идентичные вопросы могут казаться маловероятными, фактически они происходят регулярно. Протокол Greenstone является простым. Чтобы сгенерировать страницу результатов, подобную изображенной на рисунке ## , но для документов с 11 по 20 того же самого запроса, поиск роизводится снова, на сей раз оговорив заранее, возврат документов 11-20. Кэширование делает это эффективным, тот факт, что поиск был уже выполнен, обнаруженные результаты могут быть извлечены прямо из кэша.

Оба поля данных применимы к каждому унаследованному объекту, который осуществляет механизм поиска. Это - то, почему они появляются в азовом классе, и объявлены защищенной секцией класса так, чтобы унаследованные классы могли получить доступ к ним непосредственно.

Поиск с MG

Greenstone использует MG (сокращенно от Managing Gigabytes, CM.Witten et al., 1999) для индексации и восстановления документов, исходная программа включена в директорию GSDLHOME/packages. MG использует методы сжатия, чтобы максимально использовать место на диске, не ставя под угрозу скорость выполнения. Для коллекции документов на английском языке сжатый текст и полный текст индексируются вместе и оычно занимают одну треть места, занимаемого несжатым текстом. Поиск и исправление часто происходят быстрее, чем подобное действие на несжатой версии, потому что производится меньше дисковых операций.

ArrayAPI

13: для прямого доступа к MG (сокращенный вариант)

enum result_kinds {
   result_docs,           // Return the documents found in last search
   result_docnums,     // Return document id numbers and weights
   result_termfreqs, // Return terms and frequencies
   result_terms           // Return matching query terms
};
int mgq_ask(char *line);
int mgq_results(enum result_kinds kind, int skip, int howmany,
                               int (*sender)(char *, int, int, float, void *),
                               void *ptr);
int mgq_numdocs(void);
int mgq_numterms(void);
int mgq_equivterms(unsigned char *wordstem,
                           int (*sender)(char *, int, int, float, void *),
                           void *ptr);
int mgq_docsretrieved (int *total_retrieved, int *is_approx);
int mgq_getmaxstemlen ();
void mgq_stemword (unsigned char *word);

MG обычно используется в интерактивном режиме, печатая команды в командной строке. Один из способов активации mgsearchclass заключается в использовании библиотеки С systemQ, вызываемой с объектом, запуском соответствующей команды MG. Более эффективный подход, однако, состоит в том, чтобы открыть программу MG непосредственно, используя функцию вызова. Однако, для этого требуется более глубокое знание программы MG. Большая часть трудностей может быть скрыта за новым API , который становится точкой соприкосновения для объекта mgsearchclass. Это - роль colserver/mgq. с, чей API показан на рисунке ## .

Способ передачи параметров к MG - через mgq_ask (), который берет варианты текста в формате, идентичном используемому в командной строке:

mgq_ask( ".set casefold off ");

Это также используется при вызове запроса. К результатам обращаются через mgq_results, который использует указатель на функцию, как ее четвертый параметр. Это обеспечивает гибкий способ преобразования информации, возвращенной в структуру данных MG по требованию mgsearchclass. Вызов mgqjiumdocs О, mgqjiumterms () и mgq_docsretrieved () также возвращает информацию, но на сей раз с более жесткими условиями. Последние два оказывают поддержку при восстановлении.

Обьект Source

ArrayAPI

14:

class sourceclass {
public:
   sourceclass ();
   virtual ~sourceclass ();
   // configure should be called once for each configuration line
   virtual void configure (const text_t &key, const text_tarray &cfgline);
   // init should be called after all the configuration is done but
   // before any other methods are called
   virtual bool init (ostream &logout);
   // translate_OID translates OIDs using " .pr " , . " fc " etc.
   virtual bool translate_OID (const text_t &OIDin, text_t &OIDout, comerror_t &err, ostream &logout);
   // get_metadata fills out the metadata if possible, if it is not
   // responsible for the given OID then it return s false.
   virtual bool get_metadata (const text_t &requestParams, const text_t &refParams,
                           bool getParents, const text_tset &fields, const text_t &OID,
                           MetadataInfo_tmap &metadata, comerror_t &err, ostream &logout);
   virtual bool get_document (const text_t &OID, text_t &doc, 
                           comerror_t &err, ostream &logout);
};

Роль Source (см. рисунок ## ) - доступ к метаданным и тексту документа. Его базовый класс представлен на рисунке ## . Функция-член наносит на карту к каждой задаче: getjnetadata () и get_document () соответственно. Оба объявлены virtual, так что версию, обеспечивающуюся выполнением базового класса, вызывают во время работы. Одна унаследованная версия этого объекта использует GDBM, чтобы запустить get_metadata 0 и MG, чтобы запустить get_document (): мы детализируем эту версию ниже.

Другая функция-член представлена на рисунке ## - configure^, init () и translate_OID Q. Первые два касаются процесса инициализации, описанного в Разделе initialisation.

Оставшаяся, translate_OID (), работает с синтаксисом для того, чтобы выразить идентификаторы документа. На рисунке ## мы видели, как номер страницы мог быть добавлен в конец к идентификатору документа, чтобы вызвать только эту страницу. Это было возможно, потому что страницы были идентифицированы как "разделы" при формировании коллекции. Добавление в конец " . 1" к OID вызывает первый раздел соответствующего документа. Разделы могут быть вложенными и доступны для обращения благодаря определенному номеру, разделенному периодами.

Так же, как иерархические номера разделов, синтаксис идентификатора документа поддерживает форму относительного доступа. Для текущего раздела документа возможно получить доступ к first child, добавляя в конец /с, к last child, добавляя в конец .1с, к parent, добавляя в конец .рг, к next sibling, добавляя в конец .ns и ^previous sibling, добавляя в конец .ps.

Функция translate_OID () использует параметры OIDin и OIDout, чтобы хранить исходный вариант и результат преобразования. Требуется два дополнительных параметра - err и logout. Они сообщают любой статус ошибки, который может возникнуть во время перевода, и решают, когда и куда послать регистрационную информацию. Параметры являются близкими союзниками протокола, мы к этому вернемся в Разделе protocol.

Исправление баз данных с gdbm

Программа GDBM - менеджер базы данных GNU (www.gnu.org). Она осуществляет простую структуру записей пар ключ/данные и совместима с DBM и NDBM. Операции включают хранение, исправление и удаление записей по ключу, а также пресечение всех незаказанных ключей.

Array

15: GDBM база данных для коллекции Gutenberg (фрагмент)

[HASH01d7b30d4827b51282919e9b]
<doctype>         doc
<hastxt>           0
<Title>             The Winter's Tale
<Creator>         William Shakespeare
<archivedir>   HASH01d7/b30d4827.dir
<thistype>       Invisible
<childtype>     Paged
<contains>        " .1; " .2; " .3; " .4; " .5; " .6; " .7; " .8; " .9; " .10; " .11; " .12;            \ <br/>                           " .13; " .14; " .15; " .16; " .17; " .18; " .19; " .20; " .21; " .22;            \ <br/>                           " .23; " .24; " .25; " .26; " .27; " .28; " .29; " .30; " .31; " .32;            \ <br/>                           " .33; " .34; " .35
<docnum>           168483
———————————————————————-
[CL1]
<doctype>         classify
<hastxt>           0
<childtype>     HList
<Title>             Title
<numleafdocs> 1818
<thistype>       Invisible
<contains>       " .1; " .2; " .3; " .4; " .5; " .6; " .7; " .8; " .9; " .10; " .11; " .12;          \ <br/>                           " .13; " .14; " .15; " .16; " .17; " .18; " .19; " .20; " .21; " .22;          \ <br/>                            " .23; " .24
———————————————————————-
[CL1.1]
<doctype>         classify
<hastxt>           0
<childtype>     VList
<Title>             A
<numleafdocs> 118
<contains>      HASH0130bc5f9f90089b3723431f;HASH9cba43bacdab5263c98545;\
                          HASH12c88a01da6e8379df86a7;HASH9c86579a83e1a2e4cf9736;   \
                           HASHdc2951a7ada1f36a6c3aca;HASHea4dda6bbc7cdeb4abfdee;   \
                          HASHce55006513c47235ac38ba;HASH012a33acaa077c0e612b9351;\
                          HASH010dd1e923a123826ae30e4b;HASHaf674616785679fed4b7ee;\
                         HASH0147eef4b9d1cb135e096619;HASHe69b9dbaa83ffb045d963b;\
                         HASH01abc61c646c8e7a8ce88b10;HASH5f9cd13678e21820e32f3a;\
                         HASHe8cbba1594c72c98f9aa1b;HASH01292a2b7b6b60dec96298bc;\
                         ...

Рисунок ## представляет фрагмент информационной базы данных коллекции, которая создана при формировании коллекции Gutenberg. Фрагмент был создан, используя утилиту db2txt системы Greenstone, которая конвертирует GDBM двойной формат базы данных в текстовую форму. Рисунок ## содержит три записи, отделенные горизонтальными линиями. Первый - вход документа, другие два - часть иерархии, созданной классификатором AZList для заголовков коллекции. Первая строка каждой записи - ее ключ.

Запись документа хранит заглавие книги, автора и любые другие метаданные, созданные (или извлеченные) во время формирования коллекции. Запись такжебывает для внутреннего пользования и хранит информацию о том, где находятся файлы, связанные с этим документом (<archivedir>), и номер документа, используемый внутри MG (<docnum>).

Поле <contains> хранит список элементов, отделенных точками с запятой. Это точки, связывающие записи в базе данных. Для записи документа <contains> используется, чтобы указать на вложенные разделы. Последующие ключи записи сформированы, связывая текущий ключ с одним из дочерних элементов (отделенных периодом).

Вторая запись на рисунке ## - главный узел для иерархии классификации Titles A—Z. Его дети доступны через поле <contains>, включая CL 1.1, CL1.2, CL1.3 и так далее, соответствующие индивидуальным страницам для символов А, В, С и т.д. Имеется только 24 ребенка: классификатор AZList слил Q-R и Y-Z вхождения, потому что они охватили только несколько заглавий.

Дети в поле <contains> третьей записи, CL 1.1,- это конечные документы. Возможны и более сложные структуры - поле <contains> может включать смесь документов в качестве CL узлов. Ключи, выраженные относительно текущего, отличают от абсолютных ключей, потому что они начинаются с кавычек (").

Использование MG и GDBM для реализации объекта Source

ArrayAPI

16: для sourceclass базовой версии MG и GDBM (сокращенный вариант)

class mggdbmsourceclass : public sourceclass {
protected:
   // Omitted, data fields that store:
   //     collection specific file information
   //     index substructure
   //     information about parent
   //     pointers to gdbm and mgsearch objects
public:
   mggdbmsourceclass ();
   virtual ~mggdbmsourceclass ();
   void set_gdbmptr (gdbmclass *thegdbmptr);
   void set_mgsearchptr (searchclass *themgsearchptr);
   void configure (const text_t &key, const text_tarray &cfgline);
   bool init (ostream &logout);
   bool translate_OID (const text_t &OIDin, text_t &OIDout,
                                           comerror_t &err, ostream &logout);
   bool get_metadata (const text_t &requestParams,
                                           const text_t &refParams,
                                         bool getParents, const text_tset &fields,
                                         const text_t &OID, MetadataInfo_tmap &metadata,
                                         comerror_t &err, ostream &logout);
   bool get_document (const text_t &OID, text_t &doc,
                                         comerror_t &err, ostream &logout);
};

Объект, который соединяет MG и GDBM, чтобы реализовать выполнение sourceclass -это mggdbmsourceclass. Рисунок ## демонстрирует его API. Две новых функции-члена set_gdbmptr () и set_mgsearchptr () хранят указатели на соответствующие им объекты, так, чтобы при выполнении getjnetadata О и get_document () иметь доступ к соответствующим инструментальным средствам для завершения работы.

Объект Filter

ArrayAPI

17: for the Filter base class

class filterclass {
protected:
   text_t gsdlhome;
   text_t collection;
   text_t collectdir;
   FilterOption_tmap filterOptions;
public:
   filterclass ();
   virtual ~filterclass ();
   virtual void configure (const text_t &key, const text_tarray &cfgline);
   virtual bool init (ostream &logout);
   // returns the name of this filter
   virtual text_t get_filter_name ();
   // returns the current filter options
   virtual void get_filteroptions (InfoFilterOptionsResponse_t &response,
                                 comerror_t &err, ostream &logout);
   virtual void filter (const FilterRequest_t &request,
                         FilterResponse_t &response,
                         comerror_t &err, ostream &logout);
};

API базового класса для объекта Filter (см. рисунок ## ) показан на Рисунке ## . Он начинается с защищенных полей данных gsdlhome, collection и collectdir. Они обычно происходят в классах, которые должны обратиться к определенным коллекцией файлам.

mggdbsourceclass - другой класс, который включает эти три поля данных.

Функции-члены conflgure() и init() (ранее упоминавшиеся в sourceclass) используются процессом инициализации. Сам объект находится недалеко от соответствующей части фильтра протокола; в особенности getjilteroptions О и fllter() соответствуют один другому.

Array

18: Как хранится опция filter

struct FilterOption_t {
   void clear (); \   void check_defaultValue ();
   FilterOption_t () {clear();}
   text_t name;
   enum type_t {booleant=0, integert=1, enumeratedt=2, stringt=3};
   type_t type;
   enum repeatable_t {onePerQuery=0, onePerTerm=1, nPerTerm=2};
   repeatable_t repeatable;
   text_t defaultValue;
   text_tarray validValues;
};
struct OptionValue_t {
   void clear ();
   text_t name;
   text_t value;
};

К центральным опциям фильтра относятся два класса, показанные на рисунке ## . Сохраненные внутри FilterOption_t - это пате опции, ее type и действительно ли это - repeatable. Интерпретация validValues зависит от типа опции. Для Булева типа первым значением переменой является^г/5е,а вторым - true. Для целочисленного типа первое значение - минимальный номер, второй - максимальный. Для перечисляемого типа все значения перечислены. Для строкового типа значение игнорируется. Для более простых ситуаций используется OptionValue_t, в качестве записи как text_t name опции и ее value.

Запрос и ответ объекта проходят как параметры juuLJilterclass. Созданью из них два класса используют ассоциативные массивы, чтобы сохранить набор типов опций, требуемых для InfoFilterOptionsResponseJ. Для детального исследования вопроса смотрите GSDLHOME/src/recpt/comtypes.h.

Объекты наследования Filter

Array

19: Иерархия наследования Filter

Два уровня наследования используются для фильтров, как показано на рисунке ## . Сначала было сделано различие между фильтрами Query и Browse, а затем первому из них определено выполнение, основанное на MG. Для корректной работы mgqueryfilterclass требуется доступ к MG через mgsearchclass и к GDBM через gdbmclass. browsefllterclass нуждается в доступе только к GDBM. Указатели на эти объекты сохранены как защищенные поля данных в пределах соответствующих классов.

Программа сервера коллекции

Рассмотрим файлы заголовка в GSDLHOME/SRC/COLSERVR с описанием каждого из них. Имя файла вообще повторяет имя объекта, определенное в его пределах.

<tblcaption table_table_1|##HIDDEN##></tblcaption>

browsefilter.h Унаследованный mfilterdass, этот объект обеспечивает доступ к GDBM (Описан выше).
collectserver.h Этот объект связывает вместе Filters и Sources для одной коллекции, формируя объект Collection, показанный на рисунке ## .
colservrconfig.h Функциональная поддержка для чтения определенных коллекцией файлов etc/'collect, cfg и index/build, cfg. Первый из них - файл конфигурации коллекции. Последний - файл, сгенерированный процессом формирования, который делает запись времени последней успешной компоновки, карту индексного списка, показывает сколько документов было индексировано и как сколько байт они занимают (в распакованном виде).
filter.h Объект базового класса Filter fllterclass описан выше.
maptools.h Определяет класс, названный stringmap, который обеспечивает отображение и быстрый просмотр, помнит первоначальный порядок карты text_t. Использется в mggdbmsourceclass и query'fllterclass.
mggdbmsource.h Унаследованный от sourcedass, этот объект предоставляет доступ к MG и GDBM (описан выше).
mgppqueryfilter.h Унаследованный от query'filterclass, этот объект обеспечивает выполнение QueryFilter, основанного на MG++, улучшенной версии MG, написанной на C++. Обратите внимание, что Greenstone установлены, чтобы использовать MG по умолчанию, так как MG++ находится все еще в развитии.
mgppsearch.h Унаследованный от searchclass, этот объект обеспечивает выполнение Search /Поиска, используя MG++. Подобно mgppqueryfllterclass, он не используется по умолчанию.
mgq.h Интерфейс функционального уровня к пакету MG. Основные функции mg_ask() и mg_results().
mgqueryfilter.h Унаследованный от queryfllterclass, этот объект обеспечивает выполнениеОиегуРШег, основанного на MG.
mgsearch.h Унаследованный от searchclass, этот объект обеспечивает выполнение Search, используя MG (описан выше.)
phrasequeryfilter.h Унаследованный от mgqueryclass, этот объект обеспечивает выполнение запроса, основанного на фразе. Он не используется в заданной по умолчанию инсталляции. Вместо этого mgqueryfllterclass обеспечивает эту возможность через функциональную поддержку от phrasesearch.h.
phrasesearch.h Функциональная поддержка проведения поиска по фразе, как операция постобработки.
querycache.h Используется searchclass и его унаследованными классами для кэширования результатов запроса, при генерации страниц поисковых результатов наиболее эффективен (описан выше.)
queryfilter.h Унаследованный от базового класса Filter filterclass, этот объект основывает базовый класс для объектов Query filter (описан выше.)
queryinfo.h Поддержка поиска: структуры данных и объекты содержат параметры запроса, результаты поиска документа и частоту встречаемости термина.
search.h Базовый класс Search объект searchclass (описан выше.)
source.h Базовый классЗоигсе объект sourceclass (описан выше.)

Протокол

<tblcaption table_list_of_protocol_calls|Список запросов протокола></tblcaption>

get_protocol_name() Возвращает имя этого протокола. Выборы включают nullproto, corbaproto и z3950proto. Используется во время работы системы чувствительными к протоколу частями, чтобы решить, какие программы запустить на выполнение.
get_collection_list() Возвращает список коллекций, о которых этот протокол имеет сведения.
has_collection() Возвращает значение истины, если протокол может связаться с названной коллекцией, то есть это - в пределах списка коллекции.
ping() Возвращает значение истины, если успешно была установлена связь с названной коллекцией. В нулевом протоколе выполнение идентично has_collection().
get_collectinfo() Получает общую информацию о названной коллекции: когда она была сформирована, сколько документов она содержит и т.д. Также включает метаданные файла конфигурации коллекции: текст для страницы"аЪои1 this collection"; иконку коллекции и т.д.
get_filterinfo() Получает список всех Filters для названной коллекции. get
get_filteroptions() Получает все варианты для специфического Filter в пределах названной коллекции.
filter() Поддерживает поиск и просмотр, для данного типа фильтра и параметров настройки, обращается к содержанию названных коллекций, чтобы воспроизвести результат, который отфильтрован в соответствии с параметрами настройки. Возвращенные поля данных также зависят от параметров настройки: примеры включают частоту встречаемости термина запроса и метаданные документа.
get_document() Получает документ или раздел документа.

Таблица <tblref table_list_of_protocol_calls> представляет список запросов функции к протоколу и резюме для каждого вхождения. Примеры в Разделе how_the_conceptual_framework_fits_together охватили большинство из них. Функции, не упомянутые предварительно - has_collection (), ping (), get_protocol_name () и get_filteroptions (). Первые две обеспечивают ответы да\нет на вопросы "коллекция существует на этом сервере? " и "это выполняется? ". Цель двух других состоит в том, чтобы поддержать множественные протоколы в пределах архитектуры, которая распределена по различным компьютерам, а не только нулевой протокол, базирующийся на отдельно выполняемой программе, описанной здесь. Одна из них различает, какой протокол используется. Другая позволяет регистратору опрашивать сервер коллекции, чтобы найти, какие варианты поддерживаются, и непосредственно динамически выбирать конфигурации, чтобы использовать все преимущества услуг, предлагаемых специфическим сервером.

ArrayAPI

20: (сокращенный вариант)

class nullproto : public recptproto {
public:
   virtual text_t get_protocol_name ();
   virtual void get_collection_list (text_tarray &collist,
                comerror_t &err, ostream &logout);
   virtual void has_collection (const text_t &collection,
                bool &hascollection,
                comerror_t &err, ostream &logout);
   virtual void ping (const text_t &collection,
                  bool &wassuccess,
                  comerror_t &err, ostream &logout);
   virtual void get_collectinfo (const text_t &collection,
                  ColInfoResponse_t &collectinfo,
                  comerror_t &err, ostream &logout);
   virtual void get_filterinfo (const text_t &collection,
                   InfoFiltersResponse_t &response,
                   comerror_t &err, ostream &logout);
   virtual void get_filteroptions (const text_t &collection,
                   const InfoFilterOptionsRequest_t &request,
                   InfoFilterOptionsResponse_t &response,
                   comerror_t &err, ostream &logout);
   virtual void filter (const text_t &collection,
                   FilterRequest_t &request,
                   FilterResponse_t &response,
                   comerror_t &err, ostream &logout);
   virtual void get_document (const text_t &collection,
                  const DocumentRequest_t &request,
                  DocumentResponse_t &response,
                  comerror_t &err, ostream &logout);
};

Рисунок ## показывает API для нулевого протокола. Комментарии и некоторые подробности низкого уровня были опущены (см. исходный файл recpt/nullproto.h для получения подробностей).

Этот протокол наследовался от базового класса recptproto. Виртуальное наследование используется так, чтобы больше, чем один тип протокола, даже не задуманного, все же мог легко поддерживаться остальной частью исходной программы.

За исключением get_protocol_name (), который не использует параметры и возвращает имя протокола как строку текста Unicode, все функции протокола включают параметр ошибки и выходной поток, как последние два аргумента. Параметр ошибки делает запись любых ошибок, которые происходят в ходе выполнения запроса протокола, а выходной поток используется для регистрации цели. Функции относятся к типу void - они не возвращают информацию как их заключительная инструкция, но вместо этого возвращают данные через определяемые параметры типа уже введенного параметра ошибки. В некоторых языках программирования такие подпрограммы были бы определены как процедуры, а не функции, но C++ не делает никакого синтаксического различия.

Большинство функций использует имя коллекции как параметр. Три функции-члены, get_filteroptions (), filterQ, и get_document (), следуют за обеспечением параметра Request и получением результатов в параметре Response.

Регистратор

Заключительный уровень концептуальной модели - регистратор. Как только CGI-аргументы будут проанализированы, основная деятельность запускает на выполнение Action, поддерживаемую объектами Format и Macro Language. Они описаны ниже. Хотя они представлены как объекты в концептуальной структуре, объекты Format и Macro Language - не совсем являются объектами с точки зрения C++. В действительности, Format - коллекция структур данных с набором функций, которые оперируют ими, а объект Macro Language сформирован вокруг display class, определен в lib/display.h, с потоковой поддержкой конвертации от lib/gsdlunicode.h.

Действия

<tblcaption table_actions_in_greenstone|Actions в системе Greenstone></tblcaption>

action Базовый класс для виртуального наследования.
authenaction Поддержка идентификации пользователя: запрос пользователю относительно пароля, если не был введен; проверка правильности; возможность предоставления пользователю повторного входа, если достаточное время истекло между доступами.
collectoraction Генерирует страницы для Collector (Создателя).
documentaction Отыскивает документы, разделы документа, части иерархии классификации или информацию для форматирования .
extlinkaction Переносит пользователя непосредственно к URL, который является внешним для коллекции, no-возможности сначала генерируя аварийную страницу (продиктованную установками Preferences).
pageaction Генерирует страницу вместе с макроязыком. pingaction Выясняет, интерактивна ли коллекция. queryaction Выполняет поиск.
pingaction Checks to see whether a collection is online.
queryaction Произвести поиск.
statusaction Генерирует страницы администрирования.
tipaction Выдает случайный совет для пользователя.
usersaction Добавляет поддержку, удаление и управление пользовательским доступом.

Greenstone поддерживает одиннадцать действий, сведенных в Таблице <tblref table_actions_in_greenstone>.

Array––

21: %

cgiarginfo arg_ainfo;
arg_ainfo.shortname = " a " ;
arg_ainfo.longname = " action" ;
arg_ainfo.multiplechar = true;
arg_ainfo.argdefault = " p" ;
arg_ainfo.defaultstatus = cgiarginfo::weak;
arg_ainfo.savedarginfo = cgiarginfo::must;
argsinfo.addarginfo (NULL, arg_ainfo);
 
arg_ainfo.shortname = " p" ;
arg_ainfo.longname = " page" ;
arg_ainfo.multiplechar = true;
arg_ainfo.argdefault = " home" ;
arg_ainfo.defaultstatus = cgiarginfo::weak;
arg_ainfo.savedarginfo = cgiarginfo::must;
argsinfo.addarginfo (NULL, arg_ainfo);

CGI-аргументы являются необходимыми действиями формально объявленными в функции конструктора, использующими cgiarginfo (определенный в recpt/cgiargs.h). Рисунок ## показывает выборку из pageaction функции конструктора, которая определяет размер и свойства CGI-аргументов а и р.

Для каждого CGI-аргумента конструктор должен определить его краткое имя (строки 2 и 10), которое непосредственно является именем CGI-переменной; полное имя (строки 3 и 11), которое используется, чтобы обеспечить более значимое описание действия; представляет ли это единственное или множественное символьное значение (строки 4 и 12); возможное значение по умолчанию (строки 5 и 13); что случается, когда задано больше чем одно значение по умолчанию (строки 6 и 14) (так как значения по умолчанию могут также быть установлены в файлах конфигурации); действительно ли значение сохраняется в конце этого действия (строки 7 и 15).

Так как это встроено в программу, web-страницы, которые детализируют информацию, могут быть сгенерированы автоматически. Statusaction производит эту информацию. Вы можете увидеть это, введя URL страницы администрирования Greenstone.

Двенадцать унаследованных действий созданы в main(), функция верхнего уровня для выполняемой программы library, определение которой дается в recpt/librarymain.cpp, там же, где был создан объект регистратора (определенный в recpt/receptionist.cpp). ответственность за все действия передают регистратору, который обрабатывает их, обслуживая как поле данных ассоциативного массива базового класса Action, индексированного названием действия.

ArrayAPI

22:

class action {
protected:
   cgiargsinfoclass argsinfo;
   text_t gsdlhome;
public:
   action ();
   virtual ~action ();
   virtual void configure (const text_t &key, const text_tarray &cfgline);
   virtual bool init (ostream &logout);
   virtual text_t get_action_name ();
   cgiargsinfoclass getargsinfo ();
   virtual bool check_cgiargs (cgiargsinfoclass &argsinfo,
              cgiargsclass &args, ostream &logout);
   virtual bool check_external_cgiargs (cgiargsinfoclass &argsinfo,
              cgiargsclass &args,
              outconvertclass &outconvert,
              const text_t &saveconf,
              ostream &logout);
   virtual void get_cgihead_info (cgiargsclass &args,
              recptprotolistclass *protos,
              response_t &response,
              text_t &response_data,
              ostream &logout);
   virtual bool uses_display (cgiargsclass &args);
   virtual void define_internal_macros (displayclass &disp,
              cgiargsclass &args,
              recptprotolistclass *protos,
              ostream &logout);
   virtual void define_external_macros (displayclass &disp,
              cgiargsclass &args,
              recptprotolistclass *protos,
              ostream &logout);
   virtual bool do_action (cgiargsclass &args,
              recptprotolistclass *protos,
              browsermapclass *browsers,
              displayclass &disp,
              outconvertclass &outconvert,
              ostream &textout,
              ostream &logout);
};

Рисунок ## показывает API для базового класса Action. При выполнении действия, receptionist (регистратор) вызывает несколько функций, начиная с check_cgiargs (). Большинство помогают проверить, установить, и определить значения и макросы; в то время как dojzction () фактически генерирует страницу вывода. В частности, унаследованный объект не имеет никакого определения для специфической функции-члена, это проходит через определение базового класса, которое осуществляет заданное по умолчанию поведение.

Объяснения функций-членов следующие.

В начале определения класса argsinfo - это защищенное поле данных (используемое в выборке программы, см.рисунок ## ), которое хранит информацию CGI-аргумента, указанную в унаследованной функции конструктора Action. Другое поле данных, gsdlhome, создает запись GSDLHOME для удобного доступа1). Объект также включает conflgure() и init () с целью инициализации.

Форматирование

Array

23: Основные структуры данных в Format

enum command_t {comIf, comOr, comMeta, comText, comLink, comEndLink,
         comNum, comIcon, comDoc,
         comHighlight, comEndHighlight};
enum pcommand_t {pNone, pImmediate, pTop, pAll};
enum dcommand_t {dMeta, dText};
enum mcommand_t {mNone, mCgiSafe};
struct metadata_t {
   void clear();
   metadata_t () {clear();}
   text_t metaname;
   mcommand_t metacommand;
   pcommand_t parentcommand;
   text_t parentoptions;
};
// The decision component of an {If}{decision,true-text,false-text}
// formatstring. The decision can be based on metadata or on text;
// normally that text would be a macro like
// _cgiargmode_.
struct decision_t {
   void clear();
   decision_t () {clear();}
   dcommand_t command;
   metadata_t meta;
   text_t text;
};
struct format_t {
   void clear();
   format_t () {clear();}
   command_t command;
   decision_t decision;
   text_t text;
   metadata_t meta;
   format_t *nextptr;
   format_t *ifptr;
   format_t *elseptr;
   format_t *orptr;
};

Хотя на рисунке ## форматирование представлено как отдельный объект, в действительности оно составляет коллекцию структур данных и функций. Они собраны вместе под файлом заголовка recpt/formattools.h. Основные структуры данных показаны на рисунке ## .

Array

24: Структуры данных, сформированные для выборки оператора /ormutf

Этот процесс лучше всего объяснить на примере. Когда оператор задания формата

format CL1Vlist
<!-- id:1025 -->"[link][Title]{If}{[Creator], by [Creator]}[/link]} "

читается из файла конфигурации коллекции, он анализируется функциями в formattools.cpp и формирует связанные структуры данных, показанные на рисунке ## .

Значение для gsdlhome исходит из gsdlsite.cfg, расположенного в том же самом каталоге, что и CGI-выполняемая library, тогда как GSDLHOME устанавливается запуском скрипта setup, который обращается к другому файлу, так как технически это возможно для двух различных значений. Хотя это и возможно, но все же не желательно, и все вышесказанное написано в предположении, что файлы те же самые. Когда оператор задания формата должен быть оценен действием, структура данных пересекается. Маршрут, предпринятый в comIf и comOr узлах, зависит от метаданных, которые возвращают запрос протоколу. Одно осложнение состоит в том, что, когда метаданные найдены, они могут включать последующие макросы и формат синтаксиса. При необходимости это обрабатывается переключеним назад и вперед между синтаксическим анализом и оценкой, как необходимо.

Макроязык

Macro Language, представленный на рисунке ## , так же, как Format не является функцией одного класса C++. В этом случае - это основной класс, но выполнение макроязыка также вызывает функции поддержки и классы.

И снова в объяснении используем пример. Сначала мы даем некоторые типовые макроопределения, которые иллюстрируют макростаршинство, затем, при помощи диаграммы, мы описываем основные структуры данных, сформированные, чтобы поддержать эту деятельность. Наконец, мы представляем и описываем открытые функции-члены displayclass, макрообъекта верхнего уровня.

Array

25: Иллюстрация макро старшинства

package query
_header_ []         {_querytitle_}
_header_ [l=en]     {Search page}
_header_ [c=demo]   {<table bgcolor=green><tr><td>_querytitle_</td></tr></table>}
_header_ [v=1]      {_textquery_}
_header_ [l=fr,v=1,c=hdl] {HDL Page de recherche}

В типичной инсталляции Greenstone, макростаршинство обычно: с (для коллекции) имеет приоритет над v (для графического или текстового интерфейса), который имеет приоритет над / (для языка). Это достигается строкой

macroprecedence c,v,l

в основном файле конфигурации main.cfg. Макроинструкции на рисунке ## определяют типовой макрос для _header_ в пакете запроса для различных параметров настройки с, v и /. Если CGI -аргумент задан, когда вызванное действие включает c=dls, v=l и 1=еп, макрокоманда Jieader _ [v=l] была бы выбрана для отображения. Она была бы выбрана раньше of _content _ [1=еп], потому что v имеет более высокий приоритет, чем /. А макрокоманда _content_[l=fr, v=l, c=dls] не была бы выбрана вообще, потому что параметр / для страницы задан совсем другой.

Array

26: Структуры данных, представляющие макрос, заданный по умолчанию

Рисунок ## показывает основную структуру данных, сформированную при чтении макрофайлов, указанных в etc/main.cfg. По существу, это -ассоциативный массив ассоциативных массивов ассоциативных массивов. Высший уровень (показанный слева) - это индексы, которые упаковывают макрокоманду, второй уровень индексирует макроимя. Конечный уровень индексирует любые параметры, которые были определены, сохраняя каждый как тип mvalue, который создает запись, наряду с макрозначением, файла, из которого оно исходило. Например, текст, определенный для Jieader _ [1=еп] на рисунке ## можно увидеть сохраненным ниже двух записей mvalue на рисунке ## .

ArrayDisplayclassAPI

27: (сокращенный вариант)

class displayclass
{
public:
   displayclass ();
   ~displayclass ();
   int isdefaultmacro (text_t package, const text_t &macroname);
   int setdefaultmacro (text_t package, const text_t &macroname,  
         text_t params, const text_t &macrovalue);
   int loaddefaultmacros (text_t thisfilename);
   void openpage (const text_t &thispageparams,
         const text_t &thisprecedence);
   void setpageparams (text_t thispageparams,
         text_t thisprecedence);
   int setmacro (const text_t &macroname,
         text_t package,
         const text_t &macrovalue);
   void expandstring (const text_t &inputtext, text_t &outputtext);
   void expandstring (text_t package, const text_t &inputtext,
         text_t &outputtext, int recursiondepth = 0);
   void setconvertclass (outconvertclass *theoutc) {outc = theoutc;}
   outconvertclass *getconvertclass () {return outc;}
   ostream *setlogout (ostream *thelogout);
};

Центральный объект, который поддерживает макроязык - displayclass, определенный в lib/display, h. Его открытые функции-члены показаны на рисунке ## . Класс читает указанные макрофайлы, используя loaddefaultmacros (), сохраняя в защищенном разделе класса (не показан) тип структуры данных, показанной на рисунке ## . Для макроса также допустимо быть установленным системой поддержки выполнения, используя setmacro () (в последнем примере Раздела how_the_conceptual_framework_fits_together, pageaction устанавливает _homeextra_ как динамически сгенерированную таблицу доступных коллекций, используя эту функцию). Это поддерживается набором ассоциативных массивов, подобных используемым для представления макрофайлов (они не идентичны, потому что в первом случае не требуется уровень "параметра"). В displayclass чтение макроса из файла упоминается как default macros. Локальный макрос, указанный через setmacro (), упоминается как current macros и удаляется из памяти, как только страница была сгенерирована.

Когда страница должна быть воспроизведена, сначала вызывается openpage О, чтобы сообщить текущие параметры настройки параметров страницы (1=еп и так далее). Следом, текст и макрос потоково проходят через класс, обычно с actionclass, используя строку программы:

cout << text_t2ascii << display << "_amacro_ "
         << "_anothermacro_ ";

Результат - макрос, расширенный согласно настройкам параметров страницы. Если требуется, эти параметры настройки могут быть отчасти изменены, используя setpageparams(). Остающиеся открытые функции-члены обеспечивают поддержку более низкого уровня.

Программа регистратора

Основные объекты регистратора были описаны. Ниже мы детализируем классы поддержки, которые постоянно находятся в GSDLHOME/SRC/RECPT. Кроме того, там где главным является эффективность, когда определения встроены, подробности выполнения содержатся в пределах копии файла заголовка .срр. Файлы поддержки часто включают слово tool как часть имени файла, как в OIDtools.h nformattools.h.

Второй набор лексически определенных файлов включает префикс z3950. Файлы обеспечивают удаленный доступ к интерактивным базам данных и каталогам, которые делают их содержимое общедоступным, используя протокол Z39.50 .

Другая большая группа файлов поддержки включает термин browserclass. Это файлы, связанные через виртуальную иерархию наследования. Как группа, они поддерживают абстрактное понятие просмотра: последовательная генерация страницы документа, разделенного содержанием или метаданными. Просматривающие действия включают просмотр документов, упорядоченных в алфавитном порядке в соответствии с заголовком или хронологически по времени; развитие через заголовки, возвращенные запросом, - десять входов одновременно; доступ к отдельным страницам книги, используя механизм "go to page" (перейти к странице) . Каждое действие просмотра наследовано от базового класса browserclass:

Действия обращаются к объектам browserclass через browsetools.h.

<tblcaption table_table_2|##HIDDEN##></tblcaption>

OIDtools.h Функциональная поддержка оценки идентификаторов документа по протоколу.
action.h Базовый класс для объекта Actions , изображенного на рисунке ## .
authenaction.h Унаследованное действие для идентификации пользователя.
browserclass.h Базовый класс для резюме действия просмотра.
browsetools.h Функциональная поддержка, которая обращается к иерархии browserclass. Функциональные возможности включают расширение и заключение содержимого, вывода оглавления и создания механизма управления типа "go to page" (перейти к странице).
cgiargs.h Определяет cgiarginfo используемый на рисунке ## , при поддержке структуры данных для CGI-аргументов.
cgiutils.h Функциональная поддержка CGI-аргументов, используя структуры данных, определенные в cgiargs.h.
cgiwrapper.h Функциональная поддержка, которая делает все необходимое для вывода страницы, используя CGI-протокол. Доступ через функцию
void cgiwrapper (receptionist &recpt, text_t collection);
которая является единственной функцией, объявленной в файле заголовка. Все остальные функции - .срр копии, лексически ограниченные, чтобы быть локальными по отношению к файлу (используя ключевое слово C++ static). Если функция выполняется для специфической коллекции, тогда collection должна быть установлена, иначе это должна быть пустая строка " ". Программа включает поддержку Fast-CGI.
collectoraction.h Унаследованное действие, которое облегчает формирование коллекции конечного пользователя через Collector. Сгенерированная страница исходит из collect.dm и управляется параметром CGI -аргумента p=page.
comtypes.h Основные типы протоколов.
converter.h Объектная поддержка потоковым конвертерам.
datelistbrowserclass.h Унаследованный от browserclass, этот объект обеспечивает поддержку просмотра хронологических списков, типа виденного нами ранее в коллекции Greenstone Archives просмотра по "датам" в навигационном меню.
documentaction.h Унаследованное действие, используемое для восстановления документа или части иерархии классификации.
extlinkaction.h Унаследованное действие, которое проверяет, действительно ли пользователь идет прямо по внешней ссылке или проходит через страницу предупреждения, оповещающую пользователя о том факте, что он собирается покинуть цифровую библиотечную систему.
formattools.h Функциональная поддержка анализа и оценки конфигурации коллекции операторами/ormutf. Подробное описание в Разделе formatting.
historydb.h Структуры данных и функциональная поддержка управления базой данных предыдущих запросов, так что пользователь может запустить новый запрос, который включает предыдущие условия запроса.
hlistbrowserclass.h Унаследованный от browserclass, этот объект обеспечивает поддержку просмотра горизонтальных списков.
htmlbrowserclass.h Унаследованный от browserclass, этот объект обеспечивает поддержку просмотра страниц HTML.
htmlgen.h Функция поддержки подсветки терминов запроса в text_t строке.
htmlutils.h Функциональная поддержка, которая конвертирует text_t строку в эквивалентный HTML. Символы ", &, <, и > преобразовываются в &quot;, &атр;, < и > соответственно.
infodbclass.h Определяет два класса: gdbmclass и infodbclass. Первый обеспечивает Greenstone API к GDBM; последний - объектный класс, используемый для хранения записей элементов чтения из GDBM базы данных, а по существу - ассоциативный массив индексированных целым числом массивов text_t строк.
invbrowserclass.h Унаследованный от browserclass, этот объект обеспечивает поддержку просмотра списков, которые не предназначены для просмотра (невидимые).
nullproto.h Унаследованный от recptproto, этот класс понимает нулевой протокол, реализованный через функциональные запросы от регистратора на сервер коллекции.
pageaction.h Унаследованное действие, которое вместе с макрофайлом, названным sp=page, генерирует web-страницу.
pagedbrowserclass.h Унаследованный от browserclass, этот объект обеспечивает поддержку механизма просмотра "go to page" (перейти к странице), например, в Gutenberg коллекции.
pingaction.h Унаследованное действие, которое выясняет, отвечает ли частная коллекция.
queryaction.h Унаследованное действие, которое берет предусмотренный запрос, параметры настройки и предпочтения и исполняет поиск, генерируя в результате подмножество о=пит, соответствующее документам, начинающимся в позиции г=пит.
querytools.h Функциональная поддержка запросу.
receptionist.h Объект верхнего уровня регистратора. Поддерживает запись информации CGI-аргумента, реализацию каждого унаследованного действия, реализацию каждого унаследованного броузера, основной макроязык объекта displayclass и все возможные конвертеры.
recptconfig.h Функциональная поддержка читения сайта и основных файлов конфигурации.
recptproto.h Базовый класс для протокола.
statusaction.h Унаследованное действие, которое вместе со status.dm генерирует различные страницы администрирования.
tipaction.h Унаследованное действие, которое производит вместе с tip.dm web-страницу, содержащую совет, взятый наугад из списка подсказок, сохраненных в tip.dm.
userdb.h Структура данных и функциональная поддержка GDBM базы данных обслуживания пользователей: их пароли, группы и так далее.
usersaction.h Действия администратора, наследуемые базовым классом, который поддерживает добавление и удаление пользователей, а также изменение групп, в которых они находятся.
vlistbrowserclass.h Унаследованный от browserclass, этот объект обеспечивает поддержку просмотра для вертикальных списков, основы классификаторов. Например, дочерние записи узла для заголовков, начинающихся с символа N предусмотрены в VList.
z3950cfg.h Структура данных, поддерживающая протокол Z39.50. Используемый z3950proto. cpp, который определяет основной класс протокола (унаследованный от базового класса recptproto) и синтаксический анализатор файла конфигурации zparse.y (письменное использование YACC).
z3950proto.h Унаследованный от recptproto, этот класс реализует протокол Z39.50 так, чтобы регистратор Greenstone мог обратиться к отдаленным библиотечным сайтам, работающим на серверах Z39.50.
z3950server.h Дополнительная поддержка для протокола Z39.50.

Инициализация

Инициализация в Greenstone - сложная операция, которая обрабатывает файлы конфигурации и присваивает полям данных значения по умолчанию . В дополнение к наследованию и функциям конструктора, основные объекты определяют функции init () и conflgure(), чтобы помочь стандартизовать задачу. Даже в этом случае порядок выполнения может быть затруднен. Настоящий раздел описывает как все это происходит.

Greenstone использует несколько файлов конфигурации для различных целей, но все они используют один и тот же синтаксис. Если строка не начинается с хэш-символа (#) или состоит полностью из пустого пространства, первое слово определяет ключевое слово, а остающиеся слова представляют установку частности для того ключевого слова.

Строки файлов конфигурации передают, по одному, для conflgure() два параметра: ключевое слово и массив остающихся слов. Основанная на ключевом слове, специфическая версия выбора configure() решает, представляет ли информация интерес, и если это так то сохраняет ее. Например, collectserver (который показан на рисунке ## ), обрабатывает операторы задания формата в файле конфигурации коллекции. Когда формат ключевого слова передают configure(), оператор if запускает сохраненную в объекте копию второго аргумента функции.

После обработки ключевого слова и прежде, чем функция закончит выполнение, некоторые версии conflgure() передают данные функции configure() в других объектах. Объект Receptionist (регистратор) вызывает выбор configureQ для Actions , Protocols и Browsers. Объект NullProtocol вызывает conflgure() для каждого объекта Collection; Collection вызывает Filters и Sources.

В C++ поля данных обычно инициализируются функцией конструктора объекта. Однако, в Greenstone некоторая инициализация зависит от чтения значений из файлов конфигурации, так что необходим второй раунд инициализации. Это - цель init () функции-члена, в некоторых случаях она ведет к последующему вызову conflgure().

Array

28: Инициализация Greenstone, с использованием, нуль-протокола

============
Main program
============
Statically construct Receptionist
Statically construct NullProtocol
Establish the value for 'gsdlhome' by reading gsdlsite.cfg
Foreach directory in GSDLHOME/collect that isn't "modelcol":
   Add directory name (now treated as collection name) to NullProtocol:
       Dynamically construct Collection
       Dynamically construct Gdbm class
       Dynamically construct the Null Filter
       Dynamically construct the Browse Filter
       Dynamically construct MgSearch
       Dynamically construct the QueryFilter
       Dynamically construct the MgGdbmSource
       Configure Collection with 'collection'
           Passing 'collection' value on to Filters and Sources:
       Configure Receptionist with 'collectinfo':
           Passing 'collectinfo' value on to Actions, Protocols, and Browsers:
Add NullProtocol to Receptionist
Add in UTF-8 converter
Add in GB converter
Add in Arabic converter
Foreach Action:
   Statically construct Action
   Add Action to Receptionist
Foreach Browsers:
   Statically construct Browser
   Add Browser to Receptionist
Call function cgiwrapper:
   =================
   Configure objects
   =================
   Configure Receptionist with 'collection'
       Passing 'collection' value on to Actions, Protocols, and Browsers:
       NullProtocol not interested in 'collection'
   Configure Receptionist with 'httpimg'
       Passing 'httpimg' value on to Actions, Protocols, and Browsers:
       NullProtocol passing 'httpimg' on to Collection
       Passing 'httpimg' value on to Filters and Sources:
   Configure Receptionist with 'gwcgi'
       Passing 'gwcgi' value on to Actions, Protocols, and Browsers:
       NullProtocol passing 'gwcgi' on to Collection
           Passing 'gwcgi' value on to Filters and Sources:
   Reading in site configuration file gsdlsite.cfg
       Configure Recptionist with 'gsdlhome'
           Passing 'gsdlhome' value on to Actions, Protocols, and Browsers:
           NullProtocol passing 'gsdlhome' on to Collection
               Passing 'gsdlhome' value on to Filters and Sources:
       Configure Recptionist with ...
       ... and so on for all entries in gsdlsite.cfg
   Reading in main configuration file main.cfg
       Confiugre Recptionist with ...
       ... and so on for all entries in main.cfg
   ====================
   Initialising objects
   ====================
   Initialise the Receptionist
       Configure Receptionist with 'collectdir'
           Passing 'collectdir' value on to Actions, Protocols, and Browsers:
           NullProtocol not interested in 'collectdir'
       Read in Macro files
       Foreach Actions
           Initialise Action
       Foreach Protocol
           Initialise Protocol
           When Protocol==NullProtocol:
               Foreach Collection
                   Reading Collection's build.cfg
                   Reading Collection's collect.cfg
                       Configure Collection with 'creator'
                           Passing 'creator' value on to Filters and Sources:
                       Configure Collection with 'maintainer'
                           Passing 'maintainer' value on to Filters and Sources:
                       ... and so on for all entries in collect.cfg
       Foreach Browsers
           Initialise Browser
   =============
   Generate page
   =============
   Parse CGI arguments
   Execute designated Action to produce page
End.

На рисуноке ## показаны диагностические инструкции, сгенерированные Greenstone, увеличенные так, чтобы выделить процесс инициализации. Программа начинается с функции main() в recpt/librarymain.cpp. Она создает объект Receptionist и объект NullProtocol, затем просматривает gsdlsite.cfg (расположенный в том же самом каталоге, что и выполняемая программа library) для gsdlhome и сохраняет его значение в переменной.

Далее mainQ добавляет объект NullProtocol к Receptionist (Регистратору), который сохраняет массив протоколов базового класса в защищенном поле данных, а затем устанавливает несколько конвертеров. main() создает все Actions и Browsers, используемые в выполняемой программе, и добавляет их к Регистратору. В завершение функция вызывает cgiwrapper () в cgiwrapper.cpp, который непосредственно включает существенную объектную инициализацию.

Существуют три этапа cgiwrapper(): конфигурация, инициализация и генерация страницы. Сначала производятся аппаратные запросы conflgure(). Затем читается gsdlsite.cfg и вызывается configure() для каждой строки. То же самое производится для etc/main.cfg.

Второй этап cgiwrapper () делает запросы к init (). Регистратор делает только один запрос к своей функции init (), но действием вызова запускает функции init () в различных объектах, сохраненных в его пределах. Сначала производится аппаратный запрос conflgure(), чтобы установить collectdir, после чего читаются макрофайлы. Для каждого действия вызывают его init () функцию. То же самое происходит для каждого протокола, сохраненного в регистраторе, но в описываемой системе сохранен только один протокол - NullProtocol. Запрос init () для этого объекта вызывает дальнейшую конфигурацию: для каждой коллекции в NullProtocol читаются и обрабатываются определенные коллекцией build.cfg и collect.cfg, с запросом configure() для каждой строки.

На заключительном этапе cgiwrapper () должен проанализировать CGI -аргументы и затем вызвать соответствующее действие. Оба этих запроса производятся при поддержке объекта Receptionist.

Причина для разделения конфигурации, инициализации и программы генерации страницы состоит в том, что Greenstone оптимизирован для работы в качестве сервера (используя Fast-cgi, или протокол Corba, или Windows Local Library). В этом режиме работы конфигурация и программа инициализации запускаются однажды, программа остается в памяти и генерирует множество web-страниц в ответ на запросы от клиентов, не требуя переустановки.

1) начение для gsdlhome исходит из gsdlsite.cfg, расположенного в том же самом каталоге, что и CGI-выполняемая library, тогда как GSDLHOME устанавливается запуском скрипта setup, который обращается к другому файлу, так как технически это возможно для двух различных значений. Хотя это и возможно, но все же не желательно, и все вышесказанное написано в предположении, что файлы те же самые.

Navigation
Toolbox