platieshop2013good.ru
Главная Рейтинг пластических хирургов города москвы

Испытания полиуритановых лаков

Иглотерапия при грыжах позвононика отзывы


Читать дальше

Невроз при алкоголизме

Дакриоцистит грудничка пройдет ли сам


Читать дальше

Где можно сделать фгдс под наркозом спб

Питание для инсулинозависимых диабетиков


Читать дальше

Задействовать более одного процессора в виртуальной машине


перелом позвоночника th 12 ушиб спинного мозга нижняя параплегия

Введение


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

Традиционные методы персональной идентификации, основанные на применении паролей или материальных носителей, таких как пропуск, паспорт, водительское удостоверение, не всегда отвечают современным требованиям безопасности.

Решением проблемы точной идентификации личности может быть применение радиочастотных систем идентификации.

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

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

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

В рамках поставленной задачи предполагается разработка информационно-компьютерной системы контроля и управления доступом к охраняемым объектам. Назначение данной СКУД не столь примитивно по сравнению со многими существующими - обеспечить не только автоматическую фильтрацию посетителей по признаку - можно войти/нельзя, но и учет проведенного времени сотрудником предприятия на своем рабочем месте. Автоматическая фильтрация посетителей позволяет контролировать ситуацию, безопасность персонала и сохранность материальных ценностей и информации, а также порядок на объекте. Учет проведенного времени на рабочем месте - позволить повысить эффективность работы персонала предприятия, так как на основе данной статистики можно будет ввести систему штрафов и пощрений. Качество выполнения этой совокупности задач зависит от вида СКУД, её функциональности и удобства работы с самой системой. Данная компьютерная система должна иметь простой и наглядный интерфейс, который будет понятен любому пользователю.


1. Анализ существующих компьютерных систем контроля и управления доступом (СКУД)


Прежде чем начать анализ существующих компьютерных систем контроля и управления доступом (СКУД), необходимо дать определение понятию СКУД. Согласно ГОСТ 51241-2008 Средства и системы контроля и управления доступом. Классификация. Общие технические требования. Методы испытаний, СКУД - это совокупность средств контроля и управления доступом, обладающих технической, информационной, программной и эксплуатационной совместимостью.

Средства управления (СУ) - аппаратные средства (устройства) и программные средства, обеспечивающие установку режимов доступа, прием и обработку информации со считывателей, проведение идентификации и аутентификации, управление исполнительными и преграждающими устройствами, отображение и регистрацию информации.

Средства контроля и управления доступом (средства КУД) - механические, электромеханические устройства и конструкции, электрические, электронные, электронные программируемые устройства, программные средства, обеспечивающие реализацию контроля и управления доступом.

Устройства, преграждающие управляемые (УПУ) - устройства, обеспечивающие физическое препятствие доступу и оборудованные исполнительными устройствами для управления их состоянием (турникеты, проходные кабины, двери и ворота, оборудованные исполнительными устройствами СКУД).

Устройство считывающее (УС), считыватель - это устройство, предназначенное для считывания (ввода) идентификационных признаков.

Устройства исполнительные (УИ) - это устройства или механизмы, обеспечивающие приведение в открытое или закрытое состояние УПУ (электромеханические, электромагнитные замки, электромагнитные защелки, механизмы привода шлюзов, ворот, турникетов и другие подобные устройства).

Считыватель - устройство в составе УВИП, предназначенное для считывания (ввода) идентификационных признаков.

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


1.1Общие принципы работы систем контроля и управления доступом


Существуют различные конфигурации систем контроля управления доступом: самые простые из них рассчитаны всего на одну входную дверь, а самые сложные предназначены для контроля доступа на крупных объектах - предприятиях, заводах и банках. При этом самый простой вариант СКУД представляет из себя обычный домофон. Независимо от конфигурации СКУД, каждая подобная система состоит из нескольких обязательных узлов, это - контролеры для управления, считыватели для идентификации, а также всевозможные исполнительные устройства ограничения доступа: турникеты, электромагнитные замки и защелки. Электронные бесконтактные карты в качестве пропусков являются самым распространенным и удобным средством идентификации в системах контроля доступа.

Работает система контроля и управления доступом следующим образом: на проходной предприятия, при входе в ответственные помещения устанавливаются средства контроля доступа: электромеханические турникеты, электромеханические или электромагнитные замки, считыватели бесконтактных карт. Все эти устройства подключаются к контроллерам системы управления доступом. Контроллеры предназначены для приема и анализа информации о предъявляемых картах доступа, а также для управления различными исполнительными устройствами. В состав оборудования системы контроля доступа могут входить 2 типа контроллеров: контроллеры замка и контроллеры турникета, каждый из которых отвечает за контроль работы собственного узла. Каждому сотруднику предприятия выдается персональный идентификатор, чаще всего это оказывается бесконтактная карта доступа - пластиковая карточка с уникальным электронным кодом (Proximity карта). Но возможно и применение магнитных карт или т.н. Touch memory устройств. Этот идентификатор одновременно является пропуском на проходной организации и ключом от тех помещений, куда сотруднику разрешен доступ. Для прохода через турникет или входа в ответственное помещение работники предприятия должны поднести свою карту доступа к считывателю, после чего считыватель передает код предъявленной карты в контроллер, а контроллер доступа принимает решение о разрешении или запрете прохода на основании заложенной в него информации. В случае если доступ разрешен, система контроля доступа автоматически разблокирует турникет или замок на двери. Так, например, контроллер СКУД может быть запрограммирован на пропуск конкретных сотрудников в определенные помещения только в заданные промежутки времени, скажем, с 9 до 18 часов. К контроллеру СКУД также можно подключить охранную сигнализацию, в состав которой входят охранные датчики. Все события о проходах через контрольные пункты фиксируются в памяти системы управления доступом и могут использоваться для автоматизированного учета рабочего времени, а также для получения отчетов по дисциплине труда или для возможных служебных расследований на предприятии. Также с помощью СКУД можно осуществлять контроль въезда автотранспорта на территорию объекта, в этом случае после предъявления персонального идентификатора происходит открытие ворот или подъем шлагбаума.


1.2Основные возможности системы контроля и управления доступом (СКУД)


Перечислим ниже основные возможности, которые предоставляет установка СКУД на охраняемом объекте:

Контроль и управление доступом -это основная функция системы. Как уже было замечено ранее, с помощью данной функции производится разделение прав доступа сотрудников в определенные помещения, а также отказ в доступе нежелательным лицам. Кроме того, возможно дистанционное управление блокирующими устройствами (замки, турникеты и пр.). СКУД позволяет запретить проход для сотрудников в праздничные и выходные дни, а также после окончания рабочего дня.

Сбор и предоставление статистики. СКУД собирает информацию о лицах, которые прошли через определенные точки контроля доступа. По каждому сотруднику возможно получение следующей информации: время входа и выхода, попытки доступа в запрещенные для него помещения и зоны, а также попытки прохода в неразрешенное время. Также возможно отследить перемещение сотрудника по территории с указанием места и времени. Таким образом, все выявленные нарушения трудовой дисциплины могут быть занесены в личное дело сотрудника, а руководство нарушителя уведомлено в рабочем порядке. Кроме того, следуя информации о последней точке прохода, СКУД позволяет определить местонахождение сотрудника в любой момент времени.

Доступ сотрудника только по личному идентификатору. При проходе с помощью идентификационной карты на экране монитора в пункте охраны может отображаться вся информация по сотруднику и его фотография, что исключает возможность прохода по чужому идентификатору. Также на уровне правил реакции СКУД можно обеспечить защиту от передачи идентификатора другому лицу и блокировать повторный вход на территорию объекта по той же самой карте доступа.

Учет рабочего времени. С помощью встроенной в СКУД системы учета рабочего времени, регистрируется время выхода на работу и время ухода с рабочего места. В результате предоставляется возможность определить суммарное время пребывания сотрудника на рабочем месте с учетом обедов. А в самом начале дня, например, в 9:30 система учета рабочего времени, встроенная в СКУД, может формировать групповой отчет о сотрудниках, не прошедших через контрольную точку входа на территорию. Это позволяет в массовом порядке выявлять опоздавших или не явившихся на рабочее место сотрудников. Аналогичный отчет можно получить и в конце рабочего дня на пункте выхода с территории предприятия или офиса.

Автономность работы системы. СКУД оснащается системой бесперебойного питания, что позволяет не прерывать работу в случае отключения электричества в здании. Также система контроля доступом благодаря функционалу контроллера имеет возможность продолжать работу, например, при выходе управляющего компьютера из строя.

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

Удаленное управление системой через интернет или с мобильного телефона. Если при установке подключить СКУД к сети Интернет, то у администрации появляется возможность вести удаленное управление и контроль за работой системы. Аналогичное можно сказать и про возможность управления СКД со своего мобильного телефона, правда это больше относится к GSM системам контроля доступа.

Интеграция СКУД и СКД с другими системами безопасности и охраны. Системы контроля и управления доступом прекрасно сочетаются и встраиваются с другими системами безопасности: системой видео- наблюдения, охранной и пожарной сигнализацией. Так, например, контроль доступом вместе с видеонаблюдением обеспечивают абсолютный контроль над охраняемыми помещениями. При возникновении внештатной ситуации такая система в кратчайшие сроки позволит выявить и заблокировать нарушителя.

При интеграции СКУД и охранной сигнализации имеется возможность настроить совместную реакцию системы на несанкционированное проникновение в то или иное помещение. Например, можно включить сирену на пункте охраны, тревожную лампу или же и вовсе заблокировать все двери в требуемой части здания.

Интеграция СКУД с системой пожарной сигнализации позволяет автоматически разблокировать двери, турникеты и проходные в случае пожара. Все эти меры значительно упрощают эвакуацию персонала в столь трудный период.


1.3Обзор компьютерных систем контроля и управления доступом

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

В наше время существует большое количество СКУД систем. Анализ существующих компьютерных систем поможет определить их достоинства и недостатки.

СКУД на основе идентификации по геометрическому строению руки и пальцев

Эти способы личной идентификации очень хорошо известны. Идентификация по форме руки была доступна на протяжении 20 лет. Для того, чтобы идентифицировать человека, системе достаточно измерить либо физические характеристики пальцев, либо руки, такие как длина, ширина, толщина и поверхностные области руки. Одной интересной характеристикой этой технологии является малый объем биометрического образца, необходимого для идентификации (несколько байтов). Идентификация по руке уже доказала свои преимущества в большом числе применений.

Практически всё о конкретном человеке можно прочитать по его руке. Однако, в биометрике в целях идентификации (или аутентификации) используется сейчас только простая геометрия руки - размеры и форма, а также некоторые информационные знаки на тыльной стороне руки (образы на сгибах между фалангами пальцев, узоры расположения кровеносных сосудов).

В биометрике выделяются два основных метода распознавания по геометрии кисти руки:

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

На рисунке 1.1 показаны контрольные (характеристические) точки силуэта руки и 17 исходных геометрических признаков руки, в данном случае отмеченные отрезками прямых линий, которые не входят в силуэты кисти. Как видно, исходными биометрическими признаками руки являются ширина ладони, радиус вписанной в ладонь окружности, длины пальцев (определяемые как расстояния от выделенных верхних контрольных точек до середин линий, соединяющих нижние контрольные точки), ширина пальцев и высота кисти руки в трех пунктах, отмеченных линиями а, b и c.


Рисунок 1.1 - Контрольные (характеристические) точки силуэта руки


Второй (более современный) - основан на смешанных характеристиках геометрических и образовых. К последним относятся образы на сгибах между фалангами пальцев, узоры (расположение) подкожных кровеносных сосудов. С руки снимаются четыре характеристики, из которых три являются скалярами и относятся к размерам пальцев.

Три первые характеристики - это ширина указательного пальца 1, высота указательного пальца 2 и длина среднего пальца 3, оцениваемая так, как показано на рисунке 1.2. Характеристика 4, в рассматриваемом случае, представляет собой изображение складок кожи на сгибе между средней и нижней фалангами указательного пальца. Вся информация о руке в рассматриваемом классе систем может быть записана не более чем 9 байтами.


Рисунок 1.2 - Геометрические и образовые характеристики силуэта руки


В качестве примера рассмотрим считыватель HandKey. Современные биометрические системы компании Recognition Systems предназначены для идентификации персонала, проходящего на территорию охраняемого объекта. В отличие от традиционных систем контроля доступа, работающих с различными электронными картами, в биометрических системах, работающих по технологии HandKey, идентификатором является рука сотрудника. Биометрические считыватели HandKey распознают персонал по размеру и форме кисти руки, что обеспечивает высокий уровень безопасности в силу уникальности строения кисти руки каждого человека.

Метод трехмерной идентификации HandKey предусматривает сличение профиля руки входящего человека с ранее полученным шаблоном по размеру ладони, длине, ширине и толщине пальцев и по ряду других параметров. Первоначальная запись шаблона геометрии руки реализуется с помощью трехразового сканирования кисти руки сотрудника и усреднения полученной информации.

Для того чтобы биометрическая система могла произвести считывание, человек должен положить ладонь руки на панель устройства, а специальные штырьки-фиксаторы помогают скорректировать ее расположение. Встроенные светодиоды на панели считывателя сигнализируют о корректности расположения ладони, что упрощает взаимодействие человека с устройством.

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

Ссистемы HandKey осуществляют процедуру идентификации личности в два взаимосвязанных этапа: набор уникального идентификационного номера, состоящего из 1-10 цифр, и непосредственно сканирование кисти руки на панели считывателя. В сравнении с традиционными системами контроля доступа, использующими считыватели различных электронных карт, биометрические системы требуют только запоминания кода. Также важно подчеркнуть то, что второй этап идентификации - сканирование кисти руки пользователя и полностью исключает несанкционированный проход в охраняемые помещения по чужой или украденной карте доступа.

В то же время биометрические системы доступа (созданные на основе биометрических считывателей HandKey II) предусматривают возможность подключения считывателей карт доступа, что позволяет использовать проксимити-, виганд- и другие электронные карты вместо набора уникального идентификационного номера на клавиатуре считывателя. Как правило, считыватели карт доступа подключают к биометрическим считывателям с целью оптимизации времени идентификации - при большом потоке людей не нужно терять время на набор своего идентификационного номера перед процедурой верификации кисти руки.

Двухэтапная процедура идентификации пользователя с одной стороны существенно повышает уровень безопасности, а с другой стороны позволяет практически мгновенно осуществить проверку из базы данных. То есть, набирая свой индивидуальный код на клавиатуре системы (или, как вариант, используя карту доступа) человек, перед тем как пройти верификацию по форме кисти руки, заранее «сообщает» биометрическому считывателю с каким именно шаблоном сравнивать полученные данные. Таким образом, время верификации по форме кисти руки не превышает 1 секунды, а общее время идентификации в системе с учетом набора кода или использования электронной карты составляет 1-5 секунд.

Архитектура СКУД на базе биометрического считывателя HandKey II представлена на рисунке 1.3.


Рисунок 1.3 - Архитектура СКУД на базе биометрического считывателя HandKey II

Достоинства метода идентификации по геометрическому строению руки и пальцев:

"ключ" всегда с пользователем;

не предъявляются требования к чистоте, влажности, температуре;

Недостатки метода:

громоздкость устройств (за некоторым исключением);

невысокая сложность изготовления муляжа для устройств первого типа (использующих только геометрические характеристики).

СКУД на основе RFID карт

Основным элементом бесконтактных идентификационных средств является обрамленная электроникой специально организованная память, оформленная в виде пластиковой идентификационной карты или в иной конструкции. Увеличение объема памяти идентификационной карты, разделение этой памяти на независимые секторы превратило ее в многофункциональную(информационную) карту (ИК).

Возможности идентификационной карты позволяют создать единый многофункциональный электронный документ для каждого объекта. В зависимости от характера объекта различают два основных типа информационных карт:

информационная карта имущества(животного, автомобиля и т.д.);

информационная карта человека, выполненная, как правило, в виде стандартной пластиковой карты.

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

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

Для осуществления бесконтактной радиочастотной идентификации требуются три компонента:

Транспондер(ответчик-идентификатор), размещенный на объекте, подлежащем идентификации;

Считыватель информации с идентификатора(он же, если предусмотрено, записывает информацию в транспондер);

Получатель информации- приложение, компьютерная система обработки данных или оператор.


Рисунок 1.4 - Блок-схема системы радиочастотной идентификации


Считыватель обычно содержит радиочастотный модуль(передатчик и приемник), блок управления, включающий микропроцессор и память, и элемент связи с транспондером. Кроме того, многие считыватели оборудуются дополнительным интерфейсом (RS 232, RS 485), что бы иметь возможность передавать принятые данные в другую систему(ПК, систему обработки данных).

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

Процесс радиочастотной идентификации выполняется следующим образом:

Передатчик считывателя через антенну непрерывно(или в заданное время) излучает посылку радиосигнала с принятой в данной системе частотой;

Транспондер, находящийся в зоне действия считывателя, через свою антенну принимает этот радиосигнал и использует его энергию для электропитания(в этом заключается пассивность идентификатора - ему не требуется источник питания). Транспондер считывает код из своего запоминающего устройства(ЗУ) и моделирует им ответный радиосигнал;

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

Частота электромагнитного излучения и обратного сигнала, передаваемого транспондером, значительно влияют на характеристики работы RFID-системы, тем больше значения дальности, на которых считывается информация с радиочастотных меток.

Рабочая частота RFID-системы определяет ее сферу применения. Низкочастотные RFID-системы используются там, где допустимо небольшое расстояние между объектом и считывателем. Обычное расстояние считывания составляет 0,5 м, а для миниатюрных тегов дальность чтения, как правило еще меньше- около 0,1 м. Низкую частоту используют большинство систем управления доступом, системы управления складами и производством.системы с промежуточными значениями рабочей частоты используются там, где необходимо передавать большие количества данных, например в системах контроля доступа, в смарт-картах.

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

С помощью RFID-систем успешно решается целый ряд сложных организационно-технических задач:

Сокращение затрат на ввод данных и исключение ошибок, связанных с ручным вводом информации.

Полностью автоматическая регистрация идентифицированных объектов с последующей компьютерной обработкой результатов(пример: система регистрации пассажиров маршрутного такси или автобуса с автоматическим взиманием платы за проезд)

Обеспечение высокой оперативности регистрационной информации для менеджеров и клиентов компании

Высокая степень автоматизации управления имуществом, складами, транспортом, доступом людей в помещения

Улучшение контроля качества в производственных, складских и транспортных операциях

Сокращение учетного документооборота и трудозатрат.

На основе средств бесконтактной радиочастотной идентификации могут быть настроены самые разнообразные прикладные системы.

Преимущества RFID:

Бесконтактная работа - RFID-метка может быть прочитана без какого-либо физического контакта между меткой и ридером.

Перезапись данных - данные RFID-метки с перезаписью (RW-метки) могут быть перезаписаны большое число раз.

Работа вне прямой видимости - чтобы RFID-метка была прочитана RFID-ридером, в общем случае не требуется ее нахождения в зоне прямой видимости ридера.

Разнообразие диапазонов чтения - диапазон чтения RFID-метки может составлять от нескольких сантиметров до 30 метров и более.

Широкие возможности хранения данных - RFID-метка может хранить информацию объемом от нескольких байтов до практически неограниченного количества данных.

Поддержка чтения нескольких меток - RFID-ридер может автоматически читать несколько RFID-меток в своей зоне чтения за очень короткий период времени.

Прочность - RFID-метки могут в значительной мере противостоять жестким условиям окружающей среды.

Выполнение интеллектуальных задач - кроме хранения и передачи данных, RFID-метка может предназначаться для выполнения других задач (например, для измерения таких условий окружающей среды, как температура и давление).

Высокая точность чтения - RFID является точной на 100%.

RFID-метки практически невозможно подделать, так как при производстве метке присваивается уникальное неизменяемое число-идентификатор. Данные на метке могут быть зашифрованы. Как и любое цифровое устройство, радиочастотная метка обладает возможностью закрыть паролем операции записи и считывания данных, а также зашифровать их передачу. В одной метке одновременно можно хранить открытые и закрытые данные.

Однако RFID имеет недостатки:

Необходимо обеспечивать безопасность данных так, чтобы метка не могла быть перезаписана либо случайно (имеющим на то право ридером), либо намеренно (ридером, используемым мошенниками).

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

Кроме того, увеличение объема передаваемых данных ведет к повышению частоты возникновения ошибок передачи.

Метка с большим объемом памяти будет дороже меток, которые могут хранить только уникальный идентификатор.

СКУД на основе идентификации рисунка радужной оболочки и сетчатки глаза

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

Первая основана на идентификации рисунка радужной оболочки глаза. Вторая технология использует метод сканирования глазного дна - сетчатки глаза и базируется на уникальности углового распределения кровеносных сосудов для каждого человека.

Идентификация по радужке. При идентификации по радужной оболочке глаза используются индивидуальные различия сложных рисунков радужной оболочки глаза человека для установления индивидуальных особенностей. Идентификация по радужной оболочке глаза является самой точной из всех биометрических идентификационных систем. Коэффициент ошибочной идентификации является настолько низким, что вероятность ошибочной идентификации одной личности в качестве другой практически равна нулю. Радужка и сетчатка глаза представлены на рисунке 1.5.

Характеристики радужной оболочки глаза:

очень сложный рисунок, который отличается даже у близнецов;

рисунок стабилизируется в возрасте от шести месяцев до двух лет и остается неизмененным в течение всей жизни;


Рисунок 1.5 - Радужка и сетчатка глаза


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

Следующий этап идентификации - это приведение размера изображения радужки к эталонному. Это нужно по двум причинам. Во-первых, в зависимости от условий съемки (освещенность, расстояние для объекта) размер изображения может изменяться. Соответственно и элементы радужки тоже будут получаться разными. Впрочем, с этим особых проблем не возникает, так как задача решается путем масштабирования. А вот со второй причиной дела обстоят не так хорошо. Дело в том, что под воздействием некоторых факторов может меняться размер самой радужки. При этом расположение ее элементов относительно друг друга становится несколько иным. Для решения этой задачи используются специально разработанные алгоритмы. Они создают модель радужной оболочки глаза и по определенным законам воссоздают возможное перемещение ее элементов.

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

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

Ну и, наконец, последним этапом идентификации человека по радужной оболочке глаза является сравнение полученных параметров с эталонами. И у этого действия есть одно отличие от многих других подобных задач. Дело в том, что при выделении уникальных характеристик необходимо учитывать закрытые области. Кроме того, часть изображения может быть искажена веками или бликами от зрачка. Таким образом, некоторые параметры могут существенно отличаться от эталонного. Впрочем, эта проблема довольно легко решается благодаря избыточному содержанию на радужной оболочке глаза уникальных для каждого человека элементов. Как уже было сказано, совпадения 40% из них достаточно для надежной идентификации личности. Остальные же могут считаться "испорченными" и просто-напросто игнорироваться.

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

Идентификация по сетчатке. Сетка кровеносных сосудов сетчатки глаза также уникальна для каждого человека. Она не предопределена генетически и, поэтому, различна даже у близнецов. В тоже время она стабильна на протяжении всей жизни человека, что делает ее чрезвычайно удобным идентификатором. В терминалах для идентификации по сетчатке используется специальная камера с электромеханическим сенсором, регистрирующим отражающие и поглощающие характеристики сетчатки с определенного расстояния. Излучающая лампа имеет малую мощность, что исключает какое либо негативное воздействие на человека и не вызывает дискомфорта. Перед процессом идентификации клиент вводит свой PIN-код и смотрит в специальный окуляр. Вероятность ошибки второго рода (ложный допуск) FAR= одна миллионная (при любых обстоятельствах).

С точки зрения удобства самого процесса, технология идентификации по радужной оболочке глаза имеет существенное преимущество в сравнении с сетчаткой, поскольку нет необходимости смотреть в окуляр с расстояния 3 см, а достаточно просто подойти к считывателю на расстояние порядка 25 см.

На рисунке 1.6 представлена архитектура СКУД на основе идентификации по сетчатке и радужной оболочке глаза.


Рисунок 1.6 - Архитектура СКУД на основе идентификации по сетчатке и радужной оболочке глаза


Достоинства метода идентификации по сетчатке и радужной оболочке глаза:

статистическая надежность метода;

захват изображения радужной оболочки можно производить на расстоянии от нескольких сантиметров до нескольких метров, при этом физический контакт человека с устройством не происходит;

радужная оболочка защищена от повреждений роговицей (например, отпечатки пальцев легко портятся царапинами или пачкаются);

большое количество методов противодействия подделкам.

Недостатки метода:

цена системы для захвата радужной оболочки выше стоимости сканера отпечатка пальца и камеры для захвата 2D изображения лица;

Идентификацию по сетчатке глаза вполне можно обмануть


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


1.4Сравнительная характеристика методов идентификации


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

Рассмотрим характеристики, которые будет иметь каждая из систем: устойчивость к подделке, устойчивость к окружающей среде, простота использования, стоимость, скорость, стабильность во времени (таблица 1.2). Расставим оценки от 1 до 10 в каждой графе. Чем ближе оценка к 10, тем лучше система в этом отношении.


Таблица 1.2 - Оценка систем идентификации

Устойч. к подделкеУстойч. к окружающей средеСтоим.Скор.Стаби-льность призн. во времениКонфиг. ладони56365Радужная оболочка/сетчатка7/59/101/57/36/6Rfid-карта5810108

Исходя из требований, описанных в техническом задании, в качестве идентификатора для информационно-компьютерной СКУД, наиболее подходящие - идентификация по радиочастотным картам. Ключевыми особенностями, из-за которых, собственно, выбор и был остановлено именно на этом методе идентификации, является:

относительно низкая стоимость таких систем

