ЛОЦМАН API + Java

Автор sumoist, 21.08.09, 11:33:25

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

sumoist

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

SmaLL75

думаю надо искать инфу на тему JAVA и DCOM

sumoist

Цитата: SmaLL75 от 21.08.09, 11:49:17
думаю надо искать инфу на тему JAVA и DCOM
Ага, спасибо за совет! Буду теперь хоть знать в каком направлении копать! Тут вот люди еще советовали осуществлять работу с COM-объектами с помощью библиотек SWT и Jacob.

teplinskiy

полагаю любой редактор java скриптов способен отображать лоцмановые интерфейсы:
LoodsmanServerApplication.MainSystem
DataProvider.LoodsmanConnection
и т.д...
если в них покопаться...можно найти самое необходимое...

вот пример работы на "басике"...не java...но действовать можно в этом направлении:

Const APP_TITLE="Test"
Set cnn = CreateObject("DataProvider.LoodsmanConnection")
cnn.Connected = True
MsgBox cnn.API8.RunMethod("AppServerName", Array())
s = cnn.API8.RunMethod("GetDBList", Array())
Do
  s = InputBox("Database. Input only one name", APP_TITLE, s)
  If s="" Then break
Loop While InStr(1, s, ",")>0

i = cnn.API8.ShowDBConnectionDialog(s)
MsgBox i
If i=-1 Then break

cnn.API8.RunMethod "ConnectToDB", Array(s)

Set ds = cnn.API8.GetDataSet("GetProjectList", Array())

s = ""
Do While Not ds.Eof
  s = s & ds.FieldValue("_TYPE") & Chr(9) & ds.FieldValue("_PRODUCT") & Chr(13)
  ds.Next
Loop

MsgBox s, vbOKOnly, APP_TITLE & " - GetProjectList"

-----------------------------
и еще...
как вариант можно также попробовать получить TLB и использовать в проектах из:
"DataProvider.dll"...
лежит она по следующему пути:
c:\Program Files\Common Files\ASCON Shared\Loodsman

sumoist

Цитата: teplinskiy от 21.08.09, 13:03:01
LoodsmanServerApplication.MainSystem
- вот с помощью этого достучался до Лоцмана...
Цитата: teplinskiy от 21.08.09, 13:03:01
DataProvider.LoodsmanConnection
- а тут что-то ошибку выдает, надо будет еще посмотреть. Ну в любом случае, спасибо за совет! Думаю, что вопросов будет еще много.
P.S. (Это скорее будет интересно java-разработчикам) Для работы с com-объектами использую Jacob. А вот то что,
Цитата: SmaLL75 от 21.08.09, 11:49:17
JAVA и DCOM
посоветовали, пока четкой информации не нашел, но очень уж это заинтриговало, думаю, что потом и с этим надо будет разобраться.

sumoist

И так... тут появилось много вопросов и неразрешимых проблем   :|
Ну во-первых, при связи с Лоцманом, единственное что удалось у него узнать - так это версию приложения (то бишь версию самого Лоцмана) ну еще и название текущей базы данных, но не на прямую, а с помощью "GetDBList". Если же использовать метод "CurrentBase", то в ответ можно получить пустую строчку: System.out.println("Версия сервер приложения: "
+ loodsman.getPropertyAsString("CurrentBase"));

Причем пустую строчку возвращают все методы из "Свойства сервера приложений", которые должны возвращать данные типа String. Остальные методы из этой группы, которые по идее типа Boolean, тоже выдают неодекватные данные, причем, всегда одни и теже, независимо от того залогинился ли ты под администратором или обычным пользователем (или как там называется?..)
Вообще, сколько методов и функций не использовал, в ответ либо NULL либо пустая строка, что бы не быть галословным приведу пример:Variant сurrentConfig = Dispatch.call(loodsman, "GetCurrentConfig", param1,param2,
strError);

