From b396fba04342d5cb416e412692f2d5ca9358edc8 Mon Sep 17 00:00:00 2001 From: Alan Orth Date: Thu, 6 Oct 2022 14:27:51 +0300 Subject: [PATCH] src: format Java files with google-java-format Using AOSP format so we get four spaces instead of two. --- .../ctasks/CGSpaceCountriesVocabulary.java | 10 +- .../cgspace/ctasks/CountriesVocabulary.java | 43 +-- .../cgspace/ctasks/CountryCodeTagger.java | 109 +++++--- .../ctasks/ISO3166CountriesVocabulary.java | 20 +- .../cgspace/scripts/FixJpgJpgThumbnails.java | 247 ++++++++++-------- .../scripts/FixLowQualityThumbnails.java | 18 +- 6 files changed, 252 insertions(+), 195 deletions(-) diff --git a/src/main/java/io/github/ilri/cgspace/ctasks/CGSpaceCountriesVocabulary.java b/src/main/java/io/github/ilri/cgspace/ctasks/CGSpaceCountriesVocabulary.java index c1cbec5..517dbd1 100644 --- a/src/main/java/io/github/ilri/cgspace/ctasks/CGSpaceCountriesVocabulary.java +++ b/src/main/java/io/github/ilri/cgspace/ctasks/CGSpaceCountriesVocabulary.java @@ -1,8 +1,8 @@ /* -* Copyright (C) 2020 Alan Orth -* -* SPDX-License-Identifier: GPL-3.0-or-later -*/ + * Copyright (C) 2020 Alan Orth + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ package io.github.ilri.cgspace.ctasks; @@ -10,4 +10,4 @@ import java.util.List; public class CGSpaceCountriesVocabulary extends CountriesVocabulary { List countries; -} \ No newline at end of file +} diff --git a/src/main/java/io/github/ilri/cgspace/ctasks/CountriesVocabulary.java b/src/main/java/io/github/ilri/cgspace/ctasks/CountriesVocabulary.java index 32590f9..6130c0f 100644 --- a/src/main/java/io/github/ilri/cgspace/ctasks/CountriesVocabulary.java +++ b/src/main/java/io/github/ilri/cgspace/ctasks/CountriesVocabulary.java @@ -1,8 +1,8 @@ /* -* Copyright (C) 2020 Alan Orth -* -* SPDX-License-Identifier: GPL-3.0-or-later -*/ + * Copyright (C) 2020 Alan Orth + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ package io.github.ilri.cgspace.ctasks; @@ -11,26 +11,29 @@ import javax.annotation.Nullable; public class CountriesVocabulary { class Country { - private String name; //required - private String common_name; //optional - private String official_name; //optional - private String cgspace_name; //optional - private String numeric; //required Hmmmm need to cast this... - private String alpha_2; //required - private String alpha_3; //required + private String name; // required + private String common_name; // optional + private String official_name; // optional + private String cgspace_name; // optional + private String numeric; // required Hmmmm need to cast this... + private String alpha_2; // required + private String alpha_3; // required - public Country(String name, - @Nullable String common_name, - @Nullable String official_name, - @Nullable String cgspace_name, - String numeric, - String alpha_2, - String alpha_3) { + public Country( + String name, + @Nullable String common_name, + @Nullable String official_name, + @Nullable String cgspace_name, + String numeric, + String alpha_2, + String alpha_3) { this.name = name; this.common_name = common_name; this.official_name = official_name; this.cgspace_name = cgspace_name; - this.numeric = numeric; // fuuuuu this is a string and we can't cast to Integer because some values are zeropadded like "004" + this.numeric = + numeric; // fuuuuu this is a string and we can't cast to Integer because some + // values are zeropadded like "004" this.alpha_2 = alpha_2; this.alpha_3 = alpha_3; } @@ -63,4 +66,4 @@ public class CountriesVocabulary { return cgspace_name; } } -} \ No newline at end of file +} diff --git a/src/main/java/io/github/ilri/cgspace/ctasks/CountryCodeTagger.java b/src/main/java/io/github/ilri/cgspace/ctasks/CountryCodeTagger.java index e6ed005..d5b0173 100644 --- a/src/main/java/io/github/ilri/cgspace/ctasks/CountryCodeTagger.java +++ b/src/main/java/io/github/ilri/cgspace/ctasks/CountryCodeTagger.java @@ -1,17 +1,12 @@ /* -* Copyright (C) 2020 Alan Orth -* -* SPDX-License-Identifier: GPL-3.0-or-later -*/ + * Copyright (C) 2020 Alan Orth + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ package io.github.ilri.cgspace.ctasks; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; +import com.google.gson.Gson; import org.apache.log4j.Logger; import org.dspace.authorize.AuthorizeException; @@ -22,13 +17,18 @@ import org.dspace.core.Constants; import org.dspace.curate.AbstractCurationTask; import org.dspace.curate.Curator; -import com.google.gson.Gson; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; -public class CountryCodeTagger extends AbstractCurationTask -{ +public class CountryCodeTagger extends AbstractCurationTask { public class CountryCodeTaggerConfig { private final String isocodesJsonPath = "/io/github/ilri/cgspace/ctasks/iso_3166-1.json"; - private final String cgspaceCountriesJsonPath = "/io/github/ilri/cgspace/ctasks/cgspace-countries.json"; + private final String cgspaceCountriesJsonPath = + "/io/github/ilri/cgspace/ctasks/cgspace-countries.json"; private final String iso3166Field = taskProperty("iso3166.field"); private final String iso3166Alpha2Field = taskProperty("iso3166-alpha2.field"); private final boolean forceupdate = taskBooleanProperty("forceupdate", false); @@ -58,17 +58,15 @@ public class CountryCodeTagger extends AbstractCurationTask } @Override - public int perform(DSpaceObject dso) throws IOException - { + public int perform(DSpaceObject dso) throws IOException { // gotta define this here so we can access it after the if context... CountryCodeTaggerResult alpha2Result = new CountryCodeTaggerResult(); - if (dso.getType() == Constants.ITEM) - { + if (dso.getType() == Constants.ITEM) { // Load configuration CountryCodeTaggerConfig config = new CountryCodeTaggerConfig(); - Item item = (Item)dso; + Item item = (Item) dso; try { alpha2Result = performAlpha2(item, config); @@ -78,16 +76,18 @@ public class CountryCodeTagger extends AbstractCurationTask setResult(alpha2Result.getResult()); report(alpha2Result.getResult()); - } + } - return alpha2Result.getStatus(); + return alpha2Result.getStatus(); } - public CountryCodeTaggerResult performAlpha2(Item item, CountryCodeTaggerConfig config) throws IOException, SQLException { + public CountryCodeTaggerResult performAlpha2(Item item, CountryCodeTaggerConfig config) + throws IOException, SQLException { CountryCodeTaggerResult alpha2Result = new CountryCodeTaggerResult(); String itemHandle = item.getHandle(); - List itemCountries = itemService.getMetadataByMetadataString(item, config.iso3166Field); + List itemCountries = + itemService.getMetadataByMetadataString(item, config.iso3166Field); // skip items that don't have country metadata if (itemCountries.size() == 0) { @@ -96,36 +96,60 @@ public class CountryCodeTagger extends AbstractCurationTask } else { Gson gson = new Gson(); - // TODO: convert to try: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html - BufferedReader reader = new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream(config.isocodesJsonPath))); - ISO3166CountriesVocabulary isocodesCountriesJson = gson.fromJson(reader, ISO3166CountriesVocabulary.class); + // TODO: convert to try: + // https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html + BufferedReader reader = + new BufferedReader( + new InputStreamReader( + this.getClass().getResourceAsStream(config.isocodesJsonPath))); + ISO3166CountriesVocabulary isocodesCountriesJson = + gson.fromJson(reader, ISO3166CountriesVocabulary.class); reader.close(); - reader = new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream(config.cgspaceCountriesJsonPath))); - CGSpaceCountriesVocabulary cgspaceCountriesJson = gson.fromJson(reader, CGSpaceCountriesVocabulary.class); + reader = + new BufferedReader( + new InputStreamReader( + this.getClass() + .getResourceAsStream(config.cgspaceCountriesJsonPath))); + CGSpaceCountriesVocabulary cgspaceCountriesJson = + gson.fromJson(reader, CGSpaceCountriesVocabulary.class); reader.close(); - // split the alpha2 country code field into schema, element, and qualifier so we can use it with item.addMetadata() + // split the alpha2 country code field into schema, element, and qualifier so we can use + // it with item.addMetadata() String[] iso3166Alpha2FieldParts = config.iso3166Alpha2Field.split("\\."); if (config.forceupdate) { - itemService.clearMetadata(Curator.curationContext(), item, iso3166Alpha2FieldParts[0], iso3166Alpha2FieldParts[1], iso3166Alpha2FieldParts[2], Item.ANY); + itemService.clearMetadata( + Curator.curationContext(), + item, + iso3166Alpha2FieldParts[0], + iso3166Alpha2FieldParts[1], + iso3166Alpha2FieldParts[2], + Item.ANY); } // check the item's country codes, if any - List itemAlpha2CountryCodes = itemService.getMetadataByMetadataString(item, config.iso3166Alpha2Field); + List itemAlpha2CountryCodes = + itemService.getMetadataByMetadataString(item, config.iso3166Alpha2Field); if (itemAlpha2CountryCodes.size() == 0) { List newAlpha2Codes = new ArrayList(); for (MetadataValue itemCountry : itemCountries) { - //check ISO 3166-1 countries + // check ISO 3166-1 countries for (CountriesVocabulary.Country country : isocodesCountriesJson.countries) { - if (itemCountry.getValue().equalsIgnoreCase(country.getName()) || itemCountry.getValue().equalsIgnoreCase(country.get_official_name()) || itemCountry.getValue().equalsIgnoreCase(country.get_common_name())) { + if (itemCountry.getValue().equalsIgnoreCase(country.getName()) + || itemCountry + .getValue() + .equalsIgnoreCase(country.get_official_name()) + || itemCountry + .getValue() + .equalsIgnoreCase(country.get_common_name())) { newAlpha2Codes.add(country.getAlpha_2()); } } - //check CGSpace countries + // check CGSpace countries for (CountriesVocabulary.Country country : cgspaceCountriesJson.countries) { if (itemCountry.getValue().equalsIgnoreCase(country.getCgspace_name())) { newAlpha2Codes.add(country.getAlpha_2()); @@ -135,7 +159,14 @@ public class CountryCodeTagger extends AbstractCurationTask if (newAlpha2Codes.size() > 0) { try { - itemService.addMetadata(Curator.curationContext(), item, iso3166Alpha2FieldParts[0], iso3166Alpha2FieldParts[1], iso3166Alpha2FieldParts[2], "en_US", newAlpha2Codes); + itemService.addMetadata( + Curator.curationContext(), + item, + iso3166Alpha2FieldParts[0], + iso3166Alpha2FieldParts[1], + iso3166Alpha2FieldParts[2], + "en_US", + newAlpha2Codes); itemService.update(Curator.curationContext(), item); } catch (SQLException | AuthorizeException sqle) { config.log.debug(sqle.getMessage()); @@ -143,7 +174,11 @@ public class CountryCodeTagger extends AbstractCurationTask alpha2Result.setStatus(Curator.CURATE_ERROR); } - alpha2Result.setResult(itemHandle + ": added " + newAlpha2Codes.size() + " alpha2 country code(s)"); + alpha2Result.setResult( + itemHandle + + ": added " + + newAlpha2Codes.size() + + " alpha2 country code(s)"); } else { alpha2Result.setResult(itemHandle + ": no matching countries found"); } @@ -156,4 +191,4 @@ public class CountryCodeTagger extends AbstractCurationTask return alpha2Result; } -} \ No newline at end of file +} diff --git a/src/main/java/io/github/ilri/cgspace/ctasks/ISO3166CountriesVocabulary.java b/src/main/java/io/github/ilri/cgspace/ctasks/ISO3166CountriesVocabulary.java index d02159b..003b68b 100644 --- a/src/main/java/io/github/ilri/cgspace/ctasks/ISO3166CountriesVocabulary.java +++ b/src/main/java/io/github/ilri/cgspace/ctasks/ISO3166CountriesVocabulary.java @@ -1,16 +1,18 @@ /* -* Copyright (C) 2020 Alan Orth -* -* SPDX-License-Identifier: GPL-3.0-or-later -*/ + * Copyright (C) 2020 Alan Orth + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ package io.github.ilri.cgspace.ctasks; -import java.util.List; - import com.google.gson.annotations.SerializedName; +import java.util.List; + public class ISO3166CountriesVocabulary extends CountriesVocabulary { - // support reading iso_3166-1.json from Debian's iso-codes package using SerializedName since our class needs to match the JSON exactly - @SerializedName("3166-1") List countries; -} \ No newline at end of file + // support reading iso_3166-1.json from Debian's iso-codes package using SerializedName since + // our class needs to match the JSON exactly + @SerializedName("3166-1") + List countries; +} diff --git a/src/main/java/io/github/ilri/cgspace/scripts/FixJpgJpgThumbnails.java b/src/main/java/io/github/ilri/cgspace/scripts/FixJpgJpgThumbnails.java index 49f9bbd..7537815 100644 --- a/src/main/java/io/github/ilri/cgspace/scripts/FixJpgJpgThumbnails.java +++ b/src/main/java/io/github/ilri/cgspace/scripts/FixJpgJpgThumbnails.java @@ -1,16 +1,11 @@ /* -* Copyright (C) 2020 Alan Orth -* -* SPDX-License-Identifier: GPL-3.0-or-later -*/ + * Copyright (C) 2020 Alan Orth + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ package io.github.ilri.cgspace.scripts; -import java.io.IOException; -import java.sql.SQLException; -import java.util.Iterator; -import java.util.List; - import org.apache.commons.lang.StringUtils; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Bitstream; @@ -28,6 +23,11 @@ import org.dspace.core.Context; import org.dspace.handle.factory.HandleServiceFactory; import org.dspace.handle.service.HandleService; +import java.io.IOException; +import java.sql.SQLException; +import java.util.Iterator; +import java.util.List; + /** * @author Andrea Schweer schweer@waikato.ac.nz for the LCoNZ Institutional Research Repositories * @author Alan Orth for the International Livestock Research Institute @@ -35,122 +35,139 @@ import org.dspace.handle.service.HandleService; * @since 5.1 */ public class FixJpgJpgThumbnails { - //note: static members belong to the class itself, not any one instance - public static ItemService itemService = ContentServiceFactory.getInstance().getItemService(); - public static HandleService handleService = HandleServiceFactory.getInstance().getHandleService(); - public static BundleService bundleService = ContentServiceFactory.getInstance().getBundleService(); + // note: static members belong to the class itself, not any one instance + public static ItemService itemService = ContentServiceFactory.getInstance().getItemService(); + public static HandleService handleService = + HandleServiceFactory.getInstance().getHandleService(); + public static BundleService bundleService = + ContentServiceFactory.getInstance().getBundleService(); - public static void main(String[] args) { - String parentHandle = null; - if (args.length >= 1) { - parentHandle = args[0]; - } + public static void main(String[] args) { + String parentHandle = null; + if (args.length >= 1) { + parentHandle = args[0]; + } - Context context = null; - try { - context = new Context(); - context.turnOffAuthorisationSystem(); + Context context = null; + try { + context = new Context(); + context.turnOffAuthorisationSystem(); - if (StringUtils.isBlank(parentHandle)) { - process(context, itemService.findAll(context)); - } else { - DSpaceObject parent = handleService.resolveToObject(context, parentHandle); - if (parent != null) { - switch (parent.getType()) { - case Constants.COLLECTION: - process(context, itemService.findByCollection(context, (Collection) parent)); - break; - case Constants.COMMUNITY: - List collections = ((Community) parent).getCollections(); - for (Collection collection : collections) { - process(context, itemService.findAllByCollection(context, collection)); - } - break; - case Constants.SITE: - process(context, itemService.findAll(context)); - break; - case Constants.ITEM: - processItem(context, (Item) parent); - context.commit(); - break; - } - } - } - } catch (SQLException | AuthorizeException | IOException e) { - e.printStackTrace(System.err); - } finally { - if (context != null && context.isValid()) { - context.abort(); - } - } - } + if (StringUtils.isBlank(parentHandle)) { + process(context, itemService.findAll(context)); + } else { + DSpaceObject parent = handleService.resolveToObject(context, parentHandle); + if (parent != null) { + switch (parent.getType()) { + case Constants.COLLECTION: + process( + context, + itemService.findByCollection(context, (Collection) parent)); + break; + case Constants.COMMUNITY: + List collections = ((Community) parent).getCollections(); + for (Collection collection : collections) { + process( + context, + itemService.findAllByCollection(context, collection)); + } + break; + case Constants.SITE: + process(context, itemService.findAll(context)); + break; + case Constants.ITEM: + processItem(context, (Item) parent); + context.commit(); + break; + } + } + } + } catch (SQLException | AuthorizeException | IOException e) { + e.printStackTrace(System.err); + } finally { + if (context != null && context.isValid()) { + context.abort(); + } + } + } - private static void process(Context context, Iterator items) throws SQLException, IOException, AuthorizeException { - while (items.hasNext()) { - Item item = items.next(); - processItem(context, item); - itemService.update(context, item); - } - } + private static void process(Context context, Iterator items) + throws SQLException, IOException, AuthorizeException { + while (items.hasNext()) { + Item item = items.next(); + processItem(context, item); + itemService.update(context, item); + } + } - private static void processItem(Context context, Item item) throws SQLException, AuthorizeException, IOException { - // Some bitstreams like Infographics and Maps are large JPEGs and put in the ORIGINAL bundle on purpose so we shouldn't - // swap them. - List itemTypes = itemService.getMetadataByMetadataString(item, "dcterms.type"); - for (MetadataValue itemType: itemTypes) { - if (itemType.getValue().equals("Infographic") || itemType.getValue().equals("Map")) { - System.out.println(item.getHandle() + ": item has an Infographic or Map, skipping."); - return; - } - } + private static void processItem(Context context, Item item) + throws SQLException, AuthorizeException, IOException { + // Some bitstreams like Infographics and Maps are large JPEGs and put in the ORIGINAL bundle + // on purpose so we shouldn't + // swap them. + List itemTypes = + itemService.getMetadataByMetadataString(item, "dcterms.type"); + for (MetadataValue itemType : itemTypes) { + if (itemType.getValue().equals("Infographic") || itemType.getValue().equals("Map")) { + System.out.println( + item.getHandle() + ": item has an Infographic or Map, skipping."); + return; + } + } - List thumbnailBundles = item.getBundles("THUMBNAIL"); - for (Bundle thumbnailBundle : thumbnailBundles) { - List thumbnailBundleBitstreams = thumbnailBundle.getBitstreams(); - for (Bitstream thumbnailBitstream : thumbnailBundleBitstreams) { - String thumbnailName = thumbnailBitstream.getName(); - String thumbnailDescription = thumbnailBitstream.getDescription(); + List thumbnailBundles = item.getBundles("THUMBNAIL"); + for (Bundle thumbnailBundle : thumbnailBundles) { + List thumbnailBundleBitstreams = thumbnailBundle.getBitstreams(); + for (Bitstream thumbnailBitstream : thumbnailBundleBitstreams) { + String thumbnailName = thumbnailBitstream.getName(); + String thumbnailDescription = thumbnailBitstream.getDescription(); - // There is no point continuing if the thumbnail's description is empty or null - if (StringUtils.isEmpty(thumbnailDescription)) { - continue; - } + // There is no point continuing if the thumbnail's description is empty or null + if (StringUtils.isEmpty(thumbnailDescription)) { + continue; + } - if (thumbnailName.toLowerCase().contains(".jpg.jpg")) { - List originalBundles = item.getBundles("ORIGINAL"); - for (Bundle originalBundle : originalBundles) { - List originalBundleBitstreams = originalBundle.getBitstreams(); + if (thumbnailName.toLowerCase().contains(".jpg.jpg")) { + List originalBundles = item.getBundles("ORIGINAL"); + for (Bundle originalBundle : originalBundles) { + List originalBundleBitstreams = originalBundle.getBitstreams(); - for (Bitstream originalBitstream : originalBundleBitstreams) { - String originalName = originalBitstream.getName(); + for (Bitstream originalBitstream : originalBundleBitstreams) { + String originalName = originalBitstream.getName(); - long originalBitstreamBytes = originalBitstream.getSize(); + long originalBitstreamBytes = originalBitstream.getSize(); - /* - - check if the original file name is the same as the thumbnail name minus the extra ".jpg" - - check if the thumbnail description indicates it was automatically generated - - check if the original bitstream is less than ~100KiB - - Note: in my tests there were 4022 items with ".jpg.jpg" thumbnails totaling 394549249 - bytes for an average of about 98KiB so ~100KiB seems like a good cut off - */ - if ( - originalName.equalsIgnoreCase(StringUtils.removeEndIgnoreCase(thumbnailName, ".jpg")) - && ("Generated Thumbnail".equals(thumbnailDescription) || "IM Thumbnail".equals(thumbnailDescription)) - && originalBitstreamBytes < 100000 - ) { - System.out.println(item.getHandle() + ": replacing " + thumbnailName + " with " + originalName); + /* + - check if the original file name is the same as the thumbnail name minus the extra ".jpg" + - check if the thumbnail description indicates it was automatically generated + - check if the original bitstream is less than ~100KiB + - Note: in my tests there were 4022 items with ".jpg.jpg" thumbnails totaling 394549249 + bytes for an average of about 98KiB so ~100KiB seems like a good cut off + */ + if (originalName.equalsIgnoreCase( + StringUtils.removeEndIgnoreCase(thumbnailName, ".jpg")) + && ("Generated Thumbnail".equals(thumbnailDescription) + || "IM Thumbnail".equals(thumbnailDescription)) + && originalBitstreamBytes < 100000) { + System.out.println( + item.getHandle() + + ": replacing " + + thumbnailName + + " with " + + originalName); - //add the original bitstream to the THUMBNAIL bundle - bundleService.addBitstream(context, thumbnailBundle, originalBitstream); - //remove the original bitstream from the ORIGINAL bundle - originalBundle.removeBitstream(originalBitstream); - //remove the JpgJpg bitstream from the THUMBNAIL bundle - thumbnailBundle.removeBitstream(thumbnailBitstream); - } - } - } - } - } - } - } + // add the original bitstream to the THUMBNAIL bundle + bundleService.addBitstream( + context, thumbnailBundle, originalBitstream); + // remove the original bitstream from the ORIGINAL bundle + originalBundle.removeBitstream(originalBitstream); + // remove the JpgJpg bitstream from the THUMBNAIL bundle + thumbnailBundle.removeBitstream(thumbnailBitstream); + } + } + } + } + } + } + } } diff --git a/src/main/java/io/github/ilri/cgspace/scripts/FixLowQualityThumbnails.java b/src/main/java/io/github/ilri/cgspace/scripts/FixLowQualityThumbnails.java index 89a87a9..80dc18d 100644 --- a/src/main/java/io/github/ilri/cgspace/scripts/FixLowQualityThumbnails.java +++ b/src/main/java/io/github/ilri/cgspace/scripts/FixLowQualityThumbnails.java @@ -1,16 +1,11 @@ /* -* Copyright (C) 2022 Alan Orth -* -* SPDX-License-Identifier: GPL-3.0-or-later -*/ + * Copyright (C) 2022 Alan Orth + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ package io.github.ilri.cgspace.scripts; -import java.io.IOException; -import java.sql.SQLException; -import java.util.Iterator; -import java.util.List; - import org.apache.commons.lang.StringUtils; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Bitstream; @@ -27,6 +22,11 @@ import org.dspace.core.Context; import org.dspace.handle.factory.HandleServiceFactory; import org.dspace.handle.service.HandleService; +import java.io.IOException; +import java.sql.SQLException; +import java.util.Iterator; +import java.util.List; + /** * Fix low-quality thumbnails in a DSpace repository. *