вторым фактором является тот факт, что не нужно будет каждый раз подносить идентификатор к считывателю, достаточно подойти к считывателю на расстояние до 1-2 метров и считыватель произведет считывание с карты.

1.5Определение основных требований и ограничений


С развитием технологий радиочастотной идентификации, к ним выдвигаются и определённые требования.

Согласно ГОСТ 51241-2008 общие требования к системам контроля и управления доступом заключаются в следующем:

обеспечение защиты от несанкционированного доступа на охраняемый объект (помещение, зону) в режиме снятия их с охраны;

контроль и учет доступа персонала (посетителей) на охраняемый объект (помещение, зону) в режиме снятия их с охраны;

автоматизация процессов взятия/снятия охраняемого объекта (помещения, зоны) с помощью средств идентификации СКУД в составе устройств и приборов охранной сигнализации;

защита и контроль доступа к компьютерам автоматизированных рабочих мест (АРМ) пультового оборудования систем охранной сигнализации;

защита от несанкционированного доступа к информации.

СКУД в рабочем режиме должна обеспечивать автоматическую работу. Режим ручного или автоматизированного управления (с участием оператора) должен обеспечиваться только при возникновении чрезвычайных, аварийных или тревожных ситуаций, либо при наличии соответствующих требований в техническом задании.

Проектируемая СКУД должна также обеспечивать:

выдачу сигнала на открытие УПУ при считывании зарегистрированного в памяти системы идентификационного признака;

запрет открытия УПУ при считывании незарегистрированного в памяти системы идентификационного признака;

запись идентификационных признаков в память системы;

защиту от несанкционированного доступа при записи кодов идентификационных признаков в памяти системы;

сохранение идентификационных признаков в памяти системы при отказе и отключении электропитания;

ручное, полуавтоматическое или автоматическое открытие УПУ для прохода при аварийных ситуациях, пожаре, технических неисправностях в соответствии с правилами установленного режима и правилами противопожарной безопасности;

автоматическое формирование сигнала закрытия на УПУ при отсутствии факта прохода;

выдачу сигнала тревоги при аварийном открытии УПУ для несанкционированного проникновения.

Режим контроля доступа разрабатываемой СКУД - односторонний, с предъявлением идентификатора при входе и свободным выходом по нажатию кнопки.

Также разрабатываемая СКУД должна обеспечивать возможность непрерывной работы с учетом проведения регламентного технического обслуживания.

Кроме того, при проектировании СКУД следует учесть такие моменты:

считыватель должен быть отделен от контроллера, чтобы цепи, по которым производится открытие замка, были недоступны;

предпочтительно использовать оборудование в антивандальном исполнении с учетом климатических требований;

система должна обладать минимальной избыточностью оборудования;

система должна быть легко масштабируемой;

система должна иметь запас масштабируемости;

система должна легко интегрироваться с другими системами;

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

Требования к методу идентификации:

низкая стоимость радиочастотного считывателя;

привычность и понятность самой процедуры и правил идентификации для персонала.


2. Разработка информационно-компьютерной системы контроля и управления доступом


Система контроля и управления доступом предназначена для обеспечения безопасности охраняемого объекта и предотвращения несанкционированного проникновения.

СКУД может представлять собой как набор автономных элементов, предназначенных для решения простых задач по обеспечению безопасности, так и комплексную систему, отвечающую специфическим требованиям.

В процессе проектирования СКУД необходимо:

определить тип решаемых задач;

выбрать состав элементов системы, позволяющий наиболее эффективно решить поставленные задачи;

подобрать специализированное ПО, обеспечивающее возможность учета рабочего времени, централизованного управления системой при помощи АРМ и т.д.;

исходя из особенностей объекта и условий технического задания определить места установки оборудования;

для повышения эффективности СКУД может быть объединена с системой видеонаблюдения и охранно-пожарной сигнализацией.


2.1Разработка архитектуры СКУД


Прежде чем преступить к разработке СКУД системы нужно ознакомиться с классификацией архитектур таких систем и принять правильное решение по выбору архитектуры, основываясь на требованиях к системе.

Существующие типы архитектуры СКУД

По типу архитектуры СКУД классифицируются следующим образом:

автономные СКУД;

сетевые СКУД.

Автономные СКУД (рисунок 2.1) предполагают установку на объекте одного или ряда независимых контроллеров, каждый из которых реализует функции контроля и управления доступом в определенной локальной зоне. В таких СКУД отсутствует центральный контроллер - сервер системы. При этом конфигурирование каждого контроллера требуется производить отдельно. Учитывая, что контроллеры обычно устанавливаются в труднодоступных местах (например, за подвесным потолком), и, беря в учет возможное количество дверей и сотрудников на предприятии, становится понятно, что такой подход практически применим только для небольших объектов.


Рисунок 2.1 - Структура автономной СКУД


В противоположность автономным, сетевые СКУД (рисунок 2.2) имеют в своем составе центральный контроллер - сервер системы, с которым связаны все локальные контроллеры. Таким образом, для построения сетевой СКУД требуется прокладка кабельных трасс, обеспечивающих информационную связь контроллеров. Однако при использовании для связи контроллеров сетевого интерфейса Ethernet появляется возможность задействовать для этих целей существующую на объекте компьютерную сеть.

Достоинства сетевых СКУД:

возможность оперативно управлять всей системой: изменять полномочия доступа сотрудников, дистанционно разблокировать определенные двери или турникеты и т.д.;

возможность централизованного мониторинга с протоколированием всех событий;

возможность использовать систему учета рабочего времени (возможна только в случае применения административных мер по отношению к сотрудникам, проходящим через одно УПУ групой);

возможность реализации сложных алгоритмов (например, глобальный antipassback (APB) - защита от недобросовестных сотрудников, пытающихся пройти вдвоем по одному пропуску).


Рисунок 2.2 - Структура сетевой СКУД


Так как, исходя из требований, описанных в техническом задании, разрабатываемая система должна контролировать максимум 100 УПУ, то целесообразно применить сетевую архитектуру построения СКУД.

Архитектура компьютерной системы контроля и управления доступом к охраняемым объектам

Разработка архитектуры является неотъемлемой частью этапа разработки системы. Разрабатываемая система представляет собой службу для большого количества пользователей, т.к. согласно техническому заданию, максимальное количество пользователей разрабатываемой СКУД - >100 человек, а количество УПУ равно 20, то, разрабатываемая СКУД относится к среднему типу, тоесть десятки точек доступа и десятки-сотни пользователей (предприятия, учреждения, гостиницы и т.д.).

Все данные разрабатываемой СКУД (данные обо всех проходах через УПУ - время, дата, Ф.И.О. и должность пользователя) должны храниться в одном месте, т.е. в одной базе данных. Из вышесказанного можно сделать вывод, что наиболее соответствующей архитектурой для разрабатываемой системы будет являться архитектура клиент-сервер (рисунок 2.3).


Рисунок 2.3 - Архитектура клиент-сервер


Архитектура клиент-сервер - это архитектура распределенной вычислительной системы, в которой приложение делится на клиентский и серверный процессы.

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

На основе анализа существующих решений, была разработана собственная архитектура компьютерной системы контроля и управления доступом (СКУД), которая состоит из двух частей - программной и аппаратной подсистем.

Исходя из требований, описанных в техническом задании, в качестве идентификатора, решено было использовать RFID идентификацию, т.к. затраты на построение системы на основе такого метода существенно ниже чем при использовании любого другого метода идентификации. Также, RFID идентификация является относительно привычной для человека.

Общая архитектура информационно-компьютерной системы контроля и управления доступом к охраняемым объектам представлена на рисунке 2.4.


Рисунок 2.4 - Архитектура компьютерной системы контроля и управления доступом к охраняемым объектам


Программная подсистема состоит из серверной части, которая отвечает непосредственно за контроль и управление доступом и ОС Linux.

Серверная часть состоит из web-сервера и сервера баз данных.

Часть, отвечающая за контроль и управление доступом, представлена в виде «толстого» клиента. «Толстый» клиент выполняет идентификацию и аутентификацию пользователей.

Аппаратная подсистема состоит из серверного оборудования, средств контроля и управления доступом и исполнительных устройств.

Серверная часть программной подсистемы работает на серверном оборудовании.

Средства КУД представляют собой: считывающее устройство (для считывания RFID идентификатора), блок памяти и внешняя периферия (для хранения ядра системы). Для приема и обработки информации необходим управляющий элемент. Для передачи/получения данных с сервера, необходим интерфейс передачи данных, в нашем случае - предполагается использовать Ethernet.

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


2.2Выделение основных элементов СКУД


К аппаратной подсистеме СКУД относятся:

УС (предназначены для считывания идентификаторов и передачи соответствующей информации в контроллеры);

контроллеры (осуществляют обработку полученной от считывателей информации, принимают решение о допуске или запрете прохода, передают информацию на сервер системы);

серверы (осуществляют накапливать информацию обо всех проходах через УПУ - время, дата, Ф.И.О. и должность пользователей);

компьютеры с ПО (обеспечивают мониторинг, централизованное управление системой, ведение журнала событий, построение отчетов);

исполнительные устройства (в нашем случае - замки, которые обеспечивают блокировку дверей и проходов);

блоки питания (обеспечивают электропитание устройств системы как от сети, так и от автономных источников питания);

прочее оборудование (кнопки выхода - обеспечивают разблокирование исполнительных устройств при выходе из контролируемой зоны; доводчики - обеспечивают закрытие двери).

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

Данные будут храниться в базе данных. А так как потеря этих данных может привести к значительным последствиям, следовательно, на сервере должны быть предусмотрены аппаратные средства резервного копирования этой базы в виде репликации БД.

Управляющий элемент

Аппаратные средства управления должны обеспечивать прием информации от считывателей, обработку информации и выработку сигналов управления на исполнительные устройства.

В качестве управляющего элемента в разрабатываемой СКУД предполагается использовать микроконтроллер.

Микроконтроллер в СКУД должен обеспечивать:

обмен информацией по линии связи между контроллерами и средствами централизованного управления;

сохранность данных в памяти системы, при обрыве линий связи со средствами централизованного управления, отключении питания и при переходе на резервное питание;

контроль линий связи между контроллерами и средствами централизованного управления.

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

Микроконтроллеры должны иметь входы для подключения кнопки запроса на выход, контакта вскрытия корпуса, контакта отрыва от стены. Микроконтроллеры СКУД дополнительно могут иметь входы для подключения шлейфов охранной сигнализации.

Микроконтроллеры должны иметь выходы для подключения цепей управления исполнительными устройствами, выходы управления световой индикацией состояния доступа по каждому направлению, выходы управления световой и звуковой индикацией тревожных состояний.

Исходя из того, что в разрабатываемой системе данные со считывателя радиочастотной информации будут передаваться на сервер через Ethernet, то необходимо предусмотреть защиту передаваемых данных, а также, найти решение возможных проблем, возникающих при прохождении информационных пакетов через различные шлюзы и маршрутизаторы, разделяющие подсети. Решением вышеописанных проблем является организация VPN-соединения (Virtual Private Network) по SSL-протоколу (Secure Socket Layer) между сетевыми контроллерами и сервером системы. VPN в комбинации с SSL на данный момент считается самым безопасным методом для передачи данных в сетях.

Безусловно, это требует реализации VPN в ПО контроллера, для чего, опять же, более выигрышно смотрятся варианты со встраиваемыми ОС.

Для работы с операционной системой потребуется микроконтроллер, оперативная память, а также статическая память - такой конфигурации будет вполне достаточно для запуска ОС. Но так же не стоит забывать, о необходимости присутствия инструментария QT, с целью создания автономной подсистемы СКУД, в случае если средства централизованного управления выйдут из строя. Так же QT необходим, для создания процесса-демона, для опроса портов, с целью обеспечения связи между устройством считывания и сервером системы.

Учитывая вышеперечисленные характеристики, попробуем подобрать оптимальные ОС и оборудование. Для поддержки QT, нам достаточна операционная система Linux с ядром не ниже версии 2.6.32. или Windows Embedded Compact 7.

Чтобы запустить Linux с ядром не ниже версии 2.6.32. Windows Embedded Compact 7 необходимо 512 Мб оперативной памяти и 256Мб на жестком диске.

Для эффективной работы графической системы Windows Embedded Compact 7 необходимо: процессор с частотой 1ГГц.

Исходя из написанного выше, основными требования к микроконтроллеру будут:

частота не менее 1ГГц;

возможность подключения оперативной памяти объемом <512Мб;

поддержка загрузки операционной системы из Flash памяти;

NAND-flash памяти (с функцией ECC) и CompactFlash;

Устройство считывания (УС)

Считывающее устройство должно обеспечивать:

считывание идентификационного признака;

преобразование введенной информации в электрический сигнал;

передачу информации на контроллер СКУД.

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

Поскольку в качестве идентификатора в разрабатываемой СКУД была выбрана RFID карта, то считывающим устройством должен быть RFID сканер.

Основные требования к считывающему устройству:

-передача данных по USB, RS- 232.

-диапазон частот 13,56МГц.

2.2.1Анализ и выбор технологии считывающего устройства

Одним из основных элементов системы контроля и управления доступом к охраняемым объектам является считывающее устройство. В качестве УС был выбран RFID считыватель.

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

Антенна излучает электромагнитные волны, активизирующие RFID-метку и позволяющие производить запись и считывание данных с этой метки. Антенна является своеобразным каналом между меткой и приемопередатчиком, она контролирует весь процесс получения и передачи данных. Антенны отличаются по размерам и форме. Они могут быть встроены в специальные сканеры, а также в ворота, турникеты, дверные проёмы и т.д. Для получения информации от предметов или людей, проходящих через зону действия антенны. Конструктивно антенна и приемопередатчик с декодером могут находиться в одном корпусе. Сигнал, поступающий с антенны, демодулируется, расшифровывается и передается через стандартный интерфейс в компьютер для дальнейшей обработки.

Классификация типов частот RFID выглядит следующим образом:

Низкие частоты(НЧ).

Высокие частоты(ВЧ).

Ультравысокие частоты(УВЧ).

Микроволновые частоты.

В следующих разделах будут рассмотрены все типы частот.

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

Интерфейс - узел контроллера, состоящий из разъема, соединительного кабеля, а также драйвера (например, конвертора сигналов ТТЛ в RS-232 и обратно). Он предназначен для передачи информации от контроллера к главному управляющему узлу системы, например, к компьютеру. Наиболее часто сканеры оснащаются интерфейсами RS-232, RS-485, а в последнее время - чаще используется USB.

Низкие частоты (НЧ)

Низкими считаются частоты между 30 и 300 кГц, и в системах RFID обычно используются частоты в диапазоне от 125 до 134 кГц. Типичная НЧ RFID-система работает на частоте 125 или 134,2 кГц. В RFID-системах, работающих на низких частотах, обычно используются пассивные метки, принцип работы пассивных меток будет рассмотрен ниже, данные от метки к сканеру передаются с низкими скоростями, и они особенно хорошо подходят для рабочей среды, содержащей металлы, жидкости, различные виды загрязнений и снег (это очень важная характеристика НЧ- систем). Изготовителями также поставляются активные НЧ- метки. Вследствие высокой отработанности этого типа меток системы с НЧ- метками, возможно, имеют самое большое количество внедренных реализаций. НЧ- диапазон принят во всемирном масштабе.

Высокие частоты (ВЧ)

ВЧ находятся в диапазоне от 3 до 30 МГц, и типичной частотой, используемой в ВЧ RFID-системах, является 13,56 МГц. В типичной ВЧ RFID-системе используются пассивные метки к сканеру передаются с низкой скоростью и обеспечиваются хорошие рабочие характеристики в присутствии металлов и жидкостей. ВЧ- системы применяются также широко, особенно в больницах (где они не взаимодействуют с уже существующим оборудованием). ВЧ- диапазон принят во всемирном масштабе.

Следующий частотный диапазон называется диапазоном очень высоких частот (ОВЧ), и он охватывает частоты от 30 до 300 МГЦ. К сожалению в этом диапазоне современные RFID- системы не работают, поэтому нет смысла обсуждать этот тип частот.

Ультравысокие частоты (УВЧ)

УВЧ находятся в диапазоне от 300 МГц до 1 ГГц. Типичная пассивная УВЧ RFID-система работает на частотах 915 МГц в Соединенных Штатах и 868 МГц в Европе. Типичная активная УВЧ RFID-система работает на частотах 315 и 433 МГц. Следовательно, в УВЧ-системе могут использоваться как активные, так и пассивные метки. Данные между меткой и сканером передаются с высокой скоростью, но не обеспечиваются высокие характеристики в присутствии металлов и жидкостей (правда, не на нижних частотах УВЧ-диапазона 315 и 433 МГц). Развертывание УВЧ RFID-систем начало широко распространяться на основе недавних заказов на них от нескольких крупных частных и государственных предприятий, таких, как международные и национальные компании розничной торговли. Министерство обороны США и т.д. УВЧ-диапазон не принят во всемирном масштабе.

Микроволновые частоты (УВЧ)

Типичная микроволновая RFID-система работает либо на 2,45, либо на 5,8 ГГц, (хотя первая из частот более распространена). В ней могут использоваться как активные, так и полуактивные метки. Данные между меткой и ридером передаются с самой высокой скоростью и обеспечиваются самые низкие рабочие характеристики в присутствии металлов и жидкостей. Вследствие того что длина антенны обратно пропорциональна частоте, антенна пассивной метки, работающей в микроволновом диапазоне, имеет самую малую длину (что ведет к малому размеру метки, поскольку микрочип метки также может изготовляться очень малого размера). Частотный диапазон 2,4 ГГц называется промышленным, научным и медицинским диапазоном (Industry Scientific and Medical - ISM) и принят во всемирном масштабе. На частоты, которые используются для RFID, накладываются как международные, так и внутригосударственные ограничения. Поэтому некоторые из ранее обсуждавшихся частот могут не действовать во всемирном масштабе.

RFID метка

Метка (tag) RFID - это устройство, способное хранить данные и передавать их сканеру бесконтактным способом с помощью радиоволн.

Класификация RFID- меток может быть выполнена двумя различными способами. В приведенном ниже перечне показан первый способ классификации, основанный на наличии в метке встроенного источника питания и /или возможности поддержки специализированных задач:

Пассивные

Активные

Подробно рассмотрим их в следующих подразделах.

Пассивные меткиметка этого типа не содержит встроенного источника питания(например, батарею) и вместо этого для своего питания и передачи данных сканер использует энергию, излучаемую считывателем. Пассивная метка конструктивно проста и не содержит движущихся частей. В результате такая метка имеет большой срок службы в общем случае хорошо выдерживает жесткие условия окружающей среда. Например некоторые пассивные метки могут сопротивляться таким коррозионным химическим веществам, как кислоты, и нагреву свыше 200°С. При обмене информацией в направлении от метки к считывателю первым инициирует связь считыватель, а затем обмен осуществляет метка. Для передачи данных такими метками обязательно наличие считывателя.

Пассивная метка, как правило, меньше активной или полуактивной метки. Значение расстояния считывания у нее может быть самым различным - от менее 2,5 см и примерно до 9 м.

Стоимость пассивной метки также в общем случае меньше, чем у активной или полуактивной метки.

Бесконтактная смарт-карта является особым типом пассивной RFID- метки и используется сегодня в различных областях (например, в качестве жетонов-удостоверений в системах безопасности). Данные хранящиеся на такой карте, считываются в непосредственной близости от считывателя. Для считывания не нужно что бы карта была в физическом контакте с устройством чтения.

Пассивная метка состоит из следующих основных компонентов:

Микрочипа

Антенны

На рисунке 2.5 показаны компоненты пассивной метки


Рисунок 2.5 - Компоненты пассивной метки


Устройство управления питанием/выпрямитель преобразует питающее напряжение переменного тока, получаемое от сигнала с антенны считывателя, в питающее напряжение постоянного тока. Это устройство подает питание на остальные компоненты микрочипа. Выделитель тактовой частоты извлекает тактовый сигнал из сигнала, получаемого от антенны устройства чтения. Модулятор модулирует получаемый от считывателя сигнал. В модулированный сигнал вводится ответ метки, и этот сигнал затем передается обратно считывателю. Логическая схема отвечает за реализацию протокола информационного обмена между меткой и УС. Для хранения данных используется память микрочипа.

На рисунке 2.6 показаны компоненты микрочипа. В общем случае память разбита на сегменты(т.е. состоит из нескольких блоков или полей). Адресуемость означает способность обратится(т.е. прочитать или записать информацию) к отдельным участкам памяти микрочипа. Блок памяти метки может содержать данные различных типов, например порцию идентификационных данных отмеченного объекта, разряды контрольной суммы(например, циклический избыточный код - CRC) для проверки точности передаваемых данных и т.д. Последние технические достижения позволяют сделать микрочипы размером с песчинку. Но физически размеры метки определяются не величиной микрочипа, а расположением и размером ее антенны.


Рисунок 2.6 - Основные компоненты микрочипа


Антенна метки используется для извлечения энергии, питающей метку, из сигнала считывателя и приема-передачи данных между меткой и считывателем. Эта антенна физически прикреплена к микрочипу. Возможны бесчисленные конструкции антенн, особенно для УВЧ-диапазона, и их проектировании является настолько же искусством, как и наукой. Длина антенны прямо пропорциональна рабочей длине волны метки. Дипольная антенна состоит из прямолинейного отрезка проводника (например, из меди) с разрывом по средине. Общая длина дипольной антенны, оптимально передающей энергию сигнала, получаемого с антенны считывателя, равна половине длины волны используемой частоты. Двойная дипольная антенна состоит из двух диполей и значительно уменьшает чувствительность метки к ориентации. В результате этого считыватель может читать такую метку под различными углами. Петлевой диполь состоит из двух и более параллельно соединенных прямолинейных проводников, каждый длинной в половину волны (используемой частоты). Если он содержит два проводника, то получается 2-проводной петлевой диполь; 3-проводной петлевой диполь состоит из трех параллельно соединенных проводников. На рис. 2.7 показаны эти типы антенн.

Длинна антенны метки значительно превышает размеры микрочипа метки и следовательно, является главным параметром, определяющим физические характеристики метки. На выбор конструкции антенны оказывают влияние следующие факторы:

Расстояние считывания между меткой и считывателем.

Известная ориентация метки относительно считывателя.

Произвольная ориентация метки относительно считывателя.

Скорость движения метки.

Особые условия работы(окружающей среды).

Поляризация антенны считывателя.

Точки соединения микрочипа метки и ее антенны являются самыми слабыми местами метки. Если повреждается любая из этих точек соединения, то метка перестает работать или значительно ухудшает свои рабочие характеристики. Антенна, предназначена для конкретной задачи(например, отметка упаковочного ящика), может плохо выполнять другую задачу(например, отметка отдельного предмета в ящике).Произвольное изменение геометрии антенны(например, простым «откусыванием», перерезанием или сгибанием), как правило приводит к негативным результатам, так как метка теряет настройку и оптимальные рабочие характеристики.

В настоящее время большинство антенн меток изготовляется из тонкой металлической полоски(например, медной, серебряной или алюминиевой). Однако в будущем, возможно, антенны будут печатать непосредственно на поверхности метки токопроводящими чернилами, содержащими медь, углерод или никель. В результате этого стоимость RFID -метки может стать значительно ниже намеченных 5 центов США за метку.


Рисунок 2.7 - Типы дипольных антенн


Активные метки

В активных RFID- метках имеется внутренний источник питания(например, химическая батарея; но возможны и другие источники- такие, как солнечная батарея) и электроника для выполнения специализированных задач. В активной метке используется свой внутренний источник питания для передачи данных метки считывателю. Для передачи данных не требуется излучаемой считывателем энергии. Встроенная электроника может содержать микропроцессоры, датчики и порты ввода-вывода, получающие питание от внутреннего источника. Поэтому, например, такие компоненты могут измерять температуру окружающей среды и вырабатывать информацию о средней температуре и вырабатывать информацию для определения других параметров - скажем, срока годности товара, на котором они находятся. Затем метка может передавать эту информацию считывателю(вместе со своим уникальным идентификатором). Активную метку можно представить себе как компьютер с беспроводной связью, обладающий дополнительными свойствами (характерными, на пример, для датчика или набора датчиков).

В обмене информацией от метки к считывателю при таком типе метки связь всегда инициируется меткой с последующим участием считывателя. Так как для передачи данных присутствие считывателя не является обязательным, то активная метка может транслировать данные в окружающую среду даже при отсутствии считывателя. Активная метка такого типа передающая данные при наличии считывателя и при его отсутствии, так же называется передатчиком. В другом типе активной метки предусмотрен переход в спящее состояние, или состояние малой мощности, если нет запроса от считывателя. Считыватель выносит такую метку из спящего состояния, посылая соответствующую команду. Такое состояние экономит энергию батареи, и поэтому метка такого типа, как правило, имеет более продолжительный срок службы по сравнению с активной меткой-передатчиком. Кроме того, как метка ведет передачу только при запросе, то уровень радиочастотных помех в окружающей ее среде снижается. Этот тип активной метки называется передатчиком-приемником (или приемопередатчиком). Расстояние считывания активной метки может составлять около 30 м. и более при использовании активного передатчика такой метки.

Активная метка состоит из следующих компонентов:

Микрочипа. Размеры и функциональные возможности микропроцессора обычно превышают подобные параметры микрочипов пассивных меток.

Антенны. Она может иметь вид радиочастотного модуля, который может передавать сигналы метки и принимать в ответ сигналы устройства чтения.

Внутреннего источника питания.

Внутренней электроники.

На рисунке 2.8 - показаны примеры активной метки.

Рисунок 2.8 - Пример активной метки