Может я в коде что не так пишу... так нет, если ошибки есть они сразу отображаюстя, а так вроде программа работает, но ничего не выдает. Вообщем, нужны советы и примеры, желательно на Java :shu:, но и другие советы тоже приветствуются.
Вот напишу, над чем работал только что: private static void createNewObject() {
String strTypeName = "Temp";
String strStateName = "Temp";
String strProductName = "Temp";
int intProject = 0;
int intRerurnCode = 0;
String strErrorMessage = "";
Variant newObject = Dispatch.call(loodsman, "NewObject", strTypeName,
strStateName, strProductName, intProject, intRerurnCode,
strErrorMessage);
System.out.println("Индификатор созданной версии: "
+ newObject.toString());
}
Согласно официальной документации должен создаться объект. Что за объект-непонятно, единственное могу ему сказать, что бы этот объект был проектом или не был им. Программа говорит, что объект создан, сам Лоцман его не отображает. Может я не там смотрю, здесь, короче тоже непонятно что делать. :%:
P.S. Тут вот в коде пару раз было написано "loodsman", так это у меня вот что:ActiveXComponent loodsman = new ActiveXComponent("LoodsmanServerApplication.MainSystem");

Prog2

 Для создания и "подцепления" нового объекта можно пользоваться связкой следующих методов сервера приложений:
--- ExistsObject    // Проверяем, может такой объект уже существует (дальше - либо создавать новый, либо цеплять существующий - по задаче).
--- NewObject   // Создаём объект (он не отобразится в дереве, хотя и будет создан).
--- CheckUniqueName   // Этим методом можно получить версию вновь созданного объекта (мне пригодилось, а так - по ситуации).
--- UpLink   // "Цепляем" созданный объект к какому нибудь родителю (т.е. настраиваем связь). После этого новый объект будет виден в дереве.

sumoist

Цитата: Prog2 от 25.08.09, 14:56:26
--- ExistsObject    // Проверяем, может такой объект уже существует
ну очевидно, что для вновь созданного его еще не будет

Цитата: Prog2 от 25.08.09, 14:56:26
NewObject   // Создаём объект (он не отобразится в дереве, хотя и будет создан).
тут тоже какая-то нестыковка идет, получается объект будет создан в воздухе, т.к. дерево отображает отображает элементы базы данных, а он...(ну новый объект) в базе как бы есть, но его там и нет, т.к. он не отображается. Или я чего не понимаю?

Цитата: Prog2 от 25.08.09, 14:56:26
--- CheckUniqueName   // Этим методом можно получить версию вновь созданного объекта (мне пригодилось, а так - по ситуации).
Ну у вновь созданного, мне кажется, будет всегда версия ноль, или я тут тоже чего напутал?

Цитата: Prog2 от 25.08.09, 14:56:26
--- UpLink   // "Цепляем" созданный объект к какому нибудь родителю
Тут вот тоже думаю проблемы у меня будут, т.к. никакой объект получить не могу, в данном случае даже родителя.

Ну это так, были мысли вслух, а так Prog2 спасибо за участие ;) Попробую сейчас сделать так, как вы посоветовали, о результатах отпишу!

teplinskiy

#8
вот пример JScript написанный буквально на коленке:

/* ======================================================================
JScript Source File -- Created with SAPIEN Technologies PrimalScript 3.1
========================================================================= */
var Loodsman;
var ErrCode, ErrStr;
var dbList;

Loodsman = new ActiveXObject("LoodsmanServerApplication.MainSystem");

//dbList = Loodsman.GetDBList(ErrCode,ErrStr) ;
//WScript.Echo(dbList);

Loodsman.ConnectToDB("Демо10",ErrCode,ErrStr);
Loodsman.NewObject("Папка","Проектирование","Тест из Жабы",1,ErrCode,ErrStr);
------------------------------------------------------------------

Этот скрипт после отработки создаст папку (как проект) в дереве проектов...

