/** * Merges chunks found in a target translation Project that do not exist in the source translation * to a sibling chunk so that no data is lost. * * @param library * @param targetTranslation target translation to merge * @return */ public static boolean migrateChunkChanges( final Library library, final TargetTranslation targetTranslation) { try { Logger.i( TargetTranslationMigrator.class.getName(), "Migrating chunks in target translation " + targetTranslation.getProjectId()); final SourceTranslation sourceTranslation = library.getDefaultSourceTranslation(targetTranslation.getProjectId(), "en"); if (sourceTranslation == null) { Logger.w( TargetTranslationMigrator.class.getName(), "Could not find a source translation for the target translation " + targetTranslation.getId()); return false; } if (targetTranslation.getPath().exists()) { boolean migrationSuccess = true; // perform the chunk migration on each chapter of the target translation for (ChapterTranslation chapterTranslation : targetTranslation.getChapterTranslations()) { Chapter chapter = library.getChapter(sourceTranslation, chapterTranslation.getId()); if (chapter != null) { boolean success = mergeInvalidChunksInChapter(library, sourceTranslation, targetTranslation, chapter); migrationSuccess = migrationSuccess && success; } } return migrationSuccess; } } catch (Exception e) { Logger.e( TargetTranslationMigrator.class.getName(), "Failed to merge the chunks in the target translation " + targetTranslation.getProjectId()); } return false; }
/** * Merges invalid chunks found in the target translation with a valid sibling chunk in order to * preserve translation data. Merged chunks are marked as not finished to force translators to * review the changes. * * @param library * @param sourceTranslation * @param targetTranslation * @param chapter * @return */ private static boolean mergeInvalidChunksInChapter( final Library library, final SourceTranslation sourceTranslation, final TargetTranslation targetTranslation, final Chapter chapter) { boolean success = true; Logger.i( TargetTranslationMigrator.class.getName(), "Searching chapter " + chapter.getId() + " for invalid chunks "); // TRICKY: the translation format doesn't matter for migrating FrameTranslation[] frameTranslations = targetTranslation.getFrameTranslations(chapter.getId(), TranslationFormat.DEFAULT); String invalidChunks = ""; Frame lastValidFrame = null; for (FrameTranslation frameTranslation : frameTranslations) { Frame frame = library.getFrame(sourceTranslation, chapter.getId(), frameTranslation.getId()); if (frame != null) { lastValidFrame = frame; // merge invalid frames into the existing frame if (!invalidChunks.isEmpty()) { targetTranslation.applyFrameTranslation( frameTranslation, invalidChunks + frameTranslation.body); invalidChunks = ""; targetTranslation.reopenFrame(frame); } } else if (!frameTranslation.body.trim().isEmpty()) { if (lastValidFrame == null) { // collect invalid frame invalidChunks += frameTranslation.body + CHUNK_MERGE_MARKER; } else { // if last frame is not null, then append invalid chunk to it FrameTranslation lastFrameTranslation = targetTranslation.getFrameTranslation(lastValidFrame); targetTranslation.applyFrameTranslation( lastFrameTranslation, lastFrameTranslation.body + CHUNK_MERGE_MARKER + frameTranslation.body); targetTranslation.reopenFrame(lastValidFrame); } targetTranslation.applyFrameTranslation(frameTranslation, ""); // clear out old data } } // clean up remaining invalid chunks if (!invalidChunks.isEmpty()) { if (lastValidFrame == null) { // push remaining invalid chunks onto the first available frame String[] frameslugs = library.getFrameSlugs(sourceTranslation, chapter.getId()); if (frameslugs.length > 0) { lastValidFrame = library.getFrame(sourceTranslation, chapter.getId(), frameslugs[0]); } else { Logger.w( TargetTranslationMigrator.class.getName(), "No frames were found for chapter " + chapter.getId()); } } if (lastValidFrame != null) { FrameTranslation frameTranslation = targetTranslation.getFrameTranslation(lastValidFrame); targetTranslation.applyFrameTranslation( frameTranslation, invalidChunks + CHUNK_MERGE_MARKER + frameTranslation.body); targetTranslation.reopenFrame(lastValidFrame); } } return success; }