Классификация меток по способности поддерживать перезапись данных:

Только с чтением (read-only - RO).

С однократной записью и многократным чтением (write once read many - WORM).

С многократной перезаписью (read-write - RW).

Метки SAW-типа.

Как активные, так и пассивные метки могут быть RO, WORM и RW-типа.

Метки RO-типа

Метка RO-типа может быть запрограммирована (т.е. записана) только один раз в своем жизненном цикле.

Данные заносятся в метку постоянным образом в заводских условиях только на этапе ее изготовления. Для этого в микрочип метки с помощью тонкого лазерного луча пережигаются отдельные плавкие перемычки. После того как это сделано, данные нельзя будет перезаписать в течение всего срока службы метки.

Метки такого типа также называются метками с заводским программированием. Изготовитель метки вводит в метку данные, и пользователь метки, как правило, не может оказывать на них никакого влияния.

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

Такой тип метки используется сегодня в небольших проектах и на малых предприятиях.

Метки WORM-типа

Метка WORM-типа может быть запрограммирована (записана) однократно, и это делается обычно не изготовителем, а пользователем метки в то время, когда необходимо создать метку.

Тем не менее, на практике для исправления ошибок при такой записи допускается возможность перезаписи некоторых типов WORM-меток (нередко встречается возможность перезаписи до 100 раз!). Если данные для такой метки перезаписываются более разрешенного количества раз, то метка может получить необратимое повреждение.

Метка WORM-типа также называется меткой с эксплуатационным программированием.

Метки RW-типа

Метка RW-типа может быть перепрограммирована (перезаписана) большое количество раз. Обычно это число варьируется от 10 000 до 100 000 раз и более! Такая способность перезаписи дает огромное преимущество, так как данные могут перезаписываться либо ридерами, либо самой меткой (в случае активной метки).

В метке RW-типа обычно содержится устройство памяти Flash или EEPROM-типа.метка также называется меткой с эксплуатационным программированием или перепрограммируемой меткой.

Для меток этого типа возможно решение задачи - обеспечение безопасности хранения информации.

Такая метка обеспечивает хорошее соотношение цены и рабочих характеристик, приемлемую безопасность данных и является наиболее распространенным типом метки.

Метки SAW-типа

Метки SAW-типа, работающие на принципе поверхностной акустической волны (surface acoustic wave - SAW).

Метка SAW-типа в корне отличается от меток на основе микрочипов. SAW-метки уже стали появляться на рынке и могут широко использоваться в будущем. В настоящее время устройства SAW широко применяются в сотовых телефонах, цветных телевизорах и т.д.

Для работы меток SAW-типа используются радиоволны малой мощности в частотном диапазоне 2,45 ГГц.

В отличие от меток с микрочипами SAW-метке не нужен источник постоянного тока для ее питания при передаче данных.метка состоит из дипольной антенны, присоединенной к встречно-штыревому преобразователю (interdigital transducer - IDT), расположенному на пьезоэлектрической подложке из ниобата лития или танталата лития. На подложке в точно рассчитанных местах расположены отдельные электроды, действующие как рефлекторы, изготовленные из алюминия или вытравленные на подложке. Антенна после приема радиочастотного сигнала от SAW-ридера подает электрический импульс на IDT. Этот импульс генерирует поверхностные волны, также называемые волнами Рэлея, и эти волны обычно проходят по подложке со скоростью от 3000 до 4000 м/с. Часть этих волн отражается рефлекторами обратно в IDT, а остальная часть поглощается подложкой. Отраженные волны образуют уникальную структуру, определяемую позициями рефлекторов и представляющую собой данные метки. Эти волны преобразуются в IDT обратно в радиосигнал и передаются через антенну метки назад RFID-ридеру. Затем ридер декодирует принятый сигнал и извлекает данные метки.метка имеет следующие преимущества:

Очень малое потребление энергии, так как ей не нужен источник постоянного тока для своего питания.

С ее помощью можно с хорошими результатами отмечать радионепрозрачные и радиопоглощающие материалы, например, металл и воду соответственно.

Большее расстояние чтения, чем у метки с микрочипом, работающей в том же частотном диапазоне (т.е. 2,45 ГГц).

Может работать с более короткими пачками радиосигналов в отличие от меток на микрочипах, требующих более продолжительного сигнала от ридера к метке.

Высокие степени точности чтения.

Большая прочность вследствие простоты конструкции.

Не требует применения антиколлизионных протоколов.

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

Выбор технологии передачи данных

Технология передачи данных определяет потенциальную удаленность контроллеров от компьютера, а также сложность и стоимость монтажа сетевой СКУД. Ориентироваться надо в первую очередь на стандартизированные технологии. На данный момент возможны несколько вариантов, а именно:

-сеть на базе протокола RS-232;

-сеть на базе технологии Ethernet;

-сеть на базе технологий USB.

Интерфейс RS-232 - интерфейс передачи информации между двумя устройствами на расстоянии до 20 м. Информация передается по проводам с уровнями сигналов, отличающимися от стандартных 5В, для обеспечения большей устойчивости к помехам. Асинхронная передача данных осуществляется с установленной скоростью при синхронизации уровнем сигнала стартового импульса.

Интерфейс RS-232-C был разработан для простого применения, однозначно определяемого по его названию "Интерфейс между терминальным оборудованием и связным оборудованием с обменом по последовательному двоичному коду". Каждое слово в названии значимое, оно определяет интерфейс между терминалом (DTE) и модемом (DCE) по передаче последовательных данных

Сигналы после прохождения по кабелю ослаюляются и искажаются. Ослабление растет с увеличением длины кабеля. Этот эффект сильно связан с электрической емкостью кабеля. По стандарту максимальная нагрузочная емкость составляет 2500 пФ. Типичная погонная емкость кабеля составляет 130 пФ, поэтому максимальная длина кабеля ограничена примерно 17 м.

Сетевая СКУД на базе технологии Ethernet позволяет организовать достаточно большое количество точек доступа, количество которых ограничивается только возможностями программного обеспечения. Такая сетевая СКУД может носить как локальный, так и распределенный характер и может взаимодействовать с составными частями через интернет.(ю-эс-би, англ. Universal Serial Bus - «универсальная последовательная шина») - последовательный интерфейс передачи данных для среднескоростных и низкоскоростных периферийных устройств в вычислительной технике. Символом USB являются четыре геометрические фигуры: большой круг, малый круг, треугольник и квадрат, расположенные на концах древовидной блок-схемы.

Разработка спецификаций на шину USB производится в рамках международной некоммерческой организации USB Implementers Forum (USB-IF), объединяющей разработчиков и производителей оборудования с шиной USB.

Для подключения периферийных устройств к шине USB используется четырёхпроводный кабель, при этом два провода (витая пара) в дифференциальном включении используются для приёма и передачи данных, а два провода - для питания периферийного устройства. Благодаря встроенным линиям питания USB позволяет подключать периферийные устройства без собственного источника питания (максимальная сила тока, потребляемого устройством по линиям питания шины USB, не должна превышать 500 мА, у USB 3.0 - 900 мА).


2.3Разработка программной подсистемы


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

Диаграммы вариантов использования системы контроля и управления доступом к охраняемым объектам

Информационно-компьютерная система контроля и управления доступом предназначена для автоматического управления входом/выходом людей в здания и помещения.

С данной системой могут работать оператор и пользователи. Для каждого из них предоставляются свои права в системе.

Пользователю (сотруднику предприятия) доступны два действия (рисунок 2.9) - идентификация (процесс опознавания субъекта по присущему ему или присвоенному ему идентификационному признаку) и аутентификация (процесс опознавания субъекта путем сравнения введенных идентификационных данных с эталоном).


Рисунок 2.9 - Диаграмма вариантов использования системы для пользователя


Все пользователи, которые обладают правом доступа к охраняемому объекту, предварительно должны пройти идентификацию, должен быть создан ID-номер идентифицирующий пользователя. Затем, когда пользователь хочет получить доступ к охраняемому объекту, он проходит аутентификацию, т.е. подносит устройство, хранящее ID-номер к считывающему устройству. Если если id номера на сервере и хранящем устройстве совпадают, то пользователь получает доступ к объекту (на сервер отправляется сообщение о санкционированном доступе), в противном случае - в доступе будет отказано, и на сервер будет отправлено сообщение о несанкционированной попытке получения доступа к объекту.

Оператор имеет доступ к настройке и управлению оборудованием, просмотру текущих событий системы, управлению списком объектов доступа, просмотру архива, а также получению отчетов (рисунок 3.28).


Рисунок 2.10 - Диаграмма вариантов использования системы для оператора


Настройка и управление оборудованием (рисунок 2.11) подразумевает под собой возможность оператора выполнять следующие действия:

-добавление новой точки доступа (ТД); точка доступа - это место, где осуществляется контроль доступа, в разрабатываемой системе в качестве ТД выступают только двери;

-удаление существующих ТД;

-оценка качества связи с микроконтроллером;

-ручное управление точками доступа (возможна установка трех режимов работы - нормального, заблокированного и разблокированного);

-настройка ТД (установка IP-адреса);

-управление микроконтроллером (получение технической информации о МК, просмотр и регистрация или удаление персонала на выбранной ТД).


Рисунок 2.11 - Диаграмма вариантов использования настройки и управления оборудованием


Просмотр событий системы (рисунок 2.12) заключается в том, что оператор может выбрать интересующие его точки доступа (одну, несколько, либо же все), настроить фильтр событий системы (например, показывать только события по зарегистрированных попытках несанкционированного доступа) и получить доступ к последним подобным событиям, имевшим место на данных точках доступа. Также, оператор может просмотреть учетные карточки пользователей.


Рисунок 2.12 - Диаграмма вариантов использования просмотра событий системы

События системы - это разрешённые или запрещённые попытки прохода через точку доступа, а также факты изменения (потери или появления) связи с контроллерами.

События доступа регистрируются микроконтроллером автономно и независимо от наличия связи с сервером, время и дата события регистрируются в соответствии со встроенными часами реального времени.

Все зарегистрированные события хранятся в энергонезависимой памяти контроллера и автоматически передаются на сервер СКУД при наличии связи.

Таким образом, в базе данных сервера хранятся все события СКУД, по которым можно получать отчёты за заданные промежутки времени.

Система хранит всю информацию о зарегистрированных ею событиях, начиная с момента её первого запуска, без временных ограничений. Количество событий в системе - неограниченно.

Управление списком объектов доступа (рисунок 2.13) заключается в том, что оператор может добавить либо удалить отдел предприятия, и доступна возможность редактирования данных учетных карточек пользователей. Присутствует также возможность поиска по списку объектов доступа (пользователей системы).


Рисунок 2.13 - Диаграмма вариантов использования управления списком объектов доступа

Просмотр архива (рисунок 2.14) заключается в том, что оператор имеет доступ к архиву абсолютно всех событий системы. Присутствует возможность использования фильтра событий (состоявшиеся проходы, проходы, санкционированные оператором, запрещенные проходы и взломы). Оператор также может просмотреть информацию о пользователях системы.


Рисунок 2.14 - Диаграмма вариантов использования просмотра архива


Получение отчетов (рисунок 2.15) подразумевает то, что оператор может, предварительно настроив нужные параметры и выбрав тип отчета, получить полный список интересующих его событий или данных.


Рисунок 2.15 - Диаграмма вариантов использования получения отчетов


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

Выбор СУБД для хранения данных

Выбор системы управления баз данных (СУБД) представляет собой сложную многопараметрическую задачу и является одним из важных этапов при разработке приложений баз данных. Выбранный программный продукт должен удовлетворять как текущим, так и будущим потребностям, при этом следует учитывать финансовые затраты на приобретение необходимого оборудования, самой системы, разработку необходимого программного обеспечения на ее основе, а также обучение персонала. Кроме того, необходимо убедиться, что новая СУБД способна принести реальные выгоды.

Из перечня требований к СУБД можно выделить несколько групп критериев:

моделирование данных;

особенности архитектуры и функциональные возможности;

контроль работы системы;

особенности разработки приложений;

производительность;

надежность;

требования к рабочей среде.

В таблице 2.3 приведены основные преимущества и недостатки трех наиболее популярных open-source СУБД - PostgreSQL, MySQL и FirebirdSQL.


Таблица 2.1 - Преимущества и недостатки различных СУБД

СУБД для хранения данныхMySQLPostgreSQLFirebirdSQLПреимущества- быстродействие; - безопасность и надежность; - отсутств. высоких требований к аппаратным ресурсам; - переносимость.- поддержка БД практически неограниченного размера; - мощные и надёжные механизмы транзакций и репликации; - наследование; - легкая расширяемость.- многоверсионная архитектура; - компактность (дистрибутив 5Mb); - высокая эффективн. и мощная языковая поддержка для хранимых процедур и триггеров.Недостатки- отсутствие транзакций и триггеров; - отсутствуют хранимые процедуры и вложенные запросы; - нет поддержки инструкции UNION; - отсутствие каскадного обновления данных.- относительная сложность инсталляции; - неверная работа окружения PostgreSQL; - отсутствие полной поддержки языков программирования VB и С#; - отсутствие Intellisense при программиров.- отсутствие кеша результатов запросов; - отсутствие полнотекстовых индексов.

Каждая база данных имеет свои особенности и отличия. Но так как для разрабатываемой системы необходимо быстрое хранилище для простых запросов с минимальной настройкой, то в качестве СУБД для хранения данных будет использоваться СУБД MySQL.

Разработка классов-сущностей

При разработке системы, было принято решение использовать ORM. ORM (аббревиатура от Object Relational Mapping- Объектно-реляционная проекция)- технология программирования, которая связывает базы данных с концепциями объектно-ориентированных языков программирования, создавая «виртуальную объектную базу данных». Суть проблемы, которая решается с помощью ORM-слоя, заключается в необходимости преобразования объектных структур в памяти приложения в форму, удобную для сохранения в реляционных базах данных, а также для решения обратной задачи - развертывания реляционной модели в объектную, с сохранением свойств объектов и отношений между ними. - это технология, обеспечивающая объектно-реляционное отображение простых JAVA объектов и предоставляющая API для сохранения, получения и управления такими объектами. - это спецификация (документ, утвержденный как стандарт, описывающий все аспекты технологии), часть EJB3 спецификации.

Сам JPA не умеет ни сохранять, ни управлять объектами. JPA определяет интерфейсы, которые должны будут быть реализованы провайдерами. JPA определяет правила о том, как должны описываться метаданные отображения и о том, как должны работать провайдеры. Дальше, каждый провайдер, реализуя JPA, определяет получение, сохранение и управление объектами. У каждого провайдера реализация разная.

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

«Уровень доступа»- Данную сущность будет создано для ограничения или же разрешения доступа тому или иному сотруднику в различные помещения.

«Группа сотрудников»- сущность будет служить для объединения сотрудников с одинаковыми правами доступа в одно подмножество. Чаще всего персонал из одного и того же отдела и с одной и той же должностью владеют одинаковым уровнем доступа, для объединения персонала с одним и тем же уровнем доступа будет создана данная сущность.

«Рабочие места»- сущность указывающая в какие комнаты сможет входить сотрудник, владея определенными правами доступа. Эта сущность необходима, так как, прежде чем пустить сотрудника в помещение, необходимо знать, имеет ли он на это право.

«Пользователь»- рабочий персонал. Данная сущность хранит персональные данные каждого работника компании, такие как Ф.И.О., дата рождения или должность.

«Пропущено по болезни»- для учета дней, проведенных сотрудниками на больничном. С помощью данной сущности система может точно подсчитать какую сумму заработной платы стоит начислить сотрудникам, с учетом больничных дней.

«Реальная зарплата»- сума заработанных денег за месяц, с учетом больничных, премиальных и штрафных.

«Переходы»- сущность для контроля и хранения всех переходов персонала из одного помещения в другое. Содержит информацию о времени входа в помещении, о месте от куда совершен переход. Если сотрудник впервые за день вошел в данную комнату, то в поле «от куда» будет храниться 0. Таким образом, можно отследить, куда в первую очередь ходил сотрудник. Так же сущность хранит данные о проведенном времени в том или ином помещении.

«Комната»- хранит номер комнаты и требуемый уровень доступа, для совершения положительного перехода.

«Этаж»- служит для хранения номера этажа и пути к SVG файлу (векторный рисунок), на котором изображен план помещения этажа.

«Здание»- сущность на случай, если офис расположен на территории более чем 1-го здания. Хранит номер здания,адрес по которому оно расположено и файл SVG, на котором размещено схематическое изображение здания.

Алгоритмы учета доступа к помещениям

При разработке системы было реализовано множество алгоритмов, но не хотелось бы останавливаться на всех. Поэтому будут рассмотрены несколько алгоритмов основного назначения системы, а именно алгоритмы учета доступа в помещения.

