Библиотека API-интерфейса для Python, соответствующая спецификации CMIS: Часть 1. Введение в cmislib

API-интерфейс на стороне клиента, соответствующий спецификации CMIS (Content Management Interoperability Services)

Это первая статья в серии из двух частей, которая познакомит Вас с библиотекой на стороне клиента под названием cmislib, которая предназначена для работы со CMIS-совместимыми репозитариями контента. Спецификация CMIS (Content Management Interoperability Services) стандартизирует способ получения доступа к контенту, не зависящий от реализации обеспечивающего репозитария или от выбора языка программирования приложений пользовательского интерфейса. В этой статье описывается API-интерфейс для Python под названием cmislib с использованием нескольких примеров.

Джефф Поттс, старший директор по управлению корпоративным контентом (ECM), Optaros

Photo of Jeff PottsДжефф Поттс (Jeff Potts) является старшим директором по управлению корпоративным контентом в глобальной консалтинговой компании Optaros, специализирующейся на сборке решений типа Content/Community/Commerce (контент/сообщество/коммерция) на базе компонентов с открытым исходным кодом. Дж. Поттс более 12 лет руководит ECM-направлением и более 18 лет занимается технологическими реализациями в ИТ-подразделениях и в организациях по оказанию специализированных услуг. Он обладает глубокими знаниями в области платформ для управления контентом (как с закрытым, так и с открытым исходным кодом), в особенности в области платформы Alfresco, где он является активным и заметным членом сообщества. В 2008 г. Дж. Поттс написал книгу Alfresco Developer Guide (Руководство разработчика Alfresco), которая была опубликована в издательстве Packt Publishing и принесла ему награду «Packt's Author of the Year Award» за 2008 г. В нынешнем году Дж. Поттс внес свой вклад в проект Apache Chemistry в виде библиотеки cmislib. С Джеффом Поттсом можно побеседовать в его блоге: http://ecmarchitect.com.



13.12.2010

Представляем cmislib: API-интерфейс для языка Python, соответствующий спецификации CMIS

Похоже, для спецификации Content Management Interoperability Services (CMIS) наступает напряженное время. Организация OASIS занимается подготовкой материалов для выпуска 1.0 данной спецификации, поставщики репозитариев упорно трудятся над завершением своих реализаций на стороне сервера, а разработчики из сообщества по управлению контентом выпускают стандартизованные клиентские компоненты и API-интерфейсы, призванные облегчить исследование и работу с репозитариями насыщенного контента за счет применения стандартных способов.

Часто используемые сокращения

  • ACL: Access control list (Список управления доступом)
  • API: Application program interface (Интерфейс прикладного программирования, API-интерфейс)
  • HTTP: Hypertext transfer protocol (Протокол передачи гипертекстовых файлов)
  • OASIS: Organization for the Advancement of Structured Information Standards (Организация по продвижению стандартов для структурированной информации)
  • REST: Representational State Transfer (Архитектурный подход, основанный на передаче состояния представления)
  • SDK: Software development kit (Инструментарий для разработки программного обеспечения)
  • SQL: Structured Query Language (Язык структурированных запросов)
  • URL: Uniform Resource Locator (Унифицированный указатель информационного ресурса, URL-адрес)
  • WSDL: Web Services Description Language (Язык описания Web-сервисов)
  • XML: Extensible Markup Language (Расширяемый язык разметки)

Если вам когда-либо приходилось создавать контентно-ориентированные приложения, то вы знаете, что обычно первая трудность состоит в выяснении того, как следует «говорить» с обеспечивающим репозитарием контента. Сначала ваша команда проходит ускоренный курс обучения по SDK-инструментарию этого репозитария. Затем вы проектируете вышеупомянутое приложение, в том числе интеграцию между уровнем представления (Presentation tier) и уровнем контентных сервисов (Content services tier). И, наконец, вы исполняете свой план, после чего отмечаете достигнутый успех большим банкетом с напитками и закусками. Однако, помимо увеличения окружности вашей талии, отрицательный момент такого подхода состоит в том, что этот процесс повторяется для каждой новой комбинации фронтального и серверного компонентов, поскольку каждый репозитарий имеет свой уникальный API-интерфейс. И если, как это часто бывает, вашему приложению нужно разговаривать с несколькими репозитариями, то вы должны будете изучить несколько интерфейсов и написать соответствующий программный код.

