Лёгкое программирование под Autodesk Vault Часть 45
Это раздел будет об исходном коде. Здесь вы найдете полезные фрагменты кода для работы со свойствами.
Как получить список допустимых значений для определения свойства
Если у вас есть определение свойства, который содержит список допустимых значений, необходимо получить объект PropDefInfo для того, чтобы прочитать этот список значений. GetPropertyDefinitionInfosByEntityClassId является единственным способом для получения этого объекта, но кажется, вам необходимо иметь права администратора, чтобы вызвать эту функцию. Существует недокументированная хитрость, которая позволяет получить эту информацию с нормальными разрешениями. Перейдите null в параметр 'propertyDefIds'. Это вернет все объекты PropDefInfo и это снимет требование по наличию разрешений администратора.
- // Получить все файловые объекты PropDefInfo
- PropDefInfo[] propDefInfos = webServiceManager.PropertyService.GetPropertyDefinitionInfosByEntityClassId("FILE", null);
- 'Получить все файловые объекты PropDefInfo
- Dim propDefInfos As PropDefInfo() = webServiceManager.PropertyService.GetPropertyDefinitionInfosByEntityClassId("FILE", Nothing)
Как найти системное свойство
Для системных свойств является нормальным жесткое кодирование системного имени, поскольку имя будет одинаково во всех хранилищах и для всех языков. FindPropertyDefinitionsBySystemNames является функцией API для этих целей, и она довольно проста в работе. Хитрость заключается в нахождении системного имени. В диалоговом окне свойств можно настроить колонки, для отображения системное имя каждого определения свойства.
Обратите внимание, что системные имена красивы и просты. Однако любые UDP, которые вы создаете, будут иметь случайно сгенерированный GUID, связанный с ними. Таким образом, системное имя не является хорошим способом для поиска UDP.
Как найти отображенное свойство
Иногда все, что вас волнует, это свойство файла, и вы хотите увидеть PropDef хранилища, который имеет отображение на чтение этого файлового свойства. Жесткая запись системного имени будет не полезной, так как имена UDP и отображения свойств могут изменяться от хранилища к хранилищу.
Что вам нужно, так это найти псевдоним для свойства файла и использовать этот файл, чтобы найти PropDef хранилища. Примечание: может быть вообще никаких отображений, либо несколько отображения на свойство файла.
- // Прозвище для «Компания« свойства в файле Inventor.
- string moniker = "15!{D5CDD502-2E9C-101B-9397-08002B2CF9AE}!nvarchar";
- List<PropDefInfo> mappedToContent = new List<PropDefInfo>();
- foreach (PropDefInfo propDefInfo in propDefInfos)
- {
- bool matchFound = false;
- if (propDefInfo.EntClassCtntSrcPropCfgArray == null)
- continue;
- foreach (EntClassCtntSrcPropCfg contentSource in propDefInfo.EntClassCtntSrcPropCfgArray)
- {
- if (contentSource.EntClassId != "FILE" || contentSource.CtntSrcPropDefArray == null)
- continue;
- for (int i = 0; i < contentSource.CtntSrcPropDefArray.Length; i++)
- {
- if (contentSource.CtntSrcPropDefArray[i].Moniker == moniker &&
- contentSource.MapDirectionArray[i] == MappingDirection.Read)
- {
- mappedToContent.Add(propDefInfo);
- matchFound = true;
- break;
- }
- }
- if (matchFound)
- break;
- }
- }
- 'Прозвище для «Компания« свойства в файле Inventor.
- Dim moniker As String = "15!{D5CDD502-2E9C-101B-9397-08002B2CF9AE}!nvarchar"
- Dim mappedToContent As New List(Of PropDefInfo)()
- For Each propDefInfo As PropDefInfo In propDefInfos
- Dim matchFound As Boolean = False
- If propDefInfo.EntClassCtntSrcPropCfgArray Is Nothing Then
- Continue For
- End If
- For Each contentSource As EntClassCtntSrcPropCfg In propDefInfo.EntClassCtntSrcPropCfgArray
- If contentSource.EntClassId <> "FILE" OrElse contentSource.CtntSrcPropDefArray Is Nothing Then
- Continue For
- End If
- For i As Integer = 0 To contentSource.CtntSrcPropDefArray.Length - 1
- If contentSource.CtntSrcPropDefArray(i).Moniker = moniker AndAlso contentSource.MapDirectionArray(i) = MappingDirection.Read Then
- mappedToContent.Add(propDefInfo)
- matchFound = True
- Exit For
- End If
- Next
- If matchFound Then
- Exit For
- End If
- Next
- Next
Как найти псевдоним
Это немного сложнее. Я не рекомендую пытаться выяснить, какой синтаксис мы используем. Вместо этого я рекомендую следующее:
- Создайте новое UDP и отобразите его в свойство в файле.
- Напишите фрагмент кода, который получает этот объект PropDefInfo для вашего UDP.
- В отладчике отобразите на экране EntClassCtntSrcPropCfgArray объекта PropDefInfo.
- Вы должны быть в состоянии найти отображение вместе со значением псевдонима.
- Скопируйте значение псевдонима в код.
Как найти объект CtntSrc для файла
CtntSrc является объектом, который представляет поставщику исходное содержимое. Каждый файл будет иметь одного и только одного поставщика. Вы можете найти правильный объект, используя системное свойство Provider файла.
- IEnumerable<PropDefInfo> results = propDefInfos.Where(prop => prop.PropDef.SysName == "Provider");
- PropDefInfo providerProp = results.First();
- PropInst[] values = webServiceManager.PropertyService.GetProperties("FILE", new long[] { file.Id }, new long[] { providerProp.PropDef.Id });
- string providerName = (string)values[0].Val;
- ServerCfg config = webServiceManager.AdminService.GetServerConfiguration();
- IEnumerable<CtntSrc> providers = config.CtntSrcArray.Where(source => source.DispName == providerName);
- if (providers.Count() == 0)
- providers = config.CtntSrcArray.Where(source => source.SysName == "IFilter");
- CtntSrc provider = providers.First();
- Dim results As IEnumerable(Of PropDefInfo) = From propDefInfo In propDefInfos _
- Where propDefInfo.PropDef.SysName = "Provider" _
- Select propDefInfo
- Dim providerProp As PropDefInfo = results.First()
- Dim values As PropInst() = webServiceManager.PropertyService.GetProperties("FILE", New Long() {file.Id}, New Long() {providerProp.PropDef.Id})
- Dim providerName As String = DirectCast(values(0).Val, String)
- Dim config As ServerCfg = webServiceManager.AdminService.GetServerConfiguration()
- Dim providers As IEnumerable(Of CtntSrc) = From source In config.CtntSrcArray _
- Where source.DispName = providerName _
- Select source
- If providers.Count() = 0 Then
- providers = config.CtntSrcArray.Where(Function(source) source.SysName = "IFilter")
- End If
- Dim provider As CtntSrc = providers.First()
Примечание: "IFilter" представляет собой системное имя к поставщику "All Files". Это должно использоваться, если значение поставщика пустое или нет соответствия с любым другим поставщиком.
Как обновить значение UDP для файла
Есть два способа сделать это. Правильный способ зависит от того, UDP отображается или нет.
Неотображенное UDP является простым случаем, вы просто вызываете UpdateFileProperties. Если UDP имеет отображение чтения, UpdateFileProperties не поможет вам. Причина в том что, когда файл выдан, внутреннее значение файла перезапишет значение UDP, которое вы только что установили. Правильно будет обновить свойство внутри локального файла до возвращения его обратно в хранилище. Это значит, что вы должны использовать соответствующее API САПР для установки данных файла. После того как файл возвращен, сервер Vault обновит отображенное значение UDP.
- // СДЕЛАТЬ: выдать файл
- if (isMapped)
- {
- // Сделать: обновить локальный файла при помощи API САПР
- }
- else
- {
- // СДЕЛАТЬ: вызов UpdateFileProperties
- }
- // СДЕЛАТЬ: Вернуть файл
Как сообщить о том, что UDP отображается
Ниже приведен код, который позволяет определить, имеет ли свойство отображение чтения или нет. Так как каждый поставщик устанавливает свои собственные отображения, вам нужен объект CtntSrc из предыдущего раздела.
- IEnumerable<PropDefInfo> results = propDefInfos.Where(prop => prop.PropDef.Id == propDefId);
- PropDefInfo theProperty = results.First();
- bool isMapped = false;
- if (theProperty.EntClassCtntSrcPropCfgArray != null)
- {
- foreach (EntClassCtntSrcPropCfg contentSource in theProperty.EntClassCtntSrcPropCfgArray)
- {
- if (contentSource.EntClassId != "FILE" || contentSource.CtntSrcPropDefArray == null)
- continue;
- for (int i = 0; i < contentSource.CtntSrcPropDefArray.Length; i++)
- {
- if (contentSource.CtntSrcPropDefArray[i].CtntSrcId == provider.Id &&
- contentSource.MapDirectionArray[i] == MappingDirection.Read)
- {
- isMapped = true;
- }
- }
- }
- }
- Dim results As IEnumerable(Of PropDefInfo) = From prop In propDefInfos _
- Where prop.PropDef.Id = propDefId _
- Select prop
- Dim theProperty As PropDefInfo = results.First()
- Dim isMapped As Boolean = False
- If theProperty.EntClassCtntSrcPropCfgArray IsNot Nothing Then
- For Each contentSource As EntClassCtntSrcPropCfg In theProperty.EntClassCtntSrcPropCfgArray
- If contentSource.EntClassId <> "FILE" OrElse contentSource.CtntSrcPropDefArray Is Nothing Then
- Continue For
- End If
- For i As Integer = 0 To contentSource.CtntSrcPropDefArray.Length - 1
- If contentSource.CtntSrcPropDefArray(i).CtntSrcId = provider.Id AndAlso contentSource.MapDirectionArray(i) = MappingDirection.Read Then
- isMapped = True
- End If
- Next
- Next
- End If
Источник: справка Autodesk Vault API.
Обсуждение: http://adn-cis.org/forum/index.php?topic=1134
Опубликовано 05.12.2014Отредактировано 05.12.2014 в 15:18:26