Сначала рассмотрим алгоритм учета входа в помещение. При совершении входа в помещение, система создает объект класса Transition(переход) и в локальную переменную tempId заносятся данные с карточки, а именно Id пользователя, которые считываются устройством чтения. Далее производится поиск данного пользователя в системе по его ID, если пользователь не найден, то в поля класса Transition, «isAccessPermitted» заносятся данные булевого типа «false», а в поле «reason»- «nu»(No User), после чего происходит завершение метода и возврат false. В противном случае, то есть в случае если пользователь с имеющимся ID присутствует в системе происходит запись в поля класса «toRoom» заносятся соответственные данные -номер комнаты, в которую совершаем переход, «timeIn» -время вхождения в комнату. После чего система проверяет имеет ли право сотрудник войти в данное помещение, если работник не обладает таким правом, то система заносит в поля класса «isAccessPermitted» данные булевого типа «false», а в поле «reason»- «na»(No Access) и завершает метод с возвратом false. В случае положительного результата проверки система заносит данные в поля «isAccessPermitted» булевого типа «true», а в поле «reason»- «ok»(и завершает метод возвращая true.

Второй алгоритм, который будет представлен ниже, обеспечивает учет выхода из помещения. При совершении выхода система производит поиск уже совершенного входа в комнату, требуемым сотрудником. В случае возвращения результата null методом поиска, метод выхода завершается возвращая false. В ином случае в поля объекта(объект передается методом findTransition) найденной транзакции заносятся данные, а именно в поле timeout заносится время выхода а в поле «spendtime» вводится число времени проведенное в помещении.

Выбор встраиваемой операционной системы (ОС) и языков программирования

На сегодняшний день наиболее популярными встраиваемыми операционными системами являются Embedded Linux и Windows Embedet compact. Embedded Compact 7 (известная ранее как Windows Embedded CE 7.0) - седьмая версия операционной системы реального времени Windows Embedded CE, развивающейся отдельно от семейства Windows NT, и ориентированной на предприятия, изготавливающие промышленные контроллеры и устройства бытовой электроники. Windows Embedded Compact может работать на различных микропроцессорных архитектурах и поддерживает x86, SuperH и ARM.Embedded Compact 7- это компонентная, многозадачная, многопоточная, многоплатформенная операционная система с поддержкой реального времени. Разработчикам доступны около 600 компонентов, используя которые они могут создавать собственные образы операционной системы, которые включает только необходимый данному конкретному устройству функционал.CE предоставляет разработчикам приложений набор API, основанный на стандартном Win32 API и дополненный специализированным API для встраиваемых устройств. Поскольку CE поддерживает только часть Win32 API и имеет определённую специфику, связанную со встраиваемой природой операционной системы, приложения, написанные для настольных версий операционной системы Windows, могут потребовать дополнительной адаптации и модификации для запуска их на встраиваемых устройствах; и в любом случае, для запуска программ на устройстве потребуется их перекомпиляция.

Но так же, как и настольные версии Windows, Windows CE использует стандартный формат исполняемого файла - Portable Executable (PE). Это позволяет разработчикам использовать большинство стандартных утилит, работающих с форматом PE, например Dependency Walker (проверка зависимостей) или DumpBin.

На базе Windows CE основано множество платформ, включая Handheld PC, Palm-size PC, Pocket PC, Windows Mobile, Meizu OS, а также множество промышленных устройств и встроенных систем.

Под Embedded Linux имеются в виду различные варианты ОС, в основе которых лежит ядро Linux, сконфигурированное для заданной аппаратной платформы, а также свободное программное обеспечение GNU: компилятор gcc, библиотека GNU libc и другие программные компоненты, выпускаемые под одной из открытых лицензий. Embedded Linux активно используется в проектах, связанных с разработкой отладочных плат и пакетов поддержки (BSP), программно-аппаратных комплексов на базе современных процессоров ARM, Blackfin, AVR32, MIPS, PowerPC.

Преимущества Embedded Linux перед Windows CE:

распространяется вместе с исходными кодами;

кроссплатформенность;

большое количество наборов разработчика;

бесплатная;

обширное количество материалов по использованию;

использование ядра Linux позволяет освободиться от написания драйверов для разного рода периферии.

В качестве встраиваемой ОС, в разрабатываемой системе будет использоваться Embedded Linux, исходя из преимуществ Linux, но пожеланию можно использовать и Windows, что никак не повлияет на работу системы в общем.

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

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

Си позволяет создавать программы с гораздо большим комфортом, предоставляя разработчику все преимущества языка высокого уровня. Компиляция исходных текстов, написанных на Си, осуществляется быстро и дает компактный, эффективный код.

Основные преимущества Си перед ассемблером:

высокая скорость разработки программ;

универсальность, не требующая досконального изучения архитектуры микроконтроллера;

лучшая документируемость и читаемость алгоритма; наличие библиотек функций;

поддержка вычислений с плавающей точкой.

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

Проанализировав основные особенности языков программирования Си и ассемблера, выбор был остановлен на Си.

Для разработки серверной части было принято решение использовать язык высокого уровня, а именно объектно-ориентированный язык программирования. На рассмотрение было предложено два языка программирования, удовлетворяющие условия(объектно-ориентированные, с синтаксисом, унаследованным от C):

C#,Разработан группой инженеров под руководством Андерса Хейлсберга в компании Microsoft как язык разработки приложений для платформы Microsoft.NET Framework

Java, разработанный компанией Sun Microsystems (в последующем приобретённой компанией Oracle). Приложения Java обычно компилируются в специальный байт-код, поэтому они могут работать на любой виртуальной Java-машине (JVM) вне зависимости от компьютерной архитектуры.

Решено использовать, в качестве языка разработки серверной части- Java, который, в отличии от C#, является межплатформенным.

Для создания web-интерфейса будет использоваться библиотека Vaadin.- это платформа веб-приложений с открытым исходным кодом для создания полнофункциональных интернет-приложений. В противоположность библиотекам JavaScript и решениям на основе браузеров/подключаемых модулей, в ее состав входит архитектура на стороне сервера, что означает выполнение большей части программной логики на серверах. Технология AJAX используется на стороне браузера для обеспечения функционально насыщенного и интерактивного интерфейса пользователя. На стороне клиента Vaadin строится на основе GWT и может быть расширена с ее помощью.

Основным элементом Vaadin является библиотека Java, рассчитанная на упрощение создания и обслуживания высококачественных веб-интерфейсов пользователей. Основная идея сервероцентричной модели программирования Vaadin состоит в том, что она позволяет забыть о сети и программировать интерфейсы пользователей точно так же, как мы программируем все настольные приложения Java, то есть с помощью обычных наборов средств, таких как AWT, Swing или SWT - только еще проще. Сервероцентричная модель программирования позволяет Vaadin взять на себя управление пользовательским интерфейсом в браузере и связь AJAX между браузером и сервером. Подход Vaadin позволяет не тратить силы на изучение и отладку технологий на стороне браузеров, таких как HTML или JavaScript.

Библиотека Vaadin четко отделяет представление пользовательского интерфейса от логики и позволяет разрабатывать их по отдельности. Подход Vaadin состоит в использовании тем, определяющих внешний вид приложений. Темы контролируют внешний вид интерфейсов пользователей посредством шаблонов CSS и (при желании) HTML. Vaadin предоставляет темы по умолчанию, но при необходимости можно создавать свои собственные. В серверной части Vaadin используется Google Web Toolkit (GWT) для визуализации интерфейса пользователя в браузере. Программы GWT пишутся на Java, но компилируются в JavaScript. GWT идеально подходит для реализации дополнительных компонентов интерфейса пользователя (или компонентов оформления окна, по терминологии GWT) и логики взаимодействия в браузере, тогда как Vaadin обрабатывает логику самого приложения на сервере. Платформа Vaadin разработана с расчетом на расширяемость и позволяет легко использовать любые компоненты GWT от сторонних производителей в дополнение к компонентам, предлагаемым в Vaadin. Использование GWT также означает, кто весь необходимый код пишется исключительно на Java.

Возможности Vaadin:

Использование Java как едиого языка программирования при создании веб-приложений и веб-контента - одна из наиболее значимых функций в Vaadin. Фреймворкиспользует событийную модель и определенные элементы пользовательского интерфейса, виджеты, что делает её очень близкой к модели разработки десктоп-приложений на Java с использованием HTML и Javascript

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

Использование Google Web Toolkit для отображения страниц с результатами поиска и обработки действий пользователя (наподобие терминального клиента). Так как Google Web Toolkit функционирует только на стороне клиента, Vaadin добавляет дополнительную валидацию данных на стороне сервера: это решает проблемы безопасности, связанные с возможностью подмены данных или кода Javascript. Соответственно, при изменении и повреждении данных, поступающих от браузера, сервер, определив это, не пропускает запросы.

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

Диаграммы классов

Во время проектирования системы были созданы диаграммы классов, для упрощения понимания «логики» системы. Рассмотрим набор классов, при помощи которых обеспечивается обмен данными между системой и базой данных.

В верху находиться интерфейс IID, который расширяют все классы сущности. Он создан для упрощения восприятия кода программы. Для того что бы не представлять все классы в виде AbstractClass<ClassName, ID>, с помощью данного интерфейса, мы представляем классы как AbstractClass<ClassName>. Рассмотрим каждую сущность по отдельности. Класс «AccessLevel» существует для хранения уровня доступа к тому или иному объекту для каждой группы персонала. Класс «GroupWorker» необходим для объединения персонала в некое множество, по различным принципам, для обеспечения прав доступа. «WorkBench» хранит данные о том, в каких помещениях трудиться тот или иной сотрудник, на предприятии. Это необходимо для того что бы корректно подсчитать время проведенное на рабочем месте. На пример, сотрудник IT отдела имеет право посещать помещение своего отдела, серверную, столовую и кабинет отдела маркетинга, но в столовой и в отделе маркетинга- он не проводит никаких полезных работ для предприятия, соответственно проведенное время на этих местах -не считается за время проведенное на работе. В случае отсутствия какого либо из помещений в данном списке- указывает на то что соответственная группа пользователей не имеет права доступа к помещению. Класс «RealSalary», хранит информацию о заработной плате за месяц, с учетом больничных, штрафных или же премиальных. Класс «MissByIll» для ведения учета о больничных каждого сотрудника, эта информация необходима, для корректного подсчета заработной платы,за месяц.

Класс «User» служит для хранения и верификации персональной информации о сотрудниках предприятия. Используя эти данные система принимает решение относительно разрешения доступа в помещение. Если сотрудника с данным ID не существует в базе данных, то система запретит доступ к любому помещению.«Transition» необходим для учета информации о переходах совершенных рабочим персоналом. На основе данной информации строится список переходов определенного сотрудника, высчитывается время проведенное на рабочем месте и расчет заработной платы, а так же основываясь данной информацией можно узнать где находиться работник в данный момент.

Ниже представлена диаграмма классов бизнес логики системы контроля и управления доступом. Класс «Index» выступает в роли главной страницы системы, он создает объект класса в котором инициализируются все необходимые компоненты размещенные на главной странице и производится разметка страницы. Так же класс «Index»отвечает за вызов всех форм, внутри которых размещена вся необходимая информация для управления системой, на пример форма «User» отображает список всех пользователей с возможность фильтровать список по различным критериям. На форме «Stage» отображен план этажа, кликнув на нужную комнату на плане помещения открывается список всех сотрудников находящихся в данной комнате в данный момент. Так же можно найти определенного пользователя на плане помещения задав его id или же Фамилию и инициалы.

Класс «AbstractForm» содержит все обобщенные методы всех классов форм, такие как добавление, удаление, замена, которые открывают пользователю компоненты полей для ввода данных. Каждая из форм занимается отображением данных на экран, а так же их добавлением, удалением и заменой.

Так же на схеме присутствует вспомогательный класс. «SpringContextHelper»-этот класс обеспечивает получение данных из репозиториев к контроллерам. Вместо DAO классов используется PagingAndSortingRepository - это интерфейс библиотеки spring-data, который входит в состав фреймворка «Spring». Используя данную библиотеку, не требуется создавать абстрактную фабрику DAO и наследовать всеми DAO классами обобщенные методы. Но для нормальной передачи информации из базы данных, через репозитории, к контроллеру, необходмо создать SpringContextHelper. Внутри этого класса необходимо создать конструктор внутри которого передать переменную которая определяет набор методов, которые сервлет использует для связи с его контейнером сервлетов. В противном случае данные не выводиться не будут.

В классе «Components» описана разметка, которая будет применена к главной странице, там же инициализируются все компоненты интерфейса главной страницы.


.4 Разработка аппаратной подсистемы


В качестве аппаратной подсистемы выступают устройства КУД. К ним относятся: считыватель (RFID -считыватель), управляющий элемент (контроллер). Также необходимо выбрать наиболее походящий интерфейс передачи данных между УС и контроллером. Совокупное взаимодействие этих аппаратных средств собственно и обеспечивает контроль и управление доступом.

Разработка структурной схемы устройства контроля и управления доступом (КУД)

Характерными особенностями проектируемого устройства КУД являются:

-наличие модуля NAND FLASH, с которого будет производиться загрузка операционной системы;

-наличие модуля SD/MMC для подключения карт памяти;

-использование ИБП для обеспечения постоянного питания устройств КУД, а также для автоматического обеспечения питания подключенных к ИБП устройств от встроенного аккумулятора в случае сбоев в электроснабжении;

-использование Ethernet-контроллера, для обеспечения связи сервера с проектируемым устройством.

Основными элементами структуры устройства КУД для аутентификации пользователей являются:

-считыватель RFID;

-микроконтроллер;

-Ethernet-контроллер;

-модуль DDR3;

-модуль NAND FLASH;

-модуль SD/MMC.

Ethernet-контроллер состоит из двух блоков. Блок Ethernet MAC отвечает за прием и формирование пакетов Ethernet. Блок PHY отвечает за формирование сигналов на линиях физического уровня интерфейса Ethernet. Блок PHY соединятся с блоком Ethernet MAC через интерфейс IEEE 802.3 MII (Media Independed Interface).

Для увеличения производительности контроллера к блоку MAC подключен буфер пакетов размеров 8 Кбайт. Увеличение производительности достигается за счет того, что внутренняя шина данных 32 разрядная, а внешний интерфейс для связи с микроконтроллером может быть как 32 разрядным, так и 8 или 16 разрядным. Опционально, к контроллеру Ethernet может подключаться энергонезависимая память для хранения различных настроек, таких например, как MAC адрес контроллера. К блоку PHY подключается внешний приемопередатчик для обеспечения подключения к шине Ethernet.

Выбор управляющего элемента

При выборе управляющего элемента необходимо учесть и оценить большое количество факторов.

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

Основные критерии выбора микроконтроллера в порядке значимости:

пригодность для прикладной системы;

доступность;

поддержка разработчика;

информационная поддержка;

надежность фирмы производителя.

В качестве управляющего элемента был выбран микроконтроллер из семейства Integra ARMCortex-A8- SK-iMX53, который полностью удовлетворяет всем вышеупомянутым критериям.

Микроконтроллер SK-iMX53 содержит процессор ARMCortex-A8.

Основные характеристики:

Основа платы - высокопроизводительный процессор фирмы FreeScale iMX536 (ARM Cortex-A8 до 1ГГц), имеет широчайший набор периферии и высокоскоростных интерфейсов (SATA, HS USB, Ethernet, LVDS...), встроенные сопроцессоры 3D (с поддержкой OpenGL ES 1.1 и OpenGL ES 2.0) и 2D графики, модуль кодирования-декодирования видео (декодирование 1080p - Full HD, кодирование 720p), модуль арифметики с плавающей точкой.

Подключенная периферия:

256МБайт SLC NAND flash

Ethernet 10/100M

SATA HDD разъем

I2S TLV320 аудио CODEC

SPDIF выход

RS232 приемопередатчик

CAN

2 x USB host (USB-A), питание одного из разъемов приведено через джампер, что позволяет использовать его как Device

512MБайт (128Mx32) DDR3-800. Внимание!!! предыдущий вариант платы (V2) содержал 256МБайт DDR2-800

2 x LCD LVDS, возможность подключения SK-ATM0700D4-Plug или SK-TFT1024x768TP-Plug c двумя раздельными системными Framebuffer.

74 линии I/O, два разъема, один из которых подразумевает прямое подключение SK-HDMI-Plug (или аналогичной платы расширения), SK-VideoADC-Plug

Загрузка

-Штатная загрузка осуществляется с NAND flash

-Загрузка по USB

Выбор считывающего устройства

В разрабатываемой системе будем использовать Matrix III RD-ALL.

Применение:

Предназначен для работы с сетевыми и автономными системами безопасности контроля и доступа, а также платёжными и системами лояльности. Выход RS-232 и RS485 позволяет подключить считыватель к PC как непосредственно, так и на большом расстоянии до 1200 метров через конвертер USB 422(485). Для изделия отдельно поставляется комплект разработчика SDK-RDAll, позволяющий быстро освоить работу с изделием.

Основные характеристики:

-Одновременная работа в двух диапазонах 13,56MHz&125КHz

-Выбор коммуникационных интерфейсов

-Влага-и пыле защищенный корпус

-Привлекательная цена

-Гарантия: 18 месяцев с даты продажи, не более 24 месяцев от даты производства.

Технические характеристики:

-Рабочая частота: 13,56MHz & 125КHz одновременно

-Работа с картами: Mifare-UL (чтение и запись)

-Работа с картами&брелками: EM Marine,HID ProxCard II, Mifare

-Дальность чтения: 4-10 cm

-Напряжение питания: 8 - 18 В постоянного тока

-Потребление тока: 135mA(max)

-Звуковая/световая индикация: сигнал зумера, двухцветный светодиод

-Рабочая температура: -30°С +40°С

-Материал корпуса: ABS пластик

-Выходной интерфейс: RS-232, RS485, Wiegand 26, Dallas Touch Memory

-Размер(mm): 115х75х22

Так же будет использована еще одна модель RFID считыватель Z2-Usb.

Надежный настольный мультиформатный считыватель. Выход и питание USB. Одновременная работа с картами стандарта EM Marine 125Khz и Mifare 13.56Mhz. Все это позволит успешно применять считыватель Z-2 для дисконтных и платежных ситем, пункты проката, СКУД, идентификации, персонализации и других проектов использующих RFID технологии. Для изделия отдельно поставляется комплект разработчика SDK-Z2USB и бесплатная программа PlaceCard для автоматизации ввода номеров RFID карт в формы программ СКУД.Это позволяет быстро освоить работу с изделием.

Основные характеристики:

-Одновременная работа в двух диапазонах 13,56MHz & 125kHz
Питание и выход USB
-Технические характеристики:

-Рабочая частота: 13,56MHz&125КHz одновременно

-Чтение карт & брелков стандарта: EM Marine, HID, ProxCard II, Mifare (только чтение)

-Дальность чтения: 4-8 cm

-Питание: USB

-Звуковая/световая индикация: сигнал зуммера, двухцветный светодиод

-Рабочая температура: 0°С до +50°С

-Материал корпуса: ABS пластик

-Цвет корпуса: матовый чёрный

-Выходной интерфейс: USB

-Размер(mm): 110х80х24

Исполнительные устройства (УИ)

Согласно ГОСТ 51241-2008, устройства исполнительные (УИ) - это устройства или механизмы, обеспечивающие приведение в открытое или закрытое состояние УПУ (электромеханические, электромагнитные замки, электромагнитные защелки, механизмы привода шлюзов, ворот, турникетов и другие подобные устройства).

Для обеспечения блокирования двери при отсутствии проходов через нее и возможности автоматического ее отпирания при разрешении прохода применяются электрические управляемые замки и защелки, которые делятся на две основные категории:

-электромеханические;

-электромагнитные.

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

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

Врезной электромеханический замок модели EL480 финской компании ABLOY относится к группе замков соленоидного типа и предназначен для установки на узкие профильные двери. В отличие от других замков Abloy, этот электромеханический замок имеет независимые внешнюю и внутреннюю ручки, может работать в режимах «нормально открыт» и «нормально закрыт», имеет световую индикацию состояния и устанавливается как на «правые», так и на «левые» двери. При работе под управлением контроллера СКУД или «кнопки выхода» электромеханический замок блокирует / разблокирует только внешнюю ручку, а замок всегда можно открыть либо ключом, либо внутренней ручкой.

Специалисты ABLOY рекомендуют использовать электромеханический замок EL480 в качестве исполнительного устройства системы контроля и управления доступом (СКУД) для внутренних профильных дверей офисов, торговых помещений, общественных или административных зданий, складов, служебных помещений банков и др. Замок EL480 можно устанавливать на двери запасных выходов и на противопожарные двери. При необходимости электромеханический замок можно в любой момент открыть ключом или внутренней ручкой.

При работе EL480 под управлением СКУД, контроллер СКУД осуществляет блокировку или разблокировку внешней ручки электромеханического замка путем отключения или подачи напряжения питания на замок. В дежурном режиме электромеханический замок находится в запертом состоянии («нормально закрыт»), его внешняя ручка заблокирована и напряжение на замок не подается. Если на контроллер СКУД со считывателя поступает код владельца карты доступа, которому разрешен проход через дверь с EL480, контроллер подает на электромеханический замок напряжение, внешняя ручка замка разблокируется и дверь можно открыть извне. При этом внутренней ручкой электромеханический замок можно открыть всегда.

В зависимости от конфигурации СКУД электромеханический замок может управляться не только контроллером, но и считывателем, таймером, кнопкой выхода и другими устройствами. Схема подключения замка EL480 к устройствам СКУД представлена на рисунке 2.26.

В отличие от других замков ABLOY соленоидного типа, электромеханический замок EL480 имеет раздельные шпиндели оригинальной конструкции, благодаря чему ручки замка независимы друг от друга. Кроме того, EL480 универсален: его можно настроить для работы как на «правых», так и на «левых» дверях, перевести в режим «нормально открыт» или «нормально закрыт», поменяв направление соленоида, а также использовать источник постоянного тока напряжением 12 или 24 вольта.

Если электромеханический замок настроен для работы в режиме «нормально закрыт» и на него не подается напряжение питания, то ригель EL480 выдвинут в ответную часть и замок находится в закрытом состоянии, а его внешняя ручка заблокирована. В этом случае дверь заперта и ее можно открыть снаружи только ключом. Изнутри дверь всегда можно открыть внутренней ручкой.

Для открытия двери внешней ручкой на электромеханический замок необходимо подать напряжение питания. Как правило, электромеханические замки с режимом «нормально закрыт» устанавливают на внешние профильные двери офисов, находящиеся внутри офисного здания, поскольку при возможных сбоях в электропитании они всегда будут заперты.

Если во внутренних помещениях офиса, магазина, склада и других объектов двери должны быть разблокированы на открытие извне в дневное время и заблокированы в ночное, специалисты ABLOY рекомендуют использовать электромеханические замки EL480, настроенные на работу в режиме «нормально открыт». В этом случае, в дневное время суток напряжение питания на электромеханические замки не подается и внешние ручки замков не заблокированы. Чтобы электромеханический замок каждой двери перевести в запертое состояние, например, одновременно в 19-00, контроллер СКУД автоматически подает напряжение питания на все замки и блокирует их внешние ручки. Отпереть двери можно либо внутренней ручкой или ключем. После открытия и закрытия двери электромеханический замок снова заблокирует внешнюю ручку.

Как и другие замки Abloy, электромеханический замок EL480 сертифицирован по высшему классу устойчивости к взлому и имеет высокую износоустойчивость. Такие высокие эксплуатационные характеристики этих замков обусловлены особенностями их конструкции и применением запатентованных цилиндров Abloy. В зависимости от важности охраняемого объекта, в электромеханический замок этой модели можно установить цилиндры скандинавского овального или финского типа серий ASSA, Abloy Classic, Trio Ving, RUKO, Abloy Pro, а также цилиндры новой серии Protec, обладающие самой высокой надежностью в мире. Кроме того, от сверления и распиливания электромеханический замок предохраняют стальные шайбы и специальные пластины. Все детали замка EL480 выполнены из антикоррозионных сплавов, а ригель изготовлен из высококачественной стали.

Поскольку EL480 предназначен для установки в профильные двери, то электромеханический замок имеет очень малое расстояние от края двери до середины цилиндра (29 или 35 мм), узкую переднюю планку в 22 мм, а также скандинавский стандарт врезки. В корпус электромеханического замка встроен микропереключатель для установки положения ригеля, который выдвигается на длину до 14 мм. В комплект поставки EL480 входят переходные пластины, контактные муфты, крепежные винты, схема сверления и подключения, а также инструкция по монтажу замка на дверь.

Технические характеристики на электромеханический замок Abloy 480 представлены в таблице 2.2.


Таблица 2.2 - Технические характеристики замка EL480

ПараметрыЗначенияИндикация:- положения ригеля - положения ручки (нажата - не нажата)Рабочее напряжение:12 или 24 В постоянного тока (-10% - +15%)Рабочий ток:- максимальный 0,35 А - ток покоя 0,12 А (12 В) или 0,07 А (24 В)Диапазон температур:-20°С…+60°СВыход ригеля:14 ммШпиндель замка:8 ммОбработка планки:ХромированиеКомплект поставки EL480:электромеханический замок, контактные муфты, крепежные винты, инструкция установке и монтажу, схема подключения замка

Датчик открытия двери используется для регистрации факта прохода или взлома двери. При не подключенном датчике открытия двери:

-контроллер не будет регистрировать взломы двери;

-открытый контролером замок будет запираться только по таймеру, а не сразу при закрытии двери;

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

Как правило, в качестве датчика открытия двери используется геркон (герметичный контакт, управляемый магнитом).

Работа датчика открытия двери основана на замыкании магнитных контактов геркона (контактное устройство) при приближении постоянного магнита (задающее устройство).

Разработка протокола передачи данных

СКУД может использовать следующие протоколы - это UDP, TCP/IP и HTTP.- самый быстрый и ненакладный протокол. Позволяет обмениваться пакетами размером не более одного Ethernet-кадра (примерно 1500 байт). Но в СКУД контроллер редко обменивается с ПК пакетами размером более 100 байт. Таким образом, за счет скорости и простоты UDP - первый кандидат на использование в системе реального времени. Недостаток UDP - отсутствие гарантированной доставки сообщений - легко обходится теми же методами, что и при работе с RS-485: квитированием, т.е. передачей подтверждения приема каждого пакета./IP. Данный протокол обеспечивает гарантированную доставку, сам умеет на передающей стороне «резать», а на приемной «склеивать» большие пакеты данных, но это нам не очень и нужно. Зато он менее расторопен и намного более накладен в программной реализации. Преимущество его только в том, что чаще всего по умолчанию проходит через корпоративные коммутаторы и маршрутизаторы.

HTTP - это самый медленный из протоколов, он «надстроен» над TCP/IP и используется в качестве основного в WEB, т.е. именно с его помощью мы получаем информацию из Internet. Из этого следует, что он проходим практически в мировом масштабе, в чем его определенное преимущество. Но в системах реального времени его применение практически невозможно из-за медлительности.

Из краткого обзора очевидно, что для систем реального времени, какими являются системы управления доступом, предпочтительнее использовать протокол UDP.

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

-установление транспортного соединения;

-передача данных;

-разрыв транспортного соединения.

Функции, выполняемые транспортным уровнем:

-преобразование транспортного адреса в сетевой;

-межоконечное мультиплексирование транспортных соединений в сетевые;

-установление и разрыв транспортных соединений;

-межоконечное упорядочивание блоков данных по отдельным соединениям;

-межоконечное обнаружение ошибок и необходимый контроль за качеством услуг;

-межоконечное восстановление после ошибок;

-межоконечное сегментирование, объединение и сцепление;

-межоконечное управление потоком данных по отдельным соединениям;

-передача срочных транспортных блоков данных.

Протокол UDP, являясь дейтаграммным протоколом, реализует сервис по возможности, то есть не гарантирует доставку своих сообщений, а, следовательно, никоим образом не компенсирует ненадежность дейтаграммного протокола IP.

Единица данных протокола UDP называется UDP-пакетом или пользовательской дейтаграммой (user datagram). Каждая дейтаграмма переносит отдельное пользовательское сообщение. Это приводит к естественному ограничению: длина дейтаграммы UDP не может превышать длины поля данных протокола IP, которое, в свою очередь, ограничено размером кадра технологии нижнего уровня. Поэтому если UDP-буфер переполняется, то данные приложения отбрасываются. Заголовок UDP-пакета, состоящий из четырех 2-байтовых полей, содержит поля порт источника, порт получателя, длина UDP и контрольная сумма.

Поля Порт источника и порт получателя идентифицируют передающий и получающий процессы.

Поле Длина UDP содержит длину пакета UDP в байтах.

Поле Контрольная сумма содержит контрольную сумму пакета UDP, вычисляемую по всему пакету UDP с добавленным псевдозаголовком.

В поле Данные передается следующая информация: код сотрудника, который получил доступ к охраняемому объекту, а также дата и время прохода через УПУ.

Поле Протокол (длина 8 бит) идентифицирует протокол из заголовка пакета IP. Для UDP это значение равно 17. Одной из областей, где UDP применяется особенно широко, является область клиент-серверных приложений.

Недостаток UDP - отсутствие гарантированной доставки сообщений решается при помощи квитирования, т.е. передачи подтверждения приема каждого пакета.

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

Существуют два подхода к организации процесса обмена положительными и отрицательными квитанциями: с простоями и с организацией "окна".

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

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

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

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

Т.к. проектируемая система является системой реального времени, то целесообразнее использовать алгоритм квитирования методом "окна", за счет достижения максимально возможной величины скорости обмена.- интерфейс передачи информации между двумя устройствами на расстоянии до 20 м. Информация передается по проводам с уровнями сигналов, отличающимися от стандартных 5В, для обеспечения большей устойчивости к помехам. Асинхронная передача данных осуществляется с установленной скоростью при синхронизации уровнем сигнала стартового импульса.

Широко используемый последовательный интерфейс синхронной и асинхронной передачи данных, определяемый стандартом EIA RS-232-C и рекомендациями V.24 CCITT. Изначально создавался для связи компьютера с терминалом. В настоящее время используется в самых различных применениях.

Интерфейс RS-232-C соединяет два устройства. Линия передачи первого устройства соединяется с линией приема второго и наоборот (полный дуплекс) Для управления соединенными устройствами используется программное подтверждение (введение в поток передаваемых данных соответствующих управляющих символов). Возможна организация аппаратного подтверждения путем организации дополнительных RS-232 линий для обеспечения функций определения статуса и управления.


Таблица 2.3 - Каналы передачи данных RS-232

НаименованиеНаправлениеОписаниеКонтакт (25-контактный разъем)Контакт (9-контактный разъем)DCDINCarrie Detect (Определение несущей)81RXDINReceive Data (Принимаемые данные)32TXDOUTTransmit Data (Передаваемые данные)23DTROUTData Terminal Ready (Готовность терминала)204GND-System Ground (Корпус системы)75DSRINData Set Ready (Готовность данных)66RTSOUTRequest to Send (Запрос на отправку)47CTSINClear to Send (Готовность приема)58RIINRing Indicator (Индикатор)229

Интерфейс RS-232C предназначен для подключения к компьютеру стандартных внешних устройств (принтера, сканера, модема, мыши и др.), а также для связи устройств между собой. Основными преимуществами использования RS-232C по сравнению с Centronics являются возможность передачи на значительно большие расстояния и гораздо более простой соединительный кабель. В то же время работать с ним несколько сложнее. Данные в RS-232C передаются в последовательном коде побайтно. Каждый байт обрамляется стартовым и стоповыми битами. Данные могут передаваться как в одну, так и в другую сторону (дуплексный режим).

Различают 25-контактный (DB25P) или 9-контактный (DB9P) разъем для подключения RS-232C. Назначение контактов разъема приведено в таблице.

Назначение сигналов следующее:

-FG - защитное заземление (экран).

-TxD - данные, передаваемые компьютером в последовательном коде (логика отрицательная).

-RxD - данные, принимаемые компьютером в последовательном коде (логика отрицательная).

-RTS - сигнал запроса передачи. Активен во все время передачи.

-CTS - сигнал сброса (очистки) для передачи. Активен во все время передачи. Говорит о готовности приемника.

-DSR - готовность данных. Используется для задания режима модема.

-SG - сигнальное заземление, нулевой провод.

-DCD - обнаружение несущей данных (детектирование принимаемого сигнала).

-DTR - готовность выходных данных.

-RI - индикатор вызова. Говорит о приеме модемом сигнала вызова по телефонной сети.

Наиболее часто используются трех- или четырехпроводная связь (для двунапрвленной передачи).

Для двухпроводной линии связи в случае только передачи из компьютера во внешнее устройство используются сигналы SG и TxD. Все 10 сигналов интерфейса задействуются только при соединении компьютера с модемом.

Формат передаваемых данных показан на рисунке 2.34. Собственно данные (5, 6, 7 или 8 бит) соопровождаются стартовым битом, битом четности и одним или двумя стоповыми битами. Получив стартовый бит, приемник выбирает из линии биты данных через определннные интервалы времени. Очень важно, чтобы тактовые частоты приемника и передатчика были одинаковыми, допустимое расхождение - не более 10%). Скорость передачи по RS-232C может выбираться из ряда: 110, 150, 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200 бит/с.

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

Для подключения произвольного УС к компьютеру через RS-232C обычно используют трех- или четырехпроводную линию связи (см. рис. 1.1), но можно задействовать и другие сигналы интерфейса.

Обмен по RS-232C осуществляется с помощью обращений по специально выделенным для этого портам COM1 (адреса 3F8h...3FFh, прерывание IRQ4), COM2 (адреса 2F8h...2FFh, прерывание IRQ3), COM3 (адреса 3F8h...3EFh, прерывание IRQ10), COM4 (адреса 2E8h...2EFh, прерывание IRQ11). Форматы обращений по этим адресам можно найти в многочисленных описаниях микросхем контроллеров последовательного обмена UART (Universal Asynchronous Receiver/Transmitter), например, i8250, КР580ВВ51.

Шина USB (Universal Serial Bus - универсальная последовательная шина) появилась по компьютерным меркам довольно давно - версия первого утвержденного варианта стандарта появилась 15 января 1996 года. Разработка стандарта была инициировна весьма авторитетными фирмами - Intel, DEC, IBM, NEC, Northen Telecom и Compaq.