К счастью, подобная проблема уже решалась ранее. Аналогичная ситуация имела место до стандартизации SQL. Реляционные базы данных, созданные IBM® и другими компаниями, начали появляться еще в начале 1970-х годов, однако первое официальные работы по стандартизации языка запросов SQL начались только в 1986 г. Когда это, наконец, произошло, особенно после выпуска крупной ревизии в 1992 г., разработчики получили возможность для создания фронтальных приложений – с достаточной степенью уверенности в том, что эти приложения смогут работать с несколькими реляционными серверными компонентами. Спецификация CMIS потенциально способна сделать для контентно-ориентированных приложений то же самое, что язык SQL сделал для приложений реляционных баз данных. CMIS предоставляет стандартный способ для взаимодействия с серверным компонентом, не зависящий от реализации обеспечивающего репозитария или от выбора языка программирования для фронтального компонента. Только на этот раз вместо строк и столбцов мы говорим о неструктурированном и полуструктурированном контенте – обычно это файлы той или иной разновидности – который, как правило, размещается в иерархической структуре папок.

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

Эта статья описывает библиотеку стороны клиента под названием cmislib, которая предназначена для работы со CMIS-репозитариями из среды Python. Эта библиотека, которая в настоящее время сопровождается в рамках проекта Apache Chemistry, призвана упростить разработчикам на языке Python написание контентно-ориентированных приложений, способных работать с любым серверным компонентом, соответствующим спецификации CMIS. Для многих разработчиков этот API-интерфейс окажется удобным способом практического знакомства с возможностями CMIS.

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

Побудительные мотивы для создания описываемого API-интерфейса

В силу множества причин создание клиентского API-интерфейса для CMIS на языке Python представлялось разумной идеей. Некоторые из этих причин относятся к категории «стратегических» и «идеалистических». Другие причины являются более «тактическими» и «эгоистическими». Начнем с причин первой категории.

Поставщики продуктов, соответствующих CMIS, обязаны предлагать как связывание на основе Web-сервисов, так и RESTful-связывание на основе протокола AtomPub (Atom Publishing Protocol). Каждое из этих связываний имеет определенные преимущества перед другим, однако одно из различий между ними состоит в том, как осуществляется обнаружение и вызов CMIS-сервисов на различных серверах. Связывание через Web-сервисы предусматривает наличие WSDL-файла, который может использоваться для автоматической генерации клиентского кода. Если вы желаете использовать связывание на основе Web-сервисов, то с небольшими дополнительными усилиями (помимо создания WSDL-файла для своего CMIS-сервера) вы сможете сгенерировать свой API-интерфейс для стороны клиента.

С другой стороны, RESTful-связывание на основе протокола AtomPub не имеет стандартного способа для описания своих сервисов. Поскольку это «RESTful-связывание», то доступ ко всем его сервисам осуществляется посредством URL-адреса, однако спецификация CMIS оставляет каждому поставщику определенные URL-адреса. Таким образом, если вы хотите написать код, который будет работать со всеми «CMIS-совместимыми» поставщиками с использованием RESTful-связывания на основе AtomPub, то на стороне клиента вам придется выполнить несколько больший объем работы. Вместо повторения этой работы во всех проектах целесообразно сделать это в рамках проекта с открытым исходным кодом, результаты которого будут доступны всем желающим.

