--- /dev/null
+package org.simantics.export.core.impl;\r
+\r
+import java.io.File;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Map.Entry;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\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.mutable.Variant;\r
+import org.simantics.databoard.forms.DataboardForm;\r
+import org.simantics.databoard.type.Datatype;\r
+import org.simantics.databoard.type.RecordType;\r
+import org.simantics.databoard.type.StringType;\r
+import org.simantics.export.core.ExportContext;\r
+import org.simantics.export.core.error.ExportException;\r
+import org.simantics.export.core.intf.Format;\r
+import org.simantics.export.core.intf.PublisherClass;\r
+import org.simantics.export.core.manager.Content;\r
+import org.simantics.export.core.util.ExporterUtils;\r
+import org.simantics.utils.datastructures.collections.CollectionUtils;\r
+\r
+/**\r
+ * There is one output field for each content: \r
+ * [ ] Overwrite file(s)\r
+ * file1.ext [________________________] (Select)\r
+ * file2.ext [________________________] (Select)\r
+ * ...\r
+ * fileN.ext [________________________] (Select)\r
+ * \r
+ * @author toni.kalajainen@semantum.fi\r
+ */\r
+public class FilePublisher implements PublisherClass {\r
+\r
+ public static LabelReference P_ALLOW_OVERWRITE = new LabelReference("Overwrite file(s)");\r
+ \r
+ @Override\r
+ public void publish(ExportContext ctx, List<Content> contents, Variant options, Variant locationOptions, IProgressMonitor monitor) throws ExportException {\r
+ \r
+ Boolean canOverwrite = ExporterUtils.getBoolean(locationOptions, P_ALLOW_OVERWRITE);\r
+ \r
+ for ( Content content : contents ) {\r
+ if ( content.tmpFile == null ) throw new ExportException("Internal error, tmpFile was null for "+content.label+content.formatExt );\r
+ \r
+ String filePath = ExporterUtils.getString( locationOptions, new LabelReference( content.filename ) );\r
+ filePath = PublisherUtil.ensureEndsWith(true, content.formatExt, filePath);\r
+ File file = new File( filePath );\r
+ if ( file.exists() ) {\r
+ if ( canOverwrite ) {\r
+ file.delete();\r
+ } else {\r
+ throw new ExportException("Would not overwrite " + file.getAbsolutePath());\r
+ }\r
+ }\r
+ \r
+ content.tmpFile.renameTo(file);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public List<String> validate(ExportContext ctx, List<Content> contents, Variant options, Variant locationOptions) throws ExportException {\r
+ List<String> result = new ArrayList<String>();\r
+\r
+ Boolean canOverwrite = ExporterUtils.getBoolean(locationOptions, P_ALLOW_OVERWRITE);\r
+ if ( canOverwrite == null ) { result.add("CanOverwrite option missing?"); return result; }\r
+\r
+ List<String> missingPaths = new ArrayList<String>();\r
+ \r
+ for ( Content content : contents ) {\r
+ String filePath = ExporterUtils.getString( locationOptions, new LabelReference( content.filename ) );\r
+ if ( filePath == null || filePath.isEmpty() ) {\r
+ missingPaths.add( content.filename );\r
+ } else {\r
+ filePath = PublisherUtil.ensureEndsWith(true, content.formatExt, filePath);\r
+ File file = new File( filePath );\r
+ if ( !canOverwrite && file.exists() ) {\r
+ result.add(file.getAbsolutePath()+" already exists.");\r
+ }\r
+ }\r
+ }\r
+\r
+ if ( !missingPaths.isEmpty() ) {\r
+ result.add(0, "Path for " + CollectionUtils.toString(missingPaths, ", ") + " is required."); \r
+ }\r
+ \r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public RecordType locationOptions(ExportContext ctx, List<Content> contents) throws ExportException {\r
+ \r
+ RecordType rt = new RecordType(); \r
+ for ( Content content : contents ) {\r
+ Format format = ctx.eep.getFormat( content.formatId ); \r
+ rt.addComponent(content.filename, DataboardForm.fileSaveDialog( format.label(), "*"+format.fileext() ) );\r
+ }\r
+ rt.addComponent(P_ALLOW_OVERWRITE.label, Datatypes.BOOLEAN);\r
+ \r
+ return rt;\r
+ }\r
+\r
+ @Override\r
+ public Variant createLocation(ExportContext ctx, Variant locationOptions) throws ExportException {\r
+ // Make Dirs to the path.\r
+ for ( File file : readLocations(locationOptions).values() ) {\r
+ File parentFile = file.getParentFile();\r
+ if ( parentFile == null ) continue;\r
+ if ( parentFile.exists() && !parentFile.isDirectory() ) throw new ExportException( parentFile+" is not directory.");\r
+ if ( parentFile.exists() ) continue;\r
+ if (!parentFile.mkdirs()) throw new ExportException( "Failed to create "+parentFile );\r
+ }\r
+ return locationOptions;\r
+ }\r
+ \r
+ @Override\r
+ public boolean locationExists(ExportContext ctx, Variant locationOptions) throws ExportException {\r
+ \r
+ boolean exists = true;\r
+ for ( File file : readLocations(locationOptions).values() ) {\r
+ File parentFile = file.getParentFile();\r
+ if ( parentFile == null ) continue; \r
+ exists &= parentFile.exists() && parentFile.isDirectory(); \r
+ }\r
+ return exists;\r
+ }\r
+ \r
+ @Override\r
+ public void fillDefaultPrefs(ExportContext ctx, List<Content> contents, Variant options, Variant locationOptions) throws ExportException {\r
+ try {\r
+ RecordAccessor ra = Accessors.getAccessor(locationOptions);\r
+ ra.setValue(P_ALLOW_OVERWRITE, Bindings.BOOLEAN, true);\r
+ \r
+ // Fill defaults using dir location and content filename :D\r
+ String path = ExporterUtils.getString( options, new LabelReference("Dir", DirPublisher.P_EXPORT_LOCATION) );\r
+ if ( path != null ) {\r
+ RecordType rt = ra.type();\r
+ for ( int i=0; i<rt.getComponentCount(); i++ ) {\r
+ String label = rt.getComponent(i).name;\r
+ if ( label.equals(P_ALLOW_OVERWRITE.label)) continue;\r
+ ra.setFieldValue(i, Bindings.STRING, path+"/"+label);\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
+ @Override\r
+ public void savePref(Variant locationOptions, Preferences contentScopeNode, Preferences workspaceScopeNode) throws ExportException {\r
+ try {\r
+ RecordAccessor ra = Accessors.getAccessor(locationOptions);\r
+\r
+ // File name specific \r
+ RecordType rt = (RecordType) locationOptions.type();\r
+ for (int i=0; i<rt.getComponentCount(); i++) {\r
+ if ( rt.getComponentType(i) instanceof StringType == false ) continue;\r
+ String fieldName = rt.getComponent(i).name;\r
+ String value = (String) ra.getFieldValue(i, Bindings.STRING); \r
+ if ( value!=null ) {\r
+ workspaceScopeNode.put(fieldName, value);\r
+ contentScopeNode.put(fieldName, value);\r
+ }\r
+ }\r
+ \r
+ Boolean b = (Boolean) ra.getValue(P_ALLOW_OVERWRITE, Bindings.BOOLEAN);\r
+ if ( b!=null ) {\r
+ contentScopeNode.putBoolean(P_ALLOW_OVERWRITE.tail().toString(), b);\r
+ workspaceScopeNode.putBoolean(P_ALLOW_OVERWRITE.tail().toString(), b);\r
+ }\r
+ \r
+ } catch (AccessorException e) {\r
+ throw new ExportException( e );\r
+ } catch (AccessorConstructionException e) {\r
+ throw new ExportException( e );\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ public void loadPref(Variant locationOptions, Preferences contentScopePrefs, Preferences workspaceScopePrefs) throws ExportException {\r
+ try {\r
+ RecordAccessor ra = Accessors.getAccessor(locationOptions);\r
+ \r
+ for ( Entry<String, File> entry : readLocations(locationOptions).entrySet() ) {\r
+ String key = entry.getKey();\r
+ String value = ExporterUtils.getPrefString(contentScopePrefs, workspaceScopePrefs, key);\r
+ if ( value != null ) {\r
+ ChildReference ref = new LabelReference( key ); \r
+ ra.setValue( ref, Bindings.STRING, value ); \r
+ }\r
+ }\r
+ \r
+ String key = P_ALLOW_OVERWRITE.tail().toString();\r
+ Boolean b = ExporterUtils.getPrefBoolean(contentScopePrefs, workspaceScopePrefs, key);\r
+ if ( b!=null ) ra.setValue(P_ALLOW_OVERWRITE, Bindings.BOOLEAN, b);\r
+ \r
+ } catch (AccessorConstructionException e) {\r
+ throw new ExportException( e );\r
+ } catch (AccessorException e) {\r
+ throw new ExportException( e );\r
+ } \r
+ }\r
+\r
+ Map<String, File> readLocations(Variant location) throws ExportException {\r
+ HashMap<String, File> result = new HashMap<String, File>();\r
+ \r
+ try {\r
+ RecordAccessor ra = Accessors.getAccessor(location);\r
+ RecordType rt = (RecordType) location.type();\r
+ for (int i=0; i<rt.getComponentCount(); i++) \r
+ {\r
+ Datatype ct = rt.getComponent(i).type;\r
+ if ( ct instanceof StringType == false ) continue;\r
+ String fieldName = rt.getComponent(i).name;\r
+ String value = (String) ra.getFieldValue(i, Bindings.STRING);\r
+ if ( fieldName.equals(P_ALLOW_OVERWRITE.label) ) continue;\r
+ File file = new File( value );\r
+ result.put(fieldName, file);\r
+ }\r
+ \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
+ \r
+}\r