То есть ваша задача подцепиться к "LoodsmanServerApplication.MainSystem" и пользовать его методы...без страха и упрека...

teplinskiy

Цитата: Prog2 от 25.08.09, 14:56:26
Для создания и "подцепления" нового объекта можно пользоваться связкой следующих методов сервера приложений:
--- ExistsObject    // Проверяем, может такой объект уже существует (дальше - либо создавать новый, либо цеплять существующий - по задаче).
--- NewObject   // Создаём объект (он не отобразится в дереве, хотя и будет создан).
--- CheckUniqueName   // Этим методом можно получить версию вновь созданного объекта (мне пригодилось, а так - по ситуации).
--- UpLink   // "Цепляем" созданный объект к какому нибудь родителю (т.е. настраиваем связь). После этого новый объект будет виден в дереве.

для этой задачи достаточно использовать методы:
- InsertObject
- CheckUniqueName (в случае если объект версионный, иначе не стоит его и пользовать)

sumoist

Цитата: teplinskiy от 25.08.09, 15:53:52
вот пример JScript написанный буквально на коленке:
спасибо конечно за столь детальную помощь, но тут уже походу проблема либо во мне, либо в тех людях (думаю, что информация с этого форума им недоступна  :o:), которые мне дали задание по интеграции программы с помощью API c Лоцманом. Но одним из условий было то, что бы программа была на Java, а не JScript. А вот в самой Java, в отличии от JScript работа с com-объектами происходит не на прямую, а с помощью так называемых коннекторов, т.е. явно указать Loodsman.GetDBList()" или "Loodsman.NewObject я не могу, компилятор выдаст мне ошибку и пошлет подальше, вместо этого приходится писать сложные симантические конструкции типа Dispatch.call(loodsman, "NewObject", strTypeName, strStateName, strProductName, intProject, intRerurnCode,strErrorMessage);
Цитата: teplinskiy от 25.08.09, 15:53:52
То есть ваша задача подцепиться к "LoodsmanServerApplication.MainSystem" и пользовать его методы...без страха и упрека...
Я был бы очень рад, и пользовался бы с удовольствием. Да, и не боюсь я ничего!

teplinskiy

Цитата: sumoist от 25.08.09, 16:30:33
А вот в самой Java

конкретно укажите в чем (среда, оболочка, IDE) ведете разработку...???
Там присутствует возможность работы через DCOM компоненты...???

sumoist

Цитата: sumoist от 25.08.09, 15:41:31
Цитата: Prog2 от 25.08.09, 14:56:26
NewObject   // Создаём объект (он не отобразится в дереве, хотя и будет создан).
тут тоже какая-то нестыковка идет, получается объект будет создан в воздухе, т.к. дерево отображает отображает элементы базы данных, а он...(ну новый объект) в базе как бы есть, но его там и нет, т.к. он не отображается. Или я чего не понимаю?

Вот тут я извеняюсь за свою некомпетентность, просто с Лоцманом работаю 2 недели и то чисто с программной точки зрения. Вот узнал, что помимо самой БД существует так называемы checkOut, в котором и хранятся так называемые "горячие данные". Поэтому, данный вопрос можно считать решенным.  :um:

teplinskiy

Цитата: sumoist от 25.08.09, 16:30:33
А вот в самой Java

конкретно укажите в чем (среда, оболочка, IDE) ведете разработку...???
Там присутствует возможность работы через DCOM компоненты...???

sumoist

Цитата: teplinskiy от 25.08.09, 16:39:05
конкретно укажите в чем (среда, оболочка, IDE) ведете разработку...???
JDK 1.6.0,  Eclipse 3.5, для работы с COM-объектами использую Jacob.

Цитата: teplinskiy от 25.08.09, 16:39:05
Там присутствует возможность работы через DCOM компоненты...???
вот этого я вам точно не скажу, что-то в моем окружении никто про это не слышал...

teplinskiy