Следующая причина состоит в принятии рассматриваемой нами спецификации разработчиками приложений и поставщиками репозитариев контента. Разработчики могут просматривать соответствующие Web-семинары, сообщения в блогах, трафик Twitter и т.п., однако до тех пор, пока они не попробуют это своими руками и не осознают ценность на собственном опыте, CMIS остается для них не более чем очередным модным словечком. Если бы программное обеспечение по-прежнему поставлялось в коробках, то можно было бы вообразить ярко раскрашенные лозунги типа: «Теперь – на основе CMIS!». Язык Python – чистый, продуктивный, простой в установке – выглядит как прекрасный выбор для тех разработчиков, которые действительно хотят разобраться в том, что спецификация CMIS способна реально сделать для них и для их приложений. API-интерфейс cmislib ограждает разработчиков от деталей реализации и обеспечивает им интуитивно понятный, объектно-ориентированный и совместимый способ работы. Хотелось бы надеяться, что разработчики возьмут его на вооружение, как и многое другое, что попадает в поле их зрения, и начнут использовать CMIS в качестве стандартного способа для взаимодействия заказных контентно-ориентированных приложений с репозитариями насыщенного контента – вне зависимости от языка, на котором построен соответствующий клиент – на языке Python или на каком-либо другом языке.

Если спецификация CMIS будет принята хотя бы одним или двумя поставщиками, то конечная целая цель уже будет достигнута. Таким образом, всем тем, кто выигрывает от использования этого стандарта, определенно имеет смысл сделать все возможное, чтобы стимулировать принятие со стороны поставщика. В состав дистрибутива cmislib включены т.н. модульные тесты (unit test), предназначенные для использования в качестве наилучшей типовой методики разработки. Этот набор тестов существенно помогает гарантировать сохранение всех функциональных возможностей в процессе разработки API, а также является также удобным способом для воспроизводимой валидации такой характеристики, как «способность к взаимодействию». В любом случае, эти модульные тесты функционируют как набор тестов для поставщиков – и это очень хорошо! Каждый из таких поставщиков, как IBM, Alfresco™, OpenText и Nuxeo, использовал cmislib для выявления проблем в своих реализациях. Они не ограничивались только библиотекой cmislib – для валидации своей работы эти поставщики использовали все разновидности построенных сообществом CMIS-инструментов и CMIS-клиентов, что является весьма позитивным явлением.

«Все за одного и один за всех» – это сильная мотивация, однако она редко приводит к появлению хотя бы одной строки написанного кода. Образно говоря, каждый проект с открытым исходным кодом начинается с того, что у разработчика возникает непреодолимое желание почесать некое «зудящее место». В рассматриваем случае зуд начался с интранет-проекта, который компания Optaros™ выполнила для своего клиента. Этот проект должен был обеспечить интеграцию между Django® (инфраструктура на базе Python для разработки Web-приложений) и Alfresco (платформа с открытым исходным кодом для управления контентом). На момент реализации этого проекта спецификация CMIS еще не вышла за рамки идеи в организации OASIS, поэтому указанная интеграция использует на стороне сервера Web-скрипты Alfresco (инфраструктура для развертывания собственного RESTful API-интерфейса к платформе Alfresco) для передачи XML по HTTP между основанным на Django уровнем представления и Alfresco-репозитарием. Все это работает прекрасно, но является «Alfresco-специфическим». Казалось разумным провести рефакторинг этой интеграции Django с целью использования CMIS. Тем не менее, чтобы избежать привязки к Django, мы решили сначала развернуть библиотеку cmislib в качестве API-интерфейса нижнего уровня для Python. Преимущество этого подхода состоит в том, что благодаря использованию библиотеки cmislib он существенно облегчает интеграцию с CMIS-совместимыми репозитариями не только Django, но и других Python-проектов, таких как Zope® и Plone®, а так же заказных Python-приложений.

Последняя «эгоистическая» причина – это производительность труда разработчика. Большинство предприятий не могут позволить себе такой роскоши, как работа с единственным репозитарием. Кроме того, во многих случаях ИТ-решение неспособно предугадать, с каким именно репозитарием ему придется иметь дело, или, по меньшей мере, нуждается в возможностях для переключения на соответствующий репозитарий при наступлении нужного момента. Вполне очевидно, что стандарт CMIS помогает преодолеть эти проблемы, однако чтобы работа стала действительно продуктивной, необходимы соответствующие библиотеки на стороне клиента. В настоящее время осуществляются и другие проекты по созданию клиентских библиотек для CMIS, основанных на Java™ и PHP. Однако язык Python также очень распространен на уровне представления, поэтому столь важна клиентская библиотека для CMIS, основанная на Python.