Основная цель стандарта, поставленная перед его разработчиками - создать реальную возможность пользователям работать в режиме Plug&Play с периферийными устройствами. Это означает, что должно быть предусмотрено подключение устройства к работающему компьютеру, автоматическое распознавание его немедленно после подключения и последующей установки соответствующих драйверов. Кроме этого, желательно питание маломощных устройств подавать с самой шины. Скорость шины должна быть достаточной для подавляющего большинства периферийных устройств. Попутно решается историческая проблема нехватки ресурсов на внутренних шинах IBM PC совместимого компьютера - контроллер USB занимает только одно прерывание независимо от количества подключенных к шине устройств.

Возможности USB следуют из ее технических характеристик:

-Высокая скорость обмена (full-speed signaling bit rate) - 12 Mb/s

-Максимальная длина кабеля для высокой скорости обмена - 5 m

-Низкая скорость обмена (low-speed signaling bit rate) - 1.5 Mb/s

-Максимальная длина кабеля для низкой скорости обмена - 3 m

-Максимальное количество подключенных устройств (включая размножители) - 127

-Возможно подключение устройств с различными скоростями обмена

-Отсутствие необходимости в установке пользователем дополнительных элементов, таких как терминаторы для SCSI

-Напряжение питания для периферийных устройств - 5 V

-Максимальный ток потребления на одно устройство - 500 mA

Поэтому целесообразно подключать к USB практически любые периферийные устройства, кроме цифровых видеокамер и высокоскоростных жестких дисков. Особенно удобен этот интерфейс для подключения часто подключаемых/отключаемых приборов, таких как цифровые фотокамеры. Конструкция разъемов для USB рассчитана на многократное сочленение/расчленение.

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

Питание непосредственно от USB возможно только для устройств с малым потреблением, таких как клавиатуры, мыши, джойстики и т.п.

Сигналы USB передаются по 4-х проводному кабелю


Таблица 2.4. - контакты USB

Номер контакта Назначение Цвет провода 1 V BUS Красный 2 D- Белый 3 D+ Зеленый 4 GND Черный Оплетка Экран Оплетка

Здесь GND - цепь "корпуса" для питания периферийных устройств, VBus - +5V также для цепей питания. Шина D+ предназначена для передачи данных по шине, а шина D- для приема данных.

Разработка структурированной кабельной системы (СКС)

Структурированная кабельная система (СКС) - это универсальная кабельная система здания, группы зданий, предназначенная для использования достаточно длительный период времени без реструктуризации.

Универсальность СКС подразумевает использование ее для различных систем:

-компьютерная сеть;

-телефонная сеть;

-охранная система;

-пожарная сигнализация.

Такая кабельная система независима от оконечного оборудования, что позволяет создать гибкую коммуникационную инфраструктуру предприятия. Структурированная кабельная система - это совокупность пассивного коммуникационного оборудования: кабель (этот компонент используется как среда передачи данных СКС), розетки (этот компонент используют как точки входа в кабельную сеть здания), коммутационные панели (используются для администрирования кабельных систем в коммутационных центрах этажей и здания в целом), коммутационные шнуры (используются для подключения офисного оборудования в кабельную сеть здания, организации структуры кабельной системы в центрах коммутации).

Для получения СКС, соответствующей международным стандартам, которая будет служить долгие годы не требуя модернизации и замены, при проектировании должны быть учтены нижеперечисленные требования:

-структурированная кабельная система должна быть выполнена в соответствии со стандартами - международным (ISO 11801), европейским (EN 50173);

-все коммуникации этажа должны быть сведены в единый центр коммутации (этажный распределитель), что ускоряет обслуживание сети и уменьшает время, затрачиваемое на переключение абонентов;

-СКС проектируется с учетом избыточности, как по числу абонентов, так и по пропускной способности, таким образом, закладывается возможность для дальнейшего ее расширения без реструктуризации;

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

-если на момент построения сети не известно точное количество необходимых рабочих мест, то СКС проектируется из расчета - одно рабочее место на каждые 6 м2.

-на каждое рабочее место должно быть подведено два взаимозаменяемых разъема RJ45.

Устройства контроля и управления доступом предполагается устанавливать на двери, ведущие к следующим помещениям банка: кредитному отделу, отделу обслуживания частных клиентов, бухгалтерии, приемной дирекции, комнате охраны, отделу обслуживания корпоративных клиентов, серверной, отделу технической поддержки, отделу по связям с общественностью, отделу WEB-дизайна, а также кабинету начальника отдела технической поддержки. Помимо этого, предполагается установить устройство КУД на дверь, ведущую из приемной в общий коридор отделения банка, для учета рабочего времени сотрудников банка (для этого необходимо установить два устройства КУД, на вход и на выход). Значит, общее количество устанавливаемых устройств КУД равно двенадцати.


3. Реализация информационно-компьютерной системы контроля и управления доступом


В состав информационно-компьютерной системы контроля и управления доступом к охраняемым объектам предприятия входят аппаратная и программная подсистемы.


3.1 Реализация структуры базы данных


Основными критериями, предъявляемыми к информационной БД являются:

-простота и удобство в создании базы данных и последующей работе с ней;

-удобный пользовательский интерфейс, который позволяет иметь доступ к любой информации, а также оперативно менять информацию в БД;

-удобное и наглядное отображение результатов поиска нужной информации;

-возможность вывода на печать любой информации из БД.

Прежде чем начать создавать любую базу данных, надо четко определить следующее:

-назначение базы данных;

-как БД будет использоваться;

-какие сведения в этой базе данных будут храниться, т.е. надо выявить цель создания базы данных.

В разрабатываемой БД будут содержаться сведения:

-о группе (название);

-об уровне доступа (номер доступа);

-о рабочем месте (номер кабинета);

-о пользователях (Ф.И.О., адрес, телефон, фото, паспортные данные, дата рождения);

-о зарплате (месяц, зарплата, время проведенное на рабочем месте);

-о пропусках по болезни (дата начала больничного, дата окончания больничного);

-о переходе (время проведенное, переход из, переход в, индикатор удачного перехода, причина запрета, время входа, время выхода);

-о комнате (номер комнаты, уровень доступа);

-об этаже (номер этажа, путь к макету чертежа);

-о зданиях (адрес, номер здания, путь к макету плана);

Т.к. создается реляционная БД, то выделение объектов предметной области - это один из важных этапов проектирования БД.

Процесс выделения информационных объектов предметной области может производиться двумя подходами: аналитическим и интуитивным.

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

Интуитивный подход - сразу устанавливаются типовые объекты предметной области и их взаимосвязи.

Наиболее рационально - это сочетание обоих подходов, т.к. на начальном этапе, как правило, нет полных сведений обо всех задачах.

Далее выполняется информационный анализ, который включает в себя:

-структурирование информации предметной области, т.е. ее представление отдельными структурными единицами - реквизитами и их размещение в источниках - документах (структурные единицы информации - реквизиты);

-формализация и моделирование данных, для их организации и обработки во внутримашинной сфере.

Проектирование БД начинается со сбора информации обо все объектах предметной области.

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

При построении модели данных в каноническом виде совокупность реквизитов объектов должна отвечать требованиям нормализации.

Реквизиты каждого объекта канонической модели должны отвечать требованиям, соответствующим третьей нормальной форме реляционной модели данных:

-объект должен содержать уникальный идентификатор - ключ;

-между описательными реквизитами не должно быть функциональных зависимостей;

-все реквизиты, входящие в составной ключ, должны быть взаимонезависимы;

-каждый описательный реквизит должен функционально полно зависеть от ключа;

-каждый описательный реквизит должен зависеть от ключа нетранзитивно, т.е. не должен зависеть через другой промежуточный реквизит.

Выполнение требований нормализации обеспечивает построение реляционной БД без дублирования данных и возможность поддержания целостности при внесении изменений.

Анализируя цель создания БД системы контроля и управления доступом, есть возможность сразу выделить объект «Оператор», который будет иметь следующие характеристики, приведенные на рисунке 3.34.


Таблица 3.1 - Описание таблицы «GroupWorker»

Название колонкиТип данныхОграниченияОписаниеIdbigint(20)not nullПервичный ключ, уникальный идентификатор группы пользователей.groupnameVarchar(255)not nullНазвание группы

Данные этого объекта отвечают требованиям нормализации:

-имеет уникальный идентификатор - ключ;

-между описательными реквизитами нет функциональной зависимости;

-каждый описательный реквизит функционально зависит от ключа.

Т.е. в полученных объектах все описательные реквизиты логически связаны.

Также, в проектируемую БД необходимо ввести еще девять объектов: «Уровень доступа», «Рабочее место», «Пользователь», «Пропущено по болезни», «Зарплата», «Переход», «Комната», «Этаж» и «Здание» описаны в таблицах 3.2-3.10.


Таблица 3.2 - Описание таблицы «AccessLevel»

Название колонкиТип данныхОграниченияОписаниеIdbigint(20)not nullПервичный ключ, уникальный идентификатор уровня доступа.levelnumberbigint(20)not nullУровень доступа к комнате, которую разрешено посещать

Таблица 3.3 - Описание таблицы «WorkBench»

Название колонкиТип данныхОграниченияОписаниеIdbigint(20)not nullПервичный ключ, уникальный идентификатор рабочего места.workbenchNumberbigint(20)not nullНомер помещения- являющееся рабочим местом

Таблица 3.4 - Описание таблицы «User»

Название колонкиТип данныхОграниченияОписаниеidbigint(20)not nullПервичный ключ, уникальный идентификатор работника.FirstNamebigint(20)not nullИмя сотрудникаLastNameVarchar(255)not nullФамилия сотрудникаbirthdayDatenot nullДата рожденияjobVarchar(255)not nullДолжность сотрудникаsalaryBigint(20)not nullставкаaddressVarchar(255)not nullДомашний адрессphoneVarchar(255)not nullТелефонPassportDataVarchar(255)not nullСерия и номер паспортаphotoVarchar(255)not nullПуть к фотографии на сервереdepartmentNameVarchar(255)not nullНазвание отделаobligedspendTimeBigin(20)not nullОбязательное время проведенное на рабочем месте

Таблица 3.5 - Описание таблицы «ReralSalary»

Название колонкиТип данныхОграниченияОписаниеIdbigint(20)not nullПервичный ключ, уникальный идентификатор заработной платы.DateDatenot nullНомер помещения- являющееся рабочим местомRealTimeWorkBigint(20)not nullВремя проведенное на рабочем месте, за месяцSalaryBigint(20)not nullНасчитанная заработная плата с учетом штрафов, больничных и премиальных

Таблица 3.6 - Описание таблицы «MissedByIllnes»

Название колонкиТип данныхОграниченияОписаниеIdbigint(20)not nullПервичный ключ, уникальный идентификатор больничного.FromDateDatenot nullДата начала больничногоToDateDatenot nullДата окончания больничного

Таблица 3.7 - Описание таблицы «Transition»

Название колонкиТип данныхОграниченияОписаниеIdbigint(20)not nullПервичный ключ, уникальный идентификатор перехода.fromRoomBigint(20)not nullНомер помещенияIoVarchar(255)not nullВремя проведенное на рабочем месте, за месяцisAccessPermitedTinyint(1)not nullНасчитанная заработная плата с учетом штрафов, больничных и премиальныхReasonVarcharnot nullПричина запрета доступаspendTimeBigint(20)Проведенное время в помещенииtimeInDatenot nullВремя входаTimeoutDatenot nullВремя выходаtoRoomBigint(20)not nullНомер помещения из которого выходим

Таблица 3.8 - Описание таблицы «Room»

Название колонкиТип данныхОграниченияОписаниеIdbigint(20)not nullПервичный ключ, уникальный идентификатор помещения.roomNumberInt(11)not nullНомер комнатыacessLevelInt(11)not nullУровень доступа

Таблица 3.9 - Описание таблицы «Stage»

Название колонкиТип данныхОграниченияОписаниеIdbigint(20)not nullПервичный ключ, уникальный идентификатор этажа.StageNumberInt(11)not nullНомер этажаsvgFilePathDatenot nullПуть к SVG файлу

Таблица 3.10 - Описание таблицы «Buildings»

Название колонкиТип данныхОграниченияОписаниеIdbigint(20)not nullПервичный ключ, уникальный идентификатор больничного.AddressVarchar(255)not nullДата начала больничногоbuildingsNumberInt(11)not nullДата окончания больничногоsvgFilePathVarchar(255)not nullПуть к SVG файлу

Были выделены все объекты предметной области, опираясь на фундаментальное базовое понятие функциональных зависимостей. Совокупность реквизитов объектов предметной области отвечает требованиям нормализации. Связи между объектами предметной области приведены в таблице 3.3.


Таблица 3.11 - Связи объектов предметной области

Главный объектПодчиненный объектТип связиКлюч связиГруппаРабочее место1:МКод_группыГруппаУровень доступа1:МКод_ группыГруппаПользователь1:МКод_ группыПользовательЗар. плата1:МКод_пользователяПользовательПропуск по болезне1:МКод_ пользователяПользовательПереход1:МКод_ пользователяПереходКалендарьМ:1Код_календаряПереход КомнатаМ:1Код_комнатыЗданиеЭтаж1:МКод_зданияЭтажКомната1:МКод_этажа

3.2 Описание процесса автоматизации сборки


Процесс сборки проводился с помощью Maven. Для иллюстрации настроек данного программного обеспечения, рассмотрим содержимое файла настроек pom.xml:


<?xml version="1.0" encoding="UTF-8"?>

<project>

<modelVersion>4.0.0</modelVersion>

<groupId>com.vaadin.tutorial</groupId>

<artifactId>Skudy</artifactId>

<packaging>war</packaging>

<version>1.0</version>

<name>Vaadin Web Application</name>


<properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<vaadin.version>7.0.0</vaadin.version>

<vaadin.plugin.version>${vaadin.version}</vaadin.plugin.version>

</properties>

<repositories>

<repository>

<id>vaadin-addons</id>

<url>#"justify"></repository>

<repository>

<id>vaadin-snapshots</id>

<url>#"justify"><releases>

<enabled>false</enabled>

</releases>

<snapshots>

<enabled>true</enabled>

</snapshots>

</repository>

</repositories>

<pluginRepositories>

<pluginRepository>

<id>vaadin-snapshots</id>

<url>#"justify"><releases>

<enabled>false</enabled>

</releases>

<snapshots>

<enabled>true</enabled>

</snapshots>

</pluginRepository>

</pluginRepositories>

<dependencies>

<dependency>

<groupId>com.vaadin</groupId>

<artifactId>vaadin-server</artifactId>

<version>${vaadin.version}</version>

</dependency>

<dependency>

<groupId>com.vaadin</groupId>

<artifactId>vaadin-client-compiled</artifactId>

<version>${vaadin.version}</version>

</dependency>

<dependency>

<groupId>com.vaadin</groupId>

<artifactId>vaadin-client</artifactId>

<version>${vaadin.version}</version>

<scope>provided</scope>

</dependency>

<dependency>

<groupId>com.vaadin</groupId>

<artifactId>vaadin-themes</artifactId>

<version>${vaadin.version}</version>

</dependency>

<dependency>

<groupId>javax.servlet</groupId>

<artifactId>servlet-api</artifactId>

<version>2.4</version>

<scope>provided</scope>

</dependency>

<dependency>

<groupId>org.eclipse.persistence</groupId>

<artifactId>javax.persistence</artifactId>

<version>2.0.4.v201112161009</version>

</dependency>

<dependency>

<groupId>org.hibernate</groupId>

<artifactId>hibernate-core</artifactId>

<version>4.1.9.Final</version>

</dependency>

<dependency>

<groupId>org.hibernate</groupId>

<artifactId>hibernate-entitymanager</artifactId>

<version>4.1.9.Final</version>

</dependency>

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<version>5.1.23</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-core</artifactId>

<version>3.2.1.RELEASE</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context</artifactId>

<version>3.2.1.RELEASE</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-web</artifactId>

<version>3.2.1.RELEASE</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context-support</artifactId>

<version>3.2.1.RELEASE</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-orm</artifactId>

<version>3.2.1.RELEASE</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-aop</artifactId>

<version>3.2.1.RELEASE</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-beans</artifactId>

<version>3.2.1.RELEASE</version>

</dependency>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.11</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-jdbc</artifactId>

<version>3.2.1.RELEASE</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-test</artifactId>

<version>3.2.1.RELEASE</version>

</dependency>

<dependency>

<groupId>org.springframework.data</groupId>

<artifactId>spring-data-jpa</artifactId>

<version>1.3.0.RELEASE</version>

</dependency>

<dependency>

<groupId>org.aspectj</groupId>

<artifactId>aspectjweaver</artifactId>

<version>1.7.1</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-aspects</artifactId>

<version>3.2.1.RELEASE</version>

</dependency>

<dependency>

<groupId>com.vaadin.addon</groupId>

<artifactId>jpacontainer</artifactId>

<version>3.0.0.beta1</version>

</dependency>

</dependencies>


<build>

<plugins>


<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-compiler-plugin</artifactId>

<configuration>

<source>1.6</source>

<target>1.6</target>

</configuration>

</plugin>

<!-- As we are doing "inplace" GWT compilation, ensure the widgetset -->

<!-- directory is cleaned properly -->

<plugin>

<artifactId>maven-clean-plugin</artifactId>

<version>2.4.1</version>

<configuration>

<filesets>

<fileset>

<directory>src/main/webapp/VAADIN/widgetsets</directory>

</fileset>

</filesets>

</configuration>

</plugin>

<plugin>

<groupId>com.vaadin</groupId>

<artifactId>vaadin-maven-plugin</artifactId>

<version>${vaadin.plugin.version}</version>

<configuration>

<extraJvmArgs>-Xmx512M -Xss1024k</extraJvmArgs>

<!-- <runTarget>mobilemail</runTarget> -->

<!-- We are doing "inplace" but into subdir VAADIN/widgetsets. Thiscompatible with Vaadin eclipse plugin. -->

<webappDirectory>${basedir}/src/main/webapp/VAADIN/widgetsets

</webappDirectory>

<hostedWebapp>${basedir}/src/main/webapp/VAADIN/widgetsets

</hostedWebapp>

<noServer>true</noServer>

<!-- Remove draftCompile when project is ready -->

<draftCompile>false</draftCompile>

<compileReport>true</compileReport>

<style>OBF</style>

<strict>true</strict>

<runTarget>#"justify"></configuration>

<executions>

<execution>

<configuration>

<!-- if you don't specify any modules, the plugin will find them -->

<!-- <modules> <module>com.vaadin.demo.mobilemail.gwt.ColorPickerWidgetSet</module>

</modules> -->

</configuration>

<goals>

<goal>resources</goal>

<goal>update-widgetset</goal>

<goal>compile</goal>

</goals>

</execution>

</executions>

</plugin>

<plugin>

<groupId>org.mortbay.jetty</groupId>

<artifactId>jetty-maven-plugin</artifactId>

<!--<configuration>-->

<!--<jettyConfig>src/main/webapp/WEB-INF/web.xml</jettyConfig>-->

<!--</configuration>-->

</plugin>

</plugins>

</build>

</project>


3.3 Тестирование программного обеспечения


На этапе реализации программного обеспечения было проведено тестирование классов, что бы удостоверится в корректности работы классов и в работоспособности. Тестирование классов проводилось с помощью JunitTest библиотеки. Программное обеспечение, за время проектирования и тестирования было доведено до состояния полной работоспособности.

Как можно увидеть со снимка, все тестовые методы были выполнены успешно. Что бы рассмотреть подробнее некоторые из тестовых методов, ниже представлено содержимое класса «AccessLevelTets»

Листинг класса «AccessLevelTets»:


@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = { "classpath:applicationContext.xml"})class AccessLevelTest {

@AutowiredAccessRepository accessRepository;

@AutowiredGroupRepository groupDao;

@Testvoid testCreateLevel() throws Exception {accessLevel = new AccessLevel();.setLevelNumber(123L);groupWorker = new GroupWorker();.setGroupName("Banjo Men");.save(groupWorker);.setGroupAccessLevel(groupWorker);.save(accessLevel);getId = accessLevel.getId();accessLevelTest = accessRepository.findOne(getId);mustEquals=accessLevelTest.getLevelNumber();.assertNotNull("It was your mistake!", accessLevelTest);.assertEquals((Object) mustEquals, 123L);.delete(getId);mD= groupWorker.getId();.delete(mD);mustNull=accessRepository.findOne(accessLevel.getId());.assertNull("It was your mistake", mustNull);

}

@Testvoid testUpdateLevel() throws Exception {accessLevel = new AccessLevel();.setLevelNumber(123L);groupWorker = new GroupWorker();.setGroupName("Banjo Men");.save(groupWorker);.setGroupAccessLevel(groupWorker);.save(accessLevel);accessLevelTest = accessRepository.findOne(accessLevel.getId());.setLevelNumber(1234567L);.saveAndFlush(accessLevelTest);mustEquals= accessLevelTest.getLevelNumber();.assertNotNull("It was your mistake!", accessLevelTest);.assertEquals((Object)mustEquals, 1234567L);.delete(accessLevel.getId());mD= groupWorker.getId();.delete(mD);mustNull=accessRepository.findOne(accessLevel.getId());.assertNull("It was your mistake", mustNull);

}

@Testvoid testDeleteLevel() throws Exception {accessLevel = new AccessLevel();.setLevelNumber(123L);groupWorker = new GroupWorker();.setGroupName("Banjo Men");.save(groupWorker);.setGroupAccessLevel(groupWorker);.save(accessLevel);getId = accessRepository.findOne(accessLevel.getId()).getId();.delete(getId);mD= groupWorker.getId();.delete(mD);groupWorkerTest=accessRepository.findOne(getId);.assertNull("It was your mistake",groupWorkerTest);

}

@Testvoid testGetGroupById() throws Exception {accessLevel = new AccessLevel();.setLevelNumber(123L);groupWorker = new GroupWorker();.setGroupName("Banjo Men");.save(groupWorker);.setGroupAccessLevel(groupWorker);.save(accessLevel);accessLevelTest = accessRepository.findOne(accessLevel.getId());mustEquals= accessLevelTest.getLevelNumber();.assertNotNull("It was your mistake!", accessLevelTest);.assertEquals((Object)mustEquals, 123L);.delete(accessLevel.getId());mD= groupWorker.getId();.delete(mD);mustNull=accessRepository.findOne(accessLevel.getId());.assertNull("It was your mistake", mustNull);

}}


.4 Реализация web-интерфейса


Интерфейс информационной системы разработан с учетом того, чтобы не вызвать дискомфорта при ее использовании. Интерфейс должен отвечать следующим требованиям:

иметь интуитивно понятную навигацию;

иметь эффективно подобранную цветовую гамму;

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

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

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

Если пользователь не знает пароль или логин оператора и пытается его подобрать, система после 3-х неудачных попыток выдаёт сообщение о блокировке IP адреса. Такой подход необходим для того, чтобы максимально усложнить подбор пароля пользователем, который не имеет прав работы с данной системой.

После успешной аутентификации, оператор получает доступ к интерфейсу по работе с системой.

Интерфейс предоставляет оператору все средства для управления СКУД, наблюдения за её состоянием и получения отчётов о событиях системы. Нажав на иконку вверху экрана можно попасть в соответствующий раздел, а именно: управление пользователями, статистика переходов, управление группами пользователей, просмотр плана этажей, поиск пользователя в помещениях, просмотреть заработную плату за текучий месяц, просмотреть список болеющих, отправить рассылку сотрудникам, выход из системы.

Нажав на кнопку «Группы пользователей», открывается окно,со списком групп пользователей.Как можно заметить на снимке, в окне GroupWorkers присутствуют 3 кнопки- добавить, изменить и удалить. Такое же окно можно увидеть на жав на кнопку пользователи, или список болеющих.

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

Нажав на кнопку «удалить», «добавить» или «изменить» откроется окно, с соответствующими полями, что позволит произвести выбранную операцию.

Интерфейс реализован при помощи jquery и ajax, что позволяет не перезагружать страницы, при каждом же действии. Система позволяет открыть все окна управления и переключатся между ними, как в графической ОС, без обновления самой страницы, что экономит время и делает систему более удобной в использовании.

СКУД позволяет отыскать нужного сотрудника, и вывести местоположение его на территории предприятия, если он находится на предприятии в текущий момент. Различные списки в системе можно фильтровать и выравнивать по различным критериям.

Так же была разработана интерактивная карта, которая отображает местонахождение сотрудников на на схематическом изображении кабинета, на плане помещения и отображение списка персонала находящегося в кабинете. Для того что бы просмотреть список пользователей достаточно навести на изображение кабинета и произвести щелчок левой кнопкой мыши по объекту.

С целью расширения функциональности системы был разработан модуль «карта территории» предприятия. В случае если территория предприятия занимает более чем одно здание, таким образом можно централизировать контроль и управление доступом. Для наглядности модуля- создан скриншот интерфейса данного модуля.


Выводы


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

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

Программная часть реализована с архитектурой клиент/сервер. В ходе выполнения данной квалификационной работы специалиста была разработана база данных и толстый клиент (Web-приложение) для оператора.

Результатом разработки являются архитектура разработанной системы, структура и схема электрическая принципиальная устройства контроля и управления доступом.

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

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

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

Разработка данной системы дает следующие преимущества:

-возможность контролировать рабочее время сотрудников;

-контроль и ограничение доступа посетителей и в то же время беспрепятственный проход сотрудников;

-организация базы данных на каждого сотрудника.

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


Перечень использованных источников


1ГОСТ 51241-2008 Средства и системы контроля и управления доступом. Классификация. Общие технические требования. Методы испытаний.

2Биометрическая идентификация и аутентификация [Электронный ресурс]. - Режим доступа: #"justify">Приложение 1


РЕАЛИЗАЦИЯ КЛАСОВ ДОМЕНОВ

11.1 Класс AccessLevel.java

package ua.com.lejastu.entity;

javax.persistence.;java.io.Serializable;


/

