package org.korsakow.domain.command; import java.io.File; import java.io.IOException; import java.sql.SQLException; import java.util.Collection; import java.util.HashSet; import java.util.List; import javax.xml.xpath.XPathExpressionException; import org.apache.log4j.Logger; import org.dsrg.soenea.domain.MapperException; import org.dsrg.soenea.domain.command.CommandException; import org.dsrg.soenea.uow.UoW; import org.korsakow.domain.interf.IImage; import org.korsakow.domain.interf.IMedia; import org.korsakow.domain.interf.IProject; import org.korsakow.domain.interf.ISettings; import org.korsakow.domain.interf.ISound; import org.korsakow.domain.interf.IText; import org.korsakow.domain.interf.IVideo; import org.korsakow.domain.mapper.input.MediaInputMapper; import org.korsakow.domain.mapper.input.ProjectInputMapper; import org.korsakow.domain.mapper.input.SettingsInputMapper; import org.korsakow.domain.task.ITask; import org.korsakow.domain.task.IWorker; import org.korsakow.ide.lang.LanguageBundle; import org.korsakow.ide.resources.ResourceType; import org.korsakow.ide.task.AbstractTask; import org.korsakow.ide.task.TaskException; import org.korsakow.ide.task.UIWorker; import org.korsakow.ide.util.Platform; import org.korsakow.ide.util.ResourceManager; import org.korsakow.services.export.ExportException; import org.korsakow.services.export.Exporter; import org.korsakow.services.export.IVideoEncodingProfile; import org.korsakow.services.export.PropertiesVideoEncodingProfile; public class ExportDraftFlashProjectCommand extends AbstractCommand{ public static final String PROJECT_ID = ExportFlashProjectCommand.PROJECT_ID; public static final String EXPORTER = ExportFlashProjectCommand.EXPORTER; public static final String WORKER = ExportFlashProjectCommand.WORKER; public static final String EXPORT_FILE = "export_file"; public ExportDraftFlashProjectCommand(Helper request, Helper response) { super(request, response); } public void execute() throws CommandException { try { long projectId = request.getLong(PROJECT_ID); IProject project = ProjectInputMapper.map(projectId); ISettings settings = SettingsInputMapper.find(); final String tmpdir; /* * On OSX 10.6, java.io.tmpdir returns a directory like /var/folders/l6/l6UDkdbcFoyLmvTRA4UYYU+++TI/-Tmp-/ * Which always has + in it. This breaks the flash player, even if we never specify the full url explicitly. * This is due to + being a special symbol in urls, the flash player always converts to space. * (I tested and confirmed this) */ if (Platform.isMacOS()) tmpdir = "/tmp"; else tmpdir = System.getProperty("java.io.tmpdir"); /** * This is a flawed strategy since there is technically no guarantee this folder isn't already taken by some * other process (though it is unlikely). * A better solution would be to create true tempdir (File.createTemp...) and remember in some preference * what it was, perhaps storing the uuid of the project in a hidden file as a means of verifying that the tempdir * hasn't been allocated to some other process since last use. */ File exportDir = new File(tmpdir, "Korsakow_Draft_" + project.getUUID()); System.out.println("\n\n\n"+exportDir); exportDir.deleteOnExit(); String indexFilename = "index.html"; Exporter exporter = new Exporter(); IWorker exportWorker = new UIWorker(); // we want to do the setup in a task since its lengthy // however we can't generate the other tasks from the exporter until that's done // so the setup tasks does that and then adds them to the worker exportWorker.addTask(new SetupExporterTask(exportWorker, exporter, exportDir, indexFilename, project, settings)); response.set(WORKER, exportWorker); response.set(EXPORTER, exporter); response.set(EXPORT_FILE, new File(exportDir, indexFilename)); } catch (Exception e) { throw new CommandException(e); } } private static class SetupExporterTask extends AbstractTask { private final IWorker uiWorker; private final String indexFilename; private final File exportDir; private final Exporter exporter; private final IProject project; private final ISettings settings; public SetupExporterTask(IWorker uiWorker, Exporter exporter, File exportDir, String indexFilename, IProject project, ISettings settings) { this.uiWorker = uiWorker; this.exporter = exporter; this.exportDir = exportDir; this.indexFilename = indexFilename; this.project = project; this.settings = settings; } @Override public void runTask() throws TaskException, InterruptedException { UoW.newCurrent(); Collection<IMedia> media; try { media = MediaInputMapper.findReferencedMedia(); } catch (XPathExpressionException e) { throw new TaskException(e); } catch (MapperException e) { throw new TaskException(e); } catch (SQLException e) { throw new TaskException(e); } Collection<ISound> sounds = new HashSet<ISound>(); Collection<IVideo> videos = new HashSet<IVideo>(); Collection<IImage> images = new HashSet<IImage>(); Collection<IText> texts = new HashSet<IText>(); int i = 0; int size = media.size(); long before = System.currentTimeMillis(); for (IMedia medium : media) { fireProgressChanged(0, ++i*100/size); fireDisplayStringChanged("", medium.getName()); ResourceType resourceType = ResourceType.forId(medium.getType()); switch (resourceType) { case SOUND: sounds.add((ISound)medium); break; case VIDEO: videos.add((IVideo)medium); break; case IMAGE: images.add((IImage)medium); break; case TEXT: texts.add((IText)medium); break; default: Logger.getLogger(ExportFlashProjectCommand.class).error("media list contains unknown media: " + medium.getClass().getCanonicalName(), new Exception("just-for-stacktrace")); break; } } long after = System.currentTimeMillis(); System.out.println("Determination: " + (after-before)/1000 + "\t" + media.size()); exporter.setExportFonts(false); exporter.setIndexFilename(indexFilename); exporter.setProject(project); exporter.setSettings(settings); exporter.setSnus(project.getSnus()); exporter.setSounds(sounds); exporter.setImages(images); exporter.setVideos(videos); exporter.setInterfaces(project.getInterfaces()); exporter.setTexts(texts); IVideoEncodingProfile videoEncodingProfile; try { videoEncodingProfile = new PropertiesVideoEncodingProfile(ResourceManager.getResourceStream("encodingprofiles/" + "flv_low" + ".properties")); } catch (IOException e) { throw new TaskException(e); } exporter.setVideoEncodingProfile(videoEncodingProfile); fireDisplayStringChanged("", LanguageBundle.getString("export.task.initializingtasks")); List<ITask> exportTasks; try { exportTasks = exporter.createExportTasks(exportDir); } catch (IOException e) { throw new TaskException(e); } catch (ExportException e) { throw new TaskException(e); } uiWorker.addTasks(exportTasks); } @Override public String getTitleString() { return LanguageBundle.getString("export.task.determiningmediatoexport"); } } }