-package org.simantics.export.ui;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collections;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-import java.util.TreeMap;\r
-import java.util.TreeSet;\r
-import java.util.regex.Matcher;\r
-import java.util.regex.Pattern;\r
-\r
-import org.eclipse.jface.wizard.WizardPage;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.custom.ScrolledComposite;\r
-import org.eclipse.swt.layout.GridData;\r
-import org.eclipse.swt.layout.GridLayout;\r
-import org.eclipse.swt.widgets.Combo;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.swt.widgets.Control;\r
-import org.eclipse.swt.widgets.Event;\r
-import org.eclipse.swt.widgets.Listener;\r
-import org.osgi.service.prefs.BackingStoreException;\r
-import org.osgi.service.prefs.Preferences;\r
-import org.simantics.databoard.Accessors;\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.Datatypes;\r
-import org.simantics.databoard.accessor.RecordAccessor;\r
-import org.simantics.databoard.accessor.error.AccessorConstructionException;\r
-import org.simantics.databoard.accessor.error.AccessorException;\r
-import org.simantics.databoard.accessor.reference.ChildReference;\r
-import org.simantics.databoard.accessor.reference.LabelReference;\r
-import org.simantics.databoard.binding.RecordBinding;\r
-import org.simantics.databoard.binding.error.BindingException;\r
-import org.simantics.databoard.binding.error.DatatypeConstructionException;\r
-import org.simantics.databoard.binding.error.RuntimeBindingException;\r
-import org.simantics.databoard.binding.mutable.Variant;\r
-import org.simantics.databoard.forms.DataboardForm;\r
-import org.simantics.databoard.forms.DataboardForm.Problem;\r
-import org.simantics.databoard.type.RecordType;\r
-import org.simantics.databoard.type.UnionType;\r
-import org.simantics.export.core.ExportContext;\r
-import org.simantics.export.core.error.ExportException;\r
-import org.simantics.export.core.intf.ContentType;\r
-import org.simantics.export.core.intf.Exporter;\r
-import org.simantics.export.core.intf.Format;\r
-import org.simantics.export.core.intf.Publisher;\r
-import org.simantics.export.core.manager.Content;\r
-import org.simantics.export.core.manager.ExportAction;\r
-import org.simantics.export.core.manager.ExportManager;\r
-import org.simantics.export.core.manager.ExportPlan;\r
-import org.simantics.export.core.manager.ExportWizardResult;\r
-import org.simantics.export.core.util.ExporterUtils;\r
-import org.simantics.utils.datastructures.Arrays;\r
-import org.simantics.utils.datastructures.MapList;\r
-import org.simantics.utils.datastructures.ToStringComparator;\r
-import org.simantics.utils.datastructures.collections.CollectionUtils;\r
-import org.simantics.utils.ui.ExceptionUtils;\r
-import org.simantics.utils.ui.dialogs.ShowMessage;\r
-\r
-/**\r
- * Dynamic Options page. Exporter, Importer and Format contributes options to this page. \r
- * \r
- * @author toni.kalajainen@semantum.fi\r
- */\r
-public class OptionsPage extends WizardPage {\r
-\r
- public static String S_OUTPUT_OPTIONS = "Output Options";\r
- public static LabelReference P_OUTPUT_OPTIONS = new LabelReference( S_OUTPUT_OPTIONS );\r
- \r
- /** A reference to combo box selection */\r
- public static String S_PUBLISH = "Publish to";\r
- public static ChildReference P_PUBLISH = ChildReference.compile(P_OUTPUT_OPTIONS, new LabelReference(S_PUBLISH));\r
- \r
- ExportContext ctx; \r
- \r
- ScrolledComposite scroll;\r
- Composite composite;\r
- DataboardForm form;\r
-\r
- List<Content> selection;\r
- int selectionHash;\r
- String selectedPublisherId;\r
- \r
- public OptionsPage(ExportContext ctx) throws ExportException {\r
- super("Options page", "Select export options", null);\r
- \r
- this.ctx = ctx;\r
- }\r
-\r
- Listener modificationListener = new Listener() { \r
- public void handleEvent(Event event) {\r
- if ( updatingForm ) return;\r
- validate();\r
- }\r
- };\r
- \r
- boolean updatingForm;\r
- Listener outputSettingsModifiedListener = new Listener() { \r
- public void handleEvent(Event event) {\r
- updatingForm = true;\r
- try {\r
- Preferences contentScopePrefs = ctx.store.node( "Selection-"+selectionHash );\r
- Preferences workspaceScopePrefs = ctx.store;\r
- \r
- Composite outputOptions = (Composite) form.getControl(composite, P_OUTPUT_OPTIONS);\r
- Combo publishTo = (Combo) form.getControl(composite, P_PUBLISH); \r
- String newPublisherLabel = publishTo.getText();\r
- Publisher newPublisher = ctx.eep.getPublisherByLabel(newPublisherLabel);\r
- String newPublisherId = newPublisher==null?null:newPublisher.id();\r
- //if ( newPublisherId.equals(selectedPublisherId) ) return;\r
- \r
- // Save Preferences\r
- RecordBinding binding = ctx.databoard.getMutableBinding( form.type() );\r
- Object obj = binding.createDefault();\r
- form.readFields(composite, binding, obj);\r
- Variant options = new Variant(binding, obj);\r
- \r
- Publisher oldPublisher = ctx.eep.getPublisher( selectedPublisherId );\r
- if ( oldPublisher!=null ) {\r
- ChildReference oldOptionsRef = new LabelReference( oldPublisher.label() );\r
- try {\r
- Variant locationOptions = options.getComponent( oldOptionsRef );\r
- oldPublisher.publisherClass().savePref(locationOptions, contentScopePrefs, workspaceScopePrefs);\r
- } catch ( AccessorConstructionException ee ) {}\r
- }\r
-\r
- List<Content> manifest = getManifestFor(selection, options);\r
- cleanPublisherFromGroup(selectedPublisherId);\r
- addPublisherToGroup(newPublisherId, manifest);\r
- \r
- outputOptions.pack(true);\r
- outputOptions.layout(true);\r
- composite.pack(true);\r
- composite.layout(true);\r
- \r
- RecordType dummy = new RecordType();\r
- RecordType newPublisherOptions = newPublisher.publisherClass().locationOptions(ctx, manifest);\r
- dummy.addComponent( newPublisherLabel, newPublisherOptions );\r
- binding = ctx.databoard.getMutableBinding( dummy );\r
- obj = binding.createDefault();\r
- options = new Variant(binding, obj);\r
- ChildReference locationOptionsRef = new LabelReference( newPublisherLabel );\r
- Variant locationOptions = options.getComponent( locationOptionsRef );\r
- newPublisher.publisherClass().fillDefaultPrefs(ctx, selection, options, locationOptions);\r
- newPublisher.publisherClass().loadPref(locationOptions, contentScopePrefs, workspaceScopePrefs); \r
- //loadPublisherPref(newPublisherId, options, contentScopePrefs, workspaceScopePrefs);\r
- form.writeFields(outputOptions, (RecordBinding) options.getBinding(), options.getValue());\r
- \r
- selectedPublisherId = newPublisherId;\r
-\r
- updatingForm = false;\r
- validate();\r
- } catch ( BindingException e ) {\r
- setErrorMessage( e.getClass().getName()+": "+ e.getMessage() );\r
- ExceptionUtils.logError(e); \r
- } catch (AccessorConstructionException e) {\r
- setErrorMessage( e.getClass().getName()+": "+ e.getMessage() );\r
- ExceptionUtils.logError(e); \r
- } catch (AccessorException e) {\r
- setErrorMessage( e.getClass().getName()+": "+ e.getMessage() );\r
- ExceptionUtils.logError(e); \r
- } catch (ExportException e) {\r
- setErrorMessage( e.getClass().getName()+": "+ e.getMessage() );\r
- ExceptionUtils.logError(e); \r
- } finally {\r
- updatingForm = false;\r
- }\r
- }\r
- };\r
- \r
- @Override\r
- public void createControl(Composite parent) {\r
- \r
- scroll = new ScrolledComposite(parent, SWT.V_SCROLL);\r
- composite = new Composite(scroll, 0);\r
- composite.setLayout( new GridLayout(3, false) ); \r
- composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1)); \r
- scroll.setContent(composite);\r
- scroll.setExpandHorizontal(true);\r
- scroll.setExpandVertical(false);\r
- scroll.getVerticalBar().setIncrement(scroll.getVerticalBar().getIncrement()*8);\r
-\r
- form = new DataboardForm();\r
- form.setFirstColumnWidth(200);\r
-\r
- composite.pack();\r
- setControl(scroll);\r
- setPageComplete(true);\r
- \r
- }\r
- \r
- public void update(List<Content> contents) \r
- {\r
- try {\r
- // 0. Initialization\r
- Set<String> contentUris = new TreeSet<String>();\r
- MapList<String, Content> uriToContentMap = new MapList<String, Content>();\r
- MapList<ContentType, String> contentByContentType = new MapList<ContentType, String>();\r
- MapList<Format, String> contentByFormat = new MapList<Format, String>();\r
- List<Format> formats = new ArrayList<Format>();\r
- Map<String, Format> contentFormatMap = new TreeMap<String, Format>( String.CASE_INSENSITIVE_ORDER );\r
- for (Content content : contents) {\r
- contentUris.add(content.url);\r
- ContentType ct = ctx.eep.getContentType( content.contentTypeId );\r
- contentByContentType.add(ct, content.url);\r
- Format format = ctx.eep.getFormat( content.formatId );\r
- contentByFormat.add(format, content.url);\r
- uriToContentMap.add(content.url, content);\r
- }\r
- formats.addAll( contentByFormat.getKeys() );\r
- \r
- Collections.sort(formats, new ToStringComparator());\r
- \r
- for (Content content : contents) {\r
- String id = content.formatId;\r
- Format format = contentFormatMap.get( id );\r
- if ( format != null ) continue;\r
- format = ctx.eep.getFormat(id);\r
- contentFormatMap.put(id, format);\r
- }\r
-\r
- MapList<Exporter, String> exporterContentMap = new MapList<Exporter, String>();\r
- TreeMap<String, Exporter> orderedExporters = new TreeMap<String, Exporter>( String.CASE_INSENSITIVE_ORDER );\r
- for (Content content : contents) {\r
- for (Exporter exporter : ctx.eep.getExporters(content.formatId, content.contentTypeId) ) {\r
- exporterContentMap.add(exporter, content.url);\r
- orderedExporters.put(exporter.formatId()+exporter.contentTypeId()+exporter.exportAction().getClass(), exporter);\r
- }\r
- }\r
- \r
- // 1. Save selections from previous form\r
- savePrefs();\r
- \r
- // 2. Clear previous form\r
- form.clear(composite);\r
-\r
- // 3. Create options record\r
- RecordType optionsRecord = new RecordType();\r
-\r
- // Add Output options box\r
- RecordType outputOptions = new RecordType();\r
- \r
- for ( Format format : formats ) {\r
- if ( format.isGroupFormat() && contentByFormat.getValues(format).size()>1 ) {\r
- outputOptions.addComponent("Merge "+format.fileext()+" content into one file", Datatypes.BOOLEAN);\r
- }\r
- \r
- if ( format.isContainerFormat() ) {\r
- List<String> formatsContentUris = contentByFormat.getValues(format);\r
- int attachmentCount = 0;\r
- for ( String contentUri : formatsContentUris ) {\r
- for ( Content content : uriToContentMap.getValues(contentUri) ) {\r
- if ( !content.formatId.equals(format.id()) ) attachmentCount++;\r
- }\r
- }\r
- // Add as possible attachment, all contents that don't have this format\r
- // their their content type.\r
- for ( Content content : contents ) {\r
- if ( ctx.eep.getExporters(format.id(), content.contentTypeId).length == 0) attachmentCount++;\r
- }\r
- \r
- if ( attachmentCount > 0 ) { \r
- outputOptions.addComponent("Include attachments to "+format.fileext(), Datatypes.BOOLEAN);\r
- outputOptions.addComponent("Export attachments of "+format.fileext()+" to separate files", Datatypes.BOOLEAN);\r
- }\r
- }\r
- }\r
- \r
- UnionType publisherType = new UnionType();\r
- for (Publisher publisher : ctx.eep.publishers()) publisherType.addComponent(publisher.label(), Datatypes.VOID);\r
- outputOptions.addComponent(S_PUBLISH, publisherType);\r
- \r
- optionsRecord.addComponent(S_OUTPUT_OPTIONS, outputOptions); \r
- \r
- // Add Format specific boxes\r
- for (Format format : contentFormatMap.values()) {\r
- RecordType formatOptions = format.formatActions().options(ctx);\r
- if ( formatOptions==null ) continue;\r
- optionsRecord.mergeRecord( formatOptions );\r
- }\r
- \r
- // Add Exporter specific boxes\r
- for (Exporter exporter : orderedExporters.values()) { \r
- List<String> exportSpecificContents = exporterContentMap.getValues(exporter);\r
- if ( exportSpecificContents==null || exportSpecificContents.isEmpty() ) continue;\r
- RecordType exporterOptions = exporter.exportAction().options(ctx, exportSpecificContents);\r
- if ( exporterOptions == null ) continue;\r
- optionsRecord.mergeRecord( exporterOptions );\r
- }\r
-\r
- // 4. Load default and previous selections of the options ( All but publisher )\r
- ctx.databoard.clear();\r
- RecordBinding optionsBinding = ctx.databoard.getMutableBinding( optionsRecord );\r
- Object optionsObj = optionsBinding.createDefaultUnchecked();\r
- Variant options = new Variant(optionsBinding, optionsObj);\r
- {\r
- Preferences workspaceScopePrefs = ctx.store;\r
- Preferences contentScopePrefs = ctx.store( contents );\r
- \r
- for (Exporter exporter : orderedExporters.values()) {\r
- exporter.exportAction().fillDefaultPrefs(ctx, options);\r
- exporter.exportAction().loadPref(options, contentScopePrefs, workspaceScopePrefs);\r
- }\r
- \r
- for (Format format : contentByFormat.getKeys()) {\r
- format.formatActions().fillDefaultPrefs( ctx, options );\r
- format.formatActions().loadPref(options, contentScopePrefs, workspaceScopePrefs);\r
- }\r
- \r
- fillDefaultPrefs(options);\r
- loadPref(options, contentScopePrefs, workspaceScopePrefs);\r
- }\r
- \r
- // 5. Create form\r
- form.addFields(composite, optionsRecord);\r
- form.addListener(composite, form.type(), modificationListener);\r
- Composite outputOptionsGroup = (Composite) form.getControl(composite, P_OUTPUT_OPTIONS);\r
- RecordType dummy = new RecordType();\r
- dummy.addComponent(S_OUTPUT_OPTIONS, outputOptions);\r
- form.addListener(outputOptionsGroup, dummy, outputSettingsModifiedListener);\r
- form.writeFields(composite, optionsBinding, optionsObj);\r
- \r
- // 6. Add publisher\r
- {\r
- selection = contents;\r
- Preferences workspaceScopePrefs = ctx.store;\r
- Preferences contentScopePrefs = ctx.store.node( "Selection-"+selectionHash );\r
- selectedPublisherId = ctx.store.get("publisherId", ""); \r
- Publisher publisher = ctx.eep.getPublisher(selectedPublisherId);\r
- if ( publisher != null ) {\r
- \r
- // 6A. Manifest\r
- List<Content> manifest = getManifestFor(contents, options);\r
- \r
- // 6B. Default and previous settings\r
- String label = publisher.label();\r
- RecordType publisherOptionsType = publisher.publisherClass().locationOptions(ctx, manifest);\r
- RecordType publisherOptionsRootType = new RecordType();\r
- publisherOptionsRootType.addComponent(label, publisherOptionsType);\r
- RecordBinding publisherOptionsRootBinding = ctx.databoard.getMutableBinding( publisherOptionsRootType );\r
- Object publisherOptionsRootObj = publisherOptionsRootBinding.createDefaultUnchecked();\r
- Variant publisherOptionsRoot = new Variant(publisherOptionsRootBinding, publisherOptionsRootObj);\r
- try {\r
- ChildReference locationOptionsRef = new LabelReference( label );\r
- Variant locationOptions = publisherOptionsRoot.getComponent( locationOptionsRef );\r
- publisher.publisherClass().fillDefaultPrefs(ctx, selection, options, locationOptions);\r
- publisher.publisherClass().loadPref(locationOptions, contentScopePrefs, workspaceScopePrefs); \r
- } catch ( AccessorConstructionException ee ) {\r
- }\r
- \r
- // 6C. Add Publisher form\r
- addPublisherToGroup(selectedPublisherId, manifest);\r
- form.writeFields(composite, publisherOptionsRootBinding, publisherOptionsRootObj);\r
- }\r
- }\r
-\r
- // 8. Validate page\r
- composite.pack();\r
- validate();\r
- \r
- } catch (BindingException e) {\r
- ExceptionUtils.logError(e); \r
- ShowMessage.showError("Unexpected error", e.getClass().getName()+" "+e.getMessage());\r
- throw new RuntimeBindingException(e);\r
- } catch (ExportException e) {\r
- ExceptionUtils.logError(e); \r
- ShowMessage.showError("Unexpected error", e.getClass().getName()+" "+e.getMessage());\r
- } catch (DatatypeConstructionException e) {\r
- ExceptionUtils.logError(e); \r
- ShowMessage.showError("Unexpected error", e.getClass().getName()+" "+e.getMessage());\r
- } catch (AccessorConstructionException e) {\r
- ExceptionUtils.logError(e); \r
- ShowMessage.showError("Unexpected error", e.getClass().getName()+" "+e.getMessage());\r
- } catch (AccessorException e) {\r
- ExceptionUtils.logError(e); \r
- // TODO Auto-generated catch block\r
- e.printStackTrace();\r
- }\r
- \r
- }\r
-\r
- /**\r
- * Saves publisher prefs from the UI to preference nodes.\r
- * \r
- * @throws ExportException\r
- */\r
- void savePublisherPref(String publisherId, Variant options, Preferences contentScopePrefs, Preferences workspaceScopePrefs) throws ExportException {\r
- try {\r
-// Preferences contentScopePrefs = ctx.store.node( "Selection-"+selectionHash );\r
-// Preferences workspaceScopePrefs = ctx.store;\r
-\r
-// RecordBinding binding = ctx.databoard.getMutableBinding( form.type() );\r
-// Object obj = binding.createDefault();\r
-// form.readFields(composite, binding, obj);\r
-// Variant options = new Variant(binding, obj);\r
- \r
- Publisher publisher = ctx.eep.getPublisher( publisherId );\r
- if ( publisher==null ) return;\r
- Variant locationOptions = options.getComponent( new LabelReference(publisher.label()) );\r
- publisher.publisherClass().savePref(locationOptions, contentScopePrefs, workspaceScopePrefs);\r
-// } catch (BindingException e) {\r
-// throw new ExportException( e );\r
- } catch (AccessorConstructionException e) {\r
- ExceptionUtils.logError(e); \r
- //throw new ExportException( e );\r
-// } catch (AccessorException e) {\r
-// throw new ExportException( e );\r
- }\r
- }\r
- \r
- void loadPublisherPref(String publisherId, Variant options, Preferences contentScopePrefs, Preferences workspaceScopePrefs) throws ExportException {\r
- try {\r
-// Preferences contentScopePrefs = ctx.store.node( "Selection-"+selectionHash );\r
-// Preferences workspaceScopePrefs = ctx.store;\r
- \r
- Publisher publisher = ctx.eep.getPublisher( publisherId );\r
- if ( publisher == null ) return;\r
- \r
- // There is a problem here if selection was built with manifest\r
-// RecordType optionsType = publisher.publiserClass().locationOptions(ctx, selection); \r
-// RecordBinding binding = ctx.databoard.getMutableBinding( optionsType );\r
-// Object obj = binding.createDefault();\r
-// Variant locationOptions = new Variant(binding, obj);\r
- Variant locationOptions = options.getComponent( new LabelReference( publisher.label() ) );\r
- publisher.publisherClass().fillDefaultPrefs(ctx, selection, options, locationOptions);\r
- publisher.publisherClass().loadPref(locationOptions, contentScopePrefs, workspaceScopePrefs); \r
-// } catch (BindingException e) {\r
-// throw new ExportException( e );\r
- } catch (AccessorConstructionException e) {\r
- ExceptionUtils.logError(e); \r
- //throw new ExportException( e );\r
-// } catch (AccessorException e) {\r
-// throw new ExportException( e );\r
- }\r
- }\r
-\r
- /**\r
- * Remove any publisher specific controls from output options.\r
- */\r
- void cleanPublisherFromGroup(String oldPublisherId) {\r
- Publisher publisher = ctx.eep.getPublisher(oldPublisherId);\r
- if ( publisher != null ) {\r
- String fieldName = publisher.label();\r
- if ( form.type().hasComponent(fieldName)) {\r
- form.type().removeComponent(fieldName);\r
- ctx.databoard.clear();\r
- }\r
- }\r
- Combo publishTo = (Combo) form.getControl(composite, P_PUBLISH);\r
- Composite group = (Composite) publishTo.getParent();\r
- Control children[] = group.getChildren();\r
- int index = Arrays.indexOf( children, publishTo );\r
- for (int i=children.length-1; i>index; i--) {\r
- children[i].dispose();\r
- }\r
- }\r
- \r
- /**\r
- * Add controls of a publisher id \r
- * \r
- * @param publisherId\r
- * @throws ExportException \r
- */\r
- void addPublisherToGroup( String publisherId, List<Content> contents ) throws ExportException {\r
- try {\r
- Composite group = (Composite) form.getControl(composite, P_OUTPUT_OPTIONS);\r
- if ( group == null ) return;\r
- Publisher publisher = ctx.eep.getPublisher( publisherId );\r
- if ( publisher == null ) return;\r
- RecordType publisherOptions = publisher.publisherClass().locationOptions(ctx, contents); \r
- //form.type().addComponent(publisher.label(), publisherOptions);\r
- RecordType options = new RecordType();\r
- options.addComponent(publisher.label(), publisherOptions);\r
- form.addFields(group, publisherOptions, publisher.label());\r
- form.addListener(group, options, modificationListener);\r
- ctx.databoard.clear();\r
- } catch (BindingException e) {\r
- throw new ExportException(e);\r
- } catch (AccessorConstructionException e) {\r
- throw new ExportException(e);\r
- } catch (AccessorException e) {\r
- throw new ExportException(e);\r
- }\r
- }\r
- \r
- List<Content> getManifestFor(List<Content> selection, Variant options) { \r
- try {\r
- ExportWizardResult result = new ExportWizardResult();\r
- result.options = options;\r
- result.accessor = Accessors.getAccessor(result.options);\r
- result.contents = selection;\r
- result.type = (RecordType) options.type();\r
- result.publisherId = "file";\r
- \r
- List<ExportAction> actions = new ArrayList<ExportAction>();\r
- List<Content> manifest = new ArrayList<Content>(); \r
- result.createExportActions(ctx, actions, manifest);\r
- return manifest;\r
- } catch (AccessorConstructionException e) {\r
- return selection;\r
- } catch (ExportException e) {\r
- e.printStackTrace();\r
- return selection;\r
- }\r
- } \r
- \r
- public ExportWizardResult getOutput()\r
- throws ExportException\r
- {\r
- ExportWizardResult result = new ExportWizardResult();\r
- try {\r
- ctx.databoard.clear();\r
- result.type = form.type();\r
- RecordBinding binding = (RecordBinding) ctx.databoard.getMutableBinding( result.type );\r
- Object optionsObj = binding.createDefault();\r
- result.options = new Variant(binding, optionsObj);\r
- form.readFields(composite, binding, optionsObj);\r
- result.accessor = Accessors.getAccessor(result.options);\r
- result.contents = selection;\r
- \r
- \r
- String publisherLabel = ExporterUtils.getUnionValue(result.accessor, P_PUBLISH);\r
- Publisher publisher = ctx.eep.getPublisherByLabel(publisherLabel);\r
- result.publisherId = publisher==null?"":publisher.id(); \r
- \r
- } catch (BindingException e) {\r
- throw new ExportException(e); \r
- } catch (AccessorException e) {\r
- throw new ExportException(e);\r
- } catch (AccessorConstructionException e) {\r
- throw new ExportException(e);\r
- }\r
- \r
- return result;\r
- }\r
- \r
- void validate() { \r
- List<Problem> problems = form.validate(composite);\r
- List<String> errs = DataboardForm.toStrings(problems);\r
- \r
- if ( errs.isEmpty() ) {\r
- try {\r
- ExportWizardResult result = getOutput();\r
- ExportPlan plan = new ExportPlan();\r
- result.createPlan(ctx, plan);\r
- ExportManager mgr = new ExportManager(result.options, ctx);\r
- errs.addAll( mgr.validate(ctx, plan) ) ;\r
- } catch (ExportException e) {\r
- errs.add(e.getMessage());\r
- }\r
- } else {\r
- CollectionUtils.unique( errs ); \r
- }\r
- \r
-\r
- setErrorMessage( errs.isEmpty() ? null : CollectionUtils.toString(errs, ", ") );\r
- setPageComplete( errs.isEmpty() );\r
- }\r
- \r
- /**\r
- * Save wizard preferences\r
- * \r
- * @param options\r
- * @param contentScopePrefs\r
- * @param workspaceScopePrefs\r
- * @throws ExportException\r
- */\r
- void savePref(Variant options, Preferences contentScopePrefs, Preferences workspaceScopePrefs) throws ExportException\r
- {\r
- try {\r
- RecordAccessor ra = Accessors.getAccessor(options);\r
- String publisherId = ExporterUtils.getUnionValue(ra, P_PUBLISH); \r
- Publisher publisher = ctx.eep.getPublisherByLabel(publisherId);\r
- if ( publisher!=null ) workspaceScopePrefs.put("publisherId", publisher.id());\r
- \r
- if ( ra.type().hasComponent(P_OUTPUT_OPTIONS.label) ) {\r
- RecordAccessor rao = ra.getComponent( P_OUTPUT_OPTIONS );\r
- \r
- Pattern merge_pattern = Pattern.compile("Merge ([^\\s]*) content into one file");\r
- Pattern include_pattern = Pattern.compile("Include attachments to ([^\\s]*)");\r
- Pattern export_pattern = Pattern.compile("Export attachments of ([^\\s]*) to separate files");\r
- \r
- for (int i=0; i<rao.count(); i++) {\r
- String name = rao.type().getComponent(i).name;\r
- Matcher m;\r
- \r
- m = merge_pattern.matcher(name);\r
- if ( m.matches() ) {\r
- String fileExt = m.group(1);\r
- Format format = ctx.eep.getFormatByExt(fileExt);\r
- Boolean value = (Boolean) rao.getFieldValue(i, Bindings.BOOLEAN);\r
- String key = format.id()+"_merge";\r
- contentScopePrefs.putBoolean(key, value);\r
- workspaceScopePrefs.putBoolean(key, value);\r
- }\r
- \r
- m = include_pattern.matcher(name);\r
- if ( m.matches() ) {\r
- String fileExt = m.group(1);\r
- Format format = ctx.eep.getFormatByExt(fileExt);\r
- Boolean value = (Boolean) rao.getFieldValue(i, Bindings.BOOLEAN);\r
- String key = format.id()+"_include_attachments";\r
- contentScopePrefs.putBoolean(key, value);\r
- workspaceScopePrefs.putBoolean(key, value);\r
- }\r
- \r
- m = export_pattern.matcher(name);\r
- if ( m.matches() ) {\r
- String fileExt = m.group(1);\r
- Format format = ctx.eep.getFormatByExt(fileExt);\r
- Boolean value = (Boolean) rao.getFieldValue(i, Bindings.BOOLEAN);\r
- String key = format.id()+"_export_attachments";\r
- contentScopePrefs.putBoolean(key, value);\r
- workspaceScopePrefs.putBoolean(key, value);\r
- }\r
- }\r
- }\r
- \r
- } catch (AccessorConstructionException e) {\r
- throw new ExportException(e);\r
- } catch (AccessorException e) {\r
- throw new ExportException(e);\r
- }\r
- \r
- }\r
-\r
- /**\r
- * Load wizard preferences\r
- * \r
- * @param binding\r
- * @param options\r
- * @param contentScopePrefs\r
- * @param workspaceScopePrefs\r
- * @throws ExportException\r
- */\r
- void loadPref(Variant options, Preferences contentScopePrefs, Preferences workspaceScopePrefs) throws ExportException\r
- {\r
- //Preferences workspaceScopePrefs = ctx.store;\r
- try {\r
- RecordAccessor ra = Accessors.getAccessor(options); \r
- String publisherId = workspaceScopePrefs.get("publisherId", "");\r
- Publisher publisher = ctx.eep.getPublisher(publisherId);\r
- if ( publisher != null ) ExporterUtils.setUnionValue(ra, P_PUBLISH, publisher.label());\r
- \r
- if ( ra.type().hasComponent(P_OUTPUT_OPTIONS.label) ) {\r
- RecordAccessor rao = ra.getComponent( P_OUTPUT_OPTIONS );\r
- \r
- for (Format format : ctx.eep.formats()) {\r
- if ( format.isGroupFormat() ) {\r
- String key = format.id()+"_merge";\r
- Boolean value = null;\r
- if ( containsKey(contentScopePrefs, key) ) {\r
- value = contentScopePrefs.getBoolean(key, false); \r
- } else if ( containsKey(workspaceScopePrefs, key) ) {\r
- value = workspaceScopePrefs.getBoolean(key, false);\r
- }\r
- \r
- if ( value != null ) {\r
- String key2 = "Merge "+format.fileext()+" content into one file";\r
- int index = rao.type().getComponentIndex2(key2);\r
- if ( index>=0 ) {\r
- rao.setFieldValue(index, Bindings.BOOLEAN, value);\r
- }\r
- } \r
- }\r
- \r
- if ( format.isContainerFormat() ) {\r
- String key = format.id()+"_include_attachments";\r
- Boolean value = null;\r
- if ( containsKey(contentScopePrefs, key) ) {\r
- value = contentScopePrefs.getBoolean(key, false); \r
- } else if ( containsKey(workspaceScopePrefs, key) ) {\r
- value = workspaceScopePrefs.getBoolean(key, false);\r
- }\r
- \r
- if ( value != null ) {\r
- String key2 = "Include attachments to "+format.fileext();\r
- int index = rao.type().getComponentIndex2(key2);\r
- if ( index>=0 ) {\r
- rao.setFieldValue(index, Bindings.BOOLEAN, value);\r
- }\r
- } \r
- }\r
- \r
- if ( format.isContainerFormat() ) {\r
- String key = format.id()+"_export_attachments";\r
- Boolean value = null;\r
- if ( containsKey(contentScopePrefs, key) ) {\r
- value = contentScopePrefs.getBoolean(key, false); \r
- } else if ( containsKey(workspaceScopePrefs, key) ) {\r
- value = workspaceScopePrefs.getBoolean(key, false);\r
- }\r
- \r
- if ( value != null ) {\r
- String key2 = "Export attachments of "+format.fileext()+" to separate files";\r
- int index = rao.type().getComponentIndex2(key2);\r
- if ( index>=0 ) {\r
- rao.setFieldValue(index, Bindings.BOOLEAN, value);\r
- }\r
- } \r
- }\r
- \r
- }\r
- }\r
- \r
- } catch (AccessorConstructionException e) {\r
- throw new ExportException(e);\r
- } catch (AccessorException e) {\r
- throw new ExportException(e);\r
- } \r
- }\r
- \r
- /**\r
- * Save selections from previous form\r
- */\r
- public void savePrefs() throws ExportException {\r
- try {\r
- int oldSelectionHash = selectionHash; \r
- Preferences contentScopePrefs = ctx.store.node( "Selection-"+oldSelectionHash );\r
- Preferences workspaceScopePrefs = ctx.store;\r
- \r
- RecordBinding binding = ctx.databoard.getMutableBinding( form.type() );\r
- Object obj = binding.createDefault();\r
- Variant options = new Variant(binding, obj);\r
- form.readFields(composite, binding, obj);\r
- \r
- Combo publishTo = (Combo) form.getControl(composite, P_PUBLISH); \r
- String publisherLabel = publishTo==null?null:publishTo.getText();\r
- if ( publisherLabel != null ) {\r
- Publisher publisher = ctx.eep.getPublisherByLabel( publisherLabel );\r
- if ( publisher!=null ) {\r
- try {\r
- ChildReference locationOptionsRef = new LabelReference(publisher.label());\r
- Variant locationOptions = options.getComponent( locationOptionsRef );\r
- publisher.publisherClass().savePref(locationOptions, contentScopePrefs, workspaceScopePrefs);\r
- } catch ( AccessorConstructionException e ) {} \r
- }\r
- }\r
- \r
- for (Exporter exporter : ctx.eep.exporters()) {\r
- exporter.exportAction().savePref(options, contentScopePrefs, workspaceScopePrefs);\r
- }\r
- \r
- for (Format format : ctx.eep.formats()) {\r
- format.formatActions().savePref(options, contentScopePrefs, workspaceScopePrefs);\r
- } \r
- \r
- savePref(options, contentScopePrefs, workspaceScopePrefs);\r
- } catch (BindingException e) {\r
- throw new ExportException( e ); \r
- } catch (AccessorConstructionException e) {\r
- throw new ExportException( e ); \r
- } catch (AccessorException e) {\r
- throw new ExportException( e ); \r
- } catch (ExportException e) {\r
- throw new ExportException( e ); \r
- }\r
- }\r
-\r
- public void fillDefaultPrefs(Variant options) throws ExportException {\r
- try {\r
- RecordAccessor ra = Accessors.getAccessor(options);\r
-\r
- if ( ra.type().hasComponent(P_OUTPUT_OPTIONS.label) ) {\r
- RecordAccessor rao = ra.getComponent( P_OUTPUT_OPTIONS );\r
- \r
- for (Format format : ctx.eep.formats()) {\r
- if ( format.isContainerFormat() ) {\r
- String key = "Include attachments to "+format.fileext();\r
- int index = rao.type().getComponentIndex2(key);\r
- if ( index>=0 ) rao.setFieldValue(index, Bindings.BOOLEAN, true);\r
- \r
- key = "Export attachments of "+format.fileext()+" to separate files";;\r
- index = rao.type().getComponentIndex2(key);\r
- if ( index>=0 ) rao.setFieldValue(index, Bindings.BOOLEAN, true);\r
- } \r
- }\r
- \r
- }\r
- \r
- } catch (AccessorConstructionException e) {\r
- throw new ExportException(e);\r
- } catch (AccessorException e) {\r
- throw new ExportException(e);\r
- }\r
- } \r
- \r
- static boolean containsKey(Preferences pref, String key) {\r
- try {\r
- for (String x : pref.keys()) if ( x.equals(key) ) return true;\r
- } catch (BackingStoreException e) {\r
- e.printStackTrace();\r
- } \r
- return false; \r
- }\r
- \r
-}\r
+package org.simantics.export.ui;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.osgi.service.prefs.BackingStoreException;
+import org.osgi.service.prefs.Preferences;
+import org.simantics.databoard.Accessors;
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.Datatypes;
+import org.simantics.databoard.accessor.RecordAccessor;
+import org.simantics.databoard.accessor.error.AccessorConstructionException;
+import org.simantics.databoard.accessor.error.AccessorException;
+import org.simantics.databoard.accessor.reference.ChildReference;
+import org.simantics.databoard.accessor.reference.LabelReference;
+import org.simantics.databoard.binding.RecordBinding;
+import org.simantics.databoard.binding.error.BindingException;
+import org.simantics.databoard.binding.error.DatatypeConstructionException;
+import org.simantics.databoard.binding.error.RuntimeBindingException;
+import org.simantics.databoard.binding.mutable.Variant;
+import org.simantics.databoard.forms.DataboardForm;
+import org.simantics.databoard.forms.DataboardForm.Problem;
+import org.simantics.databoard.type.RecordType;
+import org.simantics.databoard.type.UnionType;
+import org.simantics.export.core.ExportContext;
+import org.simantics.export.core.error.ExportException;
+import org.simantics.export.core.intf.ContentType;
+import org.simantics.export.core.intf.Exporter;
+import org.simantics.export.core.intf.Format;
+import org.simantics.export.core.intf.Publisher;
+import org.simantics.export.core.manager.Content;
+import org.simantics.export.core.manager.ExportAction;
+import org.simantics.export.core.manager.ExportManager;
+import org.simantics.export.core.manager.ExportPlan;
+import org.simantics.export.core.manager.ExportWizardResult;
+import org.simantics.export.core.util.ExporterUtils;
+import org.simantics.utils.datastructures.Arrays;
+import org.simantics.utils.datastructures.MapList;
+import org.simantics.utils.datastructures.ToStringComparator;
+import org.simantics.utils.datastructures.collections.CollectionUtils;
+import org.simantics.utils.ui.ExceptionUtils;
+import org.simantics.utils.ui.dialogs.ShowMessage;
+
+/**
+ * Dynamic Options page. Exporter, Importer and Format contributes options to this page.
+ *
+ * @author toni.kalajainen@semantum.fi
+ */
+public class OptionsPage extends WizardPage {
+
+ public static String S_OUTPUT_OPTIONS = "Output Options";
+ public static LabelReference P_OUTPUT_OPTIONS = new LabelReference( S_OUTPUT_OPTIONS );
+
+ /** A reference to combo box selection */
+ public static String S_PUBLISH = "Publish to";
+ public static ChildReference P_PUBLISH = ChildReference.compile(P_OUTPUT_OPTIONS, new LabelReference(S_PUBLISH));
+
+ ExportContext ctx;
+
+ ScrolledComposite scroll;
+ Composite composite;
+ DataboardForm form;
+
+ List<Content> selection;
+ int selectionHash;
+ String selectedPublisherId;
+
+ public OptionsPage(ExportContext ctx) throws ExportException {
+ super("Options page", "Select export options", null);
+
+ this.ctx = ctx;
+ }
+
+ Listener modificationListener = new Listener() {
+ public void handleEvent(Event event) {
+ if ( updatingForm ) return;
+ validate();
+ }
+ };
+
+ boolean updatingForm;
+ Listener outputSettingsModifiedListener = new Listener() {
+ public void handleEvent(Event event) {
+ updatingForm = true;
+ try {
+ Preferences contentScopePrefs = ctx.store.node( "Selection-"+selectionHash );
+ Preferences workspaceScopePrefs = ctx.store;
+
+ Composite outputOptions = (Composite) form.getControl(composite, P_OUTPUT_OPTIONS);
+ Combo publishTo = (Combo) form.getControl(composite, P_PUBLISH);
+ String newPublisherLabel = publishTo.getText();
+ Publisher newPublisher = ctx.eep.getPublisherByLabel(newPublisherLabel);
+ String newPublisherId = newPublisher==null?null:newPublisher.id();
+ //if ( newPublisherId.equals(selectedPublisherId) ) return;
+
+ // Save Preferences
+ RecordBinding binding = ctx.databoard.getMutableBinding( form.type() );
+ Object obj = binding.createDefault();
+ form.readFields(composite, binding, obj);
+ Variant options = new Variant(binding, obj);
+
+ Publisher oldPublisher = ctx.eep.getPublisher( selectedPublisherId );
+ if ( oldPublisher!=null ) {
+ ChildReference oldOptionsRef = new LabelReference( oldPublisher.label() );
+ try {
+ Variant locationOptions = options.getComponent( oldOptionsRef );
+ oldPublisher.publisherClass().savePref(locationOptions, contentScopePrefs, workspaceScopePrefs);
+ } catch ( AccessorConstructionException ee ) {}
+ }
+
+ List<Content> manifest = getManifestFor(selection, options);
+ cleanPublisherFromGroup(selectedPublisherId);
+ addPublisherToGroup(newPublisherId, manifest);
+
+ outputOptions.pack(true);
+ outputOptions.layout(true);
+ composite.pack(true);
+ composite.layout(true);
+
+ RecordType dummy = new RecordType();
+ RecordType newPublisherOptions = newPublisher.publisherClass().locationOptions(ctx, manifest);
+ dummy.addComponent( newPublisherLabel, newPublisherOptions );
+ binding = ctx.databoard.getMutableBinding( dummy );
+ obj = binding.createDefault();
+ options = new Variant(binding, obj);
+ ChildReference locationOptionsRef = new LabelReference( newPublisherLabel );
+ Variant locationOptions = options.getComponent( locationOptionsRef );
+ newPublisher.publisherClass().fillDefaultPrefs(ctx, selection, options, locationOptions);
+ newPublisher.publisherClass().loadPref(locationOptions, contentScopePrefs, workspaceScopePrefs);
+ //loadPublisherPref(newPublisherId, options, contentScopePrefs, workspaceScopePrefs);
+ form.writeFields(outputOptions, (RecordBinding) options.getBinding(), options.getValue());
+
+ selectedPublisherId = newPublisherId;
+
+ updatingForm = false;
+ validate();
+ } catch ( BindingException e ) {
+ setErrorMessage( e.getClass().getName()+": "+ e.getMessage() );
+ ExceptionUtils.logError(e);
+ } catch (AccessorConstructionException e) {
+ setErrorMessage( e.getClass().getName()+": "+ e.getMessage() );
+ ExceptionUtils.logError(e);
+ } catch (AccessorException e) {
+ setErrorMessage( e.getClass().getName()+": "+ e.getMessage() );
+ ExceptionUtils.logError(e);
+ } catch (ExportException e) {
+ setErrorMessage( e.getClass().getName()+": "+ e.getMessage() );
+ ExceptionUtils.logError(e);
+ } finally {
+ updatingForm = false;
+ }
+ }
+ };
+
+ @Override
+ public void createControl(Composite parent) {
+
+ scroll = new ScrolledComposite(parent, SWT.V_SCROLL);
+ composite = new Composite(scroll, 0);
+ composite.setLayout( new GridLayout(3, false) );
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));
+ scroll.setContent(composite);
+ scroll.setExpandHorizontal(true);
+ scroll.setExpandVertical(false);
+ scroll.getVerticalBar().setIncrement(scroll.getVerticalBar().getIncrement()*8);
+
+ form = new DataboardForm();
+ form.setFirstColumnWidth(200);
+
+ composite.pack();
+ setControl(scroll);
+ setPageComplete(true);
+
+ }
+
+ public void update(List<Content> contents)
+ {
+ try {
+ // 0. Initialization
+ Set<String> contentUris = new TreeSet<String>();
+ MapList<String, Content> uriToContentMap = new MapList<String, Content>();
+ MapList<ContentType, String> contentByContentType = new MapList<ContentType, String>();
+ MapList<Format, String> contentByFormat = new MapList<Format, String>();
+ List<Format> formats = new ArrayList<Format>();
+ Map<String, Format> contentFormatMap = new TreeMap<String, Format>( String.CASE_INSENSITIVE_ORDER );
+ for (Content content : contents) {
+ contentUris.add(content.url);
+ ContentType ct = ctx.eep.getContentType( content.contentTypeId );
+ contentByContentType.add(ct, content.url);
+ Format format = ctx.eep.getFormat( content.formatId );
+ contentByFormat.add(format, content.url);
+ uriToContentMap.add(content.url, content);
+ }
+ formats.addAll( contentByFormat.getKeys() );
+
+ Collections.sort(formats, new ToStringComparator());
+
+ for (Content content : contents) {
+ String id = content.formatId;
+ Format format = contentFormatMap.get( id );
+ if ( format != null ) continue;
+ format = ctx.eep.getFormat(id);
+ contentFormatMap.put(id, format);
+ }
+
+ MapList<Exporter, String> exporterContentMap = new MapList<Exporter, String>();
+ TreeMap<String, Exporter> orderedExporters = new TreeMap<String, Exporter>( String.CASE_INSENSITIVE_ORDER );
+ for (Content content : contents) {
+ for (Exporter exporter : ctx.eep.getExporters(content.formatId, content.contentTypeId) ) {
+ exporterContentMap.add(exporter, content.url);
+ orderedExporters.put(exporter.formatId()+exporter.contentTypeId()+exporter.exportAction().getClass(), exporter);
+ }
+ }
+
+ // 1. Save selections from previous form
+ savePrefs();
+
+ // 2. Clear previous form
+ form.clear(composite);
+
+ // 3. Create options record
+ RecordType optionsRecord = new RecordType();
+
+ // Add Output options box
+ RecordType outputOptions = new RecordType();
+
+ for ( Format format : formats ) {
+ if ( format.isGroupFormat() && contentByFormat.getValues(format).size()>1 ) {
+ outputOptions.addComponent("Merge "+format.fileext()+" content into one file", Datatypes.BOOLEAN);
+ }
+
+ if ( format.isContainerFormat() ) {
+ List<String> formatsContentUris = contentByFormat.getValues(format);
+ int attachmentCount = 0;
+ for ( String contentUri : formatsContentUris ) {
+ for ( Content content : uriToContentMap.getValues(contentUri) ) {
+ if ( !content.formatId.equals(format.id()) ) attachmentCount++;
+ }
+ }
+ // Add as possible attachment, all contents that don't have this format
+ // their their content type.
+ for ( Content content : contents ) {
+ if ( ctx.eep.getExporters(format.id(), content.contentTypeId).length == 0) attachmentCount++;
+ }
+
+ if ( attachmentCount > 0 ) {
+ outputOptions.addComponent("Include attachments to "+format.fileext(), Datatypes.BOOLEAN);
+ outputOptions.addComponent("Export attachments of "+format.fileext()+" to separate files", Datatypes.BOOLEAN);
+ }
+ }
+ }
+
+ UnionType publisherType = new UnionType();
+ for (Publisher publisher : ctx.eep.publishers()) publisherType.addComponent(publisher.label(), Datatypes.VOID);
+ outputOptions.addComponent(S_PUBLISH, publisherType);
+
+ optionsRecord.addComponent(S_OUTPUT_OPTIONS, outputOptions);
+
+ // Add Format specific boxes
+ for (Format format : contentFormatMap.values()) {
+ RecordType formatOptions = format.formatActions().options(ctx);
+ if ( formatOptions==null ) continue;
+ optionsRecord.mergeRecord( formatOptions );
+ }
+
+ // Add Exporter specific boxes
+ for (Exporter exporter : orderedExporters.values()) {
+ List<String> exportSpecificContents = exporterContentMap.getValues(exporter);
+ if ( exportSpecificContents==null || exportSpecificContents.isEmpty() ) continue;
+ RecordType exporterOptions = exporter.exportAction().options(ctx, exportSpecificContents);
+ if ( exporterOptions == null ) continue;
+ optionsRecord.mergeRecord( exporterOptions );
+ }
+
+ // 4. Load default and previous selections of the options ( All but publisher )
+ ctx.databoard.clear();
+ RecordBinding optionsBinding = ctx.databoard.getMutableBinding( optionsRecord );
+ Object optionsObj = optionsBinding.createDefaultUnchecked();
+ Variant options = new Variant(optionsBinding, optionsObj);
+ {
+ Preferences workspaceScopePrefs = ctx.store;
+ Preferences contentScopePrefs = ctx.store( contents );
+
+ for (Exporter exporter : orderedExporters.values()) {
+ exporter.exportAction().fillDefaultPrefs(ctx, options);
+ exporter.exportAction().loadPref(options, contentScopePrefs, workspaceScopePrefs);
+ }
+
+ for (Format format : contentByFormat.getKeys()) {
+ format.formatActions().fillDefaultPrefs( ctx, options );
+ format.formatActions().loadPref(options, contentScopePrefs, workspaceScopePrefs);
+ }
+
+ fillDefaultPrefs(options);
+ loadPref(options, contentScopePrefs, workspaceScopePrefs);
+ }
+
+ // 5. Create form
+ form.addFields(composite, optionsRecord);
+ form.addListener(composite, form.type(), modificationListener);
+ Composite outputOptionsGroup = (Composite) form.getControl(composite, P_OUTPUT_OPTIONS);
+ RecordType dummy = new RecordType();
+ dummy.addComponent(S_OUTPUT_OPTIONS, outputOptions);
+ form.addListener(outputOptionsGroup, dummy, outputSettingsModifiedListener);
+ form.writeFields(composite, optionsBinding, optionsObj);
+
+ // 6. Add publisher
+ {
+ selection = contents;
+ Preferences workspaceScopePrefs = ctx.store;
+ Preferences contentScopePrefs = ctx.store.node( "Selection-"+selectionHash );
+ selectedPublisherId = ctx.store.get("publisherId", "");
+ Publisher publisher = ctx.eep.getPublisher(selectedPublisherId);
+ if ( publisher != null ) {
+
+ // 6A. Manifest
+ List<Content> manifest = getManifestFor(contents, options);
+
+ // 6B. Default and previous settings
+ String label = publisher.label();
+ RecordType publisherOptionsType = publisher.publisherClass().locationOptions(ctx, manifest);
+ RecordType publisherOptionsRootType = new RecordType();
+ publisherOptionsRootType.addComponent(label, publisherOptionsType);
+ RecordBinding publisherOptionsRootBinding = ctx.databoard.getMutableBinding( publisherOptionsRootType );
+ Object publisherOptionsRootObj = publisherOptionsRootBinding.createDefaultUnchecked();
+ Variant publisherOptionsRoot = new Variant(publisherOptionsRootBinding, publisherOptionsRootObj);
+ try {
+ ChildReference locationOptionsRef = new LabelReference( label );
+ Variant locationOptions = publisherOptionsRoot.getComponent( locationOptionsRef );
+ publisher.publisherClass().fillDefaultPrefs(ctx, selection, options, locationOptions);
+ publisher.publisherClass().loadPref(locationOptions, contentScopePrefs, workspaceScopePrefs);
+ } catch ( AccessorConstructionException ee ) {
+ }
+
+ // 6C. Add Publisher form
+ addPublisherToGroup(selectedPublisherId, manifest);
+ form.writeFields(composite, publisherOptionsRootBinding, publisherOptionsRootObj);
+ }
+ }
+
+ // 8. Validate page
+ composite.pack();
+ validate();
+
+ } catch (BindingException e) {
+ ExceptionUtils.logError(e);
+ ShowMessage.showError("Unexpected error", e.getClass().getName()+" "+e.getMessage());
+ throw new RuntimeBindingException(e);
+ } catch (ExportException e) {
+ ExceptionUtils.logError(e);
+ ShowMessage.showError("Unexpected error", e.getClass().getName()+" "+e.getMessage());
+ } catch (DatatypeConstructionException e) {
+ ExceptionUtils.logError(e);
+ ShowMessage.showError("Unexpected error", e.getClass().getName()+" "+e.getMessage());
+ } catch (AccessorConstructionException e) {
+ ExceptionUtils.logError(e);
+ ShowMessage.showError("Unexpected error", e.getClass().getName()+" "+e.getMessage());
+ } catch (AccessorException e) {
+ ExceptionUtils.logError(e);
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ * Saves publisher prefs from the UI to preference nodes.
+ *
+ * @throws ExportException
+ */
+ void savePublisherPref(String publisherId, Variant options, Preferences contentScopePrefs, Preferences workspaceScopePrefs) throws ExportException {
+ try {
+// Preferences contentScopePrefs = ctx.store.node( "Selection-"+selectionHash );
+// Preferences workspaceScopePrefs = ctx.store;
+
+// RecordBinding binding = ctx.databoard.getMutableBinding( form.type() );
+// Object obj = binding.createDefault();
+// form.readFields(composite, binding, obj);
+// Variant options = new Variant(binding, obj);
+
+ Publisher publisher = ctx.eep.getPublisher( publisherId );
+ if ( publisher==null ) return;
+ Variant locationOptions = options.getComponent( new LabelReference(publisher.label()) );
+ publisher.publisherClass().savePref(locationOptions, contentScopePrefs, workspaceScopePrefs);
+// } catch (BindingException e) {
+// throw new ExportException( e );
+ } catch (AccessorConstructionException e) {
+ ExceptionUtils.logError(e);
+ //throw new ExportException( e );
+// } catch (AccessorException e) {
+// throw new ExportException( e );
+ }
+ }
+
+ void loadPublisherPref(String publisherId, Variant options, Preferences contentScopePrefs, Preferences workspaceScopePrefs) throws ExportException {
+ try {
+// Preferences contentScopePrefs = ctx.store.node( "Selection-"+selectionHash );
+// Preferences workspaceScopePrefs = ctx.store;
+
+ Publisher publisher = ctx.eep.getPublisher( publisherId );
+ if ( publisher == null ) return;
+
+ // There is a problem here if selection was built with manifest
+// RecordType optionsType = publisher.publiserClass().locationOptions(ctx, selection);
+// RecordBinding binding = ctx.databoard.getMutableBinding( optionsType );
+// Object obj = binding.createDefault();
+// Variant locationOptions = new Variant(binding, obj);
+ Variant locationOptions = options.getComponent( new LabelReference( publisher.label() ) );
+ publisher.publisherClass().fillDefaultPrefs(ctx, selection, options, locationOptions);
+ publisher.publisherClass().loadPref(locationOptions, contentScopePrefs, workspaceScopePrefs);
+// } catch (BindingException e) {
+// throw new ExportException( e );
+ } catch (AccessorConstructionException e) {
+ ExceptionUtils.logError(e);
+ //throw new ExportException( e );
+// } catch (AccessorException e) {
+// throw new ExportException( e );
+ }
+ }
+
+ /**
+ * Remove any publisher specific controls from output options.
+ */
+ void cleanPublisherFromGroup(String oldPublisherId) {
+ Publisher publisher = ctx.eep.getPublisher(oldPublisherId);
+ if ( publisher != null ) {
+ String fieldName = publisher.label();
+ if ( form.type().hasComponent(fieldName)) {
+ form.type().removeComponent(fieldName);
+ ctx.databoard.clear();
+ }
+ }
+ Combo publishTo = (Combo) form.getControl(composite, P_PUBLISH);
+ Composite group = (Composite) publishTo.getParent();
+ Control children[] = group.getChildren();
+ int index = Arrays.indexOf( children, publishTo );
+ for (int i=children.length-1; i>index; i--) {
+ children[i].dispose();
+ }
+ }
+
+ /**
+ * Add controls of a publisher id
+ *
+ * @param publisherId
+ * @throws ExportException
+ */
+ void addPublisherToGroup( String publisherId, List<Content> contents ) throws ExportException {
+ try {
+ Composite group = (Composite) form.getControl(composite, P_OUTPUT_OPTIONS);
+ if ( group == null ) return;
+ Publisher publisher = ctx.eep.getPublisher( publisherId );
+ if ( publisher == null ) return;
+ RecordType publisherOptions = publisher.publisherClass().locationOptions(ctx, contents);
+ //form.type().addComponent(publisher.label(), publisherOptions);
+ RecordType options = new RecordType();
+ options.addComponent(publisher.label(), publisherOptions);
+ form.addFields(group, publisherOptions, publisher.label());
+ form.addListener(group, options, modificationListener);
+ ctx.databoard.clear();
+ } catch (BindingException e) {
+ throw new ExportException(e);
+ } catch (AccessorConstructionException e) {
+ throw new ExportException(e);
+ } catch (AccessorException e) {
+ throw new ExportException(e);
+ }
+ }
+
+ List<Content> getManifestFor(List<Content> selection, Variant options) {
+ try {
+ ExportWizardResult result = new ExportWizardResult();
+ result.options = options;
+ result.accessor = Accessors.getAccessor(result.options);
+ result.contents = selection;
+ result.type = (RecordType) options.type();
+ result.publisherId = "file";
+
+ List<ExportAction> actions = new ArrayList<ExportAction>();
+ List<Content> manifest = new ArrayList<Content>();
+ result.createExportActions(ctx, actions, manifest);
+ return manifest;
+ } catch (AccessorConstructionException e) {
+ return selection;
+ } catch (ExportException e) {
+ e.printStackTrace();
+ return selection;
+ }
+ }
+
+ public ExportWizardResult getOutput()
+ throws ExportException
+ {
+ ExportWizardResult result = new ExportWizardResult();
+ try {
+ ctx.databoard.clear();
+ result.type = form.type();
+ RecordBinding binding = (RecordBinding) ctx.databoard.getMutableBinding( result.type );
+ Object optionsObj = binding.createDefault();
+ result.options = new Variant(binding, optionsObj);
+ form.readFields(composite, binding, optionsObj);
+ result.accessor = Accessors.getAccessor(result.options);
+ result.contents = selection;
+
+
+ String publisherLabel = ExporterUtils.getUnionValue(result.accessor, P_PUBLISH);
+ Publisher publisher = ctx.eep.getPublisherByLabel(publisherLabel);
+ result.publisherId = publisher==null?"":publisher.id();
+
+ } catch (BindingException e) {
+ throw new ExportException(e);
+ } catch (AccessorException e) {
+ throw new ExportException(e);
+ } catch (AccessorConstructionException e) {
+ throw new ExportException(e);
+ }
+
+ return result;
+ }
+
+ void validate() {
+ List<Problem> problems = form.validate(composite);
+ List<String> errs = DataboardForm.toStrings(problems);
+
+ if ( errs.isEmpty() ) {
+ try {
+ ExportWizardResult result = getOutput();
+ ExportPlan plan = new ExportPlan();
+ result.createPlan(ctx, plan);
+ ExportManager mgr = new ExportManager(result.options, ctx);
+ errs.addAll( mgr.validate(ctx, plan) ) ;
+ } catch (ExportException e) {
+ errs.add(e.getMessage());
+ }
+ } else {
+ CollectionUtils.unique( errs );
+ }
+
+
+ setErrorMessage( errs.isEmpty() ? null : CollectionUtils.toString(errs, ", ") );
+ setPageComplete( errs.isEmpty() );
+ }
+
+ /**
+ * Save wizard preferences
+ *
+ * @param options
+ * @param contentScopePrefs
+ * @param workspaceScopePrefs
+ * @throws ExportException
+ */
+ void savePref(Variant options, Preferences contentScopePrefs, Preferences workspaceScopePrefs) throws ExportException
+ {
+ try {
+ RecordAccessor ra = Accessors.getAccessor(options);
+ String publisherId = ExporterUtils.getUnionValue(ra, P_PUBLISH);
+ Publisher publisher = ctx.eep.getPublisherByLabel(publisherId);
+ if ( publisher!=null ) workspaceScopePrefs.put("publisherId", publisher.id());
+
+ if ( ra.type().hasComponent(P_OUTPUT_OPTIONS.label) ) {
+ RecordAccessor rao = ra.getComponent( P_OUTPUT_OPTIONS );
+
+ Pattern merge_pattern = Pattern.compile("Merge ([^\\s]*) content into one file");
+ Pattern include_pattern = Pattern.compile("Include attachments to ([^\\s]*)");
+ Pattern export_pattern = Pattern.compile("Export attachments of ([^\\s]*) to separate files");
+
+ for (int i=0; i<rao.count(); i++) {
+ String name = rao.type().getComponent(i).name;
+ Matcher m;
+
+ m = merge_pattern.matcher(name);
+ if ( m.matches() ) {
+ String fileExt = m.group(1);
+ Format format = ctx.eep.getFormatByExt(fileExt);
+ Boolean value = (Boolean) rao.getFieldValue(i, Bindings.BOOLEAN);
+ String key = format.id()+"_merge";
+ contentScopePrefs.putBoolean(key, value);
+ workspaceScopePrefs.putBoolean(key, value);
+ }
+
+ m = include_pattern.matcher(name);
+ if ( m.matches() ) {
+ String fileExt = m.group(1);
+ Format format = ctx.eep.getFormatByExt(fileExt);
+ Boolean value = (Boolean) rao.getFieldValue(i, Bindings.BOOLEAN);
+ String key = format.id()+"_include_attachments";
+ contentScopePrefs.putBoolean(key, value);
+ workspaceScopePrefs.putBoolean(key, value);
+ }
+
+ m = export_pattern.matcher(name);
+ if ( m.matches() ) {
+ String fileExt = m.group(1);
+ Format format = ctx.eep.getFormatByExt(fileExt);
+ Boolean value = (Boolean) rao.getFieldValue(i, Bindings.BOOLEAN);
+ String key = format.id()+"_export_attachments";
+ contentScopePrefs.putBoolean(key, value);
+ workspaceScopePrefs.putBoolean(key, value);
+ }
+ }
+ }
+
+ } catch (AccessorConstructionException e) {
+ throw new ExportException(e);
+ } catch (AccessorException e) {
+ throw new ExportException(e);
+ }
+
+ }
+
+ /**
+ * Load wizard preferences
+ *
+ * @param binding
+ * @param options
+ * @param contentScopePrefs
+ * @param workspaceScopePrefs
+ * @throws ExportException
+ */
+ void loadPref(Variant options, Preferences contentScopePrefs, Preferences workspaceScopePrefs) throws ExportException
+ {
+ //Preferences workspaceScopePrefs = ctx.store;
+ try {
+ RecordAccessor ra = Accessors.getAccessor(options);
+ String publisherId = workspaceScopePrefs.get("publisherId", "");
+ Publisher publisher = ctx.eep.getPublisher(publisherId);
+ if ( publisher != null ) ExporterUtils.setUnionValue(ra, P_PUBLISH, publisher.label());
+
+ if ( ra.type().hasComponent(P_OUTPUT_OPTIONS.label) ) {
+ RecordAccessor rao = ra.getComponent( P_OUTPUT_OPTIONS );
+
+ for (Format format : ctx.eep.formats()) {
+ if ( format.isGroupFormat() ) {
+ String key = format.id()+"_merge";
+ Boolean value = null;
+ if ( containsKey(contentScopePrefs, key) ) {
+ value = contentScopePrefs.getBoolean(key, false);
+ } else if ( containsKey(workspaceScopePrefs, key) ) {
+ value = workspaceScopePrefs.getBoolean(key, false);
+ }
+
+ if ( value != null ) {
+ String key2 = "Merge "+format.fileext()+" content into one file";
+ int index = rao.type().getComponentIndex2(key2);
+ if ( index>=0 ) {
+ rao.setFieldValue(index, Bindings.BOOLEAN, value);
+ }
+ }
+ }
+
+ if ( format.isContainerFormat() ) {
+ String key = format.id()+"_include_attachments";
+ Boolean value = null;
+ if ( containsKey(contentScopePrefs, key) ) {
+ value = contentScopePrefs.getBoolean(key, false);
+ } else if ( containsKey(workspaceScopePrefs, key) ) {
+ value = workspaceScopePrefs.getBoolean(key, false);
+ }
+
+ if ( value != null ) {
+ String key2 = "Include attachments to "+format.fileext();
+ int index = rao.type().getComponentIndex2(key2);
+ if ( index>=0 ) {
+ rao.setFieldValue(index, Bindings.BOOLEAN, value);
+ }
+ }
+ }
+
+ if ( format.isContainerFormat() ) {
+ String key = format.id()+"_export_attachments";
+ Boolean value = null;
+ if ( containsKey(contentScopePrefs, key) ) {
+ value = contentScopePrefs.getBoolean(key, false);
+ } else if ( containsKey(workspaceScopePrefs, key) ) {
+ value = workspaceScopePrefs.getBoolean(key, false);
+ }
+
+ if ( value != null ) {
+ String key2 = "Export attachments of "+format.fileext()+" to separate files";
+ int index = rao.type().getComponentIndex2(key2);
+ if ( index>=0 ) {
+ rao.setFieldValue(index, Bindings.BOOLEAN, value);
+ }
+ }
+ }
+
+ }
+ }
+
+ } catch (AccessorConstructionException e) {
+ throw new ExportException(e);
+ } catch (AccessorException e) {
+ throw new ExportException(e);
+ }
+ }
+
+ /**
+ * Save selections from previous form
+ */
+ public void savePrefs() throws ExportException {
+ try {
+ int oldSelectionHash = selectionHash;
+ Preferences contentScopePrefs = ctx.store.node( "Selection-"+oldSelectionHash );
+ Preferences workspaceScopePrefs = ctx.store;
+
+ RecordBinding binding = ctx.databoard.getMutableBinding( form.type() );
+ Object obj = binding.createDefault();
+ Variant options = new Variant(binding, obj);
+ form.readFields(composite, binding, obj);
+
+ Combo publishTo = (Combo) form.getControl(composite, P_PUBLISH);
+ String publisherLabel = publishTo==null?null:publishTo.getText();
+ if ( publisherLabel != null ) {
+ Publisher publisher = ctx.eep.getPublisherByLabel( publisherLabel );
+ if ( publisher!=null ) {
+ try {
+ ChildReference locationOptionsRef = new LabelReference(publisher.label());
+ Variant locationOptions = options.getComponent( locationOptionsRef );
+ publisher.publisherClass().savePref(locationOptions, contentScopePrefs, workspaceScopePrefs);
+ } catch ( AccessorConstructionException e ) {}
+ }
+ }
+
+ for (Exporter exporter : ctx.eep.exporters()) {
+ exporter.exportAction().savePref(options, contentScopePrefs, workspaceScopePrefs);
+ }
+
+ for (Format format : ctx.eep.formats()) {
+ format.formatActions().savePref(options, contentScopePrefs, workspaceScopePrefs);
+ }
+
+ savePref(options, contentScopePrefs, workspaceScopePrefs);
+ } catch (BindingException e) {
+ throw new ExportException( e );
+ } catch (AccessorConstructionException e) {
+ throw new ExportException( e );
+ } catch (AccessorException e) {
+ throw new ExportException( e );
+ } catch (ExportException e) {
+ throw new ExportException( e );
+ }
+ }
+
+ public void fillDefaultPrefs(Variant options) throws ExportException {
+ try {
+ RecordAccessor ra = Accessors.getAccessor(options);
+
+ if ( ra.type().hasComponent(P_OUTPUT_OPTIONS.label) ) {
+ RecordAccessor rao = ra.getComponent( P_OUTPUT_OPTIONS );
+
+ for (Format format : ctx.eep.formats()) {
+ if ( format.isContainerFormat() ) {
+ String key = "Include attachments to "+format.fileext();
+ int index = rao.type().getComponentIndex2(key);
+ if ( index>=0 ) rao.setFieldValue(index, Bindings.BOOLEAN, true);
+
+ key = "Export attachments of "+format.fileext()+" to separate files";;
+ index = rao.type().getComponentIndex2(key);
+ if ( index>=0 ) rao.setFieldValue(index, Bindings.BOOLEAN, true);
+ }
+ }
+
+ }
+
+ } catch (AccessorConstructionException e) {
+ throw new ExportException(e);
+ } catch (AccessorException e) {
+ throw new ExportException(e);
+ }
+ }
+
+ static boolean containsKey(Preferences pref, String key) {
+ try {
+ for (String x : pref.keys()) if ( x.equals(key) ) return true;
+ } catch (BackingStoreException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+}