ADN Open CIS
Сообщество программистов Autodesk в СНГ

05/12/2014

Лёгкое программирование под Autodesk Vault Часть 45

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

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

Если у вас есть определение свойства, который содержит список допустимых значений, необходимо получить объект PropDefInfo для того, чтобы прочитать этот список значений.  GetPropertyDefinitionInfosByEntityClassId является единственным способом для получения этого объекта, но кажется, вам необходимо иметь права администратора, чтобы вызвать эту функцию. Существует недокументированная хитрость, которая позволяет получить эту информацию с нормальными разрешениями. Перейдите null в параметр 'propertyDefIds'. Это вернет все объекты PropDefInfo и это снимет требование по наличию разрешений администратора.

Код - C#: [Выделить]
  1. // Получить все файловые объекты PropDefInfo
  2. PropDefInfo[] propDefInfos = webServiceManager.PropertyService.GetPropertyDefinitionInfosByEntityClassId("FILE", null);

Код - VBA: [Выделить]
  1. 'Получить все файловые объекты PropDefInfo
  2. Dim propDefInfos As PropDefInfo() = webServiceManager.PropertyService.GetPropertyDefinitionInfosByEntityClassId("FILE", Nothing)

Как найти системное свойство

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

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

Как найти отображенное свойство

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

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

Код - C#: [Выделить]
  1. // Прозвище для «Компания« свойства в файле Inventor.
  2. string moniker = "15!{D5CDD502-2E9C-101B-9397-08002B2CF9AE}!nvarchar";
  3. List<PropDefInfo> mappedToContent = new List<PropDefInfo>();
  4. foreach (PropDefInfo propDefInfo in propDefInfos)
  5. {
  6.     bool matchFound = false;
  7.     if (propDefInfo.EntClassCtntSrcPropCfgArray == null)
  8.         continue;
  9.     foreach (EntClassCtntSrcPropCfg contentSource in propDefInfo.EntClassCtntSrcPropCfgArray)
  10.     {
  11.         if (contentSource.EntClassId != "FILE" || contentSource.CtntSrcPropDefArray == null)
  12.             continue;
  13.         for (int i = 0; i < contentSource.CtntSrcPropDefArray.Length; i++)
  14.         {
  15.             if (contentSource.CtntSrcPropDefArray[i].Moniker == moniker &&
  16.                 contentSource.MapDirectionArray[i] == MappingDirection.Read)
  17.             {
  18.                 mappedToContent.Add(propDefInfo);
  19.                 matchFound = true;
  20.                 break;
  21.             }
  22.         }
  23.         if (matchFound)
  24.             break;
  25.     }
  26. }

Код - VBA: [Выделить]
  1. 'Прозвище для «Компания« свойства в файле Inventor.
  2. Dim moniker As String = "15!{D5CDD502-2E9C-101B-9397-08002B2CF9AE}!nvarchar"
  3. Dim mappedToContent As New List(Of PropDefInfo)()
  4. For Each propDefInfo As PropDefInfo In propDefInfos
  5.     Dim matchFound As Boolean = False
  6.     If propDefInfo.EntClassCtntSrcPropCfgArray Is Nothing Then
  7.         Continue For
  8.     End If
  9.     For Each contentSource As EntClassCtntSrcPropCfg In propDefInfo.EntClassCtntSrcPropCfgArray
  10.         If contentSource.EntClassId <> "FILE" OrElse contentSource.CtntSrcPropDefArray Is Nothing Then
  11.             Continue For
  12.         End If
  13.         For i As Integer = 0 To contentSource.CtntSrcPropDefArray.Length - 1
  14.             If contentSource.CtntSrcPropDefArray(i).Moniker = moniker AndAlso contentSource.MapDirectionArray(i) = MappingDirection.Read Then
  15.                 mappedToContent.Add(propDefInfo)
  16.                 matchFound = True
  17.                 Exit For
  18.             End If
  19.         Next
  20.         If matchFound Then
  21.             Exit For
  22.         End If
  23.     Next
  24. Next

Как найти псевдоним

Это немного сложнее. Я не рекомендую пытаться выяснить, какой синтаксис мы используем.   Вместо этого я рекомендую следующее:

  1. Создайте новое UDP и отобразите его в свойство в файле.
  2. Напишите фрагмент кода, который получает этот объект PropDefInfo для вашего UDP.
  3. В отладчике отобразите на экране EntClassCtntSrcPropCfgArray объекта PropDefInfo.
  4. Вы должны быть в состоянии найти отображение вместе со значением псевдонима.
  5. Скопируйте значение псевдонима в код.

Как найти объект CtntSrc для файла

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

