Электронный магазин на Java и XML

       

Класс Interpreter


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

Статические методы и инструкции импорта для класса Interpreter показаны в листинге 7.9. Константы QMC и QMCM означают два допустимых в нашей версии типа вопросов: QMC — вопрос, допускающий выбор одного ответа из списка, а QMCM — вопрос, допускающий выбор нескольких ответов из списка. Рассмотрим в качестве примера код XML для вопроса о музыкальных предпочтениях, приведенный в листинге 7.8.

Листинг 7.8. Начало блока вопросов в документе XML (customersurvey.xml)

<Block name="cds" type="terminal" > <Ques type="QMCM" id="palm:1"> <Qtext>Please select all of the categories of CD that you would like to see in our catalog </Qtext> <Qopt val="0">Classical music</Qopt> <Qopt val="1">Country and Western</Qopt> <Qopt val="2">The latest Pop Groups</Qopt> <Qopt val="3">Current Rock</Qopt> <Qopt val="4">Golden Oldies Rock</Qopt> <Qopt val="5">Environmental</Qopt> <Qopt val="6">Novelty and Humor</Qopt> </Ques>

Открывающий тег Ques использует атрибут type для задания типа вопросов, в данном случае QMCM. Атрибут id является уникальным идентификатором этого вопроса.

Вместо того чтобы сравнивать строку, являющуюся значением атрибута type, с возможными типами вопросов, мы используем хэш-таблицу Hashtable и отыскиваем в ней целочисленное значение типа int, которое можно использовать в инструкции switch для выбора нужного способа представления вопроса. Эта хэш-таблица называется typeHash, а поиск в ней осуществляется с помощью метода 1 ookUpType, показанного в листинге 7.9.


Для добавления нового типа вы просто должны будете определить новую строку String и целочисленную константу типа int в качестве статических переменных класса Interpreter и в хэш-таблице typeHash.

Листинг 7.9. Константы и инструкции импорта в начале исходного кода класса Interpreter (Interpreter.java)

package com.XmlEcomBook.Chap07; // import org.w3c.dom.* ; import com.sun.xml.tree.* ; import java.io.*; import java.util.* ; import javax.servlet.*; import javax.servlet.http.*;

public class Interpreter { static final String brcrlf = "<br>\r\n"; static final int QMC = 1 ; static final int QMCM = 2 ;

static Hashtable typeHash = new Hashtable(); static { // static initialization block typeHash.put("QMC", new Integer( QMC )); typeHash.put("QMCM", new Integer( QMCM )); }



static int lookUpType( String type ){ Integer N = (Integer)typeHash.get( type ); if( N == null ) return 0 ; return N.intValue(); }

В листинге 7.10 приводятся переменные экземпляра и конструктор класса Interpreter. Для каждого сеанса работы пользователя создается экземпляр класса Interpreter, в котором хранится сам документ и отмечается текущая позиция пользователя в процессе его «продвижения» по анкете. Переменные nowBlock и nowNode являются ссылками на объекты, реализующие интерфейс org.w3c.dom.Node.



Листинг 7.10. Переменные экземпляра и конструктор класса Interpreter (Interpreter.java)

// instance variables below this Document theDom ; Node nowBlock, nowNode ; // nowNode should be quest type boolean terminal = false ; // true if the block is terminal String title ; String css = "" ; // may change from block to block String actionStr ;

NodeList blockNodeList ; // Nodes that are <Block type // the constructor public Interpreter( Document doc, String handler ){ theDom = doc ; actionStr = handler ; Element E = theDom.getDocumentElement(); // the root blockNodeList = E.getElementsByTagName("Block"); // note that in contrast to other get methods, getAttributes // returns "" if the attribute does not exist title = E.getAttribute("title"); css = E.getAttribute("css"); // used for <Intro> }



Для того чтобы обеспечить некоторую гибкость в форматировании вопросов, предусмотрена возможность задавать каскадную таблицу стилей для всего документа и заменять определенный по умолчанию стиль для каждого блока. Метод writeHead, показанный в листинге 7.11, управляет выводом начала HTML-страницы и включает в себя ссылку на таблицу стилей, если она применяется. В этом листинге также показаны методы startForm и endForm. Заметим, что переменная quesid записывается в форму как скрытая переменная, которая впоследствии извлекается в методе doPostQ (листинг 7.16).



Листинг 7.11. Методы для создания различных частей HTML-страницы (Interpreter.java)

void writeHead( PrintWriter out ){ out.println("<html>"); out.println("<head><title>" + title + "</title></head>"); if( css.length() > 0 ){ out.println("<link href=\"" + css + "\" type=\"text/css\" rel=\"stylesheet\">" ); } out.println("<body>"); }

// assumes nowNOde is set to the first question // output form start and question text public void startForm(PrintWriter out ){ out.print("<form method=\"POST\" action=\"" ); out.print( actionStr ); out.println("\" >"); }

// fills in hidden variable and button public void endForm( PrintWriter out, String id ){ out.print("<input type=\"hidden\" name=\"quesid\" value=\"" + id + "\" ><br>" ); out.print("<input type=\"submit\" value=\"" ); out.print("Next" ); out.println("\" name=\"action\" ><br>"); out.println("</form><br>"); }

 




Содержание раздела