001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.io; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.io.File; 007import java.io.IOException; 008import java.util.List; 009 010import javax.swing.JOptionPane; 011 012import org.openstreetmap.josm.Main; 013import org.openstreetmap.josm.actions.ExtensionFileFilter; 014import org.openstreetmap.josm.gui.HelpAwareOptionPane; 015import org.openstreetmap.josm.gui.MapView.LayerChangeListener; 016import org.openstreetmap.josm.gui.Notification; 017import org.openstreetmap.josm.gui.layer.Layer; 018import org.openstreetmap.josm.gui.progress.ProgressMonitor; 019import org.openstreetmap.josm.gui.util.GuiHelper; 020 021public abstract class FileImporter implements Comparable<FileImporter>, LayerChangeListener { 022 023 public final ExtensionFileFilter filter; 024 025 private boolean enabled; 026 027 public FileImporter(ExtensionFileFilter filter) { 028 this.filter = filter; 029 this.enabled = true; 030 } 031 032 public boolean acceptFile(File pathname) { 033 return filter.acceptName(pathname.getName()); 034 } 035 036 /** 037 * A batch importer is a file importer that prefers to read multiple files at the same time. 038 */ 039 public boolean isBatchImporter() { 040 return false; 041 } 042 043 /** 044 * Needs to be implemented if isBatchImporter() returns false. 045 */ 046 public void importData(File file, ProgressMonitor progressMonitor) throws IOException, IllegalDataException { 047 throw new IOException(tr("Could not import ''{0}''.", file.getName())); 048 } 049 050 /** 051 * Needs to be implemented if isBatchImporter() returns true. 052 */ 053 public void importData(List<File> files, ProgressMonitor progressMonitor) throws IOException, IllegalDataException { 054 throw new IOException(tr("Could not import files.")); 055 } 056 057 /** 058 * Wrapper to give meaningful output if things go wrong. 059 * @return true if data import was successful 060 */ 061 public boolean importDataHandleExceptions(File f, ProgressMonitor progressMonitor) { 062 try { 063 Main.info("Open file: " + f.getAbsolutePath() + " (" + f.length() + " bytes)"); 064 importData(f, progressMonitor); 065 return true; 066 } catch (IllegalDataException e) { 067 Throwable cause = e.getCause(); 068 if (cause instanceof ImportCancelException) { 069 displayCancel(cause); 070 } else { 071 displayError(f, e); 072 } 073 return false; 074 } catch (Exception e) { 075 displayError(f, e); 076 return false; 077 } 078 } 079 080 private static void displayError(File f, Exception e) { 081 Main.error(e); 082 HelpAwareOptionPane.showMessageDialogInEDT( 083 Main.parent, 084 tr("<html>Could not read file ''{0}''.<br>Error is:<br>{1}</html>", f.getName(), e.getMessage()), 085 tr("Error"), 086 JOptionPane.ERROR_MESSAGE, null 087 ); 088 } 089 090 private static void displayCancel(final Throwable t) { 091 GuiHelper.runInEDTAndWait(new Runnable() { 092 @Override 093 public void run() { 094 Notification note = new Notification(t.getMessage()); 095 note.setIcon(JOptionPane.INFORMATION_MESSAGE); 096 note.setDuration(Notification.TIME_SHORT); 097 note.show(); 098 } 099 }); 100 } 101 102 public boolean importDataHandleExceptions(List<File> files, ProgressMonitor progressMonitor) { 103 try { 104 Main.info("Open "+files.size()+" files"); 105 importData(files, progressMonitor); 106 return true; 107 } catch (Exception e) { 108 Main.error(e); 109 HelpAwareOptionPane.showMessageDialogInEDT( 110 Main.parent, 111 tr("<html>Could not read files.<br>Error is:<br>{0}</html>", e.getMessage()), 112 tr("Error"), 113 JOptionPane.ERROR_MESSAGE, null 114 ); 115 return false; 116 } 117 } 118 119 /** 120 * If multiple files (with multiple file formats) are selected, 121 * they are opened in the order of their priorities. 122 * Highest priority comes first. 123 */ 124 public double getPriority() { 125 return 0; 126 } 127 128 @Override 129 public int compareTo(FileImporter other) { 130 return Double.compare(this.getPriority(), other.getPriority()); 131 } 132 133 /** 134 * Returns the enabled state of this {@code FileImporter}. When enabled, it is listed and usable in "File->Open" dialog. 135 * @return true if this {@code FileImporter} is enabled 136 * @since 5459 137 */ 138 public final boolean isEnabled() { 139 return enabled; 140 } 141 142 /** 143 * Sets the enabled state of the {@code FileImporter}. When enabled, it is listed and usable in "File->Open" dialog. 144 * @param enabled true to enable this {@code FileImporter}, false to disable it 145 * @since 5459 146 */ 147 public final void setEnabled(boolean enabled) { 148 this.enabled = enabled; 149 } 150 151 @Override 152 public void activeLayerChange(Layer oldLayer, Layer newLayer) { 153 // To be overriden by subclasses if their enabled state depends of the active layer nature 154 } 155 156 @Override 157 public void layerAdded(Layer newLayer) { 158 // To be overriden by subclasses if needed 159 } 160 161 @Override 162 public void layerRemoved(Layer oldLayer) { 163 // To be overriden by subclasses if needed 164 } 165}