--- /dev/null
+package org.simantics.export.core.impl;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+import java.util.List;\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.LabelReference;\r
+import org.simantics.databoard.binding.mutable.Variant;\r
+import org.simantics.databoard.forms.DataboardForm;\r
+import org.simantics.databoard.type.RecordType;\r
+import org.simantics.export.core.ExportContext;\r
+import org.simantics.export.core.error.ExportException;\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.FileUtils;\r
+\r
+/**\r
+ * There are two fields in this publisher:\r
+ * [ ] Overwrite file(s)\r
+ * [ ] Export Location\r
+ * \r
+ * @author toni.kalajainen@semantum.fi\r
+ */\r
+public class DirPublisher implements PublisherClass {\r
+\r
+ public static RecordType RT_DIR;\r
+\r
+ public static LabelReference P_ALLOW_OVERWRITE = new LabelReference("Overwrite file(s)");\r
+ public static LabelReference P_EXPORT_LOCATION = new LabelReference("Export location");\r
+ \r
+ static {\r
+ RT_DIR = new RecordType();\r
+ RT_DIR.addComponent(P_EXPORT_LOCATION.label, DataboardForm.directoryDialog());\r
+ RT_DIR.addComponent(P_ALLOW_OVERWRITE.label, Datatypes.BOOLEAN);\r
+ }\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
+ String path = ExporterUtils.getString( locationOptions, P_EXPORT_LOCATION );\r
+ if ( path == null ) throw new ExportException("Path option missing");\r
+ if ( canOverwrite == null ) throw new ExportException("CanOverwrite option missing");\r
+ \r
+ for ( Content content : contents ) {\r
+ if ( content.tmpFile == null ) {\r
+ throw new ExportException("Internal error, tmpFile was null");\r
+ }\r
+\r
+ File file = new File( path, content.filename );\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
+ if ( !content.tmpFile.exists() ) {\r
+ throw new ExportException("temporary file "+content.tmpFile.getAbsolutePath()+" did not exist?");\r
+ }\r
+ if ( !content.tmpFile.renameTo(file) ) {\r
+ // File.renameTo is not guaranteed to work between file systems.\r
+ // In that case, move by copying and deleting\r
+ try {\r
+ FileUtils.copyFile(content.tmpFile, file);\r
+ if (!content.tmpFile.delete()) {\r
+ throw new IOException("Failed to delete " + content.tmpFile.getAbsolutePath() + " after copying it");\r
+ }\r
+ } catch (IOException e) {\r
+ throw new ExportException("Failed to move temporary file "+content.tmpFile.getAbsolutePath()+" to "+file.getAbsolutePath(), e);\r
+ }\r
+ }\r
+ if ( content.tmpFile.exists() ) {\r
+ throw new ExportException("Failed to move temporary file "+content.tmpFile.getAbsolutePath()+" to "+file.getAbsolutePath());\r
+ }\r
+ }\r
+ \r
+ }\r
+\r
+ @Override\r
+ public List<String> validate(ExportContext ctx, List<Content> contents, Variant options, Variant locationOptions) throws ExportException {\r
+\r
+ List<String> result = new ArrayList<String>();\r
+ \r
+ Boolean canOverwrite = ExporterUtils.getBoolean(locationOptions, P_ALLOW_OVERWRITE);\r
+ String pathName = ExporterUtils.getString( locationOptions, P_EXPORT_LOCATION );\r
+ if ( pathName == null ) { result.add("Location option missing?"); return result; }\r
+ if ( canOverwrite == null ) { result.add("CanOverwrite option missing?"); return result; }\r
+ if ( pathName.isEmpty() ) { result.add("Location must be entered."); return result; }\r
+ File path = new File( pathName );\r
+ \r
+ if ( path.exists() && !path.isDirectory() ) {\r
+ result.add( pathName+" is not a directory.");\r
+ }\r
+ \r
+ // We allow non-existing path to pass validator\r
+ // The location is created with createLocation\r
+ \r
+ if ( !canOverwrite && path.exists() ) {\r
+ for ( Content content : contents ) {\r
+ File file = new File( path, content.filename );\r
+ if ( file.exists() ) {\r
+ result.add( file.getAbsolutePath()+ " already exists." );\r
+ }\r
+ } \r
+ }\r
+ \r
+ return result;\r
+ }\r
+ \r
+ @Override\r
+ public RecordType locationOptions(ExportContext ctx, List<Content> contents) throws ExportException {\r
+ return RT_DIR;\r
+ }\r
+ \r
+ @Override\r
+ public Variant createLocation(ExportContext ctx, Variant locationOptions) throws ExportException {\r
+ // Make Dirs to the path.\r
+ String pathName = ExporterUtils.getString( locationOptions, P_EXPORT_LOCATION );\r
+ if ( pathName == null ) throw new ExportException("Location option not found?");\r
+ File path = new File( pathName );\r
+ if ( path.exists() && !path.isDirectory()) throw new ExportException(pathName+" exists but is not a directory.");\r
+ if ( !path.mkdirs() ) throw new ExportException( "Failed to create "+pathName);\r
+ return locationOptions;\r
+ }\r
+ \r
+ @Override\r
+ public boolean locationExists(ExportContext ctx, Variant locationOptions) throws ExportException {\r
+ try {\r
+ RecordAccessor ra = Accessors.getAccessor(locationOptions); \r
+ String location = (String) ra.getValue(P_EXPORT_LOCATION, Bindings.STRING);\r
+ if ( location == null ) return false;\r
+ File path = new File( location );\r
+ return path.exists() && path.isDirectory();\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 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
+ ra.setValue(P_EXPORT_LOCATION, Bindings.STRING, "");\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
+ 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
+ String s = (String) ra.getValue(P_EXPORT_LOCATION, Bindings.STRING);\r
+ if ( s!=null ) {\r
+ contentScopeNode.put(P_EXPORT_LOCATION.tail().toString(), s);\r
+ workspaceScopeNode.put(P_EXPORT_LOCATION.tail().toString(), s);\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
+ Boolean b = ExporterUtils.getPrefBoolean( contentScopePrefs, workspaceScopePrefs, P_ALLOW_OVERWRITE.tail().toString() );\r
+ if ( b!=null ) ra.setValue(P_ALLOW_OVERWRITE, Bindings.BOOLEAN, b);\r
+ \r
+ String s = ExporterUtils.getPrefString( contentScopePrefs, workspaceScopePrefs, P_EXPORT_LOCATION.tail().toString() );\r
+ if ( s!=null ) ra.setValue(P_EXPORT_LOCATION, Bindings.STRING, s);\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