Что делает API-интерфейс cmislib

Назначение интерфейса cmislib состоит в том, чтобы абстрагировать детали обеспечивающей реализации CMIS. Для того чтобы построить решения «поверх» CMIS-совместимых репозитариев, разработчикам нет необходимости изучать, как работает CMIS. Напротив, библиотека cmislib предоставляет простую в понимании модель объекта, которая знакома любому специалисту, который работает с репозитарием контента или прочитал спецификацию CMIS. Вместо «коллекций», «элементов» и «потоков» разработчики работают с такими естественными концепциями управления контентом, как репозитарии, папки, документы и ACL-списки.

Как указывалось выше, при коммуникациях со CMIS-совместимыми серверами cmislib использует связывание RESTful AtomPub. Одна из важных задач при разработке состояла в том, чтобы гарантировать отсутствие у библиотеки cmislib каких-либо знаний о специфике поставщиков серверных репозитариев, к которым она обращается – эта библиотека относится к CMIS-поставщику как к «черному ящику». Когда вы используете интерфейс cmislib для подключения к CMIS-поставщику, вы предоставляете ему точку входа CMIS-поставщика или URL-адрес сервиса и некую учетную информацию. Библиотека cmislib выясняет порядок дальнейшего взаимодействия с соответствующим сервером посредством исследования его ответов.

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

  • Коллекция извлеченных документов существует.
  • При вызове сервиса getCheckedOutDocsобязателен аргумент repositoryId.
  • Можно передать нескольких дополнительных аргументов, которые, по большей части, имеют отношение к разбиению на страницы набора результатов.
  • Ответ от сервиса будет представлять собой поток Atom.

Однако спецификация не сообщает вам точного URL-адреса для получения вышеупомянутой коллекции. Это оставлено на усмотрение поставщика. Библиотека cmislib выясняет, каков этот URL-адрес и как преобразовать отклик в объекты языка Python, с которыми вы сможете работать «Python-образным» способом. В листинге 1 показано, как это взаимодействие выглядит из оболочки Python:

Листинг 1. Перечень извлеченных из репозитария документов
>>> rs = repo.getCheckedOutDocs()

>>> len(rs)
2
>>> for doc in rs:
...     doc.title
... 
u'Response XML (Working Copy)'
u'd1 (Working Copy)'

Аналогично, предположим, что вы хотите извлечь документ из репозитария. Согласно спецификации, для изъятия вы должны отправить методом POST запись Atom в коллекцию извлеченных элементов (checkout), после чего репозитарий возвратит элемент Atom, представляющий собой частную рабочую копию (PWC - Private Working Copy) объекта, который вы извлекли. Если вы используете cmislib, то вам нет необходимости заботиться об определении коллекции, о построении и отправке XML-элемента Atom или об обработке XML-ответа. Вместо этого вы ограничиваетесь применением метода checkout к нужному объекту, а библиотека cmislib возвращает вам объект типа «Документ» в виде PWC-копии. Это взаимодействие показано в листинге 2

Листинг 2. Извлечение документа
>>> doc.title
u'testdoc'
>>> pwc = doc.checkout()
>>> pwc.title
u'testdoc (Working Copy)'
>>> doc.checkedOut
True

Подход к разработке и тестированию

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

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

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