User: LejaStu

/

// @Component

@Entity

@Table(name = "ACCESSLEVEL")class AccessLevel implements IId {

/

Fields of Class AccessLevel

/


@Id

@GeneratedValue(strategy = GenerationType.AUTO)Long id;


@ColumnLong levelNumber;


@ManyToOne

@JoinColumn(name = "group_id",referencedColumnName = "id", nullable=true)GroupWorker groupAccessLevel;


/

Constructors of Class AccessLevel

/AccessLevel() {


}

AccessLevel(Long levelNumber) {.levelNumber = levelNumber;

}


/

Getters & Setters of Class AccessLevel

/

Long getId() {id;

}

void setId(Long id) {.id = id;

}

Long getLevelNumber() {levelNumber;

}

void setLevelNumber(Long levelNumber) {.levelNumber = levelNumber;

}

GroupWorker getGroupAccessLevel() {groupAccessLevel;

}

void setGroupAccessLevel(GroupWorker groupAccessLevel) {.groupAccessLevel = groupAccessLevel;

}

}

21.2 Класс Buildings.java

package ua.com.lejastu.entity;

javax.persistence.;java.io.Serializable;java.util.List;


/

User: LejaStu

/

@Entity

@Table(name = "BUILDINGS")class Buildings implements IId {


/

Fields of Class BuildingsRepository

/


@Id

@GeneratedValue(strategy = GenerationType.AUTO)Long id;


@ColumnString address;


@ColumnInteger housingNumber;


@ColumnString pathFile;


@OneToMany(mappedBy = "buildingsStage")List<Stage> buildingsStageList;


/

Constructor of Class BuildingsRepository

/

Buildings() {


}

Buildings(String address, String pathFile) {.address = address;.pathFile = pathFile;

}


/

Getters & Setters of Class BuildingsRepository

/

Long getId() {id;

}

void setId(Long id) {.id = id;

}

String getAddress() {address;

}

void setAddress(String address) {.address = address;

}

Integer getHousingNumber() {housingNumber;

}

void setHousingNumber(Integer housingNumber) {.housingNumber = housingNumber;

}

String getPathFile() {pathFile;

}

public void setPathFile(String pathFile) {.pathFile = pathFile;

}

List<Stage> getBuildingsStageList() {buildingsStageList;

}


}

31.3 Класс Calendaring.java

package ua.com.lejastu.entity;

javax.persistence.;java.io.Serializable;java.util.Date;java.util.List;


/

User: LejaStu

/

@Entity

@Table(name = "CALENDARING")class Calendaring implements IId {


/

Fields of Class CalendaringDao

/


@Id

@GeneratedValue(strategy = GenerationType.AUTO)Long id;


@Column

@Temporal(TemporalType.DATE)Date date;


@OneToMany(mappedBy = "calendarTrans")List<Transition> calendarTransList;


/

Constructors of Class Calendaring

/Calendaring() {


}

Calendaring(Date date) {.date = date;

}

Long getId() {id;

}

void setId(Long id) {.id = id;

}

Date getDate() {date;

}

void setDate(Date date) {.date = date;

}

List<Transition> getCalendarTransList() {calendarTransList;

}

void setCalendarTransList(List<Transition> calendarTransList) {.calendarTransList = calendarTransList;

}

}

41.4 Класс GroupWorker.java

# package ua.com.lejastu.entity;

javax.persistence.;java.io.Serializable;java.util.Date;java.util.List;


/

User: LejaStu

/

@Entity

@Table(name = "CALENDARING")class Calendaring implements IId {


/

Fields of Class CalendaringDao

/


@Id

@GeneratedValue(strategy = GenerationType.AUTO)Long id;


@Column

@Temporal(TemporalType.DATE)Date date;


@OneToMany(mappedBy = "calendarTrans")List<Transition> calendarTransList;


/

Constructors of Class Calendaring

/Calendaring() {


}

Calendaring(Date date) {.date = date;

}

Long getId() {id;

}

void setId(Long id) {.id = id;

}

Date getDate() {date;

}

void setDate(Date date) {.date = date;

}

List<Transition> getCalendarTransList() {calendarTransList;

}

void setCalendarTransList(List<Transition> calendarTransList) {.calendarTransList = calendarTransList;

}

}

51.5 Класс MissByIll.java

package ua.com.lejastu.entity;

javax.persistence.;java.io.Serializable;java.util.Date;


/

User: LejaStu

/

@Entity

@Table(name = "MISSBYILL")class MissByIll implements IId {


/

Fields of Class MissByIll

/


@Id

@GeneratedValue(strategy = GenerationType.AUTO)Long id;


@Column

@Temporal(TemporalType.DATE)Date fromDate;


@Column

@Temporal(TemporalType.DATE)Date toDate;


@ManyToOne

@JoinColumn(name = "user_id",referencedColumnName = "id", nullable=false)User userMissed;


/

Constructors of Class MissByIll

/

MissByIll() {

}

MissByIll(Date fromDate, Date toDate) {.fromDate = fromDate;.toDate = toDate;

}


/

Getters & Setters of Class MissByIll

/

Long getId() {id;

}

void setId(Long id) {.id = id;

}

Date getFromDate() {fromDate;

}

void setFromDate(Date from) {.fromDate = from;

}

Date getToDate() {toDate;

}

public void setToDate(Date to) {.toDate = to;

}

User getUserMissed() {userMissed;

}

void setUserMissed(User userMissed) {.userMissed = userMissed;

}

}

61.6 Класс RealSalary.java

package ua.com.lejastu.entity;

javax.persistence.;java.io.Serializable;java.util.Date;


/

User: LejaStu

/

@Entity

@Table(name = "REALSALARY")class RealSalary implements IId {


/

Fields of Class RealSalaryForm

/

@Id

@GeneratedValue(strategy = GenerationType.AUTO)Long id;


@Column

@Temporal(TemporalType.DATE)Date month;


@ColumnLong salary;


@ColumnLong realTimeWork;


@ManyToOne

@JoinColumn(name = "user_id",referencedColumnName = "id", nullable=false)User userSalary;


/

Constructors of Class RealSalaryForm

/

RealSalary() {


}

RealSalary(Date month, long salary, long realTimeWork) {.month = month;.salary = salary;.realTimeWork = realTimeWork;


}


/

Getter & Setters of Class RealSalaryForm

/

Long getId() {id;

}

void setId(Long id) {.id = id;

}

Date getMonth() {month;

}

void setMonth(Date month) {.month = month;

}

Long getSalary() {salary;

}

void setSalary(Long salary) {.salary = salary;

}

Long getRealTimeWork() {realTimeWork;

}

void setRealTimeWork(Long realTimeWork) {.realTimeWork = realTimeWork;

}

User getUserSalary() {userSalary;

}

void setUserSalary(User userSalary) {.userSalary = userSalary;

}

}

71.7 Класс Room.java

package ua.com.lejastu.entity;

javax.persistence.;java.io.Serializable;java.util.List;


/

User: LejaStu

/

@Entity

@Table(name = "ROOM")class Room implements IId {


/

Fields of Class Room

/


@Id

@GeneratedValue(strategy = GenerationType.AUTO)Long id;


@ColumnInteger number;


@ColumnInteger accessLevel;


@OneToMany(mappedBy = "roomTrans", fetch=FetchType.LAZY)List<Transition> roomTransList;


@ManyToOne(fetch=FetchType.LAZY)

@JoinColumn(name = "stage_id",referencedColumnName = "id")Stage stageRoom;


/

Constructors of Class Room

/

Room() {


}

public Room(int number, int accessLevel) {.number = number;.accessLevel = accessLevel;

}


/

Getters & Setters of Class Room

/

Long getId() {id;

}

void setId(Long id) {.id = id;

}

Integer getNumber() {number;

}

void setNumber(Integer number) {.number = number;

}

Integer getAccessLevel() {accessLevel;

}

void setAccessLevel(Integer accessLevel) {.accessLevel = accessLevel;

}

List<Transition> getRoomTransList() {roomTransList;

}

Stage getStageRoom() {stageRoom;

}

void setStageRoom(Stage stageRoom) {.stageRoom = stageRoom;

}


}

81.8 Класс RealSalary.java

package ua.com.lejastu.entity;

javax.persistence.;java.io.Serializable;java.util.List;


/

User: LejaStu

/

@Entity

@Table(name = "STAGE")class Stage implements IId {

/

Fields of Class Room

/

@Id

@GeneratedValue(strategy = GenerationType.AUTO)Long id;


@ColumnInteger stageNumber;


@ColumnString pathSvg;


@OneToMany(mappedBy = "stageRoom",fetch = FetchType.LAZY)List<Room> stageRoomList;


@ManyToOne(fetch = FetchType.LAZY)

@JoinColumn(name = "building_id",referencedColumnName = "id")Buildings buildingsStage;

Stage() {


}

Stage(int stageNumber, String pathSvg) {.stageNumber = stageNumber;.pathSvg = pathSvg;

}

Long getId() {id;

}

void setId(Long id) {.id = id;

}

Integer getStageNumber() {stageNumber;

}

void setStageNumber(Integer stageNumber) {.stageNumber = stageNumber;

}

String getPathSvg() {pathSvg;

}

void setPathSvg(String pathSvg) {.pathSvg = pathSvg;

}

List<Room> getStageRoomList() {stageRoomList;

}

Buildings getBuildingsStage() {buildingsStage;

}

public void setBuildingsStage(Buildings buildingsStage) {.buildingsStage = buildingsStage;

}


}

91.9 Класс Transition.java

package ua.com.lejastu.entity;

javax.persistence.;java.io.Serializable;java.util.Date;


/

User: LejaStu

/

@Entity

@Table(name = "TRANSITION")class Transition implements IId {


/

Fields of Class TransitionRepository

/


@Id

@GeneratedValue(strategy = GenerationType.AUTO)Long id;


@ColumnLong spendTime;

@ColumnString io;


@ColumnLong fromRoom;


@ColumnLong toRoom;


@ColumnBoolean isAccessPermitted;


@ColumnString reason;


@Column

@Temporal(TemporalType.DATE)Date timeIn;


@Column

@Temporal(TemporalType.DATE)Date timeOut;


@ManyToOne

@JoinColumn(name = "user_id",referencedColumnName = "id")User userTransition;


@ManyToOne

@JoinColumn(name = "calendaring_id",referencedColumnName = "id")Calendaring calendarTrans;

@ManyToOne(fetch=FetchType.LAZY)

@JoinColumn(name = "room_id",referencedColumnName = "id")Room roomTrans;


/

Constructors of Class TransitionRepository

/

Transition() {


}

Transition(Long fromRoom, Long toRoom, Boolean isAccessPermitted, String reason, Date timeIn) {.fromRoom = fromRoom;.toRoom = toRoom;.isAccessPermitted = isAccessPermitted;.reason = reason;.timeIn = timeIn;

}


/

Getters of Class TransitionRepository

/

Long getId() {id;

}

void setId(Long id) {.id = id;

}

Long getSpendTime() {spendTime;

}

void setSpendTime(Long spendTime) {.spendTime = spendTime;

}

String getIo() {io;

}

void setIo(String io) {.io = io;

}

Long getFromRoom() {fromRoom;

}

void setFromRoom(Long from) {.fromRoom = from;

}

Long getToRoom() {toRoom;

}

public void setToRoom(Long to) {.toRoom = to;

}

Boolean getIsAccessPermitted() {isAccessPermitted;

}

void setIsAccessPermitted(Boolean isAccessPermitted) {.isAccessPermitted = isAccessPermitted;

}

String getReason() {reason;

}

void setReason(String reason) {.reason = reason;

}

Date getTimeIn() {timeIn;

}

void setTimeIn(Date timeIn) {.timeIn = timeIn;

}

Date getTimeOut() {timeOut;

}

void setTimeOut(Date timeOut) {.timeOut = timeOut;

}

User getUserTransition() {userTransition;

}

void setUserTransition(User userTransition) {.userTransition = userTransition;

}

Calendaring getCalendarTrans() {calendarTrans;

}

void setCalendarTrans(Calendaring calendarTrans) {.calendarTrans = calendarTrans;

}

Room getRoomTrans() {roomTrans;

}

void setRoomTrans(Room roomTrans) {.roomTrans = roomTrans;

}

}

101.10 Класс User.java

package ua.com.lejastu.entity;

javax.persistence.;java.io.Serializable;java.util.ArrayList;java.util.Date;java.util.List;


/

User: LejaStu

/


@Entity

@Table(name = "USER")class User implements IId {


/

Fields of Class User

/


@Id

@GeneratedValue(strategy = GenerationType.AUTO)Long id;


@ColumnString firstName;


@ColumnString lastName;


@Column

@Temporal(TemporalType.DATE)Date birthDay;


@ColumnString job;


@ColumnLong salary;


@ColumnString address;


@ColumnString phone;


@ColumnString passportData;


@ColumnString photo;


@ColumnString departmentName;


@ColumnLong obligedSpendTime;

@OneToMany(mappedBy = "userTransition")List<Transition> userTransitionList = new ArrayList<Transition>();


@OneToMany(mappedBy = "userMissed")List<MissByIll> userMissedList = new ArrayList<MissByIll>();


@OneToMany(mappedBy = "userSalary")List<RealSalary> userSalaryList = new ArrayList<RealSalary>();


@ManyToOne

@JoinColumn(name = "group_id",referencedColumnName = "id", nullable=false)GroupWorker groupUser;


/

Const of User's Class

/

User() {


}

User(String firstName, String lastName, Date birthDay, String job, long salary, long obligedSpendTime,GroupWorker groupUser) {.firstName = firstName;.lastName = lastName;.birthDay = birthDay;.job = job;.salary = salary;.obligedSpendTime = obligedSpendTime;.groupUser=groupUser;

}

Long getId() {id;

}

void setId(Long id) {.id = id;

}

String getFirstName() {firstName;

}

void setFirstName(String firstName) {.firstName = firstName;

}

String getLastName() {lastName;

}

void setLastName(String lastName) {.lastName = lastName;

}

Date getBirthDay() {birthDay;

}

public void setBirthDay(Date birthDay) {.birthDay = birthDay;

}

String getJob() {job;

}

void setJob(String job) {.job = job;

}

Long getSalary() {salary;

}

void setSalary(Long salary) {.salary = salary;

}

String getAddress() {address;

}

void setAddress(String address) {.address = address;

}

String getPhone() {phone;

}

void setPhone(String phone) {.phone = phone;

}

String getPassportData() {passportData;

}

void setPassportData(String passportData) {.passportData = passportData;

}

String getPhoto() {photo;

}

void setPhoto(String photo) {.photo = photo;

}

String getDepartmentName() {departmentName;

}

void setDepartmentName(String departmentName) {.departmentName = departmentName;

}

public Long getObligedSpendTime() {obligedSpendTime;

}

void setObligedSpendTime(Long obligedSpendTime) {.obligedSpendTime = obligedSpendTime;

}

List<Transition> getUserTransitionList() {userTransitionList;

}

void setUserTransitionList(List<Transition> userTransitionList) {.userTransitionList = userTransitionList;

}

List<MissByIll> getUserMissedList() {userMissedList;

}

void setUserMissedList(List<MissByIll> userMissedList) {.userMissedList = userMissedList;

}

List<RealSalary> getUserSalaryList() {userSalaryList;

}

void setUserSalaryList(List<RealSalary> userSalaryList) {.userSalaryList = userSalaryList;

}

GroupWorker getGroupUser() {groupUser;

}

void setGroupUser(GroupWorker groupUser) {.groupUser = groupUser;

}

}

111.10 Класс Workbench.java

package ua.com.lejastu.entity;

javax.persistence.;java.io.Serializable;


/

User: LejaStu

/

@Entity

@Table(name = "WORKBENCH")class Workbench implements IId {

/

Fields of Class WorkbenchDao

/


@Id

@GeneratedValue(strategy = GenerationType.AUTO)Long id;

@ColumnLong workBenchNumber;


@ManyToOne

@JoinColumn(name = "group_id",referencedColumnName = "id", nullable=false)GroupWorker groupWorkbench;


/

Constructors of Class WorkbenchDao

/Workbench() {


}

Workbench(Long workBenchNumber) {.workBenchNumber = workBenchNumber;

}


/

Getters of Class WorkbenchDao

/

Long getId() {id;

}

void setId(Long id) {.id = id;

}

public Long getWorkBenchNumber() {workBenchNumber;

}

void setWorkBenchNumber(Long workBenchNumber) {.workBenchNumber = workBenchNumber;

}

GroupWorker getGroupWorkbench() {groupWorkbench;

}

void setGroupWorkbench(GroupWorker groupWorkbench) {.groupWorkbench = groupWorkbench;

}

}


2 WEB-ИНТЕРФЕЙС СИСТЕМЫ

2.1Файл index.java

package ua.com.lejastu.design;

com.vaadin.annotations.Theme;com.vaadin.annotations.Title;com.vaadin.event.MouseEvents;com.vaadin.server.ThemeResource;com.vaadin.server.VaadinRequest;com.vaadin.ui.;ua.com.lejastu.design.inform.;

java.util.HashMap;

/

User: LejaStu

/

@Title("Skudy")

@Theme("skudytheme")class Index extends UI {navigation = new HorizontalSplitPanel();body;border;header;components;main;headBord;logo;<Integer,Component> levels;buttonGroup, buttonUser, buttonAccessLevel, littleButtonBuildings, littleButtonStage, buttonMisByIll,buttonWorkbench, buttonTransition,buttonRoom,buttonVisual;HashMap<String, Window> windowsProperties;


@Overridevoid init(VaadinRequest request) {= new Components();();();();();();();();();

}

void initLayout() {= components.initMain();= components.initHeader();= components.initBorder();= components.initBody();= components.initHeadBord();topMenu= new Panel();.setHeight("50%");.setSizeFull();(main);.addComponent(header);.addComponent(topMenu);.addComponent(border);.addComponent(body);.setExpandRatio(body, 80);.setExpandRatio(border, 0);.setExpandRatio(header, 20);.setSizeFull();.addComponent(headBord);resource = new ThemeResource("img/eye.png");= components.initImageFromResource(resource);.setStyleName("logo");.addComponent(logo);= components.initMainMenu();.setSplitPosition(16);.setLocked(true);.addComponent(navigation);.addComponent(levels.get(0));

}

Boolean findWindow(String windowName) {(windowsProperties == null) {= new HashMap<String, Window>();

}windowsProperties.containsKey(windowName);


}

Window getWindow(String windowName) {windowsProperties.get(windowName);

}

void windowsPropertiesDelete(String windowName){.remove(windowName);

}

void initGroupForm() {= (Panel) levels.get(7);.addClickListener(new MouseEvents.ClickListener() {

@Overridevoid click(MouseEvents.ClickEvent event) {temp = null;(findWindow("GroupWorkers") == false) {{gr = new GroupWorkerForm();= gr.init();

} catch (ClassNotFoundException e) {.printStackTrace();

} catch (InstantiationException e) {.printStackTrace();

} catch (IllegalAccessException e) {.printStackTrace();

}(temp);.put("GroupWorkers", temp);

} else {= getWindow("GroupWorkers");.focus();

}.addCloseListener(new Window.CloseListener(){

@Overridevoid windowClose(Window.CloseEvent e) {("GroupWorkers");

}

});

}

});

}

void initUserForm(){= (Panel) levels.get(8);.addClickListener(new MouseEvents.ClickListener() {

@Overridevoid click(MouseEvents.ClickEvent event) {temp;(findWindow("Users") == false) {= null;{us = new UserForm();= us.init();

} catch (ClassNotFoundException e) {.printStackTrace();

} catch (InstantiationException e) {.printStackTrace();

} catch (IllegalAccessException e) {.printStackTrace();

}(temp);.put("Users", temp);

} else {= getWindow("Users");.focus();

}.addCloseListener(new Window.CloseListener(){

@Overridevoid windowClose(Window.CloseEvent e) {("Users");

}

});

}

});

}

void initAccessLevelForm(){= (Panel) levels.get(9);.addClickListener(new MouseEvents.ClickListener() {

@Overridevoid click(MouseEvents.ClickEvent event) {temp;(findWindow("AccessLevel") == false) {= null;{al = new AccessLevelForm();= al.init();

} catch (ClassNotFoundException e) {.printStackTrace();

} catch (InstantiationException e) {.printStackTrace();

} catch (IllegalAccessException e) {.printStackTrace();

}(temp);.put("AccessLevel", temp);

} else {= getWindow("AccessLevel");.focus();

}.addCloseListener(new Window.CloseListener(){

@Overridevoid windowClose(Window.CloseEvent e) {("AccessLevel");

}

});

}

});

}

private void initMissByIllForm(){= (Panel) levels.get(10);.addClickListener(new MouseEvents.ClickListener() {

@Overridevoid click(MouseEvents.ClickEvent event) {temp;(findWindow("MissByIll") == false) {= null;{mi = new MissByIllForm();= mi.init();

} catch (ClassNotFoundException e) {.printStackTrace();

} catch (InstantiationException e) {.printStackTrace();

} catch (IllegalAccessException e) {.printStackTrace();

}(temp);.put("MissByIll", temp);

} else {= getWindow("MissByIll");.focus();

}.addCloseListener(new Window.CloseListener(){

@Overridevoid windowClose(Window.CloseEvent e) {("MissByIll");

}

});

}

});

}

void initRoomForm(){= (Panel) levels.get(11);.addClickListener(new MouseEvents.ClickListener() {

@Overridevoid click(MouseEvents.ClickEvent event) {temp;(findWindow("Room") == false) {= null;{bs = new RoomForm();= bs.init();

} catch (ClassNotFoundException e) {.printStackTrace();

} catch (InstantiationException e) {.printStackTrace();

} catch (IllegalAccessException e) {.printStackTrace();

}(temp);.put("Room", temp);

} else {= getWindow("Room");.focus();

}.addCloseListener(new Window.CloseListener(){

@Overridevoid windowClose(Window.CloseEvent e) {("Room");

}

});

}

});

}

void initTransitionForm(){= (Panel) levels.get(12);.addClickListener(new MouseEvents.ClickListener() {

@Overridevoid click(MouseEvents.ClickEvent event) {temp;(findWindow("Transition") == false) {= null;{tr = new TransitionForm();= tr.init();

} catch (ClassNotFoundException e) {.printStackTrace();

} catch (InstantiationException e) {.printStackTrace();

} catch (IllegalAccessException e) {.printStackTrace();

}(temp);.put("Transition", temp);

} else {= getWindow("Transition");.focus();

}.addCloseListener(new Window.CloseListener(){

@Overridevoid windowClose(Window.CloseEvent e) {("Transition");

}

});

}

});

}

void initWorkbenchForm(){= (Panel) levels.get(13);.addClickListener(new MouseEvents.ClickListener() {

@Overridevoid click(MouseEvents.ClickEvent event) {temp;(findWindow("Workbench") == false) {= null;{wb = new WorkbenchForm();= wb.init();

} catch (ClassNotFoundException e) {.printStackTrace();

} catch (InstantiationException e) {.printStackTrace();

} catch (IllegalAccessException e) {.printStackTrace();

}(temp);.put("Workbench", temp);

} else {= getWindow("Workbench");.focus();

}.addCloseListener(new Window.CloseListener(){

@Overridevoid windowClose(Window.CloseEvent e) {("Workbench");

}

});

}

});

}

}

2.2Файл Components.java

package ua.com.lejastu.design;

com.vaadin.server.ThemeResource;com.vaadin.ui.;

javax.persistence.Column;javax.persistence.Id;java.lang.annotation.Annotation;java.util.HashMap;


/

User: LejaStu

