О том как я имя файла из С++ в Java передавал

в 17:10, , рубрики: c++, indesign, java, macosx, Программирование, метки: , , ,

image
В кроссплатформенных приложениях чего только не встретишь. Или напишешь. Вот, намедни родили против шерсти очередного ежика наступили на заботливо разложенных грабель, на сей раз под маком.

Напомню предыдущую серию саги: грабли под Windows.

То есть у нас все тот же экзотический еж + питон = колючая проволока. На сей раз счастье привалило нам попался сюрприз на маке. Java в InDesign интегрировали, работает, теперь надо имя файла передать нашему коду на Java написанному.

Темный рыцарь: начало

Начиналось все так обыденно:

void FooExpFilter::ExportToStream(
	IPMStream* stream, IDocument* doc, IPMUnknown* targetboss, 
	const PMString& formatName, UIFlags uiFlags)
{
	IDFile outputFile;
	InterfacePtr<IFileStreamData> fileData(stream, IID_IFILESTREAMDATA);
	outputFile = fileData->GetSysFile();

	SDKFileHelper fh(outputFile);

	PMString pathID = fh.GetPath();
	WideString pathWID(pathID);
	std::string xID;
	StringUtils::ConvertWideStringToUTF8 (pathWID, xID);

и работало на маке и на Windows. Пока InDesign не дорос до версии CS5.5. И тут счастье наступило приехал в лог наш любимый и эпический java.io.FileNotFoundException.

Звездные войны: империя наносит ответный удар

В сторону: вот эти записи в лог «как бы чего не вышло» очень помогают, рекомендую. Если конечно логи с умом писать, а то (лично видел!) однажды от обилия логов получился performance degradation и «кодярник» (С) лог 40 секунд писал, а без лога полсекунды работает. Индусы постарались — написали свой log4j с блэкджеком но без буферизации.

Получаем лог от клиента, а там — Macintosh HD::Foo::Bar!

Приезжайте к нам в Простоквашино — если у вас нет бальных платьев

Быстрое гугление (как перевести карбоно-маковые пути в Unix) приводит к подробной инструкции, как переводить руками с учетом mount points. И applescript в качестве примера, что и в каком порядке у Finder спрашивать. Ага, ага — нам вот только ObjectiveC не хватало для полного счастья.

Хлебнув полведра кофе, и погрепав Adobe SDK, находим решение, достойное ithappens. Вот оно.

	IDFile outputFile;
	InterfacePtr<IFileStreamData> fileData(stream, IID_IFILESTREAMDATA);
	outputFile = fileData->GetSysFile();

	// URL for java
	PMString pathJ = FileUtils::SysFileToFileURL(outputFile);
	WideString pathWJ(pathJ);
	std::string xj;
	StringUtils::ConvertWideStringToUTF8 (pathWJ, xj);

и в Java появляются еще 3 строчки:

	if(externFile.startsWith("file://")) {
		File externFd = new File(new java.net.URI(externFile));
		externFile = externFd.getAbsolutePath();
	}

То есть, не найдя как передать путь, мы передали… URL!

И это даже работает.

Disclaimer: не откажусь от правильного примера — как перевести карбоновые пути в Unix без ObjectiveC. Хоть и неактуально, но интересно. Если оно вообще есть, а не «отрезать голову и поменять :: на /», неправильно я и сам умею.

Автор: viklequick

* - обязательные к заполнению поля