Цитата: sumoist от 25.08.09, 17:07:55
JDK 1.6.0,  Eclipse 3.5, для работы с COM-объектами использую Jacob.

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

sumoist


package main;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

public class Launcher {

private static ActiveXComponent loodsman;

public static void main(String[] args) {
getPropertyServerApplication();
getCurrentBase();
createNewObject();
createNewObjectVersionProg2();
}

private static void getPropertyServerApplication() {
loodsman = new ActiveXComponent("LoodsmanServerApplication.MainSystem");
System.out.println("Версия сервер приложения: "
+ loodsman.getPropertyAsString("ApplicationVersion"));
System.out.println("Работа с личными пакетами: "
+ loodsman.getPropertyAsBoolean("Impersonate"));
System.out.println("Это администратор: "
+ loodsman.getPropertyAsInt("IsAdmin"));
System.out.println("База данных: "
+ Dispatch.call(loodsman, "GetDBList", 1, "error").toString());
System.out.println();
}

private static void getCurrentBase() {
Variant currentBase = Dispatch.call(loodsman, "currentBase");
System.out.println("Текущая база данных: " + currentBase.toString());
System.out.println();
}

private static void connect2DB() {
Variant connectToDB = Dispatch.call(loodsman, "connectToDB",
"loodsman_base", 1, "error");
System.out.println("Подключение к базе данных:"
+ connectToDB.toString());
}

private static void getPropertyProjects() {
int intError = 0;
String strError = "";
Variant listProject = Dispatch.call(loodsman, "GetProjectListEx",
false, 0, "error");
System.out.println("Список проектов текущей БД:"
+ listProject.toString());
Variant list2 = Dispatch.call(loodsman, "GetCurrentConfig", 0, 0,
"error");
System.out.println(list2.toString());
Variant list3 = Dispatch.call(loodsman, "GetCurrentConfig", null, null,
null);
System.out.println(list3.toString());
}

private static void findObject() {
int stProject = 0;
int stLinkType = 0;
Variant inReturnCode = null;
Variant stErrorMessage = null;
// 1 способ
Variant fineObject = Dispatch
.callN(
loodsman,
"FindObjects",
new Object[] {
"Детали#1Комплекты#1Механообработка",
"Болт%",
"1.%",
"Аннулирован#1Доработка#1Серия",
"Наименование#2Наименование Like '%Деталь%'#1Масса#2!E#1Описание#2E",
stProject, stLinkType, inReturnCode,
stErrorMessage, });
System.out.println("Поиск объекта: " + fineObject.toString());
// 2 способ
Variant fineObject1 = Dispatch.callN(loodsman, "FindObjects",
new Object[] { "Детали#1Комплекты#1Механообработка", "Болт%",
"1.%", "Аннулирован#1Доработка#1Серия", null,
stProject, stLinkType, inReturnCode, stErrorMessage, });
System.out.println("Поиск объекта: " + fineObject1.toString());
}
private static void createNewObject() {
String strTypeName = "Temp";
String strStateName = "Temp";
String strProductName = "Temp";
int intProject = 0;
int intRerurnCode = 0;
String strErrorMessage = "";
Variant newObject = Dispatch.call(loodsman, "NewObject", strTypeName,
strStateName, strProductName, intProject, intRerurnCode,
strErrorMessage);
System.out.println("Индификатор созданной версии: "
+ newObject.toString());
}

private static void createNewObjectVersionProg2() {
String strTypeName = ""; // название типа
String strProductName = ""; // ключевой атрибут
String strVersionNumber = ""; // версия объекта
int intIdVersion = 0; // идентификатор версии
int intReturnCode = 0; // код возврата
String strErrorMessage = ""; // сообщение об ошибке
Variant existsObject = Dispatch.call(loodsman, "ExistsObject",
strTypeName, strProductName, strVersionNumber, intIdVersion,
intReturnCode, strErrorMessage);
System.out
.println("Существование объекта в текущей БД и текущем checkOut: "
+ existsObject);
}
}

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