/class Components {

Window intWindow(Class aClass) {className = aClass.getSimpleName() + "s";window = new Window(className);.setWidth("60%");.setHeight("60%");.setPositionX(300);.setPositionY(200);window;

}

Table initTable(Object o) {.lang.reflect.Field fields[] = o.getClass().getDeclaredFields();a = fields.length;table = new Table();

(int i = 0; i < a; i++) {annotations[] = fields[i].getAnnotations();(int k = 0; k < annotations.length; k++) {annotation = annotations[k];(annotation.annotationType().getSimpleName().equals(Column.class.getSimpleName()) || annotation.annotationType().getSimpleName().equals(Id.class.getSimpleName())) {.addContainerProperty(fields[i].getName(), fields[i].getType(), null);

}

}

}.setSizeFull();table;

}

VerticalLayout initMain() {main = new VerticalLayout();.setStyleName("backcol");.setSizeFull();main;

}

HorizontalLayout initBorder() {border = new HorizontalLayout();.setSizeFull();border;

}

HorizontalLayout initHeader() {header = new HorizontalLayout();.setWidth("100%");.setStyleName("header");.setSizeFull();header;

}

HorizontalLayout initBody() {body = new HorizontalLayout();.setStyleName("workspace");.setWidth("100%");body;

}

VerticalSplitPanel initHeadBord() {headBord = new VerticalSplitPanel();.setSplitPosition(0);.setLocked(true);headBord;

}

Image initImageFromResource(ThemeResource resource) {image = new Image(null, resource);image;

}

HorizontalSplitPanel initNavigation() {navigation = new HorizontalSplitPanel();.setSplitPosition(16);.setLocked(true);navigation;

}

HashMap<Integer,Component> initMainMenu() {b1 = new Panel();b2 = new Panel();b3 = new Panel();mainMenu = new VerticalLayout();.setSizeFull();level1 = new HorizontalLayout();.setHeight("100%");.setWidth("100%");.addComponent(level1);.setContent(new Label("Group"));.setSizeFull();.setContent(new Label("User"));.setSizeFull();.addComponent(b1);.addComponent(b2);.setExpandRatio(b1, 1);.setExpandRatio(b2, 1);level2 = new HorizontalLayout();.setHeight("100%");.setWidth("100%");.addComponent(level2);.setContent(new Label("Transition"));.setSizeFull();b4 = new Panel();.setSizeFull();.addComponent(b3);.addComponent(b4);.setExpandRatio(b3, 1);.setExpandRatio(b4, 1);level3 = new HorizontalLayout();.setHeight("100%");.setWidth("100%");.addComponent(level3);b5 = new Panel();.setSizeFull();b6 = new Panel();.setSizeFull();.addComponent(b5);.addComponent(b6);.setExpandRatio(b5, 1);.setExpandRatio(b6, 1);level4 = new HorizontalLayout();.setHeight("100%");.setWidth("100%");.addComponent(level4);b7 = new Panel();.setSizeFull();b8 = new Panel();.setSizeFull();.addComponent(b7);.addComponent(b8);.setExpandRatio(b7, 1);.setExpandRatio(b8, 1);

// HorizontalLayout level5 = new HorizontalLayout();

// level5.setHeight("100%");

// level5.setWidth("100%");

// mainMenu.addComponent(level5);

// Panel b9 = new Panel();

// b9.setSizeFull();

// Panel b10 = new Panel();

// b10.setSizeFull();

// level5.addComponent(b9);

// level5.addComponent(b10);

// level5.setExpandRatio(b9, 1);

// level5.setExpandRatio(b10, 1);level6 = new HorizontalLayout();

// level5.setHeight("100%");

// level5.setWidth("100%");

// mainMenu.addComponent(level5);<Integer,Component> componentsOnBrowser= new HashMap<Integer,Component>();.put(0,mainMenu);.put(1,level1);.put(2,level2);.put(3,level3);.put(4,level4);

// componentsOnBrowser.put(5,level5);.put(6,level6);.put(6,level6);.put(6,level6);.put(7,b1);.put(8,b2);.put(9,b3);.put(10,b4);.put(11,b5);.put(12,b6);.put(13,b7);.put(14,b8);

// componentsOnBrowser.put(15,b9);

// componentsOnBrowser.put(16,b10);

// Object[] levels = {mainMenu, level1, level2, level3, level4, level5, level6, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10};componentsOnBrowser;

}

}

2.3Файл AbstractForm.java

package ua.com.lejastu.design.inform;

import com.vaadin.data.Container;com.vaadin.server.VaadinServlet;com.vaadin.ui.;org.springframework.data.repository.PagingAndSortingRepository;ua.com.lejastu.design.Components;ua.com.lejastu.design.SpringContextHelper;ua.com.lejastu.entity.IId;

java.lang.reflect.ParameterizedType;java.lang.reflect.Type;


/

User: LejaStu

/

abstract class AbstractForm<BEANTYPE extends IId> extends Window {static AbstractForm instance;components = new Components();<BEANTYPE, Long> repository;Class<?> aClass;window;table = new Table();add = new Button();change = new Button();remove = new Button();container=new String();operationLayout = new VerticalLayout();

() throws ClassNotFoundException {types = getClass().getGenericSuperclass();(!(types instanceof ParameterizedType)) return;genericSuperclass = (ParameterizedType) types;[] actualTypeArguments = genericSuperclass.getActualTypeArguments();.aClass = (Class<?>) actualTypeArguments[0];

helper = new SpringContextHelper(VaadinServlet.getCurrent().getServletContext());s = "ua.com.lejastu.repository.".concat(aClass.getSimpleName()).concat("Repository");c = Class.forName(s);= (PagingAndSortingRepository) helper.getBean(c);= "ua.com.lejastu.design.containers.".concat(aClass.getSimpleName()).concat("Container");();


}

void buttonAddInit(){.addClickListener(new Button.ClickListener() {

@Overridevoid buttonClick(Button.ClickEvent event) {label = new Label();.setCaption("yhsdjkjdowsopd wi ewjiopp d");.addComponent(label);


}

});

}


Window init() throws ClassNotFoundException, IllegalAccessException, InstantiationException {verticalLayout= new VerticalLayout();.setSizeFull();tablePanel= new Panel();.setSizeFull();.addComponent(tablePanel);operationPanel= new HorizontalLayout();.setSizeFull();.addComponent(operationPanel);.setExpandRatio(tablePanel, 3);.setExpandRatio(operationPanel, 1);.addComponent(operationLayout);pn= new VerticalLayout();.setWidth("100%");.setHeight("5px");.addComponent(pn);.setCaption("add");.setWidth("100px");.setWidth("100px");.setWidth("100px");.setCaption("change");.setCaption("remove");.addComponent(add);.addComponent(change);.addComponent(remove);= components.intWindow(aClass);obj = aClass.newInstance();= components.initTable(obj);.setContent(table);.setContent(verticalLayout);c = Class.forName(container);groupWorkerContainer= c.newInstance();.setContainerDataSource((Container) groupWorkerContainer);

return window;

}

}

2.4Файл AbstractDataProvider.java

package ua.com.lejastu.design.containers;

com.vaadin.data.util.BeanContainer;com.vaadin.data.util.BeanItem;org.springframework.data.domain.Page;org.springframework.data.domain.PageRequest;org.springframework.data.repository.PagingAndSortingRepository;ua.com.lejastu.design.SpringContextHelper;ua.com.lejastu.entity.IId;

java.util.ArrayList;java.util.HashMap;java.util.List;java.util.Map;


/

author: Oleksandr.Alieinikov

/abstract class AbstractDataProvider<BEANTYPE extends IId> extends BeanContainer<Long, BEANTYPE> {

<BEANTYPE, Long> repository;

Map<Long, BEANTYPE> visibleItems = new HashMap<Long, BEANTYPE>();

String globalFilter = "";


AbstractDataProvider(Class<? super BEANTYPE> type) {(type);("id");repoName = "ua.com.lejastu.repository." + type.getSimpleName() + "Repository";<?> aClass = null;{= getClass().getClassLoader().loadClass(repoName);

} catch (ClassNotFoundException e) {.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

}

= (PagingAndSortingRepository<BEANTYPE, Long>) SpringContextHelper.getBean(aClass);


}

abstract Page<BEANTYPE> getPage(PageRequest pageRequest);

@OverrideBeanItem<BEANTYPE> getItem(Object itemId) {new BeanItem<BEANTYPE>(visibleItems.get(itemId));

}


@Overrideint size() {<BEANTYPE> page = getPage(null);page.getContent().size();

}


@OverrideList<Long> getItemIds(int startIndex, int numberOfIds) {page = Math.round(startIndex / numberOfIds);pageRequest = new PageRequest(page, numberOfIds);<BEANTYPE> all = getPage(pageRequest);<BEANTYPE> content = all.getContent();.clear();(BEANTYPE beantype: content) {.put(beantype.getId(), beantype);

}<Long> longs = new ArrayList<Long>(visibleItems.keySet());().clear();().addAll(longs);longs;

}

PagingAndSortingRepository<BEANTYPE, Long> getRepository() {repository;

}

public String getGlobalFilter() {globalFilter;

}

void setGlobalFilter(String globalFilter) {.globalFilter = globalFilter;

}

}

3 ФАЙЛЫ КОНФИГУРАЦИИ

3.1 Файл web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="#"justify"><display-name>Vaadin Web Application</display-name>

<context-param>

<description>Vaadin production mode</description>

<param-name>productionMode</param-name>

<param-value>true</param-value>

</context-param>

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>


<servlet>

<servlet-name>Vaadin</servlet-name>

<servlet-class>com.vaadin.server.VaadinServlet</servlet-class>

<init-param>

<description>Vaadin UI to display</description>

<param-name>UI</param-name>

<param-value>ua.com.lejastu.design.Index</param-value>

</init-param>

</servlet>

<servlet-mapping>

<servlet-name>Vaadin</servlet-name>

<url-pattern>/</url-pattern>

</servlet-mapping>

<!--<resource-ref>-->

<!--<res-ref-name>jdbc/DSTest</res-ref-name>-->

<!--<res-type>javax.sql.DataSource</res-type>-->

<!--<res-auth>Container</res-auth>-->

<!--<res-sharing-scope>Shareable</res-sharing-scope>-->

<!--</resource-ref>-->

</web-app>


3.2 Файл persistence.xml

<?xml version="1.0" encoding="UTF-8"?>

<persistence xmlns="#"justify"><persistence-unit name="skudy" transaction-type="RESOURCE_LOCAL">


<class>ua.com.lejastu.entity.User</class>

<class>ua.com.lejastu.entity.Workbench</class>

<class>ua.com.lejastu.entity.RealSalary</class>

<class>ua.com.lejastu.entity.MissByIll</class>

<class>ua.com.lejastu.entity.Calendaring</class>

<class>ua.com.lejastu.entity.User</class>

<class>ua.com.lejastu.entity.AccessLevel</class>

<class>ua.com.lejastu.entity.Buildings</class>

<class>ua.com.lejastu.entity.GroupWorker</class>

<class>ua.com.lejastu.entity.Stage</class>

<class>ua.com.lejastu.entity.Room</class>

</persistence-unit>


</persistence>

3.3 Файл applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="#"justify"><context:spring-configured />

<context:component-scan base-package="ua.com.lejastu" />

<tx:annotation-driven />

<jpa:repositories base-package="ua.com.lejastu.repository" />


<bean id="dataSource">

<property name="driverClassName" value="com.mysql.jdbc.Driver"/>

<property name="url" value="jdbc:mysql://localhost:3306/skudy"/>

<property name="username" value="root"/>

<property name="password" value="111111"/>

</bean>


<bean id="entityManagerFactory">

<property name="dataSource" ref="dataSource" />

<!--<property name="persistenceXmlLocation" value="META-INF/persistence.xml" />-->

<!--<property name="persistenceUnitName" value="skudy"/>-->

<property name="packagesToScan">

<list>

<value>ua.com.lejastu.entity</value>

</list>

</property>

<property name="jpaVendorAdapter">

<bean>

<property name="showSql" value="false" />

<property name="generateDdl" value="true"/>

<property name="database" value="MYSQL" />

</bean>

</property>

</bean>


<bean id="transactionManager">

<bean>

<bean>

</beans>


3КЛАССЫ-ТЕСТЫ

3.1Класс AccessLevelTest

import org.junit.Assert;org.junit.Test;org.junit.runner.RunWith;org.springframework.beans.factory.annotation.Autowired;org.springframework.test.context.ContextConfiguration;org.springframework.test.context.junit4.SpringJUnit4ClassRunner;ua.com.lejastu.dao.AccessLevelDao;ua.com.lejastu.dao.GroupDao;ua.com.lejastu.entity.AccessLevel;ua.com.lejastu.entity.GroupWorker;ua.com.lejastu.repository.AccessRepository;ua.com.lejastu.repository.GroupRepository;


/

User: LejaStu

/


