Проектирование и разработка информационно-поисковой системы
Содержание
1. Введение
Постановка задачи
Обзор возможных решений
Используемые инструменты и технологии
Проектирование базы данных
Проектирование бизнес-логики
Разработка системы
Разработка с использованием Spring MVC
The DispatcherServlet
Конфигурация приложения
Определение контроллера
Представления
Создание формы
Создание структуры проекта
Подключение сервера приложений Glassfish
Контроллер и представление
Вывод
2. Разработка системы с использованием технологий Spring web flow,
jsf
Проектирование пакетов
Разработка на Spring Web Flow
Получение информации
Вывод данных в представление
Пользовательский интерфейс
Вывод
Заключение
Список использованной литературы
Приложения
1.
Введение
Данная работа посвящена изучению технологий веб
программирования на java и созданию информационно-поисковой системы для хранения
слабоструктурированных данных для некоторого предприятия.
Данное предприятие занимается средствами массовой информации,
соответственно им необходимо хранить большие архивы информации, такие как
видео, радио, журналы и выпуски в различных форматах. Исторически все архивы
сохраняются вручную, и поиск по таким архивам так же осуществляется вручную.
Однако такой подход несет в себе много лишней ручной работы по сохранению,
редактированию и поиску.
Наиболее подходящим решением для данной задачи является web-приложение, которое
будет оперировать всеми данными с помощью базы данных и web-браузера в качестве
клиента пользователя.
Для реализации такой системы был выбран язык программирования
java, основные преимущества
которого: высокая скорость разработки и распространенность.
Постановка
задачи
Исходные условия: есть архивы информации в различных
форматах. Необходимо осуществить редактирование, добавление информации и поиск
по архивам данных.
Исходные данные: журналы в формате doc, выпуски в формате docx, видео в формате avi, звуковые файлы в
формате wav.
Так как у исходных данных нет строгой структуры, и эти
форматы не соответствуют строгой структуре таблиц и отношений в моделях
реляционных баз данных, нельзя использовать алгоритмы поиска структурированных
данных. В данной задаче вся информация будет располагаться на сетевом хранилище
NAS (Network Attached Storage), а вся метаинформация о
каждом файле будет находиться в базе данных. Благодаря такому подходу становится
возможным оперирование данными, хранящимися в различных форматах без четкой
структуры.
Для этих целей необходимо спроектировать и реализовать
информационную систему, отвечающая следующим требованиям:
· Функциональные
o Возможность добавлять
новую информацию в архив
o Возможность
редактирования существующей информации
§ Переименование
§ Изменение метаданных
o Осуществление
поиска по метаданным
o Отображение
данных
o Понятный
интерфейс для пользователей
· Инструментальные
o Реализации на
платформе java с использованием фреймворков Spring web flow, prime-faces,
spring web mvc.
o Использование Spring security для аутентификации и
обеспечения безопасности данных.
o Использование
сервера приложений Glassfish
o Использование
в качестве СУБД - Mysql
Обзор возможных
решений
Решить поставленную задачу можно следующими способами:
. Использование стандартного подхода Java2EE к созданию web-приложений с помощью EJB
(Enterprise Java Beans).
Плюсы: наличие открытой спецификации, полная интеграция
с другими технологиями Java, быстрый цикл разработки.
Минусы: сложность изучения, сложность архитектуры,
возможность неоправданного усложнения приложения.
2. Использование популярного фреймворка
Spring
Плюсы: Он работает в таких областях, где практически не
возможно использовать другие популярные фреймворки. Главная цель Spring это предоставить способ
управлять бизнес-объектами
Многослойная архитектура Spring позволяет использовать
любую свою часть отдельно от другой, несмотря на это его внутренняя архитектура
согласована.
2.1 Использование стандартного Spring mvc
Плюсы: скорость обучения,
скорость разработки
Минусы: сложность написания сложного приложения без
подключения дополнительных фреймворков
2.2 Использование технологии Spring web flow,
prime-faces, spring web mvc
Плюсы: Возможность решить любые задачи бизнес логики,
возможность использования JSF (JavaServer Faces).
JSF основывается на компонентном использовании, в
отличии от других MVC-фреймворков, которые управляются запросами.
Минусы: сложность обучения.
В данной работе я рассмотрю 2 варианта разработки
такой системы.
. С использованием стандартного Spring mvc
2. С использованием технологий Spring web flow, spring web mvc, jsf.
И наиболее оптимальный вариант будет использоваться в
реализации поисковой системы.
Используемые
инструменты и технологии
Для проектирования и разработки информационно-поисковой
системы используются следующие инструменты:
1. Intellij idea - IDE для разработки
приложений на Java.
2. Apache Glassfish - сервер приложений.
. Mysql - СУБД для хранения данных системы.
4. Mysql workbench - утилита для
проектирования базы данных.
5. Visual Use case - утилита для
проектирования системы.
Используемые языки:
. Java - объектно-ориентированный язык
программирования.
2. HTML (HyperText Markup Language) - язык гипертекстовой
разметки документов, используемый во Всемирной паутине (WWW).
3. CSS (Cascade Style Sheet) - язык для описания
внешнего стиля документа.
4. JavaScript - прототипно-ориентированный сценарный язык программирования, используемый на стороне клиента
веб-приложения.
Проектирование
базы данных
Для визуального проектирования базы данных была взята утилита
Mysql Workbench.
MySQL Workbench упрощает разработку и обслуживание баз
данных, позволяет автоматизировать отнимающих много времени и подверженных
ошибкам задач, а также улучшает коммуникацию между DBA (Администратор базы
данных) и разработчиков команд. Это позволяет архитекторам данных
визуализировать требования, общаться с заинтересованными сторонами, и решать
вопросы проектирования. Она позволяет на основе моделей проектировать базы
данных, которые являются наиболее эффективной методикой для создания
достоверных и быстрых баз данных, обеспечивая при этом гибкость для
удовлетворения меняющихся потребностей бизнеса. Модель и схема валидации данных
обеспечивает соблюдение всех стандартов для моделирования данных, а также
обеспечивает соблюдение всех MySQL стандартов физического проектирования, что
исключает возникновение ошибок при создании новых диаграмм ER или формирования
физических баз данных MySQL.
Для визуализации проектирования базы данных используем ER - диаграмму (Рис. 1):
информационная поисковая система программирование
Рис. 1. ER-диаграмма
Сущности представляются в виде прямоугольников, у которых: в
верхней части указано имя сущности, в нижней - атрибуты. Символы на концах
связей обозначают модальность связи: "один-к-одному",
"многие-ко-многим", "один-ко-многим".
При построении ER диаграммы была учтена 3 нормальная форма
отношений в реляционной базе данных.
Проектирование
бизнес-логики
Для проектирования системы была использована программа Visual Use Cases, которая позволяет
строить user stories, use cases и диаграммы, так же есть возможность работать в
команде (Рис. 2).
Рис. 2. Интерфейс программы Visual Use Case
Благодаря данной программе можно создать необходимые на начальном
этапе диаграммы и пользовательские истории, а после реализации
"скелета" добавить весь дополнительный функционал с помощью историй,
которые внесут заказчики.
Первым этапом проектирования бизнес-логики является написание
пользовательских историй, которые в последствии будут перенесены в Use case, а
затем по ним будет составлена диаграмма вариантов использования (use case).
Для реализации "скелета" необходимо реализовать следующие сценарии
использования (use case):
1. Регистрация
2. Загрузка информации в базу
. Доступ к ресурсам
. Поиск материала по базе
. Чат
6. Форма для подачи заявки на мониторинг
. Оплата за предоставленные услуги (мониторинг)
8. Расширение аккаунта до PRO версии
По данным сценариям необходимо создать диаграмму вариантов
использования (Рис. 3).
Рис. 3. Диаграмма вариантов использования (use case)
Данная диаграмма отображает возможные варианты использования
информационной системы, их требования и последовательность возникновения,
которые они реализуют. Связь extend
обозначает расширение возможностей базового класса.
Разработка
системы
Чтобы сравнить 2 варианта разработки и определить наилучший,
будет реализовано 2 приложения, использующие разные наборы фреймворков. Форма
для добавления pdf файлов в базу данных и главная система с поиском
слабо-структурированных данных.
Разработка с
использованием Spring MVC
MVC Framework Spring Web обеспечивает архитектуру
представление-модель - контроллер и готовые компоненты, которые могут быть
использованы для разработки гибких и слабо связанных веб-приложений. Шаблон MVC приводит к разделению
различных аспектов применения (входная логика, бизнес-логика), обеспечивая при
этом слабую связь между этими элементами.
Model инкапсулирует данные приложения, которые будут
состоять из POJO (Plain Old Java Object).
View отвечает за предоставление данных модели, в
целом он генерирует вывод HTML, который может интерпретировать браузер клиента.
Controller отвечает за обработку запросов пользователей и
построения соответствующей модели и передает его в представление для
рендеринга.
The
DispatcherServlet
Spring Web model-view-controller работает с
помощью DispatcherServlet, который обрабатывает все HTTP-запросы и HTTP-ответы. Обработка
запроса рабочего процесса в Spring Web MVC DispatcherServlet показана на следующей
диаграмме (Рис. 4):
Рис. 4. DispatcherServlet
Ниже приводится последовательность событий для входящего запроса HTTP к DispatcherServlet:
· После получения HTTP запроса DispatcherServlet вызывает соответствующий
контроллер с помощью HandlerMapping.
· Контроллер принимает запрос и вызывает
соответствующие методы сервисов на основе используемого метода GET или POST. Метод сервиса
устанавливает данные модели, основанные на определенной бизнес-логике и
возвращает имя представления в DispatcherServlet.
· DispatcherServlet с помощью ViewResolver обрабатывает
определенное представление в зависимости от метода запроса.
· После того как просмотр завершен, DispatcherServlet передает данные модели
представления, которая, наконец, отображает его в браузере.
Все указанные выше компоненты, т.е. HandlerMapping, Controller и ViewResolver являются частями WebApplicationContext, которая является
продолжением обычной ApplicationContext с некоторыми дополнительными функциями,
необходимыми для веб-приложений.
Конфигурация
приложения
Сперва нам необходимо отобразить запросы, которые должен
обрабатывать DispatcherServlet, используя отображение URL в файле web. xml (Рис.5).
Рис. 5. Настройка web. Xml
При инициализации appServlet DispatcherServlet фреймворк будет пытаться загрузить
контекст приложения из файла с именем [имя сервлета] - servlet. xml, который
находится в каталоге webapp / WEB-INF приложения. В этом случае наш файл будет servlet-context. xml (Рис.6).
Рис. 6. Servlet-context. xml
Далее тег <servlet-mapping> указывает на URL-адреса, которые будут обрабатываться посредством DispatcherServlet. Здесь все запросы HTTP, будут обрабатываться appServlet DispatcherServlet.
Конфигурация servlet-context. xml будет использоваться для создания beans, перекрывая любые другие beans, определенных глобально с тем же именем.
Тег <context: component-scan>
будет использоваться для активации Spring MVC аннотаций, которая позволяет использовать
сканирование с помощью аннотаций @Controller
и @RequestMapping и т.д.
InternalResourceViewResolver это определенные правила для разрешения
имен представлений. В соответствии с определенным выше правилом логическое
представление с именем "hello"
свяжется с реализацией, расположенной по адресу /WEB-INF/views/hello. jsp.
Определение
контроллера
Рис. 7. Определение контроллера
DispatcherServlet отдает запрос на контроллеры для
выполнения функциональной логики (Рис.7). Аннотация @Controller указывает на то, что конкретный класс играет роль
контроллера. Аннотация @RequestMapping
используется для отображения URL, либо целого
класса или конкретного метода обработчика.
Здесь первое использование @RequestMapping указывает на то, что все запросы будут
поступать в этот контроллер для обработки. Следующая аннотация @RequestMapping (method = RequestMethod. GET) используется для объявления метода запроса. По умолчанию контроллер
обрабатывает HTTP GET запрос.
Внутри этого метода мы определяем бизнес логику приложения. Метод
может возвращать строку, которая содержит имя представления, которое будет
использоваться для визуализации модели. Этот пример возвращает "login" в качестве имени логического
представления, и внутрь представления передается объект kantarXmlForm, который будет отображен представлением.
Представления
Spring MVC поддерживает множество типов представлений для
различных технологий. К ним относятся - JSP-страницы, HTML, PDF, электронные таблицы Excel, XML, шаблоны Velocity, XSLT, JSON, RSS-каналы, JasperReports и т.д. Но чаще всего
используются шаблоны JSP, написанных с JSTL.
Создание
формы
Для создания конфигурации приложения в Spring можно использовать несколько
способов, но основной и самый популярный - вынесение конфигурации в xml-файлы.
Такой способ используется в фреймворке Spring с первого релиза. Позже,
в Java 5 были введены
аннотации, которые так же позволяют настраивать фреймворк (с версии 2.5).
В данной работе мы будем использовать наиболее удобный XML-стиль.
Используемые инструменты
· Intellij Idea
15.0.5,Java SDK 1.5,Apache Glassfish 4.1.0,Maven.
Создание
структуры проекта
Подключение
Maven
Для начала нам надо подключить maven, создать файл pom. xml и прописать в нем все
необходимые зависимости для того, чтобы подключить используемые библиотеки. Все
библиотеки располагаются в центральном репозитории maven, что избавляет нас от
нужны каждый раз вручную подключать все библиотеки к проекту (Рис.8). В pom файле мы так же
прописываем используемую версию java и название проекта, которое будет деплоиться на
сервер приложений Glassfish. На данном этапе нам необходимы только 2 зависимости, а
именно spring-context и spring-webmvc.
Рис. 8. Подключение библиотек в файле pom. xml
Конфигурация
приложения
Далее нам необходимо настроить наше приложение, а именно
прописать настройки DispatcherServlet в файлах конфигурации web. xml и указать в servlet-context. xml, где будут находится
наши ресурсы, а также задать бину InternalResourceViewResolver расположение и тип
нашего представления.
Подключение
сервера приложений Glassfish
В inteliij idea Glassfish подключается довольно просто: необходимо
указать локальный адрес (порт по умолчанию 8080), используемый domain, а также заранее
подготовленный maven’ом war артефакт, который и будет деплоиться на сервер (Рис. 9).
Рис. 9. Настройка Glassfish
Контроллер и
представление
Так как наше приложение будет генерировать xml файл, на основе
введенных данных пользователем, нам потребуется 2 контроллера. Первый
контроллер послужит для отображения самой формы и передаче данных между
представлениями и контроллерами.
. Любой http запрос попадает в 1 контроллер, благодаря
аннотации @RequestMapping (value = "/", method = RequestMethod. GET), которая ловит все запросы начальной страницы.
Далее выводится представление login, где отображается сама форма. На вход она
принимает List<KantarXml>, где KantarXml - класс содержащий все поля, необходимого xml файла.
2. Благодаря Jsp namespace "form" мы можем
однозначно отобразить наш массив объектов с помощью размножения полей формы, а
для заполнения таких форм нам не обойтись без цикла. Естественно, стандартный
путь, где страница собирается вручную с помощью html тегов нам не подходит,
так как у нас динамическое количество объектов в массиве. В namesapce "#"897033.files/image010.jpg">
Рис. 10. До размножения полей
Рис. 11. После размножения полей
Вывод
В этом варианте я рассмотрел принципы Java spring mvc, изучил основные
принципы работы с jsp под управлением spring контроллеров. Так же была написана динамическая
форма для генерации xml файлов на основе введенных пользователем данных. Конечно,
возникает множество трудностей при использовании jsp, связанных с передачей
информации в представление, а так же сложность разбиения большой системы на
потоки.
Можно сделать вывод, что такой вариант не подходит для
написания информационно-поисковой системы, так как существует множество
ограничений связанных с бизнес логикой и выводом информации в пользовательском
интерфейсе.
2. Разработка
системы с использованием технологий Spring web flow, jsf
Проектирование
пакетов
Для построения такой системы сначала необходимо разбить ее на
небольшие подсистемы, которые будут отвечать за некоторую задачу. Так, пакет
DAO отвечает за выборку необходимых данных из базы данных определенного типа. В
нем описаны методы поиска по этим данным, которые соеденены только с объектами из
базы данных.
Пакет objects отвечает за формирование результата вывода
информации пользователю, так же там расположены некоторые вспомогательные
методы, которые необходимы для того, чтобы правильно отобразить найденную
информацию из базы данных по заданному критерию.
В пакете Servlets расположены сервлеты из стандартной спецификации
J2EE, которые необходимы для
не стандартных решений, призванных ускорить работу системы. Например, для того
что бы не загружать все изображения журналов из базы данных при загрузке
страницы, а выводить только то, что помещается на страницу и загружать
следующие изображения при переходе к данным журналам с помощью Ajax запроса, используется
сервлет ShowImage. java. Данный сервлет проверяет, какие элементы открыты на странице и
загружает к этим элементам соответствующие изображения из базы данных.
Рис. 12. Диаграмма пакетов
Разработка на
Spring Web Flow
В Spring Web Flow поток состоит из ряда шагов, называемых
"Состояние". Вход в это состояние, как правило, приводит к
представлению и отображается пользователю.
В этом представлении происходят пользовательские события,
которые обрабатываются этим состоянием. Эти события могут вызвать переходы в
другие состояния (Рис. 13).
Рис. 13. Состояния Web Flow
Каждый поток начинается со следующего корневого элемента
(Рис.14):
Рис. 14. Определение потока (flow)
Все состояния потока определяются в
пределах этого элемента. Элемент view-state определяет стадию потока (Рис.15).
Рис. 15. Определение view-state в потоке
Этот поток отобразит представление main. xhtml из того каталога, где он
расположен. С помощью элемента evaluate вызываются методы Spring или другие переменные
потока.
Получение
информации
Для доступа к базе данных используется hibernate, который позволяет
подключаться к базе данных и манипулировать данными с помощью специальных
методов без контакта с самой базой. При подключении к базе данных создается
специальный объект sessionFactory, который по JDBC соединению связывает entity классы Java с соответствующими
таблицами в СУБД. Благодаря такому подходу можно добиться целостности и
согласованности данных, ведь spring берет на себя всю работу связанную с
транзакциями и сессиями.
Формирование информации из базы данных для вывода происходит
в специальных методах классов, которые обрабатывают коллекции данных
необходимого типа из базы данных и возвращают сформировавшую коллекцию
удовлетворяющую критериям поиска представлению в потоке.
@Transactional @Override public
List<Journals> getJournal (String name) { List<Journals>
journals = createJournalList (createJournalCriteria (). add (Restrictions. ilike
("b. name",name, MatchMode. ANYWHERE)));
return journals;
}
Для доступа к данным используется
аннотация @Transactional для создания транзакции.
Вывод данных
в представление
Для вывода сформировавшейся коллекции используется компонент jsf <p: data grid> фреймворка prime-faces для встраивания данных
на страницу xhtml, который принимает список из модели и выводит его таблицей.
<p: dataGrid
rowIndexVar="rowIndex" columns="3" lazy="true"
var="b" value="${newsrussiaFacade. journals}"
id="journalsList" styleClass="list-results
list-results-underlined" paginator="true" rows="4"
paginatorPosition="bottom" rowsPerPageTemplate="12,24,80"
paginatorTemplate="{RowsPerPageDropdown} {PageLinks}" paginatorAlwaysVisible="true"
emptyMessage="">
Для вывода дополнительных данных
используются сервлеты, которые предоставляют возможность дополнительно
манипулировать данными. Так, за вывод изображений из базы данных отвечает
элемент:
<h: outputLink styleClass="content_link" target="_blank"> <p: graphicImage value="/ShowImage? index=#{rowIndex}" width="100%"/> </h: outputLink>
который вызывает сервлет showImage и передает индекс
необходимого элемента.
Пользовательский
интерфейс
Рис. 16. Главная страница
Интерфейс разделен на 4 логические части (Рис.16).
. Шапка сайта, в которую выводятся уведомления
пользователю, выбор языка интерфейса и личный кабинет. Так же по нажатию на
кнопку в правом верхнем углу открывается чат с менеджером (Рис.17).
2. С левой стороны расположено раскрывающееся по нажатию
или наведению главное меню системы.
. Строка поиска с выбором типа поиска.
4. Главная страница поиска.
Рис. 17. Чат
Главная
страница поиска выглядит следующим образом (Рис.18):
Рис. 18. Главная страница поиска
На главной странице постранично выводится вся информация
данного раздела из базы данных, разделенные пагинацией. Пользователь их может
открыть и скачать, а администратор еще и отредактировать и удалить. При нажатии
на обложку журнала открываются все выпуски данного журнала/выпуска. При нажатии
на видео запускается просмотр данного видео.
Вывод
Данный подход к созданию web-приложений является
наиболее оптимальным. Так как он позволяет строить сложную бизнес-логику без
усложнения вывода информации в представлении.
Заключение
В рамках данной работы была спроектирована и реализована
информационно-поисковая система для хранения слабо-структурированных данных для
предприятия, обладающая всем требуемым функционалом. Перед проектированием были
рассмотрены возможные решения и выделены их плюсы и минусы.
В ходе выполнения работы были выбраны инструменты и
технологии, выделены требования, была спроектирована база данных и
бизнес-логика.
Мною были изучены такие технологии как: Java, SQL, Intellij idea, Apache Glassfish, Mysql, Mysql Workbench, Visual Use case, HTML, CSS, Javascript, Apache Maven, Spring framework, Spring web flow, Spring MVC, Prime-faces framework.
Была разработана система, которая позволяет автоматизировать
работу медийного предприятия по поиску и хранению информации такой как: видео
файлы, аудио файлы, журналы и текстовые файлы без разметки.
Для системы разработан веб-интерфейс с возможностью поиска, просмотра,
редактирования материала, разделенной по ролям. Реализована верстка чата, для
клиентов и менеджеров агентства.
Список
использованной литературы
1. Официальная
документация Spring. URL: https: // spring. io/docs (Дата обращения:
24.02.2016)
2. Spring
IO Platform Reference Guide. URL: #"897033.files/image019.gif">
Приложение В.
Представления
Main. jsp
Приложение Г.
Скрипты
Script. js
Приложение Д.
Файлы конфигурации
servlet-context. xml
Приложение
2. Разработка с использованием технологий Spring web flow, jsf
Приложение
А. Используемые классы сущностей
Audio. java
package wps.
newsrussia. entities;
import java. sql.
Date;
/** * Created by
sergejsafonov on 12.05.16.
*/ public class Audio { private
long id;
private String title;
private Date date;
private String type;
private String path;
private String description;
private String annotation;
private Genre genreId;
private Storage storageId;
}
/* Getters and setters
…
*/
@Override public
boolean equals (Object o) { if (this == o) return true;
if (o == null ||
getClass ()! = o. getClass ()) return false;audio = (Audio) o;
if (id! = audio. id)
return false;
if (title! = null?!
title. equals (audio. title): audio. title! = null)
return false;
if (date! = null?!
date. equals (audio. date): audio. date! = null) return
false;
if (type! = null?!
type. equals (audio. type): audio. type! = null) return
false;
if (path! = null?!
path. equals (audio. path): audio. path! = null) return
false;
if (description! = null?!
description. equals (audio. description): audio. description!
= null) return false;
if (annotation! = null?!
annotation. equals (audio. annotation): audio. annotation!
= null) return false;
if (genreId! = null?!
genreId. equals (audio. genreId): audio. genreId! = null)
return false;
return storageId! = null?
storageId. equals (audio. storageId): audio. storageId == null;
} @Override public
int hashCode () { int result = (int) (id ^ (id >>>
32));= 31 * result + (title! = null? title. hashCode ():
0);= 31 * result + (date! = null? date. hashCode (): 0);=
31 * result + (type! = null? type. hashCode (): 0);= 31 *
result + (path! = null? path. hashCode (): 0);= 31 *
result + (description! = null? description. hashCode ():
0);= 31 * result + (annotation! = null? annotation.
hashCode (): 0);= 31 * result + (genreId! = null? genreId.
hashCode (): 0);= 31 * result + (storageId! = null? storageId.
hashCode (): 0);
return result;
} }
Di
gest. java
package wps.
newsrussia. entities;
import java. sql.
Date;
public class Digest { private
long id;
private String name;
private Date lastmodify;
private String startDate;
private String lang;
private Byte status;
private Storage storageId;
private Genre genreId;
private DigestCover digestCoverId;
/* Getters and setters
…
*/
@Override public
boolean equals (Object o) { if (this == o) return true;
if (o == null ||
getClass ()! = o. getClass ()) return false;
Digest digest = (Digest)
o;
if (id! = digest. id)
return false;
if (name! = null?!
name. equals (digest. name): digest. name! = null) return
false;
if (lastmodify! = null?!
lastmodify. equals (digest. lastmodify): digest. lastmodify!
= null) return false;
if (startDate! = null?!
startDate. equals (digest. startDate): digest. startDate!
= null) return false;
if (lang! = null?!
lang. equals (digest. lang): digest. lang! = null) return
false;
if (status! = null?!
status. equals (digest. status): digest. status! = null)
return false;
if (storageId! = null?!
storageId. equals (digest. storageId): digest. storageId!
= null) return false;
if (genreId! = null?!
genreId. equals (digest. genreId): digest. genreId! = null)
return false;
return digestCoverId! = null?
digestCoverId. equals (digest. digestCoverId): digest. digestCoverId
== null;
} @Override public
int hashCode () { int result = (int) (id ^ (id >>>
32));= 31 * result + (name! = null? name. hashCode ():
0);= 31 * result + (lastmodify! = null? lastmodify.
hashCode (): 0);= 31 * result + (startDate! = null? startDate.
hashCode (): 0);= 31 * result + (lang! = null? lang.
hashCode (): 0);= 31 * result + (status! = null? status.
hashCode (): 0);= 31 * result + (storageId! = null? storageId.
hashCode (): 0);= 31 * result + (genreId! = null? genreId.
hashCode (): 0);= 31 * result + (digestCoverId! = null? digestCoverId.
hashCode (): 0);
return result;
} }
DigestCover. java
package wps.
newsrussia. entities;
public class DigestCover { private
long id;
private String img;
/* Getters and setters
…
*/
@Override public
boolean equals (Object o) { if (this == o) return true;
if (o == null ||
getClass ()! = o. getClass ()) return false;that = (DigestCover) o;
if (id! = that. id)
return false;
if (img! = null?!
img. equals (that. img): that. img! = null) return
false;
return true;
} @Override public
int hashCode () { int result = (int) (id ^ (id >>>
32));= 31 * result + (img! = null? img. hashCode (): 0);
return result;
} }
DigestIssues. java
package wps.
newsrussia. entities;
import java. sql.
Date;
public class DigestIssues {
private long id;
private long issue;
private String title;
private Date date;
private String path;
private String keywords;
private Digest digestId;
/* Getters and setters
…
*/
@Override public
boolean equals (Object o) { if (this == o) return true;
if (o == null ||
getClass ()! = o. getClass ()) return false;that = (DigestIssues) o;
if (id! = that. id)
return false;
if (issue! = that. issue)
return false;
if (title! = null?!
title. equals (that. title): that. title! = null) return
false;
if (date! = null?!
date. equals (that. date): that. date! = null) return
false;
if (path! = null?!
path. equals (that. path): that. path! = null) return
false;
if (keywords! = null?!
keywords. equals (that. keywords): that. keywords! = null)
return false;
return digestId! = null?
digestId. equals (that. digestId): that. digestId == null;
} @Override public
int hashCode () { int result = (int) (id ^ (id >>>
32));= 31 * result + (int) (issue ^ (issue >>>
32));= 31 * result + (title! = null? title. hashCode ():
0);= 31 * result + (date! = null? date. hashCode (): 0);=
31 * result + (path! = null? path. hashCode (): 0);= 31 *
result + (keywords! = null? keywords. hashCode (): 0);= 31
* result + (digestId! = null? digestId. hashCode (): 0);
return result;
} }
Genre. java
package wps.
newsrussia. entities;
public class Genre { private
long id;
private String name;
/* Getters and setters
…
*/
@Override public
boolean equals (Object o) { if (this == o) return true;
if (o == null ||
getClass ()! = o. getClass ()) return false;genre = (Genre) o;
if (id! = genre. id)
return false;
if (name! = null?!
name. equals (genre. name): genre. name! = null) return
false;
return true;
} @Override public
int hashCode () { int result = (int) (id ^ (id >>>
32));= 31 * result + (name! = null? name. hashCode (): 0);
return result;
} @Override public String
toString () { return name;
} }
Group. java
package wps.
newsrussia. entities;
public class Group { private
int idGroup;
private String groupName;
/* Getters and setters
…
*/
if (o == null ||
getClass ()! = o. getClass ()) return false;group = (Group) o;
if (idGroup! = group. idGroup)
return false;
if (groupName! = null?!
groupName. equals (group. groupName): group. groupName! = null)
return false;
return true;
} @Override public
int hashCode () { int result = idGroup;= 31 * result + (groupName!
= null? groupName. hashCode (): 0);
return result;
} }
JournalCovers. java
package wps.
newsrussia. entities;
public class JournalCovers
{ private long id;
private String img;
/* Getters and setters
…
*/
@Override public
boolean equals (Object o) { if (this == o) return true;
if (o == null ||
getClass ()! = o. getClass ()) return false;that = (JournalCovers) o;
if (id! = that. id)
return false;
if (img! = null?!
img. equals (that. img): that. img! = null) return
false;
return true;
} @Override public
int hashCode () { int result = (int) (id ^ (id >>>
32));= 31 * result + (img! = null? img. hashCode (): 0);
return result;
} }
JournalIssues. java
package wps.
newsrussia. entities;
import java. sql.
Date;
public class JournalIssues
{ private long id;
private long issue;
private String title;
private Date date;
private String linkToPdf;
private String linkToTxt;
private String keywords;
private Journals journalsId;
/* Getters and setters
…
*/
@Override public
boolean equals (Object o) { if (this == o) return true;
if (o == null ||
getClass ()! = o. getClass ()) return false;that = (JournalIssues) o;
if (id! = that. id)
return false;
if (issue! = that. issue)
return false;
if (title! = null?!
title. equals (that. title): that. title! = null) return
false;
if (date! = null?!
date. equals (that. date): that. date! = null) return
false;
if (linkToPdf! = null?!
linkToPdf. equals (that. linkToPdf): that. linkToPdf! = null)
return false;
if (linkToTxt! = null?!
linkToTxt. equals (that. linkToTxt): that. linkToTxt! = null)
return false;
if (keywords! = null?!
keywords. equals (that. keywords): that. keywords! = null)
return false;
return journalsId! = null?
journalsId. equals (that. journalsId): that. journalsId ==
null;
} @Override public
int hashCode () { int result = (int) (id ^ (id >>>
32));= 31 * result + (int) (issue ^ (issue >>>
32));= 31 * result + (title! = null? title. hashCode (): 0);= 31 *
result + (date! = null? date. hashCode (): 0);= 31 * result +
(linkToPdf! = null? linkToPdf. hashCode (): 0);= 31 * result +
(linkToTxt! = null? linkToTxt. hashCode (): 0);= 31 * result +
(keywords! = null? keywords. hashCode (): 0);= 31 * result +
(journalsId! = null? journalsId. hashCode (): 0);
return result;
} }
Journals. java
package wps.
newsrussia. entities;
import java. sql.
Date;
public class Journals { private
long id;
private String name;
private Date startDate;
private Storage storageId;
private Date lastmodify;
private Genre genreId;
private JournalCovers journalCoversId;
/* Getters and setters
…
*/
@Override public
boolean equals (Object o) { if (this == o) return true;
if (o == null ||
getClass ()! = o. getClass ()) return false;journals = (Journals) o;
if (id! = journals. id)
return false;
if (name! = null?!
name. equals (journals. name): journals. name! = null)
return false;
if (startDate! = null?!
startDate. equals (journals. startDate): journals. startDate!
= null) return false;
if (storageId! = null?!
storageId. equals (journals. storageId): journals. storageId!
= null) return false;
if (lastmodify! = null?!
lastmodify. equals (journals. lastmodify): journals. lastmodify!
= null) return false;
if (genreId! = null?!
genreId. equals (journals. genreId): journals. genreId! = null)
return false;
return journalCoversId! = null?
journalCoversId. equals (journals. journalCoversId): journals. journalCoversId
== null;
} @Override public
int hashCode () { int result = (int) (id ^ (id >>>
32));= 31 * result + (name! = null? name. hashCode ():
0);= 31 * result + (startDate! = null? startDate. hashCode
(): 0);= 31 * result + (storageId! = null? storageId.
hashCode (): 0);= 31 * result + (lastmodify! = null? lastmodify.
hashCode (): 0);= 31 * result + (genreId! = null? genreId.
hashCode (): 0);= 31 * result + (journalCoversId! = null? journalCoversId.
hashCode (): 0);
return result;
} }
Storage. java
package wps.
newsrussia. entities;
public class Storage { private
int id;
private String name;
private String path;
/* Getters and setters
…
*/
@Override public String
toString () { return name;
} @Override public
boolean equals (Object o) { if (this == o) return true;
if (o == null ||
getClass ()! = o. getClass ()) return false;storage = (Storage) o;
if (id! = storage. id)
return false;
if (name! = null?!
name. equals (storage. name): storage. name! = null)
return false;
if (path! = null?!
path. equals (storage. path): storage. path! = null)
return false;
return true;
} @Override public
int hashCode () { int result = id;= 31 * result + (name!
= null? name. hashCode (): 0);= 31 * result + (path! = null?
path. hashCode (): 0);
return result;
} }
Users. java
package wps.
newsrussia. entities;
import java. sql.
Date;
public class Users { private
long id;
private String
userLogin;
private String
userPass;
private String
userNickname;
private String
userEmail;
private Group groupIdGroup;
private Date userRegistered;
private int userStatus;
private String displayName;
/* Getters and setters
…
*/
@Override public
boolean equals (Object o) { if (this == o) return true;
if (o == null ||
getClass ()! = o. getClass ()) return false;users = (Users) o;
if (id! = users.
id) return false;
if (userStatus! =
users. userStatus) return false;
if (userLogin! = null?!
userLogin. equals (users. userLogin): users. userLogin! = null) return
false;
if (userPass! = null?!
userPass. equals (users. userPass): users. userPass! = null) return
false;
if (userNickname!
= null?! userNickname. equals (users. userNickname): users.
userNickname! = null) return false;
if (userEmail! = null?!
userEmail. equals (users. userEmail): users. userEmail! = null) return
false;
if (groupIdGroup!
= null?! groupIdGroup. equals (users. groupIdGroup): users.
groupIdGroup! = null) return false;
if (userRegistered!
= null?! userRegistered. equals (users. userRegistered): users.
userRegistered! = null) return false;
return displayName! =
null? displayName. equals (users. displayName): users. displayName == null;
} @Override public
int hashCode () { int result = (int) (id ^ (id >>>
32));= 31 * result + (userLogin! = null? userLogin. hashCode (): 0);= 31
* result + (userPass! = null? userPass. hashCode (): 0);= 31 * result +
(userNickname! = null? userNickname. hashCode (): 0);= 31 * result +
(userEmail! = null? userEmail. hashCode (): 0);= 31 * result +
(groupIdGroup! = null? groupIdGroup. hashCode (): 0);= 31 * result +
(userRegistered! = null? userRegistered. hashCode (): 0);= 31 * result +
userStatus;= 31 * result + (displayName! = null? displayName. hashCode
(): 0);
return result;
} }
Video. java
package wps.
newsrussia. entities;
import java. sql.
Date;
public class Video { private
long id;
private String title;
private Date date;
private String type;
private String description;
private String annotation;
private String path;
private Genre genreId;
private Storage storageId;
/* Getters and setters
…
*/
@Override public
boolean equals (Object o) { if (this == o) return true;
if (o == null ||
getClass ()! = o. getClass ()) return false;video = (Video) o;
if (id! = video.
id) return false;
if (title! = null?!
title. equals (video. title): video. title! = null) return false;
if (date! = null?!
date. equals (video. date): video. date! = null) return false;
if (type! = null?!
type. equals (video. type): video. type! = null) return false;
if (description! =
null?! description. equals (video. description): video. description! = null)
return false;
if (annotation! = null?!
annotation. equals (video. annotation): video. annotation! = null) return
false;
if (path! = null?!
path. equals (video. path): video. path! = null) return false;
if (genreId! = null?!
genreId. equals (video. genreId): video. genreId! = null) return
false;
return storageId! = null?
storageId. equals (video. storageId): video. storageId == null;
} @Override public
int hashCode () { int result = (int) (id ^ (id >>>
32));= 31 * result + (title! = null? title. hashCode (): 0);= 31 * result
+ (date! = null? date. hashCode (): 0);= 31 * result + (type! = null?
type. hashCode (): 0);= 31 * result + (description! = null? description.
hashCode (): 0);= 31 * result + (annotation! = null? annotation.
hashCode (): 0);= 31 * result + (path! = null? path. hashCode (): 0);=
31 * result + (genreId! = null? genreId. hashCode (): 0);= 31 * result +
(storageId! = null? storageId. hashCode (): 0);
return result;
} }
Приложение Б.
Используемые настройки сущностей
Приложение В.
Реализация шаблона DAO
JouranalDAOImpl. java
package wps.
newsrussia. dao. impl;
import org.
hibernate. Criteria;
import org.
hibernate. SessionFactory;
import org.
hibernate. criterion. *;
import org.
hibernate. transform. Transformers;
import org.
springframework. beans. factory. annotation. Autowired;
import org.
springframework. stereotype.component;
import org.
springframework. transaction. annotation. Transactional;
import wps.
newsrussia. entities. Genre;
import wps.
newsrussia. dao. interfaces. JournalDAO;
import wps.
newsrussia. entities. Journals;
import java. util.
Date;
import java. util.
List;
@Component public
class JournalDAOImpl implements JournalDAO { @Autowired private SessionFactory
sessionFactory;
private ProjectionList
journalProjection;
public JournalDAOImpl
() { journalProjection = Projections. projectionList ();
journalProjection. add
(Projections. property ("id"), "id");
journalProjection. add
(Projections. property ("genreId"), "genreId");
journalProjection. add
(Projections. property ("journalCoversId"), "journalCoversId");
journalProjection. add
(Projections. property ("name"), "name");
journalProjection. add
(Projections. property ("startDate"), "startDate");
journalProjection. add
(Projections. property ("lastmodify"), "lastmodify");
} private DetachedCriteria
createJournalCriteria () { DetachedCriteria journalListCriteria =
DetachedCriteria. forClass (Journals. class, "b");(journalListCriteria);
return journalListCriteria;
} @Transactional
@Override public List<Journals> getJournal () {
List<Journals> journals = createJournalList (createJournalCriteria ());
return journals;
} @Transactional
@Override public List<Journals> getJournal (String name) {
List<Journals> journals = createJournalList (createJournalCriteria ().
add (Restrictions. ilike ("b. name",name, MatchMode. ANYWHERE)));
return journals;
} @Transactional
@Override public List<Journals> getJournal (Date date_upload) { return
null;
} @Transactional
@Override public List<Journals> getJournal (Genre genre) {
List<Journals> journals = createJournalList (createJournalCriteria ().
add (Restrictions. ilike ("genre. name", genre. getName
(), MatchMode. ANYWHERE)));
return journals;
} private void createAliases
(DetachedCriteria criteria) { criteria. createAlias ("b. genreId",
"genreId");. createAlias ("b. storageId",
"storageId");
} private List<Journals>
createJournalList (DetachedCriteria bookListCriteria) { Criteria criteria =
bookListCriteria. getExecutableCriteria (sessionFactory.
getCurrentSession ());. addOrder (Order. asc ("b. name")).
setProjection (journalProjection). setResultTransformer (Transformers. aliasToBean
(Journals. class));
return criteria. list
();
} }
JouranalIssueDAOImpl. java
package wps.
newsrussia. dao. impl;
public class JournalIssueDAOImpl
implements JournalissueDAO{ @Autowired private SessionFactory sessionFactory;
private DetachedCriteria
createJournalCriteria () { DetachedCriteria journalListCriteria =
DetachedCriteria. forClass (JournalIssues. class, "b");
return journalListCriteria;
} @Transactional
@Override public List<JournalIssues> getJournalIssues () {
List<JournalIssues> journalIssues = createJournalList
(createJournalCriteria ());
return journalIssues;
} @Transactional
@Override public List<JournalIssues> getJournalIssues (int journalsId)
{ List<JournalIssues> journals = createJournalList (createJournalCriteria
(). add (Restrictions. eq ("b. id",journalsId)));
return journals;
} private List<JournalIssues>
createJournalList (DetachedCriteria bookListCriteria) { Criteria criteria =
bookListCriteria. getExecutableCriteria (sessionFactory.
getCurrentSession ());. addOrder (Order. asc ("b. name")).
setResultTransformer (Transformers. aliasToBean (JournalIssues. class));
return criteria. list ();
} }
Приложение Г.
Вспомогательные классы
NewsrussiaFacade. java
package wps.
newsrussia. objects;
@Component @Scope ("singleton")
public class NewsrussiaFacade { @Autowired private JournalDAO
journalDAO;
@Autowired private SearchCriteria
searchCriteria;
private List<Journals>
journals;
public List<Journals>
getJournals () { if (journals == null) { journals =
journalDAO. getJournal ();
} return journals;
} public void searchJournalsByText
() { journals = journalDAO. getJournal (searchCriteria. getName
());
} }
SearchCriteria. java
package wps.
newsrussia. objects;
import java. io.
Serializable;
@Component @Scope ("singleton")
public class SearchCriteria implements Serializable { private
String name;
private SearchType searchType
= SearchType. TEXT;
private String title;
private Genre genre;
public String getName
() { return name;
} public void setName
(String name) { this. name = name;
} public SearchType
getSearchType () { return searchType;
} public void setSearchType
(SearchType searchType) { this. searchType = searchType;
} public String
getTitle () { return title;
} public void setTitle
(String title) { this. title = title;
} public Genre
getGenre () { return genre;
} public void setGenre
(Genre genre) { this. genre = genre;
} }
Utils. java
package wps.
newsrussia. objects;
@Component public
class Utils { private Map<String, SearchType> searchTypeList
= new HashMap<String, SearchType> ();
private SearchType selectedSearchType
= SearchType. TITLE; // значение по-умолчанию @Autowired
private MessageSource msg;
private Character [] letters
= new Character [] {'А', 'Б', 'В', 'Г', 'Д',
'Е', 'Ё', 'Ж', 'З', 'И', 'Й', 'К',
'Л', 'М', 'Н', 'О', 'П', 'Р', 'С',
'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш',
'Щ', 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я'};
public Character []
getLetters () { return letters;
} public Map<String,
SearchType> getSearchTypeList () { searchTypeList. clear ();
searchTypeList. put (msg.
getMessage ("title", null, FacesContext. getCurrentInstance
(). getViewRoot (). getLocale ()), SearchType. TITLE);
searchTypeList. put (msg.
getMessage ("text", null, FacesContext. getCurrentInstance
(). getViewRoot (). getLocale ()), SearchType. TEXT);
return searchTypeList;
} public SearchType
getSelectedSearchType () { return selectedSearchType;
} public void setSearchTypeList
(Map<String, SearchType> searchTypeList) { this. searchTypeList
= searchTypeList;
} public void setSelectedSearchType
(SearchType selectedSearchType) { this. selectedSearchType =
selectedSearchType;
} }
Приложение
Д. Servlets
ShowImage. java
package wps.
newsrussia. servlets;
@WebServlet (name =
"ShowImage", urlPatterns = {"/ShowImage"}) public
class ShowImage extends HttpServlet { // private static
Map<Long, Byte [] > imageMap = new HashMap ();
protected void processRequest
(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException { response. setContentType ("image/jpeg");out =
response. getOutputStream ();
try { int index
= Integer. valueOf (request. getParameter ("index"));newsrussiaFacade
= (NewsrussiaFacade) getServletContext (). getAttribute ("newsrussiaFacade");image
= newsrussiaFacade. getJournals (). get (index). getJournalCoversId ();fis = new
FileInputStream (new File (image. getImg ()));
byte [] img = new
byte [fis. available ()];. read (img, 0, fis. available ());.
setContentLength (img. length);. write (img);
} catch (Exception
ex) { ex. printStackTrace ();
} finally { out.
close ();
} } }
PdfContent. java
@WebServlet (name =
"PdfContent", urlPatterns = {"/PdfContent"}) public
class PdfContent extends HttpServlet { protected void processRequest
(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException { response. setContentType ("application/pdf;
charset=UTF-8");out = response. getOutputStream ();
try { long id
= Long. valueOf (request. getParameter ("id"));save =
Boolean. valueOf (request. getParameter ("save"));libraryFacade
= (NewsrussiaFacade) getServletContext (). getAttribute ("libraryFacade");
byte [] content = null;
// libraryFacade. getContent (id);
response.
setContentLength (content. length);
if (save) { String
filename = request. getParameter ("filename");. setHeader ("Content-Disposition",
"attachment; filename=" + URLEncoder. encode (filename,
"UTF-8") +". pdf");
} out. write (content);
} catch (Exception
ex) { ex. printStackTrace ();
} finally { out.
close ();
} } }
Приложение
Е. Шаблоны JSF
main. xhtml
<? xml
version="1.0" encoding="UTF-8"? >
<! DOCTYPE html PUBLIC
"- // W3C // DTD XHTML 1.0 Transitional // EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.
dtd">
<html
xmlns="http://www.w3.org/1999/xhtml": h="http://xmlns.
jcp.org/jsf/html": ui="http://xmlns. jcp.org/jsf/facelets":
f="http://xmlns. jcp.org/jsf/core":
p="http://primefaces.org/ui">
<f: view>
<ui: composition
template="/WEB-INF/templates/journals. xhtml">
<ui: define
name="title">
#{msg.
journal_list}
</ui: define>
<ui: define
name="content">
<h: form
id="journals_form">
<p: dataGrid
rowIndexVar="rowIndex" columns="3" lazy="true"
var="b" value="${newsrussiaFacade. journals}"
id="journalsList"="list-results list-results-underlined"
paginator="true" rows="4"
paginatorPosition="bottom"="12,24,80"
paginatorTemplate="{RowsPerPageDropdown} {PageLinks}"
paginatorAlwaysVisible="true"="">
<div>>
<div>>
<div>>
<h: outputLink
styleClass="content_link" value="${flowExecutionUrl}&
_eventId=showissues& _index=${rowIndex}">
<p: graphicImage
value="/ShowImage? index=#{rowIndex}" width="100%"/>
</h: outputLink>
</div>
<div>>
<div>>
<a
href="#"><i>/></a>
</div>
<div>>
<a
href="#"><i>/></a>
</div>
<div>>
<a
href="#"><i>/></a>
</div>
<div>>
<a
href="#"><i>/></a>
</div>
</div>
<div>>
<div>>
<a
id="journals_form: journalsList: 0: journalName"="journals_form:
journalsList: 0: journalName" href="" target="_blank">>#{b. name}</a>
</div>
<div>>
<p><span>#{msg.
genre}: </span>#{b. genreId}</p>
<p><span>#{msg.
last_publication}: </span>#{b. lastmodify}</p>
</div>
</div>
</div>
</div>
</p: dataGrid>
</h: form>
</ui: define>
</ui: composition>
</f: view>
</html>
issues. xhtml
<html
xmlns="http://www.w3.org/1999/xhtml": h="http://xmlns.
jcp.org/jsf/html": ui="http://xmlns. jcp.org/jsf/facelets":
f="http://xmlns. jcp.org/jsf/core">
<f: view>
<h: head>
<title><ui:
insert name="title"/></title>
<link
href='http://fonts. googleapis.com/css? family=Roboto: 300italic,400italic,300,400,500,700,900'
rel='stylesheet' type='text/css'/>
</h: head>
<h: body
styleClass="menubar-hoverable header-fixed ">
<f: facet
name="last">
<! - -<h:
outputScript library="js" name="theme-default/bootstrap. css?
1422792965" target="head"/>-->
<h:
outputStylesheet library="css" name="theme-default/bootstrap.
css" />
<h:
outputStylesheet library="css"
name="theme-default/materialadmin. css" />
<h:
outputStylesheet library="css" name="theme-default/font-awesome.
min. css" />
<h:
outputStylesheet library="css"
name="theme-default/material-design-iconic-font. min. css" />
<h:
outputStylesheet library="css" name="theme-default/main.
css" />
</f: facet>
<! - HTML5 shim and
Respond. js IE8 support of HTML5 elements and media queries - ->
<! - [if lt IE 9] >
<h: outputScript
library="js" name="libs/utils/html5shiv. js"
target="head"/>
<h: outputScript
library="js" name="libs/utils/respond. min. js"
target="head"/>
<! [endif] - ->
<header
id="header">
<ui: include
src="/WEB-INF/templates/header. xhtml"/>
</header>
<div
id="base">
<! - BEGIN OFFCANVAS
LEFT - ->
<div>>
<! - END OFFCANVAS
LEFT - ->
<ui: include
src="/WEB-INF/templates/searchTextImg. xhtml">
<ui: param
name="issue" value="#{index}"/>
</ui: include>
<ui: include
src="/WEB-INF/templates/rightbar. xhtml"/>
<ui: include
src="/WEB-INF/templates/menubar. xhtml"/>
</div>
<! - BEGIN JAVASCRIPT
- ->
<h: outputScript
library="js" name="libs/jquery/jquery-1.11.2 min. js"
target="head" />
<h: outputScript
library="js" name="libs/jquery/jquery-migrate-1.2.1 min.
js" target="head"/>
<h: outputScript
library="js" name="libs/bootstrap/bootstrap. min. js"
target="head"/>
<h: outputScript
library="js" name="libs/spin. js/spin. min. js"
target="head"/>
<h: outputScript library="js"
name="libs/autosize/jquery. autosize. min. js"
target="head"/>
<h: outputScript
library="js" name="libs/nanoscroller/jquery. nanoscroller. min.
js" target="head" />
<h: outputScript
library="js" name="core/source/App. js"
target="head"/>
<h: outputScript
library="js" name="core/source/AppNavigation. js"
target="head"/>
<h: outputScript
library="js" name="core/source/AppOffcanvas. js"
target="head"/>
<h: outputScript
library="js" name="core/source/AppCard. js"
target="head"/>
<h: outputScript
library="js" name="core/source/AppForm. js"
target="head"/>
<h: outputScript
library="js" name="core/source/AppNavSearch. js"
target="head"/>
<h: outputScript
library="js" name="core/source/AppVendor. js"
target="head"/>
<h: outputScript library="js"
name="core/demo/Demo. js" target="head"/>
<! - END JAVASCRIPT -
->
</h: body>
</f: view>
</html>
journals. xhtml
<html
xmlns="http://www.w3.org/1999/xhtml": h="http://xmlns.
jcp.org/jsf/html"
xmlns:
ui="http://xmlns. jcp.org/jsf/facelets": f="http://xmlns.
jcp.org/jsf/core">
<f: view>
<h: head>
<title><ui:
insert name="title"/></title>
<link
href='http://fonts. googleapis.com/css? family=Roboto:
300italic,400italic,300,400,500,700,900' rel='stylesheet' type='text/css'/>
</h: head>
<h: body
styleClass="menubar-hoverable header-fixed ">
<f: facet
name="last">
<! - -<h:
outputScript library="js" name="theme-default/bootstrap. css?
1422792965" target="head"/>-->
<h:
outputStylesheet library="css" name="theme-default/bootstrap.
css" />
<h: outputStylesheet
library="css" name="theme-default/materialadmin. css" />
<h:
outputStylesheet library="css" name="theme-default/font-awesome.
min. css" />
<h:
outputStylesheet library="css"
name="theme-default/material-design-iconic-font. min. css" />
<h: outputStylesheet
library="css" name="theme-default/main. css" />
</f: facet>
<! - HTML5 shim and
Respond. js IE8 support of HTML5 elements and media queries - ->
<! - [if lt IE 9] >
<h: outputScript
library="js" name="libs/utils/html5shiv. js"
target="head"/>
<h: outputScript
library="js" name="libs/utils/respond. min. js"
target="head"/>
<! [endif] - ->
<header
id="header">
<ui: include
src="/WEB-INF/templates/header. xhtml"/>
</header>
<div
id="base">
<! - BEGIN OFFCANVAS
LEFT - ->
<div>>
</div><!
- -end. offcanvas-->
<! - END OFFCANVAS
LEFT - ->
<ui: include
src="/WEB-INF/templates/searchTextImg. xhtml"/>
<ui: include
src="/WEB-INF/templates/rightbar. xhtml"/>
<ui: include
src="/WEB-INF/templates/menubar. xhtml"/>
</div>
<! - BEGIN JAVASCRIPT
- ->
<h: outputScript
library="js" name="libs/jquery/jquery-1.11.2 min. js"
target="head" />
<h: outputScript
library="js" name="libs/jquery/jquery-migrate-1.2.1 min.
js" target="head"/>
<h: outputScript
library="js" name="libs/bootstrap/bootstrap. min. js"
target="head"/>
<h: outputScript
library="js" name="libs/spin. js/spin. min. js"
target="head"/>
<h: outputScript
library="js" name="libs/autosize/jquery. autosize. min. js"
target="head"/>
<h: outputScript
library="js" name="libs/nanoscroller/jquery. nanoscroller. min.
js" target="head" />
<h: outputScript
library="js" name="core/source/App. js"
target="head"/>
<h: outputScript
library="js" name="core/source/AppNavigation. js"
target="head"/>
<h: outputScript
library="js" name="core/source/AppOffcanvas. js"
target="head"/>
<h: outputScript
library="js" name="core/source/AppCard. js"
target="head"/>
<h: outputScript
library="js" name="core/source/AppForm. js"
target="head"/>
<h: outputScript
library="js" name="core/source/AppNavSearch. js"
target="head"/>
<h: outputScript
library="js" name="core/source/AppVendor. js"
target="head"/>
<h: outputScript
library="js" name="core/demo/Demo. js"
target="head"/>
<! - END JAVASCRIPT -
->
</h: body>
</f: view>
</html>
locales. xhtml
<html
xmlns="http://www.w3.org/1999/xhtml": h="http://java.
sun.com/jsf/html": ui="http://java. sun.com/jsf/facelets":
f="http://java. sun.com/jsf/core":
p="http://primefaces.org/ui">
<h: head>
<title>Facelet
Title</title>
</h: head>
<h: body>
<ui: composition>
<div>>
<h: form>
<h: outputLink
value="?">
<h: graphicImage
library="images" name="rus. png" title="#{msg.russian}"
width="21" height="20" style="margin-right: 10px"/>
</h: outputLink>
<h: outputLink
value="?">
<h: graphicImage
library="images" name="usa. png" title="#{msg.
english}" width="21" height="15"/>
</h: outputLink>
</h: form>
</div>
</ui: composition>
</h: body>
</html>
search. xhtml
<html
xmlns="http://www.w3.org/1999/xhtml": h="http://java.
sun.com/jsf/html": ui="http://java. sun.com/jsf/facelets":
f="http://java. sun.com/jsf/core":
p="http://primefaces.org/ui">
<h: head>
<title>Facelet
Title</title>
</h: head>
<h: body>
<ui: composition>
<! - BEGIN SEARCH BAR
- ->
<div>>
<h: form>>
<div>>
<div>>
<div>>
<! - -<input
type="text">
<div>>
<h: inputText
id="searchInput" styleClass="form-control" value="#{searchCriteria.
name}"/>
<script
language="javascript">
document.
getElementById ("search_form: searchInput"). setAttribute ("placeholder","#{msg.
search}");
</script>
<div>></div>
</div>
<div>></div>
</div>
<div>>
<p: commandButton
styleClass="btn btn-floating-action btn-default-bright fa fa-search"
style="padding-top: 10px"
icon=""="_eventId_searchByText">
<p: ajax
execute="@form" render=": journals_form: journalsList"/>
</p: commandButton>
</div>
</div>
</div><!
- -end. form-group - ->
</h: form>
</div><!
- -end. card-body - ->
<! - END SEARCH BAR -
->
</ui: composition>
</h: body>
</html>
Приложение Ж.
Конфигурация Spring
Webflow. xml
<? xml
version="1.0" encoding="UTF-8"? >
<beans: beans="http://www.springframework.org/schema/webflow-config":
beans="http://www.springframework.org/schema/beans":
xsi="http://www.w3.org/2001/XMLSchema-instance":
faces="http://www.springframework.org/schema/faces": schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.
xsd://www.springframework.org/schema/faces
http://www.springframework.org/schema/faces/spring-faces.
xsd://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config.
xsd
">
<flow-executor
id="loginFlowExecutor"registry="flowRegistry" />
<flow-registry
id="flowRegistry"
flow-builder-services="flowBuilderServices"
base-path="/WEB-INF/flows">
<flow-location-pattern
value="*. xml" />
</flow-registry>
<faces:
flow-builder-services id="flowBuilderServices"
development="true" view-factory-creator="flowViewResolver" />
<! - A listener to
create and release a FacesContext - ->
<beans: bean
id="facesContextListener">/>
<flow-executor
id="flowExecutor">
<flow-execution-listeners>
<listener
ref="facesContextListener"/>
</flow-execution-listeners>
</flow-executor>
<beans: bean id="flowViewResolver"="org.
springframework. webflow. mvc. builder. MvcViewFactoryCreator">
<beans: property
name="viewResolvers">
<beans: list>
<beans: ref
bean="viewResolver" />
</beans: list>
</beans: property>
</beans: bean>
</beans: beans>
DispatcherServlet. xml
<? xml
version="1.0" encoding="UTF-8"? >
<beans
xmlns="http://www.springframework.org/schema/beans":
xsi="http://www.w3.org/2001/XMLSchema-instance":
mvc="http://www.springframework.org/schema/mvc":
context="http://www.springframework.org/schema/context":
tx="http://www.springframework.org/schema/tx":
schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.
xsd://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.
xsd http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context. xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx. xsd">
<import
resource="webflow. xml"/>
<context:
component-scan base-package="wps. newsrussia"/>
<mvc: resources
location="/" mapping="/resources/**"/>
<bean>>
<property
name="flowRegistry" ref="flowRegistry"/>
</bean>
<bean
name="resourceHandlerJSF">/>
<bean>>
<property
name="order" value="1" />
<property
name="mappings">
<value>
/javax. faces.
resource/**=resourceHandlerJSF
</value>
</property>
</bean>
<bean>>
<property
name="flowExecutor" ref="flowExecutor"/>
</bean>
<bean
id="viewResolver">>
<property
name="viewClass" value="org. springframework. faces. mvc.
JsfView"/>
<property
name="prefix" value="/WEB-INF/views/"/>
<property
name="suffix" value=". xhtml"/>
</bean>
<bean
id="msg">>
<property
name="basename" value="WEB-INF/locales/messages"/>
<property
name="defaultEncoding" value="UTF-8"/>
</bean>
<bean
id="dataSource">>
<property
name="jndiName" value="jdbc/newsrussia"/>
</bean>
<bean
id="sessionFactory">>
<property
name="dataSource" ref="dataSource"/>
<property
name="configLocation" value="classpath: hibernate. cfg.
xml"/>
</bean>
<tx:
annotation-driven />
<bean
id="transactionManager"="org. springframework. orm. hibernate4.
HibernateTransactionManager">
<property
name="sessionFactory" ref="sessionFactory" />
</bean>
<bean>>
<property
name="attributes">
<map>
<entry
key="newsrussiaFacade" value-ref="newsrussiaFacade"/>
</map>
</property>
</bean>
<bean
id="localeResolver">>
<property
name="defaultLocale" value="ru"/>
</bean>
<mvc: interceptors>
<mvc: interceptor>
<mvc: mapping
path="/**/"/>
<bean>>
<property
name="paramName" value="lang"/>
</bean>
</mvc: interceptor>
</mvc: interceptors>
</beans>
hibernate. cfg. xml
<? xml
version='1.0' encoding='utf-8'? >
<! DOCTYPE
hibernate-configuration PUBLIC
"- //
Hibernate/Hibernate Configuration DTD // EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.
dtd">
<hibernate-configuration>
<session-factory>
<property
name="hibernate. dialect">org. hibernate. dialect.
MySQLDialect</property>
<property
name="hibernate. show_sql">true</property>
<property
name="connection. url">jdbc: mysql: // localhost:
3306/newsrussia</property>
<property
name="connection. driver_class">com. mysql. jdbc. Driver</property>
<mapping
resource="wps/newsrussia/entities/Group. hbm. xml"/>
<mapping
resource="wps/newsrussia/entities/Users. hbm. xml"/>
<mapping
resource="wps/newsrussia/entities/Genre. hbm. xml"/>
<mapping
resource="wps/newsrussia/entities/Storage. hbm. xml"/>
<mapping resource="wps/newsrussia/entities/Audio.
hbm. xml"/>
<mapping
resource="wps/newsrussia/entities/Digest. hbm. xml"/>
<mapping
resource="wps/newsrussia/entities/DigestCover. hbm. xml"/>
<mapping
resource="wps/newsrussia/entities/DigestIssues. hbm. xml"/>
<mapping
resource="wps/newsrussia/entities/JournalCovers. hbm. xml"/>
<mapping
resource="wps/newsrussia/entities/JournalIssues. hbm. xml"/>
<mapping
resource="wps/newsrussia/entities/Journals. hbm. xml"/>
<mapping
resource="wps/newsrussia/entities/Video. hbm. xml"/>
</session-factory>
</hibernate-configuration>