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