@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = { "classpath:applicationContext.xml"})class AccessLevelTest {


@AutowiredAccessRepository accessRepository;

@AutowiredGroupRepository groupDao;


@Testvoid testCreateLevel() throws Exception {accessLevel = new AccessLevel();.setLevelNumber(123L);groupWorker = new GroupWorker();.setGroupName("Banjo Men");.save(groupWorker);.setGroupAccessLevel(groupWorker);.save(accessLevel);getId = accessLevel.getId();accessLevelTest = accessRepository.findOne(getId);mustEquals=accessLevelTest.getLevelNumber();.assertNotNull("It was your mistake!", accessLevelTest);.assertEquals((Object) mustEquals, 123L);.delete(getId);mD= groupWorker.getId();.delete(mD);mustNull=accessRepository.findOne(accessLevel.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testUpdateLevel() throws Exception {accessLevel = new AccessLevel();.setLevelNumber(123L);groupWorker = new GroupWorker();.setGroupName("Banjo Men");.save(groupWorker);.setGroupAccessLevel(groupWorker);.save(accessLevel);accessLevelTest = accessRepository.findOne(accessLevel.getId());.setLevelNumber(1234567L);.saveAndFlush(accessLevelTest);mustEquals= accessLevelTest.getLevelNumber();.assertNotNull("It was your mistake!", accessLevelTest);.assertEquals((Object)mustEquals, 1234567L);.delete(accessLevel.getId());mD= groupWorker.getId();.delete(mD);mustNull=accessRepository.findOne(accessLevel.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testDeleteLevel() throws Exception {accessLevel = new AccessLevel();.setLevelNumber(123L);groupWorker = new GroupWorker();.setGroupName("Banjo Men");.save(groupWorker);.setGroupAccessLevel(groupWorker);.save(accessLevel);getId = accessRepository.findOne(accessLevel.getId()).getId();.delete(getId);mD= groupWorker.getId();.delete(mD);groupWorkerTest=accessRepository.findOne(getId);.assertNull("It was your mistake",groupWorkerTest);

}


@Testvoid testGetGroupById() throws Exception {accessLevel = new AccessLevel();.setLevelNumber(123L);groupWorker = new GroupWorker();.setGroupName("Banjo Men");.save(groupWorker);.setGroupAccessLevel(groupWorker);.save(accessLevel);accessLevelTest = accessRepository.findOne(accessLevel.getId());mustEquals= accessLevelTest.getLevelNumber();.assertNotNull("It was your mistake!", accessLevelTest);.assertEquals((Object)mustEquals, 123L);.delete(accessLevel.getId());mD= groupWorker.getId();.delete(mD);mustNull=accessRepository.findOne(accessLevel.getId());.assertNull("It was your mistake", mustNull);

}

}

3.2 Класс BuildingsTest

import org.junit.Assert;org.junit.Test;org.junit.runner.RunWith;org.springframework.beans.factory.annotation.Autowired;org.springframework.test.context.ContextConfiguration;org.springframework.test.context.junit4.SpringJUnit4ClassRunner;ua.com.lejastu.dao.BuildingsDao;ua.com.lejastu.entity.Buildings;ua.com.lejastu.repository.BuildingsRepository;


/

User: LejaStu

/


@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = { "classpath:applicationContext.xml"})class BuildingsTest {


@AutowiredBuildingsRepository buildingsRepository;


@Testvoid testCreateGroup() throws Exception {buildings = new Buildings();.setPathFile("C:\\qwerty\\orange.jpg");.setAddress("KIEV IS THE CAPITAL OF UKRAINE!");.save(buildings);getId = buildings.getId();buildingsTest = buildingsRepository.findOne(getId);mustEquals=buildingsTest.getPathFile();.assertNotNull("It was your mistake!", buildingsTest);.assertEquals(mustEquals, "C:\\qwerty\\orange.jpg");.delete(getId);mustNull=buildingsRepository.findOne(buildings.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testUpdateGroup() throws Exception {buildings = new Buildings();.setPathFile("C:\\qwerty\\orange.jpg");.setAddress("KIEV IS THE CAPITAL OF UKRAINE!");.save(buildings);buildingsTest = buildingsRepository.findOne(buildings.getId());.setPathFile("C:\\qwerty\\strawberry.jpg");.saveAndFlush(buildingsTest);mustEquals= buildingsTest.getPathFile();.assertNotNull("It was your mistake!", buildingsTest);.assertEquals(mustEquals, "C:\\qwerty\\strawberry.jpg");.delete(buildings.getId());mustNull=buildingsRepository.findOne(buildings.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testDeleteGroup() throws Exception {buildings = new Buildings();.setPathFile("C:\\qwerty\\orange.jpg");.setAddress("KIEV IS THE CAPITAL OF UKRAINE!");.save(buildings);getId = buildingsRepository.findOne(buildings.getId()).getId();.delete(getId);calendaringTest=buildingsRepository.findOne(getId);.assertNull("It was your mistake",calendaringTest);

}


@Testvoid testGetGroupById() throws Exception {buildings = new Buildings();.setPathFile("C:\\qwerty\\orange.jpg");.setAddress("KIEV IS THE CAPITAL OF UKRAINE!");.save(buildings);buildingsTest = buildingsRepository.findOne(buildings.getId());mustEquals= buildingsTest.getPathFile();.assertNotNull("It was your mistake!", buildingsTest);.assertEquals(mustEquals,"C:\\qwerty\\orange.jpg");.delete(buildings.getId());mustNull=buildingsRepository.findOne(buildings.getId());.assertNull("It was your mistake", mustNull);

}


}

3.3 Класс CalendaringTest

import org.junit.Assert;org.junit.Test;org.junit.runner.RunWith;org.springframework.beans.factory.annotation.Autowired;org.springframework.test.context.ContextConfiguration;org.springframework.test.context.junit4.SpringJUnit4ClassRunner;ua.com.lejastu.dao.CalendaringDao;ua.com.lejastu.entity.Calendaring;ua.com.lejastu.repository.CalendaringRepository;

java.util.Date;


/

User: LejaStu

/


@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = { "classpath:applicationContext.xml"})class CalendaringTest {


@AutowiredCalendaringRepository calendaringRepository;


@Testvoid testCreateGroup() throws Exception {calendaring = new Calendaring();.setDate(new Date(100));.save(calendaring);getId = calendaring.getId();calendaringTest = calendaringRepository.findOne(getId);mustEquals=calendaringTest.getDate();.assertNotNull("It was your mistake!", calendaringTest);.assertEquals(mustEquals.toString(), "1970-01-01");.delete(getId);mustNull=calendaringRepository.findOne(calendaring.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testUpdateGroup() throws Exception {calendaring = new Calendaring();.setDate(new Date(100L));.save(calendaring);calendaringTest = calendaringRepository.findOne(calendaring.getId());.setDate(new Date(101L));.saveAndFlush(calendaringTest);mustEquals= calendaringTest.getDate();.assertNotNull("It was your mistake!", calendaringTest);.assertEquals(mustEquals, new Date(101L));.delete(calendaring.getId());mustNull=calendaringRepository.findOne(calendaring.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testDeleteGroup() throws Exception {calendaring = new Calendaring();.setDate(new Date(100L));.save(calendaring);getId = calendaringRepository.findOne(calendaring.getId()).getId();.delete(getId);calendaringTest=calendaringRepository.findOne(getId);.assertNull("It was your mistake",calendaringTest);

}


@Testvoid testGetGroupById() throws Exception {calendaring = new Calendaring();.setDate(new Date(100L));.save(calendaring);calendaringTest = calendaringRepository.findOne(calendaring.getId());mustEquals= calendaringTest.getDate();.assertNotNull("It was your mistake!", calendaringTest);.assertEquals(mustEquals.toString(), "1970-01-01");.delete(calendaring.getId());mustNull=calendaringRepository.findOne(calendaring.getId());.assertNull("It was your mistake", mustNull);

}

}

3.4 Класс GroupTest

import org.junit.Assert;org.junit.Test;org.junit.runner.RunWith;org.springframework.beans.factory.annotation.Autowired;org.springframework.test.context.ContextConfiguration;org.springframework.test.context.junit4.SpringJUnit4ClassRunner;ua.com.lejastu.dao.GroupDao;ua.com.lejastu.entity.GroupWorker;ua.com.lejastu.repository.GroupRepository;


/

User: LejaStu

/

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = {"classpath:applicationContext.xml"})class GroupTest {


@AutowiredGroupRepository groupRepository;


@Testvoid testCreateGroup() throws Exception {groupWorker = new GroupWorker();.setGroupName("testGroup");.save(groupWorker);getId = groupWorker.getId();groupWorkerTest = groupRepository.findOne(getId);mustEquals=groupWorkerTest.getGroupName();.assertNotNull("It was your mistake!", groupWorkerTest);.assertEquals(mustEquals, "testGroup");.delete(getId);mustNull=groupRepository.findOne(groupWorker.getId());.assertNull("It was your mistake",mustNull);

}


@Testvoid testUpdateGroup() throws Exception {groupWorker = new GroupWorker();.setGroupName("testGroup");.save(groupWorker);groupWorkerTest = groupRepository.findOne(groupWorker.getId());.setGroupName("Banjo Men");.saveAndFlush(groupWorkerTest);mustEquals= groupWorkerTest.getGroupName();.assertNotNull("It was your mistake!", groupWorkerTest);.assertEquals(mustEquals, "Banjo Men");.delete(groupWorker.getId());mustNull=groupRepository.findOne(groupWorker.getId());.assertNull("It was your mistake",mustNull);

}


@Testvoid testDeleteGroup() throws Exception {groupWorker = new GroupWorker();.setGroupName("testGroup");.save(groupWorker);getId = groupRepository.findOne(groupWorker.getId()).getId();.delete(getId);groupWorkerTest=groupRepository.findOne(getId);.assertNull("It was your mistake",groupWorkerTest);

}


@Testvoid testGetGroupById() throws Exception {groupWorker = new GroupWorker();.setGroupName("Banjo Men");.save(groupWorker);groupWorkerTest = groupRepository.findOne(groupWorker.getId());mustEquals= groupWorkerTest.getGroupName();.assertNotNull("It was your mistake!", groupWorkerTest);.assertEquals(mustEquals, "Banjo Men");.delete(groupWorker.getId());mustNull=groupRepository.findOne(groupWorker.getId());.assertNull("It was your mistake",mustNull);

}

}

3.5 Класс MissedByIllnessTest

import org.junit.Assert;org.junit.Test;org.junit.runner.RunWith;org.springframework.beans.factory.annotation.Autowired;org.springframework.test.context.ContextConfiguration;org.springframework.test.context.junit4.SpringJUnit4ClassRunner;ua.com.lejastu.dao.GroupDao;ua.com.lejastu.dao.MissedByIllnessDao;ua.com.lejastu.dao.UserDao;ua.com.lejastu.entity.Calendaring;ua.com.lejastu.entity.GroupWorker;ua.com.lejastu.entity.MissByIll;ua.com.lejastu.entity.User;ua.com.lejastu.repository.GroupRepository;ua.com.lejastu.repository.MissRepository;ua.com.lejastu.repository.UserRepository;

java.util.Date;


/

User: LejaStu

/


@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = { "classpath:applicationContext.xml"})class MissedByIllnessTest {


@AutowiredMissRepository missRepository;

@AutowiredUserRepository userRepository;

@AutowiredGroupRepository groupRepository;


@Testvoid testCreateGroup() throws Exception {missByIll = new MissByIll();.setFromDate(new Date(100L));.setToDate(new Date(105L));user = new User();.setFirstName("Maria-Jose");.setLastName("Ivanova");.setBirthDay(new Date(System.currentTimeMillis()));.setJob("Programmer");.setSalary(1234567890L);.setAddress("Kiev,Frunze street, 124, 12");.setPhone("03456789");.setPassportData("CM-56789");.setPhoto("C:\\dir\\photo\\mji.jpg");.setDepartmentName("Alpha-1");.setObligedSpendTime(123456L);group= new GroupWorker();.setGroupName("Alpha-1");.save(group);.setGroupUser(group);.save(user);.setUserMissed(user);.save(missByIll);getId = missByIll.getId();missByIllTest = missRepository.findOne(getId);mustEquals=missByIllTest.getToDate();.assertNotNull("It was your mistake!", missByIllTest);.assertEquals(mustEquals.toString(), "1970-01-01");.delete(getId);mD= user.getId();.delete(mD);gD=group.getId();.delete(gD);mustNull=missRepository.findOne(missByIll.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testUpdateGroup() throws Exception {missByIll = new MissByIll();.setFromDate(new Date(100L));.setToDate(new Date(105L));user = new User();.setFirstName("Maria-Jose");.setLastName("Ivanova");.setBirthDay(new Date(System.currentTimeMillis()));.setJob("Programmer");.setSalary(1234567890L);.setAddress("Kiev,Frunze street, 124, 12");.setPhone("03456789");.setPassportData("CM-56789");.setPhoto("C:\\dir\\photo\\mji.jpg");.setDepartmentName("Alpha-1");.setObligedSpendTime(123456L);group= new GroupWorker();.setGroupName("Alpha-1");.save(group);.setGroupUser(group);.save(user);.setUserMissed(user);.save(missByIll);missByIllTest = missRepository.findOne(missByIll.getId());.setToDate(new Date(111L));.saveAndFlush(missByIllTest);mustEquals= missByIllTest.getToDate();.assertNotNull("It was your mistake!", missByIllTest);.assertEquals(mustEquals, new Date(111L));.delete(missByIll.getId());mD= user.getId();.delete(mD);gD=group.getId();.delete(gD);mustNull=missRepository.findOne(12345L);.assertNull("It was your mistake", mustNull);

}


@Testvoid testDeleteGroup() throws Exception {missByIll = new MissByIll();.setFromDate(new Date(100L));.setToDate(new Date(105L));user = new User();.setFirstName("Maria-Jose");.setLastName("Ivanova");.setBirthDay(new Date(System.currentTimeMillis()));.setJob("Programmer");.setSalary(1234567890L);.setAddress("Kiev,Frunze street, 124, 12");.setPhone("03456789");.setPassportData("CM-56789");.setPhoto("C:\\dir\\photo\\mji.jpg");.setDepartmentName("Alpha-1");.setObligedSpendTime(123456L);group= new GroupWorker();.setGroupName("Alpha-1");.save(group);.setGroupUser(group);.save(user);.setUserMissed(user);.save(missByIll);getId = missRepository.findOne(missByIll.getId()).getId();.delete(getId);mD= user.getId();.delete(mD);gD=group.getId();.delete(gD);transitionTest=missRepository.findOne(getId);.assertNull("It was your mistake",transitionTest);

}


@Testvoid testGetGroupById() throws Exception {missByIll = new MissByIll();.setFromDate(new Date(100L));.setToDate(new Date(105L));user = new User();.setFirstName("Maria-Jose");.setLastName("Ivanova");.setBirthDay(new Date(System.currentTimeMillis()));.setJob("Programmer");.setSalary(1234567890L);.setAddress("Kiev,Frunze street, 124, 12");.setPhone("03456789");.setPassportData("CM-56789");.setPhoto("C:\\dir\\photo\\mji.jpg");.setDepartmentName("Alpha-1");.setObligedSpendTime(123456L);group= new GroupWorker();.setGroupName("Alpha-1");.save(group);.setGroupUser(group);.save(user);.setUserMissed(user);.save(missByIll);transitionTest = missRepository.findOne(missByIll.getId());mustEquals= transitionTest.getToDate();.assertNotNull("It was your mistake!", transitionTest);.assertEquals(mustEquals.toString(), "1970-01-01");.delete(missByIll.getId());mD= user.getId();.delete(mD);gD=group.getId();.delete(gD);mustNull=missRepository.findOne(missByIll.getId());.assertNull("It was your mistake", mustNull);

}


}

3.6 Класс RealSalaryTest

import org.junit.Assert;org.junit.Test;org.junit.runner.RunWith;org.springframework.beans.factory.annotation.Autowired;org.springframework.test.context.ContextConfiguration;org.springframework.test.context.junit4.SpringJUnit4ClassRunner;ua.com.lejastu.dao.GroupDao;ua.com.lejastu.dao.RealSalaryDao;ua.com.lejastu.dao.UserDao;ua.com.lejastu.entity.GroupWorker;ua.com.lejastu.entity.RealSalary;ua.com.lejastu.entity.User;ua.com.lejastu.repository.GroupRepository;ua.com.lejastu.repository.RealSalaryRepository;ua.com.lejastu.repository.UserRepository;

java.util.Date;


/

User: LejaStu

/


@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = { "classpath:applicationContext.xml"})class RealSalaryTest {


@AutowiredRealSalaryRepository realSalaryRepository;

@AutowiredUserRepository userRepository;

@AutowiredGroupRepository groupRepository;


@Testvoid testCreateGroup() throws Exception {realSalary = new RealSalary();.setMonth(new Date(100L));.setRealTimeWork(101L);.setSalary(105L);user = new User();.setFirstName("Maria-Jose");.setLastName("Ivanova");.setBirthDay(new Date(System.currentTimeMillis()));.setJob("Programmer");.setSalary(1234567890L);.setAddress("Kiev,Frunze street, 124, 12");.setPhone("03456789");.setPassportData("CM-56789");.setPhoto("C:\\dir\\photo\\mji.jpg");.setDepartmentName("Alpha-1");.setObligedSpendTime(123456L);group= new GroupWorker();.setGroupName("Alpha-1");.save(group);.setGroupUser(group);.save(user);.setUserSalary(user);.save(realSalary);getId = realSalary.getId();realSalaryTest = realSalaryRepository.findOne(getId);mustEquals=realSalaryTest.getSalary();.assertNotNull("It was your mistake!", realSalaryTest);.assertEquals((Object)mustEquals,105L);.delete(getId);mD= user.getId();.delete(mD);gD=group.getId();.delete(gD);mustNull=realSalaryRepository.findOne(realSalary.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testUpdateGroup() throws Exception {realSalary = new RealSalary();.setMonth(new Date(100L));.setRealTimeWork(101L);.setSalary(105L);user = new User();.setFirstName("Maria-Jose");.setLastName("Ivanova");.setBirthDay(new Date(System.currentTimeMillis()));.setJob("Programmer");.setSalary(1234567890L);.setAddress("Kiev,Frunze street, 124, 12");.setPhone("03456789");.setPassportData("CM-56789");.setPhoto("C:\\dir\\photo\\mji.jpg");.setDepartmentName("Alpha-1");.setObligedSpendTime(123456L);group= new GroupWorker();.setGroupName("Alpha-1");.save(group);.setGroupUser(group);.save(user);.setUserSalary(user);.save(realSalary);realSalaryTest = realSalaryRepository.findOne(realSalary.getId());.setSalary(111L);.saveAndFlush(realSalaryTest);mustEquals= realSalaryTest.getSalary();.assertNotNull("It was your mistake!", realSalaryTest);.assertEquals((Object)mustEquals, 111L);.delete(realSalary.getId());mD= user.getId();.delete(mD);gD=group.getId();.delete(gD);mustNull=realSalaryRepository.findOne(realSalary.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testDeleteGroup() throws Exception {realSalary = new RealSalary();.setMonth(new Date(100L));.setRealTimeWork(101L);.setSalary(105L);user = new User();.setFirstName("Maria-Jose");.setLastName("Ivanova");.setBirthDay(new Date(System.currentTimeMillis()));.setJob("Programmer");.setSalary(1234567890L);.setAddress("Kiev,Frunze street, 124, 12");.setPhone("03456789");.setPassportData("CM-56789");.setPhoto("C:\\dir\\photo\\mji.jpg");.setDepartmentName("Alpha-1");.setObligedSpendTime(123456L);group= new GroupWorker();.setGroupName("Alpha-1");.save(group);.setGroupUser(group);.save(user);.setUserSalary(user);.save(realSalary);getId = realSalaryRepository.findOne(realSalary.getId()).getId();.delete(getId);mD= user.getId();.delete(mD);gD=group.getId();.delete(gD);transitionTest=realSalaryRepository.findOne(getId);.assertNull("It was your mistake",transitionTest);

}


@Testvoid testGetGroupById() throws Exception {realSalary = new RealSalary();.setMonth(new Date(100L));.setRealTimeWork(101L);.setSalary(105L);user = new User();.setFirstName("Maria-Jose");.setLastName("Ivanova");.setBirthDay(new Date(System.currentTimeMillis()));.setJob("Programmer");.setSalary(1234567890L);.setAddress("Kiev,Frunze street, 124, 12");.setPhone("03456789");.setPassportData("CM-56789");.setPhoto("C:\\dir\\photo\\mji.jpg");.setDepartmentName("Alpha-1");.setObligedSpendTime(123456L);group= new GroupWorker();.setGroupName("Alpha-1");.save(group);.setGroupUser(group);.save(user);.setUserSalary(user);.save(realSalary);transitionTest = realSalaryRepository.findOne(realSalary.getId());mustEquals= transitionTest.getSalary();.assertNotNull("It was your mistake!", transitionTest);.assertEquals((Object)mustEquals,105L);.delete(realSalary.getId());mD= user.getId();.delete(mD);gD=group.getId();.delete(gD);mustNull=realSalaryRepository.findOne(realSalary.getId());.assertNull("It was your mistake", mustNull);

}

}

3.7 Класс RoomTest

import org.junit.Assert;org.junit.Test;org.junit.runner.RunWith;org.springframework.beans.factory.annotation.Autowired;org.springframework.test.context.ContextConfiguration;org.springframework.test.context.junit4.SpringJUnit4ClassRunner;ua.com.lejastu.dao.RoomDao;ua.com.lejastu.entity.Room;ua.com.lejastu.repository.RoomRepository;


/

User: LejaStu

/

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = { "classpath:applicationContext.xml"})class RoomTest {


@AutowiredRoomRepository roomRepository;

@Testvoid testCreateGroup() throws Exception {room = new Room();.setAccessLevel(11);.setNumber(33);.save(room);getId = room.getId();roomTest = roomRepository.findOne(getId);mustEquals=roomTest.getNumber();.assertNotNull("It was your mistake!", roomTest);.assertEquals((Object)mustEquals, 33);.delete(getId);mustNull=roomRepository.findOne(room.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testUpdateGroup() throws Exception {room = new Room();.setAccessLevel(11);.setNumber(33);.save(room);roomTest = roomRepository.findOne(room.getId());.setNumber(15);.saveAndFlush(roomTest);mustEquals= roomTest.getNumber();.assertNotNull("It was your mistake!", roomTest);.assertEquals((Object)mustEquals, 15);.delete(room.getId());mustNull=roomRepository.findOne(room.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testDeleteGroup() throws Exception {room = new Room();.setAccessLevel(11);.setNumber(33);.save(room);getId = roomRepository.findOne(room.getId()).getId();.delete(getId);calendaringTest=roomRepository.findOne(getId);.assertNull("It was your mistake",calendaringTest);

}


@Testvoid testGetGroupById() throws Exception {room = new Room();.setAccessLevel(11);.setNumber(33);.save(room);roomTest = roomRepository.findOne(room.getId());mustEquals= roomTest.getNumber();.assertNotNull("It was your mistake!", roomTest);.assertEquals((Object)mustEquals,33);.delete(room.getId());mustNull=roomRepository.findOne(room.getId());.assertNull("It was your mistake", mustNull);

}


}

3.8 Класс StageTest

import org.junit.Assert;org.junit.Test;org.junit.runner.RunWith;org.springframework.beans.factory.annotation.Autowired;org.springframework.test.context.ContextConfiguration;org.springframework.test.context.junit4.SpringJUnit4ClassRunner;ua.com.lejastu.dao.StageDao;ua.com.lejastu.entity.Stage;ua.com.lejastu.repository.StageRepository;


/

User: LejaStu

/


@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = { "classpath:applicationContext.xml"})class StageTest {


@AutowiredStageRepository stageRepository;

@Testvoid testCreateGroup() throws Exception {stage = new Stage();.setPathSvg("C:\\qwerty\\orange.jpg");.setStageNumber(33);.save(stage);getId = stage.getId();stageTest = stageRepository.findOne(getId);mustEquals=stageTest.getPathSvg();.assertNotNull("It was your mistake!", stageTest);.assertEquals(mustEquals, "C:\\qwerty\\orange.jpg");.delete(getId);mustNull=stageRepository.findOne(stage.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testUpdateGroup() throws Exception {stage = new Stage();.setPathSvg("C:\\qwerty\\orange.jpg");.setStageNumber(33);.save(stage);stageTest = stageRepository.findOne(stage.getId());.setPathSvg("C:\\qwerty\\strawberry.jpg");.saveAndFlush(stageTest);mustEquals= stageTest.getPathSvg();.assertNotNull("It was your mistake!", stageTest);.assertEquals(mustEquals, "C:\\qwerty\\strawberry.jpg");.delete(stage.getId());mustNull=stageRepository.findOne(stage.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testDeleteGroup() throws Exception {stage = new Stage();.setPathSvg("C:\\qwerty\\orange.jpg");.setStageNumber(33);.save(stage);getId = stageRepository.findOne(stage.getId()).getId();.delete(getId);calendaringTest=stageRepository.findOne(getId);.assertNull("It was your mistake",calendaringTest);

}

@Testvoid testGetGroupById() throws Exception {stage = new Stage();.setPathSvg("C:\\qwerty\\orange.jpg");.setStageNumber(33);.save(stage);stageTest = stageRepository.findOne(stage.getId());mustEquals= stageTest.getPathSvg();.assertNotNull("It was your mistake!", stageTest);.assertEquals(mustEquals,"C:\\qwerty\\orange.jpg");.delete(stage.getId());mustNull=stageRepository.findOne(stage.getId());.assertNull("It was your mistake", mustNull);

}


}

3.9 Класс TransitionTest

import org.junit.Assert;org.junit.Test;org.junit.runner.RunWith;org.springframework.beans.factory.annotation.Autowired;org.springframework.test.context.ContextConfiguration;org.springframework.test.context.junit4.SpringJUnit4ClassRunner;ua.com.lejastu.dao.;ua.com.lejastu.entity.;ua.com.lejastu.repository.;

java.util.Date;


/

User: LejaStu

/

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = { "classpath:applicationContext.xml"})class TransitionTest {


@AutowiredTransitionRepository transitionRepository;

@AutowiredUserRepository userRepository;

@AutowiredGroupRepository groupRepository;

@AutowiredcalendaringRepository;

@AutowiredroomRepository;


@Testvoid testCreateGroup() throws Exception {transition = new Transition();.setSpendTime(123L);.setFromRoom(1L);.setToRoom(9L);.setIsAccessPermitted(true);.setReason("OK");.setTimeIn(new Date(System.currentTimeMillis()));.setTimeOut(new Date(System.currentTimeMillis()));user = new User();.setFirstName("Maria-Jose");.setLastName("Ivanova");.setBirthDay(new Date(System.currentTimeMillis()));.setJob("Programmer");.setSalary(1234567890L);.setAddress("Kiev,Frunze street, 124, 12");.setPhone("03456789");.setPassportData("CM-56789");.setPhoto("C:\\dir\\photo\\mji.jpg");.setDepartmentName("Alpha-1");.setObligedSpendTime(123456L);group= new GroupWorker();.setGroupName("Alpha-1");.save(group);.setGroupUser(group);.save(user);.setUserTransition(user);calendaring = new Calendaring();.setDate(new Date(System.currentTimeMillis()));.save(calendaring);.setCalendarTrans(calendaring);room = new Room();.setNumber(99);.setAccessLevel(99);.save(room);.setRoomTrans(room);.save(transition);getId = transition.getId();transitionTest = transitionRepository.findOne(getId);mustEquals=transitionTest.getSpendTime();.assertNotNull("It was your mistake!", transitionTest);.assertEquals((Object) mustEquals, 123L);.delete(getId);mD= user.getId();.delete(mD);gD=group.getId();.delete(gD);rD=room.getId();.delete(rD);cD=calendaring.getId();.delete(cD);mustNull=transitionRepository.findOne(transition.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testUpdateGroup() throws Exception {transition = new Transition();.setSpendTime(123L);.setFromRoom(1L);.setToRoom(9L);.setIsAccessPermitted(true);.setReason("OK");.setTimeIn(new Date(System.currentTimeMillis()));.setTimeOut(new Date(System.currentTimeMillis()));user = new User();.setFirstName("Maria-Jose");.setLastName("Ivanova");.setBirthDay(new Date(System.currentTimeMillis()));.setJob("Programmer");.setSalary(1234567890L);.setAddress("Kiev,Frunze street, 124, 12");.setPhone("03456789");.setPassportData("CM-56789");.setPhoto("C:\\dir\\photo\\mji.jpg");.setDepartmentName("Alpha-1");.setObligedSpendTime(123456L);group= new GroupWorker();.setGroupName("Alpha-1");.save(group);.setGroupUser(group);.save(user);.setUserTransition(user);calendaring = new Calendaring();.setDate(new Date(System.currentTimeMillis()));.save(calendaring);.setCalendarTrans(calendaring);room = new Room();.setNumber(99);.setAccessLevel(99);.save(room);.setRoomTrans(room);.save(transition);transitionTest = transitionRepository.findOne(transition.getId());.setSpendTime(1234567L);.saveAndFlush(transitionTest);mustEquals= transitionTest.getSpendTime();.assertNotNull("It was your mistake!", transitionTest);.assertEquals((Object)mustEquals, 1234567L);.delete(transition.getId());mD= user.getId();.delete(mD);gD=group.getId();.delete(gD);rD=room.getId();.delete(rD);cD=calendaring.getId();.delete(cD);mustNull=transitionRepository.findOne(transition.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testDeleteGroup() throws Exception {transition = new Transition();.setSpendTime(123L);.setFromRoom(1L);.setToRoom(9L);.setIsAccessPermitted(true);.setReason("OK");.setTimeIn(new Date(System.currentTimeMillis()));.setTimeOut(new Date(System.currentTimeMillis()));user = new User();.setFirstName("Maria-Jose");.setLastName("Ivanova");.setBirthDay(new Date(System.currentTimeMillis()));.setJob("Programmer");.setSalary(1234567890L);.setAddress("Kiev,Frunze street, 124, 12");.setPhone("03456789");.setPassportData("CM-56789");.setPhoto("C:\\dir\\photo\\mji.jpg");.setDepartmentName("Alpha-1");.setObligedSpendTime(123456L);group= new GroupWorker();.setGroupName("Alpha-1");.save(group);.setGroupUser(group);.save(user);.setUserTransition(user);calendaring = new Calendaring();.setDate(new Date(System.currentTimeMillis()));.save(calendaring);.setCalendarTrans(calendaring);room = new Room();.setNumber(99);.setAccessLevel(99);.save(room);.setRoomTrans(room);.save(transition);getId = transitionRepository.findOne(transition.getId()).getId();.delete(getId);mD= user.getId();.delete(mD);gD=group.getId();.delete(gD);rD=room.getId();.delete(rD);cD=calendaring.getId();.delete(cD);transitionTest=transitionRepository.findOne(getId);.assertNull("It was your mistake",transitionTest);

}


@Testvoid testGetGroupById() throws Exception {transition = new Transition();.setSpendTime(123L);.setFromRoom(1L);.setToRoom(9L);.setIsAccessPermitted(true);.setReason("OK");.setTimeIn(new Date(System.currentTimeMillis()));.setTimeOut(new Date(System.currentTimeMillis()));user = new User();.setFirstName("Maria-Jose");.setLastName("Ivanova");.setBirthDay(new Date(System.currentTimeMillis()));.setJob("Programmer");.setSalary(1234567890L);.setAddress("Kiev,Frunze street, 124, 12");.setPhone("03456789");.setPassportData("CM-56789");.setPhoto("C:\\dir\\photo\\mji.jpg");.setDepartmentName("Alpha-1");.setObligedSpendTime(123456L);group= new GroupWorker();.setGroupName("Alpha-1");.save(group);.setGroupUser(group);.save(user);.setUserTransition(user);calendaring = new Calendaring();.setDate(new Date(System.currentTimeMillis()));.save(calendaring);.setCalendarTrans(calendaring);room = new Room();.setNumber(99);.setAccessLevel(99);.save(room);.setRoomTrans(room);.save(transition);transitionTest = transitionRepository.findOne(transition.getId());mustEquals= transitionTest.getReason();.assertNotNull("It was your mistake!", transitionTest);.assertEquals(mustEquals, "OK");.delete(transition.getId());mD= user.getId();.delete(mD);gD=group.getId();.delete(gD);rD=room.getId();.delete(rD);cD=calendaring.getId();.delete(cD);mustNull=transitionRepository.findOne(transition.getId());.assertNull("It was your mistake", mustNull);

}


}

3.10 Класс UserTest

import org.junit.Assert;org.junit.Test;org.junit.runner.RunWith;org.springframework.beans.factory.annotation.Autowired;org.springframework.test.context.ContextConfiguration;org.springframework.test.context.junit4.SpringJUnit4ClassRunner;ua.com.lejastu.dao.GroupDao;ua.com.lejastu.dao.UserDao;ua.com.lejastu.entity.GroupWorker;ua.com.lejastu.entity.User;ua.com.lejastu.repository.GroupRepository;ua.com.lejastu.repository.UserRepository;

java.util.Date;


/

User: LejaStu

/


@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = { "classpath:applicationContext.xml"})class UserTest {


@AutowiredUserRepository userRepository;

@AutowiredGroupRepository groupRepository;

@Testvoid testCreateGroup() throws Exception {user = new User();.setFirstName("Maria-Jose");.setLastName("Ivanova");.setBirthDay(new Date(System.currentTimeMillis()));.setJob("Programmer");.setSalary(1234567890L);.setAddress("Kiev,Frunze street, 124, 12");.setPhone("03456789");.setPassportData("CM-56789");.setPhoto("C:\\dir\\photo\\mji.jpg");.setDepartmentName("Alpha-1");.setObligedSpendTime(123456L);groupWorker = new GroupWorker();.setGroupName("Banjo Men");.save(groupWorker);.setGroupUser(groupWorker);.save(user);getId = user.getId();userTest = userRepository.findOne(getId);mustEquals=userTest.getFirstName();.assertNotNull("It was your mistake!", userTest);.assertEquals(mustEquals,"Maria-Jose");.delete(getId);mD= groupWorker.getId();.delete(mD);mustNull=userRepository.findOne(user.getId());.assertNull("It was your mistake", mustNull);

}

@Testvoid testUpdateGroup() throws Exception {user = new User();.setFirstName("Maria-Jose");.setLastName("Ivanova");.setBirthDay(new Date(System.currentTimeMillis()));.setJob("Programmer");.setSalary(1234567890L);.setAddress("Kiev,Frunze street, 124, 12");.setPhone("03456789");.setPassportData("CM-56789");.setPhoto("C:\\dir\\photo\\mji.jpg");.setDepartmentName("Alpha-1");.setObligedSpendTime(123456L);groupWorker = new GroupWorker();.setGroupName("Banjo Men");.save(groupWorker);.setGroupUser(groupWorker);.save(user);userTest = userRepository.findOne(user.getId());.setLastName("Compuiternaia");.saveAndFlush(userTest);mustEquals= userTest.getLastName();.assertNotNull("It was your mistake!", userTest);.assertEquals(mustEquals, "Compuiternaia");.delete(user.getId());mD= groupWorker.getId();.delete(mD);mustNull=userRepository.findOne(user.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testDeleteGroup() throws Exception {user = new User();.setFirstName("Maria-Jose");.setLastName("Ivanova");.setBirthDay(new Date(System.currentTimeMillis()));.setJob("Programmer");.setSalary(1234567890L);.setAddress("Kiev,Frunze street, 124, 12");.setPhone("03456789");.setPassportData("CM-56789");.setPhoto("C:\\dir\\photo\\mji.jpg");.setDepartmentName("Alpha-1");.setObligedSpendTime(123456L);groupWorker = new GroupWorker();.setGroupName("Banjo Men");.save(groupWorker);.setGroupUser(groupWorker);.save(user);getId = userRepository.findOne(user.getId()).getId();.delete(getId);mD= groupWorker.getId();.delete(mD);groupWorkerTest=userRepository.findOne(getId);.assertNull("It was your mistake",groupWorkerTest);

}


@Testvoid testGetGroupById() throws Exception {user = new User();.setFirstName("Maria-Jose");.setLastName("Ivanova");.setBirthDay(new Date(System.currentTimeMillis()));.setJob("Programmer");.setSalary(1234567890L);.setAddress("Kiev,Frunze street, 124, 12");.setPhone("03456789");.setPassportData("CM-56789");.setPhoto("C:\\dir\\photo\\mji.jpg");.setDepartmentName("Alpha-1");.setObligedSpendTime(123456L);groupWorker = new GroupWorker();.setGroupName("Banjo Men");.save(groupWorker);.setGroupUser(groupWorker);.save(user);userTest = userRepository.findOne(user.getId());mustEquals= userTest.getLastName();.assertNotNull("It was your mistake!", userTest);.assertEquals(mustEquals, "Ivanova");.delete(user.getId());mD= groupWorker.getId();.delete(mD);mustNull=userRepository.findOne(user.getId());.assertNull("It was your mistake", mustNull);

}

}

3.11 Класс WorkbenchTest

import org.junit.Assert;org.junit.Test;org.junit.runner.RunWith;org.springframework.beans.factory.annotation.Autowired;org.springframework.test.context.ContextConfiguration;org.springframework.test.context.junit4.SpringJUnit4ClassRunner;ua.com.lejastu.dao.GroupDao;ua.com.lejastu.dao.WorkbenchDao;ua.com.lejastu.entity.GroupWorker;ua.com.lejastu.entity.Workbench;ua.com.lejastu.repository.GroupRepository;ua.com.lejastu.repository.WorkbenchRepository;


/

User: LejaStu

/

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = { "classpath:applicationContext.xml"})class WorkbenchTest {


@AutowiredWorkbenchRepository workbenchRepository;

@AutowiredGroupRepository groupRepository;


@Testvoid testCreateGroup() throws Exception {workbench = new Workbench();.setWorkBenchNumber(123L);groupWorker = new GroupWorker();.setGroupName("Banjo Men");.save(groupWorker);.setGroupWorkbench(groupWorker);.save(workbench);getId = workbench.getId();workbenchTest = workbenchRepository.findOne(getId);mustEquals=workbenchTest.getWorkBenchNumber();.assertNotNull("It was your mistake!", workbenchTest);.assertEquals((Object) mustEquals, 123L);.delete(getId);mD= groupWorker.getId();.delete(mD);mustNull=workbenchRepository.findOne(workbench.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testUpdateGroup() throws Exception {workbench = new Workbench();.setWorkBenchNumber(123L);groupWorker = new GroupWorker();.setGroupName("Banjo Men");.save(groupWorker);.setGroupWorkbench(groupWorker);.save(workbench);workbenchTest = workbenchRepository.findOne(workbench.getId());.setWorkBenchNumber(1234567L);.saveAndFlush(workbenchTest);mustEquals= workbenchTest.getWorkBenchNumber();.assertNotNull("It was your mistake!", workbenchTest);.assertEquals((Object)mustEquals, 1234567L);.delete(workbench.getId());mD= groupWorker.getId();.delete(mD);mustNull=workbenchRepository.findOne(workbench.getId());.assertNull("It was your mistake", mustNull);

}


@Testvoid testDeleteGroup() throws Exception {workbench = new Workbench();.setWorkBenchNumber(123L);groupWorker = new GroupWorker();.setGroupName("Banjo Men");.save(groupWorker);.setGroupWorkbench(groupWorker);.save(workbench);getId = workbenchRepository.findOne(workbench.getId()).getId();.delete(getId);mD= groupWorker.getId();.delete(mD);groupWorkerTest=workbenchRepository.findOne(getId);.assertNull("It was your mistake",groupWorkerTest);

}


@Testvoid testGetGroupById() throws Exception {workbench = new Workbench();.setWorkBenchNumber(123L);groupWorker = new GroupWorker();.setGroupName("Banjo Men");.save(groupWorker);.setGroupWorkbench(groupWorker);.save(workbench);workbenchTest = workbenchRepository.findOne(workbench.getId());mustEquals= workbenchTest.getWorkBenchNumber();.assertNotNull("It was your mistake!", workbenchTest);.assertEquals((Object)mustEquals, 123L);.delete(workbench.getId());mD= groupWorker.getId();.delete(mD);mustNull=workbenchRepository.findOne(workbench.getId());.assertNull("It was your mistake", mustNull);

}

}


Источник: http://bibliofond.ru/view.aspx?id=656694


Рекомендации перед осмотром проктолога