X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.export.core%2Fsrc%2Forg%2Fsimantics%2Fexport%2Fcore%2Fmanager%2FExportGroupCreateAction.java;h=8891cefcae1f0877512525b17981374e86323870;hp=8f612f955e9a330b5b9cbb1a9467e22126e241a2;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.export.core/src/org/simantics/export/core/manager/ExportGroupCreateAction.java b/bundles/org.simantics.export.core/src/org/simantics/export/core/manager/ExportGroupCreateAction.java index 8f612f955..8891cefca 100644 --- a/bundles/org.simantics.export.core/src/org/simantics/export/core/manager/ExportGroupCreateAction.java +++ b/bundles/org.simantics.export.core/src/org/simantics/export/core/manager/ExportGroupCreateAction.java @@ -1,215 +1,215 @@ -package org.simantics.export.core.manager; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.SubMonitor; -import org.simantics.Simantics; -import org.simantics.databoard.binding.mutable.Variant; -import org.simantics.databoard.util.URIUtil; -import org.simantics.export.core.ExportContext; -import org.simantics.export.core.error.ExportException; -import org.simantics.export.core.intf.Exporter; -import org.simantics.export.core.intf.Format; -import org.simantics.export.core.util.ExporterUtils; -import org.simantics.utils.datastructures.MapList; -import org.simantics.utils.strings.AlphanumComparator; - -/** - * This action exports similar content types into one file of group format (e.g. Pdf, CSV). - * Group format is a file that can carry multiple items of one content type. - * - * @author toni.kalajainen@semantum.fi - */ -public class ExportGroupCreateAction extends ExportAction { - - // Contents and attachments - public Content dstContent; - public List contents = new ArrayList(); - // All attachments. Note, there are also attachments for the key: null - public MapList attachments = new MapList(); - public String formatId; - public File outputFile; - - public ExportGroupCreateAction(Content dstContent, String formatId) - { - this.dstContent = dstContent; - this.formatId = formatId; - } - - public void addContent(Content srcContent, List attachments) { - if ( srcContent != null ) contents.add(srcContent); - if (attachments!=null) this.attachments.addAll(srcContent, attachments); - } - - public void execute(ExportContext ctx, IProgressMonitor monitor, Variant options) throws ExportException - { - Format format = ctx.eep.getFormat( formatId ); - - // Sort content to exporter, and create the exporters - MapList, Content> map = new MapList, Content>(); - for ( Content content : contents ) { - Exporter[] exporters = ctx.eep.getExporters(content.formatId, content.contentTypeId); - if ( exporters.length == 0 ) { - throw new ExportException("No suitable exporter found for exporting "+content.contentTypeId+" to a "+format.label()); - } - map.add(Arrays.asList(exporters), content); - } - - try { - // Prefix must be at least 3 characters in length - String prefix = "___" + URIUtil.encodeFilename(dstContent.label); - dstContent.tmpFile = outputFile = File.createTempFile( prefix, URIUtil.encodeFilename(format.fileext()), Simantics.getTemporaryDirectory("export.core") ); - } catch (IOException e) { - throw new ExportException(e); - } - - // Calculate amount of total work from the amount of exporters and contents. - int totalWork = 0; - final int singleExportWork = 10000; - for (List exporters : map.getKeys()) { - List contents = map.getValuesUnsafe( exporters ); - totalWork += (contents.size() * exporters.size() + 1) * singleExportWork; - } - - SubMonitor mon = SubMonitor.convert(monitor, totalWork); - - Object writer = format.createFile(ctx, outputFile, options); - try { - // Sort exporters based on content type id to give a deterministic order - // for List -> List iteration. - List> sortedKeys = new ArrayList>( map.getKeys() ); - Collections.sort(sortedKeys, EXPORTER_LIST_COMPARATOR); - //System.out.println("sorted keys:\n" + EString.implode(sortedKeys)); - - // Write pages, exporter at a time. - for ( List exporters : sortedKeys ) { - //System.out.println("exporters:\n" + EString.implode(exporters)); - List contents = map.getValues( exporters ); - List sortedContent = ExporterUtils.sortedContent( contents ); - for (Content content : sortedContent) { - //System.out.println("content: " + content); - for ( Exporter exporter : exporters ) { - if (monitor.isCanceled()) - throw new OperationCanceledException(); - - //System.out.println("exporter: " + exporter); - mon.subTask( exporter.formatId() + ": " + content.label); - exporter.exportAction().export( - Collections.singletonList(content), - writer, - ctx, - options, - mon.newChild(singleExportWork), - attachments); - } - } - } - - // Write attachments - List remainingAttachments = attachments.getValues(null); - if ( remainingAttachments!=null && !remainingAttachments.isEmpty() ) { - format.addAttachment(ctx, writer, remainingAttachments); - } - - // Remember the output file (This is for the publisher) - dstContent.tmpFile = outputFile; - - } catch (ExportException ee) { - if ( outputFile.exists() ) outputFile.delete(); - throw ee; - } finally { - if (writer!=null) { - // TODO: pass progress monitor to closeFile since closeFile may do a lot of work in some cases - format.closeFile( ctx, writer ); - mon.worked(singleExportWork); - writer = null; - } - } - } - - /** - * Required for sorting the PDF output into a deterministic order. - */ - Comparator> EXPORTER_LIST_COMPARATOR = new Comparator>() { - String repr(List l) { - for (Exporter e : l) - return e.contentTypeId(); - throw new IllegalArgumentException("empty exporter list"); - } - @Override - public int compare(List o1, List o2) { - String k1 = repr(o1); - String k2 = repr(o2); - return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(k1, k2); - } - }; - - @Override - public String label(ExportContext ctx) { - String label; - Format format = ctx.eep.getFormat( formatId ); - if ( contents.size()==1 ) { - label = contents.iterator().next().label; - } else { - label = "Writing "+contents.size()+" items to a "+format.label()+" file"; - } - if ( outputFile == null ) return label; - return label + " export to "+outputFile.getName(); - } - - @Override - public int work(ExportContext ctx) { - return contents.size() + 1; - } - - @Override - public List validate(ExportContext ctx, Variant options) { - List result = new ArrayList(0); - - for (Content content : contents) { - - Exporter[] exporters = ctx.eep.getExporters(formatId, content.contentTypeId); - if ( exporters.length == 0 ) { - result.add("Could not find exporter for "+content.filename); - continue; - } - - for ( Exporter exporter : exporters) { - try { - result.addAll( exporter.exportAction().validate(content.url, ctx, options) ); - } catch (ExportException e) { - result.add( e.getClass().getName()+": "+e.getMessage() ); - } - } - } - - return result; - } - - @Override - public void cleanup(ExportContext ctx, IProgressMonitor progress, Variant options) throws ExportException { - if ( this.outputFile != null ) { - this.outputFile.delete(); - dstContent.tmpFile = null; - } - } - - public List getAttachments() { - List result = new ArrayList(); - for ( Content key : attachments.getKeys() ) { - for ( Content value : attachments.getValuesUnsafe(key) ) { - if ( !result.contains(value) ) result.add(value); - } - } - return result; - } - -} +package org.simantics.export.core.manager; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.SubMonitor; +import org.simantics.Simantics; +import org.simantics.databoard.binding.mutable.Variant; +import org.simantics.databoard.util.URIUtil; +import org.simantics.export.core.ExportContext; +import org.simantics.export.core.error.ExportException; +import org.simantics.export.core.intf.Exporter; +import org.simantics.export.core.intf.Format; +import org.simantics.export.core.util.ExporterUtils; +import org.simantics.utils.datastructures.MapList; +import org.simantics.utils.strings.AlphanumComparator; + +/** + * This action exports similar content types into one file of group format (e.g. Pdf, CSV). + * Group format is a file that can carry multiple items of one content type. + * + * @author toni.kalajainen@semantum.fi + */ +public class ExportGroupCreateAction extends ExportAction { + + // Contents and attachments + public Content dstContent; + public List contents = new ArrayList(); + // All attachments. Note, there are also attachments for the key: null + public MapList attachments = new MapList(); + public String formatId; + public File outputFile; + + public ExportGroupCreateAction(Content dstContent, String formatId) + { + this.dstContent = dstContent; + this.formatId = formatId; + } + + public void addContent(Content srcContent, List attachments) { + if ( srcContent != null ) contents.add(srcContent); + if (attachments!=null) this.attachments.addAll(srcContent, attachments); + } + + public void execute(ExportContext ctx, IProgressMonitor monitor, Variant options) throws ExportException + { + Format format = ctx.eep.getFormat( formatId ); + + // Sort content to exporter, and create the exporters + MapList, Content> map = new MapList, Content>(); + for ( Content content : contents ) { + Exporter[] exporters = ctx.eep.getExporters(content.formatId, content.contentTypeId); + if ( exporters.length == 0 ) { + throw new ExportException("No suitable exporter found for exporting "+content.contentTypeId+" to a "+format.label()); + } + map.add(Arrays.asList(exporters), content); + } + + try { + // Prefix must be at least 3 characters in length + String prefix = "___" + URIUtil.encodeFilename(dstContent.label); + dstContent.tmpFile = outputFile = File.createTempFile( prefix, URIUtil.encodeFilename(format.fileext()), Simantics.getTemporaryDirectory("export.core") ); + } catch (IOException e) { + throw new ExportException(e); + } + + // Calculate amount of total work from the amount of exporters and contents. + int totalWork = 0; + final int singleExportWork = 10000; + for (List exporters : map.getKeys()) { + List contents = map.getValuesUnsafe( exporters ); + totalWork += (contents.size() * exporters.size() + 1) * singleExportWork; + } + + SubMonitor mon = SubMonitor.convert(monitor, totalWork); + + Object writer = format.createFile(ctx, outputFile, options); + try { + // Sort exporters based on content type id to give a deterministic order + // for List -> List iteration. + List> sortedKeys = new ArrayList>( map.getKeys() ); + Collections.sort(sortedKeys, EXPORTER_LIST_COMPARATOR); + //System.out.println("sorted keys:\n" + EString.implode(sortedKeys)); + + // Write pages, exporter at a time. + for ( List exporters : sortedKeys ) { + //System.out.println("exporters:\n" + EString.implode(exporters)); + List contents = map.getValues( exporters ); + List sortedContent = ExporterUtils.sortedContent( contents ); + for (Content content : sortedContent) { + //System.out.println("content: " + content); + for ( Exporter exporter : exporters ) { + if (monitor.isCanceled()) + throw new OperationCanceledException(); + + //System.out.println("exporter: " + exporter); + mon.subTask( exporter.formatId() + ": " + content.label); + exporter.exportAction().export( + Collections.singletonList(content), + writer, + ctx, + options, + mon.newChild(singleExportWork), + attachments); + } + } + } + + // Write attachments + List remainingAttachments = attachments.getValues(null); + if ( remainingAttachments!=null && !remainingAttachments.isEmpty() ) { + format.addAttachment(ctx, writer, remainingAttachments); + } + + // Remember the output file (This is for the publisher) + dstContent.tmpFile = outputFile; + + } catch (ExportException ee) { + if ( outputFile.exists() ) outputFile.delete(); + throw ee; + } finally { + if (writer!=null) { + // TODO: pass progress monitor to closeFile since closeFile may do a lot of work in some cases + format.closeFile( ctx, writer ); + mon.worked(singleExportWork); + writer = null; + } + } + } + + /** + * Required for sorting the PDF output into a deterministic order. + */ + Comparator> EXPORTER_LIST_COMPARATOR = new Comparator>() { + String repr(List l) { + for (Exporter e : l) + return e.contentTypeId(); + throw new IllegalArgumentException("empty exporter list"); + } + @Override + public int compare(List o1, List o2) { + String k1 = repr(o1); + String k2 = repr(o2); + return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(k1, k2); + } + }; + + @Override + public String label(ExportContext ctx) { + String label; + Format format = ctx.eep.getFormat( formatId ); + if ( contents.size()==1 ) { + label = contents.iterator().next().label; + } else { + label = "Writing "+contents.size()+" items to a "+format.label()+" file"; + } + if ( outputFile == null ) return label; + return label + " export to "+outputFile.getName(); + } + + @Override + public int work(ExportContext ctx) { + return contents.size() + 1; + } + + @Override + public List validate(ExportContext ctx, Variant options) { + List result = new ArrayList(0); + + for (Content content : contents) { + + Exporter[] exporters = ctx.eep.getExporters(formatId, content.contentTypeId); + if ( exporters.length == 0 ) { + result.add("Could not find exporter for "+content.filename); + continue; + } + + for ( Exporter exporter : exporters) { + try { + result.addAll( exporter.exportAction().validate(content.url, ctx, options) ); + } catch (ExportException e) { + result.add( e.getClass().getName()+": "+e.getMessage() ); + } + } + } + + return result; + } + + @Override + public void cleanup(ExportContext ctx, IProgressMonitor progress, Variant options) throws ExportException { + if ( this.outputFile != null ) { + this.outputFile.delete(); + dstContent.tmpFile = null; + } + } + + public List getAttachments() { + List result = new ArrayList(); + for ( Content key : attachments.getKeys() ) { + for ( Content value : attachments.getValuesUnsafe(key) ) { + if ( !result.contains(value) ) result.add(value); + } + } + return result; + } + +}