Рабочее

Sep 11, 2009 21:40



Не уверен, что кому-либо все это особо интересно, но отпишусь т.к. тупо хочется выговориться.

Неделя прошла под знаком Зодиака "хренею без баяна".
Со среды делал простой, по идее функционал. В нашем веб-приложении есть картографический клиент, сделаный на OpenLayers. Для тех кто не в теме - Google Maps представляете? Ну вот такое, только свое, со "нашими" функциями и с "нашими" картами.
Так вот, этот картографический клиент можно использовать из третьих приложений для ввода координат, рисования простой геометрии или выбора географических объектов. Если на примере, то нужно, скажем герру Мюллеру из ведомства по охране водных источников выбрать колодцы, к которым он предоставит доступ герру Шмидту. Герр Мюллер жмет кнопочку в своем приложении, у него открывается карта, на ней герр Мюллер выбирает три колодца, жмет другую кнопочку и его система получает координаты этих колодцев.
В данный момент вся эта красота работает в одну сторону. Т.е. геометрию и объекты можно нарисовать или выбрать, но ранее нарисованную геометрию или выбранные объекты отобразить нельзя.
Задача моя состояла в том, чтобы в другую сторону все это тоже работало. Если герр Мюллер выбрал ранее три колодца, то, когда он в следующий раз нажмет свою волшебную кнопочку, его выбор должен отобразиться на карте.

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

В общем, в теории все просто.

На практике веселье началось с того, что написанные неделю назад маршаллер/анмаршаллер для GML перестали работать. Просто перестали и все. При разборе полетов оказалось, что используемая для работы с GML библиотека GeoTools неявно конфликтует с XSLT-процессором Saxon. Простое добавление в приложение новой библиотеки убивает уже реализованную функциональность.

Почти день ушел на то, чтобы решить эту проблему. В новых версиях GeoTools разработчики ввели новый подход к работе с XML-форматами в целом и с GML в частности. Мы использовали старый подход, пришлось экспериментировать с новым. Новый подход требует создания собственного профайла GML - т.е. написания своей XML-схемы, создания "конфигурации" и "связок". Я реально не понимаю на кой черт такие сложности - напоминаю, мне нужно всего только геометрию в XML-формате скинуть. Типа - вот полигон, дайте его в XML. С WKT ("well known text") на JTS это делается реально в две (!) строчки кода.
Но ладно, я понимаю, это проблема не GeoTools, это проблема в спецификации GML. Почему не сделать генеричную схему? Почему каждый вендор по спецификации обязан выдумывать для себя формат? Но не суть.
Так вот, мытьем и катаньем суровые уральские мужики профайл этот GML-ный таки сделали. Парсинг с ним работает и в GML2 и в GML3, но сериализация в GML2 не работает и все. В принципе.

Ну черт с ним, GML3 так GML3. Беда в том, что OpenLayers эту третью версию поддерживает, но в своем профайле. Приходится брать в руки вот такенный javascriptовый напильник и писать для OpenLayers GML3-формат в нужном профайле. По дороге обнаруживается, что HtmlUnit, который мы используем для тестирования JavaScript, для DOM-элементов не поддерживаются методы getAttributeNS и setAttributeNS, хотя в Firefox, например, эти методы вполне себе работают. Приходится разворачивать исходники HtmlUnit, патчить, слать патч и багрепорт разработчикам, отстраивать пропатченную версию.

Теперь тесты проходят, в браузерах сценарий не работает. Оказывается, HtmlUnit при сериализации не прописывает декларации пространств имен, поэтому мне приходилось добавлять их вручную. В Firefox и IE декларации добавляются, повторное объявление дает конфликт. Переделываю тесты, шлю тесткейс и багрепорт разработчикам HtmlUnit. Еще пара магических пассов, сценарий начинает работать в Firefox. IE сценарий не работает, судя по траффику трейсам геометрия нормально кодируется в GML и отправляется на сервер, но на клиенте разбор GML сбивается в самом начале - при банальном разборе XML.

Дебаггер в зубы, роем в чем проблема. Оказывается богоподобнейшая библиотека GeoTools при сериализации GML прописывает декларацию пространста имен XML (т.е. xmlns:xml="..."). Делать это вообще-то не нужно, но формального противоречия спецификации нет. В свою очередь, не менее богоподобнейший XML-парсер в IE с этим объявлением конфликтует, т.к. считает, что "префикс пространства имен не имеет права начинаться с 'xml'".

Ладно, сказали суровые уральские мужики и встроили в маршаллер вырезание этого пространства имен. От этого у у некогда европейского кода маршаллера начала темнеть кожа, того и гляди на лбу проступит красная точка и сам маршаллер пустится в пляс, напевая "не скроет от ветра такое жилье, но песня и пляска богатство мое". После данных пассов сценарий поднялся и в IE. Настало время интегрировать его в основное приложение.

Тут я должен оговориться, что вышеописанные танцы с бубном делались изолировано от основного приложения, в проектах карт-клиента, которые подняты на Мавене. Основное приложение, все еще не мавенизировано, т.е. в начале интеграции меня ожидал обычный аттракцион "а давай угадаем, какие библиотеки тебе нужны, чтобы все оно взлетело". Аттракцион принес несколько больше веселья, чем обычно. Оказывается, для банальной сериализации геометрии в GML GeoTools нужна половиа библиотек Eclipse Modelling Framework. Это как если бы сантехник пришел чинить унитаз и в качестве инструментов потребовал бы осциллограф, ускоритель элементарных частиц, термос с жидким азотом и двух человекоподобных роботов разного пола. Т.е. я не исключаю, что все оно нужно чтобы починить унитаз/сериализировать геометрию в GML, но реально гложут сомнения.

Ну ладно, зависимости отладил, тесты запустились. Подправил конфигурацию самого клиента, пробую запускать приложение.
Ноль. Фиг. Не стартует вообще. Причем не сбивается при старте, а вылетает с жалобой на ошибку 87 и "неправильный параметр". Ошибку отыскал, окостенел мрачно. Classpath слишком большой. Грубо говоря в "системе слишком много библиотек". Порылся - оказалось, что коллеги прицепили к проекту лишних зависимостей. Из-за этого classpath разросся и Eclipse не мог запустить приложение. А у них Linux, там этих проблем с classpath нет, поэтому они этого и не заметили. Пришлось чистить зависимости. Теперь система хотя бы стартует, но на тестирование сценария меня уже не хватило. В понедельник буду доделывать.

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

Ладно, спать.

Удач и приятных выходных.
Previous post Next post
Up