sumoist

По поводу
Цитата: Prog2 от 25.08.09, 14:56:26
Для создания и "подцепления" нового объекта можно пользоваться связкой следующих методов сервера приложений:
--- ExistsObject    // Проверяем, может такой объект уже существует (дальше - либо создавать новый, либо цеплять существующий - по задаче).
--- NewObject   // Создаём объект (он не отобразится в дереве, хотя и будет создан).
--- CheckUniqueName   // Этим методом можно получить версию вновь созданного объекта (мне пригодилось, а так - по ситуации).
--- UpLink   // "Цепляем" созданный объект к какому нибудь родителю (т.е. настраиваем связь). После этого новый объект будет виден в дереве.
Написал следующее:
private static void createNewObjectVersionProg2() {
String strTypeName0 = "temp";
String strProductName0 = "temp";
String strVersionNumber0 = "temp";
int intIdVersion0 = 0;
int intReturnCode0 = 0;
String strErrorMessage0 = "";
Variant existsObject = Dispatch.call(loodsman, "ExistsObject",strTypeName0, strProductName0, strVersionNumber0,
intIdVersion0, intReturnCode0, strErrorMessage0);
                System.out.println("Существование объекта в текущей БД и текущем checkOut: "+ existsObject);

String strTypeName1 = "temp";
String strStateName1 = "temp";
String strProductName1 = "temp";
int intProject1 = 0;
int intReturnCode1 = 0;
String strErrorMessage1 = "";
Variant newObject = Dispatch.call(loodsman, "newObject", strTypeName1,
strStateName1, strProductName1, intProject1, intReturnCode1,
strErrorMessage1);
System.out.println("Индификатор созданной версии: " + newObject);

String strTypeName2 = "temp";
String strProductName2 = "temp";
int intReturnCode2 = 0;
String strErrorMessage2 = "";
Variant сheckUniqueName = Dispatch .call(loodsman, "CheckUniqueName", strTypeName2,
strProductName2, intReturnCode2, strErrorMessage2);
System.out.println("Все версии заданного объекта: " + сheckUniqueName);

String strParentType3 = "temp";
String strParentProduct3 = "temp";
String strParentVersion3 = "temp";
String strChildType3 = "temp";
String strChildProduct3 = "temp";
String strChildVersion3 = "temp";
int intIdLink3 = 0;
int intMinQuantity3 = 0;
int intMaxQuantity3 = 0;
String strIdUnit3 = "temp";
boolean boDel3 = false;
String strLinkType3 = "temp";
int intReturnCode3 = 0;
String strErrorMessage3 = ""; // сообщение об ошибке
Variant upLink = Dispatch.callN(loodsman, "UpLink", new Object[] {
strParentType3, strParentProduct3, strParentVersion3,
strChildType3, strChildProduct3, strChildVersion3, intIdLink3,
intMinQuantity3, intMaxQuantity3, strIdUnit3, boDel3,
strLinkType3, intReturnCode3, strErrorMessage3 });
System.out.println("Индификатор созданной версии: " + upLink);
}
}

Опять же, в дереве ничего нового не появилось. Тут, походу, у меня еще и проблема с параметрами, которые я передаю методу, я имею ввиду те места, где я пишу "Temp", т.е. там возможно какие-то зарезервированные слова надо использовать, а я просто тупой текст пишу.
Как бы сильно всех беспокоиться не прошу, тем более выполнять эту работу за меня, я понимаю, что у всех дела свои есть, и как бы не привык, что бы кто-то что-то за меня делал, советы-да, помощь-да, а вот за чужой счет выезжать-это как то не очень удобно  :). Просто писал на этом форуме, думал, что кто-то уже решал такие проблемы, я имею ввиду Java+Лоцман. И мне казалось, что здесь больше шансов встретить такого человека, нежели я бы написал на форум java-программистов и спросил бы там, а не работал ли кто из них с АPI Лоцмана. Вообщем, спасибо всем за помощь и участие. Вот по совету
Цитата: teplinskiy от 25.08.09, 16:44:48
Там присутствует возможность работы через DCOM компоненты...???
Цитата: SmaLL75 от 21.08.09, 11:49:17
думаю надо искать инфу на тему JAVA и DCOM
думаю, что надо будет в эту сторону смотреть. Походу, вещь нужная. Всем еще раз спасибо, но не прощаюсь, советы будут-пишите, и если  у самого, что получиться, тоже потом сообщу!

