И наконец последний значимый тэг <input>, в отличии от первого тэга <input> у этого тэга параметр тип(type) равен “submit” - это значит что это кнопка отправки запроса обработчику который указан в тэге <form>. У кнопки тоже есть имя (name) и значение (value) кнопка называется Start. Последним тэгом, всегда является закрывающий тэг </form>.
После того как пользователь ввел запрос и нажал на кнопку “Поиск” в адресная строка браузера приобретет примерно вид :
http://localhost/serv/SearchEngein?Query=%E1%A8%E1%E2%A5%AC%A0&select=MARCFILE.Stat&Start=%8F%AE%A8%E1%AA
К ссылке на сервлет прибавилось три параметра отделенные от адреса сервлета вопросительным знаком первый параметр это Query (запрос), второй select говорящий сервлету в какой базе производить поиск.
Первое что делает программа - это считывает файл настройки db.ini – который находится в папке c:\www\db. В данном файле находятся данные о место нахождении интересующей базы данных или говоря проще локальный путь к базе данных. Определив интересующую базу данных и установив ее место нахождения, программа начинает процесс поиска всех удовлетворяющих запросу данных (библиографических описаний).
Программа считывает всю запись в массив, после чего начинается определение места нахождения полей и их длинны. Разберем код процедуры.
public void dbFileRead(String dbNamePath, PrintStream out, String query) {
Сперва производится инициализация всех переменных используемых при работе процедуры.
Первый блок. Переменные для занесения значений полей
String mAvtor = null; // 100
String msAvtor = null; // 700
String mName = null; // 245
String mPrinter = null; // 260
String mSize = null; // 300
String mKey = null; // 653
String mSeria = null; // 490
String mRubrika = null; // 650
String mBBK = null; // 91
String mKaIndex = null; // 90
Второй блок. Файловые переменные для перемещения по файлу
long fPosMarker = 0, // Позиция относительно начала
fPosData = 0; // Начальная позиция данных
boolean done = false;
Третий блок. Перемнный для работы с данными
int mC =0, // Счетчик прочитанных записей
mE =0; // Счетчик найденых соответствий
byte Jumper[] = new byte[5]; // Размер запяси - символьный
int JIndex = 0, // Размер запяси - числовой
JTemp = 0, // Размер данных + словарь
MIndex = 0, // Счетчик для массива
MTemp = 0; // Счетчик полей
Начало выполнени поика. Сперва проверяется имеет ли запрос query занчение неравное пусто, если условие выполняется и запрос имеет не нуливое занчение устанавливается связь с файлом данных. Начальная позиция чтения равна нулю.
if (query != null){
try { RandomAccessFile dbfile = new RandomAccessFile(dbNamePath,"r");
// Цикл чтения файла по маркерам
while (fPosMarker != dbfile.length()) {
try { mC++;
dbfile.seek(fPosMarker);
dbfile.read(Jumper);
String jBuf = new String(Jumper);
JIndex = Integer.parseInt(jBuf,10);
int b = 0;
Прочитав начальный блок из 5 символов говорящий о длине записи он преобразуется из символьного значенья в числовое. Затем определяется длинная словаря которая равна 12*n, где n – равно количеству заполненных полей в одной записи.
// Поиск конца словаря
while ( b != MD){
dbfile.seek(fPosMarker+24+MIndex);
b = dbfile.read();
MTemp++;
MIndex = MTemp;
}
MTemp= MTemp - 1;
Определив конечную позицию словаря производится считывание в массив блока состоящего из данных - метка поля; начальная позиция поля, относительно конца словаря; длинная поля и символах.
// чтение Словаря из файла в отдельный массив
byte Dic[] = new byte[MTemp];
dbfile.seek(fPosMarker+24);
dbfile.read(Dic);
// чтение полей данных из файла в массив
fPosData = fPosMarker+24+MTemp;
String sDic = new String(Dic);
int DI2 = 0,
DI3 = 0,
DI4 = 0,
DI5 = 0,
PNum = 0, // Номер поля числовой
PLength = 0, // Длинна поля числовая
PStart = 0; // Начальная позиция поля чиловая
Получив данные в результате преобразований, это строка, начинается последовательное вычитание метки поля, начальной позиции, размера поля.
// сканирование номеров полей
while ( DI2 != MTemp){
DI3=DI2+3;
String DStr = sDic.substring(DI2,DI3);// Номер поля
DI4=DI3+5;
String DStr2 = sDic.substring(DI3,DI4);// Начальная позиция
DI5=DI4+4;
String DStr3 = sDic.substring(DI4,DI5);// Длинна поля
DI2=DI2+12;
PLength = Integer.parseInt(DStr3,10);// Узнаем длинну поля
PStart = Integer.parseInt(DStr2,10);// Узнаем начало поля
PNum = Integer.parseInt(DStr,10);// Код
byte Pole[] = new byte[PLength];
Как только первая запись о первом поле разобрана на составляющие проверяется его метка , которая говорить относится или нет, поле к тому списку полей который нас интересует. Если да то производится считывание его из файла. После того как поле считано над значением поля производится ряд преобразований, таких как, вычитание из поля служебной информации относящейся к формату MARC.
// Чтение поля из файла
switch (PNum) {
case 100 : {
dbfile.seek(fPosData+PStart);
dbfile.read(Pole);
String Pol = new String(Pole);
if (Pol == null) Pol=" ";
mAvtor = TagRemove(Pol.substring(5));break;}
case 700 : {
dbfile.seek(fPosData+PStart);
dbfile.read(Pole);
String Pol = new String(Pole);
if (Pol == null) Pol=" ";
msAvtor = TagRemove(Pol.substring(5));break;}
case 245 : {
dbfile.seek(fPosData+PStart);
dbfile.read(Pole);
String Pol = new String(Pole);
if (Pol == null) Pol=" ";
mName = TagRemove(Pol.substring(5));break;}
case 490 : {
dbfile.seek(fPosData+PStart);
dbfile.read(Pole);
String Pol = new String(Pole);
if (Pol == null) Pol=" ";
mSeria = TagRemove(Pol.substring(5));break;}
case 91 : {
dbfile.seek(fPosData+PStart);
dbfile.read(Pole);
String Pol = new String(Pole);
if (Pol == null) Pol=" ";
mBBK = TagRemove(Pol.substring(5));break;}
case 90 : {
dbfile.seek(fPosData+PStart);
dbfile.read(Pole);
String Pol = new String(Pole);
if (Pol == null) Pol=" ";
mKaIndex = TagRemove(Pol.substring(5));break;}
case 260 : {
dbfile.seek(fPosData+PStart);
dbfile.read(Pole);
String Pol = new String(Pole);
if (Pol == null) Pol=" ";
mPrinter = TagRemove(Pol.substring(5));break;}
case 300 : {
dbfile.seek(fPosData+PStart);
dbfile.read(Pole);
String Pol = new String(Pole);
if (Pol == null) Pol=" ";
mSize = TagRemove(Pol.substring(5));break;}
case 653 : {
dbfile.seek(fPosData+PStart);
dbfile.read(Pole);
String Pol = new String(Pole);
if (Pol == null) Pol=" ";
mKey = TagRemove(Pol.substring(5));break;}
default : {}
}// switch
}// конец проверки полей
Получив все данные которые нас интересовали, создается запись состоящая из нескольких полей.
if ( mAvtor == null) mAvtor=" ";
if ( msAvtor == null) msAvtor=" ";
if ( mName == null) mName=" ";
if ( mPrinter == null) mPrinter=" ";
if ( mSize == null) mSize=" ";
if ( mKey == null) mKey=" ";
if ( mKaIndex == null) mKaIndex=" ";
if ( mBBK == null) mBBK=" ";
if ( mSeria == null) mSeria=" ";
Это собственно самая запись
MarcRecord Rec = new MarcRecord( mAvtor,
msAvtor,
mName,
mPrinter,
mSize,
mKey,
mSeria,
mBBK,
mKaIndex);
Данные которые занесены в запись теперь осуществляется сравнивание их с запросом. Сравнение осуществляется после преобразование к одному регистру, это нужно для того чтобы найти полный список всех имеющихся записей относящихся к веденному запросу.
String q = toLow(query);
String p01 = toLow(Rec.rAvtor);
String p02 = toLow(Rec.rsAvtor);
String p03 = toLow(Rec.rName);
String p04 = toLow(Rec.rKey);
Затем распознанные данные сравниваются с запросом, сравнивание производится только с несколькими полями. Список полей приведен ниже:
100 – Автор
700 – Второй автор
245 – Название произведения
653 – Ключевые слова
if ( p01.indexOf(q) != -1 ||
p02.indexOf(q) != -1 ||
p03.indexOf(q) != -1 ||
p04.indexOf(q) != -1)
{ mE++;
При совпадении запись сразу же отправляется браузеру для отображения в читабельной для пользователя форме.
out.println("<table width=\"461\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">"+
"<tr bgcolor=\"#3399FF\">"+
"<td colspan=\"3\" class=\"text\"> Автор: "+
"<font color=\"#000000\">"+
Rec.rAvtor+" "+
Rec.rsAvtor+
"</font></td></tr><tr>"+
"<td colspan=\"3\" valign=\"top\" class=\"bodytext\">"+mE+". "+mC+
" <b>Название:</b> "+
Rec.rName+"<br>"+
Rec.rPrinter+" "+
Rec.rSize+"<br>"+
Rec.rBBK+" "+
Rec.rKaIndex+" "+
Rec.rSeria+
"</td></tr></table>");
}
В конце обработки одной записи независимо соответствовала она запросу или нет производится переход к следующей записи.