source: josm/trunk/src/org/openstreetmap/josm/gui/io/importexport/ImageImporter.java@ 17553

Last change on this file since 17553 was 17553, checked in by Don-vip, 3 years ago

fix #20341 - fix Jenkins warnings and NPE caused by malformed images (patch by Bjoeni)

  • Property svn:eol-style set to native
File size: 4.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.io.importexport;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.File;
7import java.io.IOException;
8import java.util.ArrayList;
9import java.util.Arrays;
10import java.util.Collections;
11import java.util.HashSet;
12import java.util.List;
13import java.util.Set;
14import java.util.stream.Collectors;
15
16import javax.imageio.ImageIO;
17
18import org.openstreetmap.josm.actions.ExtensionFileFilter;
19import org.openstreetmap.josm.gui.layer.GpxLayer;
20import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer;
21import org.openstreetmap.josm.gui.progress.ProgressMonitor;
22import org.openstreetmap.josm.io.IllegalDataException;
23
24/**
25 * File importer allowing to import geotagged images
26 * @since 17548
27 */
28public class ImageImporter extends FileImporter {
29 private GpxLayer gpx;
30
31 /**
32 * The supported image file types on the current system
33 */
34 public static final List<String> SUPPORTED_FILE_TYPES = Collections
35 .unmodifiableList(Arrays.stream(ImageIO.getReaderFileSuffixes()).sorted().collect(Collectors.toList()));
36
37 /**
38 * The default file filter
39 */
40 public static final ExtensionFileFilter FILE_FILTER = getFileFilters(false);
41
42 /**
43 * An alternate file filter that also includes folders.
44 */
45 public static final ExtensionFileFilter FILE_FILTER_WITH_FOLDERS = getFileFilters(true);
46
47 private static ExtensionFileFilter getFileFilters(boolean folder) {
48 String typeStr = String.join(",", SUPPORTED_FILE_TYPES);
49 String humanStr = tr("Image Files") + " (*." + String.join(", *.", SUPPORTED_FILE_TYPES);
50 if (folder) {
51 humanStr += ", " + tr("folder");
52 }
53 humanStr += ")";
54
55 return new ExtensionFileFilter(typeStr, "jpg", humanStr);
56 }
57
58 /**
59 * Constructs a new {@code ImageImporter}.
60 */
61 public ImageImporter() {
62 this(false);
63 }
64
65 /**
66 * Constructs a new {@code ImageImporter} with folders selection, if wanted.
67 * @param includeFolders If true, includes folders in the file filter
68 */
69 public ImageImporter(boolean includeFolders) {
70 super(includeFolders ? FILE_FILTER_WITH_FOLDERS : FILE_FILTER);
71 }
72
73 /**
74 * Constructs a new {@code ImageImporter} for the given GPX layer. Folders selection is allowed.
75 * @param gpx The GPX layer
76 */
77 public ImageImporter(GpxLayer gpx) {
78 this(true);
79 this.gpx = gpx;
80 }
81
82 @Override
83 public boolean acceptFile(File pathname) {
84 return super.acceptFile(pathname) || pathname.isDirectory();
85 }
86
87 @Override
88 public void importData(List<File> sel, ProgressMonitor progressMonitor) throws IOException, IllegalDataException {
89 progressMonitor.beginTask(tr("Looking for image files"), 1);
90 try {
91 List<File> files = new ArrayList<>();
92 Set<String> visitedDirs = new HashSet<>();
93 addRecursiveFiles(files, visitedDirs, sel, progressMonitor.createSubTaskMonitor(1, true));
94
95 if (progressMonitor.isCanceled())
96 return;
97
98 if (files.isEmpty())
99 throw new IOException(tr("No image files found."));
100
101 GeoImageLayer.create(files, gpx);
102 } finally {
103 progressMonitor.finishTask();
104 }
105 }
106
107 static void addRecursiveFiles(List<File> files, Set<String> visitedDirs, List<File> sel, ProgressMonitor progressMonitor)
108 throws IOException {
109
110 if (progressMonitor.isCanceled())
111 return;
112
113 progressMonitor.beginTask(null, sel.size());
114 try {
115 for (File f : sel) {
116 if (f.isDirectory()) {
117 if (visitedDirs.add(f.getCanonicalPath())) { // Do not loop over symlinks
118 File[] dirFiles = f.listFiles(); // Can be null for some strange directories (like lost+found)
119 if (dirFiles != null) {
120 addRecursiveFiles(files, visitedDirs, Arrays.asList(dirFiles), progressMonitor.createSubTaskMonitor(1, true));
121 }
122 } else {
123 progressMonitor.worked(1);
124 }
125 } else {
126 if (FILE_FILTER.accept(f)) {
127 files.add(f);
128 }
129 progressMonitor.worked(1);
130 }
131 }
132 } finally {
133 progressMonitor.finishTask();
134 }
135 }
136
137 @Override
138 public boolean isBatchImporter() {
139 return true;
140 }
141
142 /**
143 * Needs to be the last, to avoid problems.
144 */
145 @Override
146 public double getPriority() {
147 return -1000;
148 }
149}
Note: See TracBrowser for help on using the repository browser.