Возможно, вы захотите взглянуть на одну из технологий интеграции Java-COM. Я лично работал с JACOB (JAva COm Bridge):
Это было довольно громоздко (подумайте, работая исключительно с отражением), но сделало работу за меня (быстрое подтверждение концепции, доступ к MapPoint из Java).
Единственная другая технология, о которой я знаю, это Jawin, но у меня нет личного опыта:
Обновление от 26.04.2009:
Просто, черт побери, я провел больше исследований в Microsoft Windows Search и нашел простой способ интеграции с ним с помощью OLE DB. Вот код, который я написал в качестве доказательства концепции:
public static void main(String[] args) {
DispatchPtr connection = null;
DispatchPtr results = null;
try {
Ole32.CoInitialize();
connection = new DispatchPtr("ADODB.Connection");
connection.invoke("Open",
"Provider=Search.CollatorDSO;" +
"Extended Properties='Application=Windows';");
results = (DispatchPtr)connection.invoke("Execute",
"select System.Title, System.Comment, System.ItemName, System.ItemUrl, System.FileExtension, System.ItemDate, System.MimeType " +
"from SystemIndex " +
"where contains('Foo')");
int count = 0;
while(!((Boolean)results.get("EOF")).booleanValue()) {
++ count;
DispatchPtr fields = (DispatchPtr)results.get("Fields");
int numFields = ((Integer)fields.get("Count")).intValue();
for (int i = 0; i < numFields; ++ i) {
DispatchPtr item =
(DispatchPtr)fields.get("Item", new Integer(i));
System.out.println(
item.get("Name") + ": " + item.get("Value"));
}
System.out.println();
results.invoke("MoveNext");
}
System.out.println("\nCount:" + count);
} catch (COMException e) {
e.printStackTrace();
} finally {
try {
results.invoke("Close");
} catch (COMException e) {
e.printStackTrace();
}
try {
connection.invoke("Close");
} catch (COMException e) {
e.printStackTrace();
}
try {
Ole32.CoUninitialize();
} catch (COMException e) {
e.printStackTrace();
}
}
}
Для компиляции вам необходимо убедиться, что JAWIN JAR находится в вашем classpath, и что jawin.dll находится в вашем пути (или системном свойстве java.library.path). Этот код просто открывает подключение ADO к локальному индексу поиска Windows Desktop, запрашивает документы с ключевым словом «Foo» и распечатывает несколько ключевых свойств в итоговых документах.
Дайте мне знать, если у вас есть какие-либо вопросы, или мне нужно что-то уточнить.
Обновление от 27.04.2009:
Я попытался реализовать то же самое в JACOB, и буду делать некоторые тесты для сравнения различий в производительности между ними. Возможно, я что-то не так делаю в JACOB, но похоже, что он постоянно использует в 10 раз больше памяти. Я также буду работать над реализацией jcom и com4j, если у меня будет время, и попытаюсь выяснить некоторые причуды, которые, как мне кажется, связаны с отсутствием безопасности потоков. Я могу даже попробовать решение на основе JNI. Я ожидаю, что все будет сделано через 6-8 недель.
Обновление от 28.04.2009:
Это просто обновление для тех, кто следил и любопытно. Оказывается, нет проблем с многопоточностью, мне просто нужно было явно закрыть ресурсы базы данных, так как соединения OLE DB предположительно объединены в пул на уровне операционной системы (я, вероятно, в любом случае должен был закрыть соединения ...). Я не думаю, что буду дальнейшими обновлениями к этому. Дайте мне знать, если у кого-нибудь возникнут проблемы с этим.
Обновление 05.01.2009:
Добавлен пример JACOB по запросу Оскара. Это проходит через ту же самую последовательность вызовов с точки зрения COM, просто используя JACOB. Хотя это правда, что в последнее время над JACOB работали гораздо активнее, я также заметил, что это довольно сложная память (использует в 10 раз больше памяти, чем версия Jawin)
public static void main(String[] args) {
Dispatch connection = null;
Dispatch results = null;
try {
connection = new Dispatch("ADODB.Connection");
Dispatch.call(connection, "Open",
"Provider=Search.CollatorDSO;Extended Properties='Application=Windows';");
results = Dispatch.call(connection, "Execute",
"select System.Title, System.Comment, System.ItemName, System.ItemUrl, System.FileExtension, System.ItemDate, System.MimeType " +
"from SystemIndex " +
"where contains('Foo')").toDispatch();
int count = 0;
while(!Dispatch.get(results, "EOF").getBoolean()) {
++ count;
Dispatch fields = Dispatch.get(results, "Fields").toDispatch();
int numFields = Dispatch.get(fields, "Count").getInt();
for (int i = 0; i < numFields; ++ i) {
Dispatch item =
Dispatch.call(fields, "Item", new Integer(i)).
toDispatch();
System.out.println(
Dispatch.get(item, "Name") + ": " +
Dispatch.get(item, "Value"));
}
System.out.println();
Dispatch.call(results, "MoveNext");
}
} finally {
try {
Dispatch.call(results, "Close");
} catch (JacobException e) {
e.printStackTrace();
}
try {
Dispatch.call(connection, "Close");
} catch (JacobException e) {
e.printStackTrace();
}
}
}