В кроссплатформенных приложениях чего только не встретишь. Или напишешь. Вот, намедни родили против шерсти очередного ежика наступили на заботливо разложенных грабель, на сей раз под маком.
Напомню предыдущую серию саги: грабли под 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