Первоначально тестирование столкнулось с определенными трудностями, поскольку не существовало никакой эталонной реализации (на тот момент связывание AtomPub в эталонной реализации Apache Chemistry функционировало лишь в режиме «только для чтения») и поскольку поставщики все еще работали над своими реализациями. Компания Alfresco, первопроходец в области CMIS, имела самую зрелую реализацию, поэтому я начал именно с нее. Как только большинство модульных тестов с реализацией Alfresco прошло успешно, я начал тестировать публично доступные CMIS-реализации других поставщиков. Корпорация IBM проявила любезность и безвозмездно предоставила свою реализацию. Добавление второй реализации прояснило многие неясные моменты, но при этом оказалось большим испытанием для cmislib и всех вовлеченных поставщиков. И на стороне клиента, и на стороне сервера мы выявили проблемы, которые, вполне возможно, не были бы обнаружены так быстро без подобного тестирования на способность к взаимодействию.

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

  • Недостаточная полнота реализации. Спецификация CMIS все еще является весьма новой. Обычной практикой является выявление недостающих сервисов (складывается впечатление, что на данный момент хуже всего поддерживаются ACL-списки, отношения, политики и журналы изменений), обязательных возможностей, которые пока не поддерживаются (напр., не предоставленные обязательные коллекции и связи) и жестко закодированные значения.
  • Различающиеся интерпретации спецификации. Спецификация CMIS представляет собой хорошо написанный и легкий для чтения документ, однако некоторые моменты по-прежнему остаются открытыми для интерпретации. Например, до выхода шестой версии проекта содержимое коллекции checkedout не было определено. Возможно, предполагалось, что она должна содержать PWC-копии извлеченных объектов? Или непосредственно сами объекты? Разные поставщики интерпретировали это по-разному и осуществили реализацию согласно своим интерпретациям. За прошедшее с тех пор время эта конкретная проблема была устранена (если вам интересно, то ответ – PWC-копии), однако можно понять, насколько трудным могло оказаться написание клиента, действительно способного к взаимодействию.
  • Плохие допущения. Иногда расширение спецификации стороны определенного поставщика является вполне очевидным, а иногда это далеко не так. Если вы пишете программный код своего API для одного сервера, а затем рассматриваете его в качестве эталонной реализации, то вы сделали допущение о том, что другие реализации будут действовать аналогичным образом. На данный момент проблема состоит в том, что пока не существует эталонной CMIS-реализации со связыванием на основе AtomPub, которая была бы функционально полна и соответствовала бы спецификации на 100%.

Несколько примеров

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

Получение объекта Repository

Объекты CmisClient и Repository – это обычные начальные точки для практически любых действий со CMIS-репозитарием. Получение экземпляра осуществляется достаточно просто – вам достаточно знать URL-адрес сервиса и учетные данные для входа в репозитарий. Выполните следующие действия:

  1. Из командной строки запустите оболочку Python, для чего введите с клавиатуры слово python, а затем нажмите на клавишу Enter.
  2. Импортируйте объект CmisClient:
    >>> from cmislib.model import CmisClient
  3. Укажите объекту CmisClient на URL-адрес сервиса в репозитарии:
    >>> client = CmisClient('http://cmis.alfresco.com/s/cmis', 'admin', 'admin')
  4. Каждый репозитарий имеет свой идентификатор (ID) – если вы знаете его, то сможете получить нужный репозитарий по его идентификатору. В рассматриваемом случае мы запросим у клиента репозитарий по умолчанию.
    >>> repo = client.defaultRepository
    >>> repo.id u'83beb297-a6fa-4ac5-844b-98c871c0eea9'
  5. Теперь вы можете получить свойства репозитария. Следующая конструкция вида for-loop выкладывает всю информацию, которую cmislib знает о репозитарии. (Я обрезал листинг для краткости).
    >>> repo.name u'Main Repository'
    >>> info = repo.info
    >>> for k,v in info.items():
        ...     print "%s:%s" % (k,v)
        ...     
        cmisSpecificationTitle:Version 1.0 Committee Draft 04
        cmisVersionSupported:1.0
        repositoryDescription:None
        productVersion:3.2.0 (r2 2440)
        rootFolderId:workspace://SpacesStore/aa1ecedf-9551-49c5-831a-0502bb43f348
        repositoryId:83beb297-a6fa-4ac5-844b-98c871c0eea9
        repositoryName:Main Repository
        vendorName:Alfresco
        productName:Alfresco Repository (Community)

Работа с объектами типа Folder (Папка) и Document (Документ)