Prog2

2 sumoist
А вообще методы отрабатывают без ошибок? Что лежит на выходе в intReturnCode, strErrorMessage?
Если с этим порядок, хм...  в Вашем коде не заметил вызова метода "CheckOut", т.е. взятие объекта в работу перед его редактированием. Без чекаута, вроде срабатывать и не должно. Только читать данные можно будет.

И ещё. Вместо абстрактных строк:
   String strParentType = "temp";
   String strParentProduct = "temp";
   String strParentVersion = "temp";
попробуйте использовать для родительского объекта что-то типа
   String strParentType = "Сборочная единица";
   String strParentProduct = "1.212.021.00";
   String strParentVersion = "1";
и аналогично для дочернего. Т.е. значения реально присутствующие в Вашей базе. Так хоть понятнее будет, что и где потом искать.

PS: Прошу прощения, что объясняю "на пальцах". С Java не шибко знаком. Но, ИМХО, сдесь дело не в языке.

teplinskiy

#19
String strTypeName0 = "temp";
Здесь пишется тип заведенный в конфигурации ("Папка", "Деталь", "Профессия" и т.д.)
т.е.
String strTypeName0 = "Деталь";
---------------
String strProductName0 = "temp";
Здесь пишется значение ключевого атрибута для этого типа (как правило ключевым является атрибут "Обозначение" или "Наименование"), например у какого то объекта типа "Деталь" атрибут "Обозначение" = "Моя деталь"...вот это значение и передавайте
т.е.
String strProductName0 = "Моя деталь";
---------------
String strVersionNumber0 = "temp";
Здесь пишется номер версии, например "1" или "2" или "3.0.5"...смотря как настроена конфигурация для версионных объектов
String strVersionNumber0 = "1";
---------------
Теперь как правило если метод имеет связку параметров type, product, version и ID,
то как сказано в таких методах:
Если inIdVersion = 0 то объект ищется по stTypeName, stProductName, stVersionNumber, иначе объект ищется по inIdVersion...Поэтому пользуйте либо ID объекта, либо связку T, P, V
т.е.
Если пользуйте ID объекта, то задавайте его, например
String strTypeName0 = "";
String strProductName0 = "";
String strVersionNumber0 = "";
int intIdVersion0 = 123456;
иначе
String strTypeName0 = "Имя типа нужного объекта";
String strProductName0 = "Значен. ключ. атриб. нужного объекта";
String strVersionNumber0 = "Номер версии нужного объекта";
int intIdVersion0 = 0;
---------------
Переменные intReturnCode0 и String strErrorMessage0 достаточно объявить.
и проверять их значения после отработки какого либо метода, например:
System.out.println(strErrorMessage0);
и вам самому будет понятно как отработал метод...
---------------

Теперь создадим объект типа "Папка" в состоянии "Проектирование" со значением ключевого атрибута
"Папка из Жабы"...и пусть она будет проектом, чтобы ее сразу увидеть в БД среди веток дерева проетов:

Variant newObject = Dispatch.call(loodsman, "NewObject", "Папка",
                                  "Проектирование",
                                                                                      "Папка из Жабы",
                                                                                      1,
                                                                                      intReturnCode1,
                                                                                      strErrorMessage1);

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

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

пример демо-конфигурации прилагаю...