Код - C#: [Выделить]
  1. IEnumerable<PropDefInfo> results = propDefInfos.Where(prop => prop.PropDef.SysName == "Provider");
  2. PropDefInfo providerProp = results.First();
  3. PropInst[] values = webServiceManager.PropertyService.GetProperties("FILE", new long[] { file.Id }, new long[] { providerProp.PropDef.Id });
  4. string providerName = (string)values[0].Val;
  5. ServerCfg config = webServiceManager.AdminService.GetServerConfiguration();
  6. IEnumerable<CtntSrc> providers = config.CtntSrcArray.Where(source => source.DispName == providerName);
  7. if (providers.Count() == 0)
  8.     providers = config.CtntSrcArray.Where(source => source.SysName == "IFilter");
  9. CtntSrc provider = providers.First();

Код - VBA: [Выделить]
  1. Dim results As IEnumerable(Of PropDefInfo) = From propDefInfo In propDefInfos _
  2.     Where propDefInfo.PropDef.SysName = "Provider" _
  3.     Select propDefInfo
  4. Dim providerProp As PropDefInfo = results.First()
  5. Dim values As PropInst() = webServiceManager.PropertyService.GetProperties("FILE", New Long() {file.Id}, New Long() {providerProp.PropDef.Id})
  6. Dim providerName As String = DirectCast(values(0).Val, String)
  7. Dim config As ServerCfg = webServiceManager.AdminService.GetServerConfiguration()
  8. Dim providers As IEnumerable(Of CtntSrc) = From source In config.CtntSrcArray _
  9.     Where source.DispName = providerName _
  10.     Select source
  11. If providers.Count() = 0 Then
  12.     providers = config.CtntSrcArray.Where(Function(source) source.SysName = "IFilter")
  13. End If
  14. Dim provider As CtntSrc = providers.First()

 

Примечание: "IFilter" представляет собой системное имя к поставщику "All Files". Это должно использоваться, если значение поставщика пустое или нет соответствия с любым другим поставщиком.

Как обновить значение UDP для файла

Есть два способа сделать это. Правильный способ зависит от того, UDP отображается или нет.

Неотображенное UDP является простым случаем, вы просто вызываете UpdateFileProperties. Если UDP имеет отображение чтения, UpdateFileProperties не поможет вам. Причина в том что, когда файл выдан, внутреннее значение файла перезапишет значение UDP, которое вы только что установили.   Правильно будет обновить свойство внутри локального файла до возвращения его обратно в хранилище.   Это значит, что вы должны использовать соответствующее API САПР для установки данных файла.   После того как файл возвращен, сервер Vault обновит отображенное значение UDP.

Код - C#: [Выделить]
  1. // СДЕЛАТЬ: выдать файл
  2. if (isMapped)
  3. {
  4.     // Сделать: обновить локальный файла при помощи API САПР
  5. }
  6. else
  7. {
  8.     // СДЕЛАТЬ: вызов UpdateFileProperties
  9. }
  10. // СДЕЛАТЬ: Вернуть файл

 

Как сообщить о том, что UDP отображается

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

Код - C#: [Выделить]
  1. IEnumerable<PropDefInfo> results = propDefInfos.Where(prop => prop.PropDef.Id == propDefId);
  2. PropDefInfo theProperty = results.First();
  3. bool isMapped = false;
  4. if (theProperty.EntClassCtntSrcPropCfgArray != null)
  5. {
  6.     foreach (EntClassCtntSrcPropCfg contentSource in theProperty.EntClassCtntSrcPropCfgArray)
  7.     {
  8.         if (contentSource.EntClassId != "FILE" || contentSource.CtntSrcPropDefArray == null)
  9.             continue;
  10.         for (int i = 0; i < contentSource.CtntSrcPropDefArray.Length; i++)
  11.         {
  12.             if (contentSource.CtntSrcPropDefArray[i].CtntSrcId == provider.Id &&
  13.                 contentSource.MapDirectionArray[i] == MappingDirection.Read)
  14.             {
  15.                  isMapped = true;
  16.             }
  17.         }
  18.     }
  19. }

Код - VBA: [Выделить]
  1. Dim results As IEnumerable(Of PropDefInfo) = From prop In propDefInfos _
  2.     Where prop.PropDef.Id = propDefId _
  3.     Select prop
  4. Dim theProperty As PropDefInfo = results.First()
  5. Dim isMapped As Boolean = False
  6. If theProperty.EntClassCtntSrcPropCfgArray IsNot Nothing Then
  7.     For Each contentSource As EntClassCtntSrcPropCfg In theProperty.EntClassCtntSrcPropCfgArray
  8.         If contentSource.EntClassId <> "FILE" OrElse contentSource.CtntSrcPropDefArray Is Nothing Then
  9.             Continue For
  10.         End If
  11.         For i As Integer = 0 To contentSource.CtntSrcPropDefArray.Length - 1
  12.             If contentSource.CtntSrcPropDefArray(i).CtntSrcId = provider.Id AndAlso contentSource.MapDirectionArray(i) = MappingDirection.Read Then
  13.                 isMapped = True
  14.             End If
  15.         Next
  16.     Next
  17. End If

Источник: справка Autodesk Vault API. 

Обсуждение: http://adn-cis.org/forum/index.php?topic=1134

Опубликовано 05.12.2014
Отредактировано 05.12.2014 в 15:18:26