После того, как вы будете располагать объектом Repository (Репозитарии), вы сможете приступить к работе с такими объектами в этом репозитарии, как Folder (Папка) и Document (Документ).

  1. Создайте новую папку в корневом каталоге. Если вы до настоящего момента следовали всем рекомендациям буквально, то сейчас дайте своей папке какое-либо уникальное имя – если вы осуществляете тестирование с публичным репозитарием.
    >>> root = repo.rootFolder
    >>> someFolder = root.createFolder('someFolder')
    >>> someFolder.id 
    u'workspace://SpacesStore/91f344ef-84e7-43d8-b379-959c0be7e8fc'
  2. Теперь вы можете создать какой-либо контент:
    >>> someFile = open('test.txt', 'r')
    >>> someDoc = someFolder.createDocument('Test Document', contentFile=someFile)
  3. При желании вы можете вывести на печать свойства только что созданного документа (как показано на следующем фрагменте листинга):
    >>> props = someDoc.properties
    >>> for k,v in props.items():
    ...     print '%s:%s' % (k,v)
    ...
    cmis:contentStreamMimeType:text/plain
    cmis:creationDate:2009-12-18T10:59:26.667-06:00
    cmis:baseTypeId:cmis:document
    cmis:isLatestMajorVersion:false
    cmis:isImmutable:false
    cmis:isMajorVersion:false
    cmis:objectId:workspace://SpacesStore/2cf36ad5-92b0-4731-94a4-9f3fef25b479

Извлечение объектов

Для извлечения какого-либо объекта можно использовать несколько различных способов:

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

Ниже приведено несколько примеров, демонстрирующих эти возможности в действии:

  1. Нахождение документа, созданного в предыдущем параграфе, с помощью полнотекстового поиска.
    >>> results = repo.query("select * from cmis:document where contains('test')")
    >>> for result in results:
    ...     print result.name
    ...
    Test Document2
    Example test script.js
  2. В качестве альтернативного варианта вы также можете получать объекты по их путям:
    >>> someDoc = repo.getObjectByPath('/someFolder/Test Document')
    >>> someDoc.id 
    u'workspace://SpacesStore/2cf36ad5-92b0-4731-94a4-9f3fef25b479'
  3. Кроме того, можно извлечь объект с использованием его идентификатора:
    >>> someDoc = repo.getObject('workspace://SpacesStore/2cf36ad5-94a4-9f3fef25b479')
    >>> someDoc.name 
    u'Test Document'
  4. У объектов типа Folder имеются методы getChildren () и getDescendants (), которые возвращают набор результатов (в постраничном виде):
    >>> children= someFolder.getChildren()
    >>> for child in children:
    ...     print child.name
    ...
    Test Document
    Test Document2
  5. У объектов типа Folder и Document имеется метод getRelationships(), который возвращает набор объектов типа Relationship (Отношение). Объект типа Relationship позволяет вам получить исходный и целевой объекты, связанные с соответствующими концами этого отношения.
    >>> rel = testDoc.getRelationships(includeSubRelationshipTypes='true')[0]
    >>> rel.source.name
    'testDoc1'
    >>> rel.target.name
    'testDoc2'
    >>> rel.properties['cmis:objectTypeId']
    'R:sc:relatedDocuments'

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


Заключение

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

  • В случае отсутствия библиотеки клиента, написанной на предпочтительном для вас языке, создайте такую библиотеку в виде проекта с открытым исходным кодом.
  • Помогите вашему поставщику репозитария протестировать его реализацию CMIS.
  • Напишите для своего любимого портала интеграционные компоненты или презентационную инфраструктуру, упрощающую работу со CMIS-совместимыми репозитариями.
  • Внесите свой вклад в существующие CMIS-проекты с открытым исходным кодом, таких как cmislib и Apache Chemistry.
  • Примите участие в совершенствовании спецификации CMIS в сотрудничестве с Техническим комитетом по CMIS в организации OASIS .

Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


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

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=XML, Open source, SOA и web-сервисы
ArticleID=600572
ArticleTitle=Библиотека API-интерфейса для Python, соответствующая спецификации CMIS: Часть 1. Введение в cmislib
publish-date=12132010