From 1bf80cd48937758aabe96702ba782642fd250a62 Mon Sep 17 00:00:00 2001 From: F43nd1r Date: Wed, 20 Apr 2016 20:03:03 +0200 Subject: [PATCH 1/5] make ACRAConfiguration final --- .../collector/CrashReportDataFactory.java | 4 +- .../org/acra/collector/DropBoxCollector.java | 7 +- .../org/acra/collector/LogCatCollector.java | 3 +- .../collector/SharedPreferencesCollector.java | 3 +- .../org/acra/config/ACRAConfiguration.java | 776 ++---------------- .../org/acra/sender/SenderServiceStarter.java | 3 +- .../java/org/acra/util/ImmutableList.java | 160 ++++ src/main/java/org/acra/util/ImmutableMap.java | 129 +++ src/main/java/org/acra/util/ImmutableSet.java | 128 +++ .../util/UnmodifiableIteratorWrapper.java | 47 ++ .../util/UnmodifiableListIteratorWrapper.java | 78 ++ 11 files changed, 630 insertions(+), 708 deletions(-) create mode 100644 src/main/java/org/acra/util/ImmutableList.java create mode 100644 src/main/java/org/acra/util/ImmutableMap.java create mode 100644 src/main/java/org/acra/util/ImmutableSet.java create mode 100644 src/main/java/org/acra/util/UnmodifiableIteratorWrapper.java create mode 100644 src/main/java/org/acra/util/UnmodifiableListIteratorWrapper.java diff --git a/src/main/java/org/acra/collector/CrashReportDataFactory.java b/src/main/java/org/acra/collector/CrashReportDataFactory.java index 2811e8aae..03dc0b4e3 100644 --- a/src/main/java/org/acra/collector/CrashReportDataFactory.java +++ b/src/main/java/org/acra/collector/CrashReportDataFactory.java @@ -42,8 +42,8 @@ import java.util.GregorianCalendar; import java.util.HashMap; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; +import java.util.Set; import java.util.UUID; import static org.acra.ACRA.LOG_TAG; @@ -167,7 +167,7 @@ public String getCustomData(@NonNull String key) { public CrashReportData createCrashData(@NonNull ReportBuilder builder) { final CrashReportData crashReportData = new CrashReportData(); try { - final List crashReportFields = config.getReportFields(); + final Set crashReportFields = config.getReportFields(); // Make every entry here bullet proof and move any slightly dodgy // ones to the end. diff --git a/src/main/java/org/acra/collector/DropBoxCollector.java b/src/main/java/org/acra/collector/DropBoxCollector.java index 97be3b650..d4241c928 100644 --- a/src/main/java/org/acra/collector/DropBoxCollector.java +++ b/src/main/java/org/acra/collector/DropBoxCollector.java @@ -28,6 +28,7 @@ import java.util.Calendar; import java.util.List; import java.util.Locale; +import java.util.Set; import static org.acra.ACRA.LOG_TAG; @@ -72,9 +73,9 @@ public String read(@NonNull Context context, @NonNull ACRAConfiguration config) if (config.includeDropBoxSystemTags()) { tags.addAll(Arrays.asList(SYSTEM_TAGS)); } - final String[] additionalTags = config.additionalDropBoxTags(); - if (additionalTags.length > 0) { - tags.addAll(Arrays.asList(additionalTags)); + final Set additionalTags = config.additionalDropBoxTags(); + if (additionalTags.size() > 0) { + tags.addAll(additionalTags); } if (tags.isEmpty()) { diff --git a/src/main/java/org/acra/collector/LogCatCollector.java b/src/main/java/org/acra/collector/LogCatCollector.java index 234a38b89..a6ac71a4a 100644 --- a/src/main/java/org/acra/collector/LogCatCollector.java +++ b/src/main/java/org/acra/collector/LogCatCollector.java @@ -29,7 +29,6 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.LinkedList; import java.util.List; @@ -79,7 +78,7 @@ public String collectLogCat(@NonNull ACRAConfiguration config, @Nullable String // "-t n" argument has been introduced in FroYo (API level 8). For // devices with lower API level, we will have to emulate its job. final int tailCount; - final List logcatArgumentsList = new ArrayList(Arrays.asList(config.logcatArguments())); + final List logcatArgumentsList = new ArrayList(config.logcatArguments()); final int tailIndex = logcatArgumentsList.indexOf("-t"); if (tailIndex > -1 && tailIndex < logcatArgumentsList.size()) { diff --git a/src/main/java/org/acra/collector/SharedPreferencesCollector.java b/src/main/java/org/acra/collector/SharedPreferencesCollector.java index 727da0597..2189cefcc 100644 --- a/src/main/java/org/acra/collector/SharedPreferencesCollector.java +++ b/src/main/java/org/acra/collector/SharedPreferencesCollector.java @@ -25,6 +25,7 @@ import org.acra.config.ACRAConfiguration; import java.util.Map; +import java.util.Set; import java.util.TreeMap; import static org.acra.ACRA.LOG_TAG; @@ -62,7 +63,7 @@ public String collect() { sharedPrefs.put("default", PreferenceManager.getDefaultSharedPreferences(context)); // Add in any additional SharedPreferences - final String[] sharedPrefIds = config.additionalSharedPreferences(); + final Set sharedPrefIds = config.additionalSharedPreferences(); for (final String sharedPrefId : sharedPrefIds) { sharedPrefs.put(sharedPrefId, context.getSharedPreferences(sharedPrefId, Context.MODE_PRIVATE)); } diff --git a/src/main/java/org/acra/config/ACRAConfiguration.java b/src/main/java/org/acra/config/ACRAConfiguration.java index 59d06ce88..95a950a78 100644 --- a/src/main/java/org/acra/config/ACRAConfiguration.java +++ b/src/main/java/org/acra/config/ACRAConfiguration.java @@ -15,7 +15,6 @@ */ package org.acra.config; -import android.os.Build; import android.support.annotation.DrawableRes; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -23,120 +22,98 @@ import android.support.annotation.StringRes; import android.support.annotation.StyleRes; -import org.acra.ACRA; import org.acra.ACRAConstants; import org.acra.ReportField; import org.acra.ReportingInteractionMode; -import org.acra.annotation.ReportsCrashes; import org.acra.builder.ReportPrimer; import org.acra.dialog.BaseCrashReportDialog; import org.acra.dialog.CrashReportDialog; import org.acra.security.KeyStoreFactory; -import org.acra.sender.HttpSender; import org.acra.sender.HttpSender.Method; import org.acra.sender.HttpSender.Type; import org.acra.sender.ReportSenderFactory; +import org.acra.util.ImmutableMap; +import org.acra.util.ImmutableSet; import java.io.Serializable; -import java.lang.annotation.Annotation; -import java.lang.reflect.Array; -import java.security.KeyStore; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.acra.ACRA.LOG_TAG; /** * Represents the configuration that ACRA will use when handling crash reports. * - * ACRAConfiguration should be considered immutable. To that end, as of 4.8.1 - * all of the set methods have been deprecated. - * * Use {@link ConfigurationBuilder} to programmatically construct an ACRAConfiguration. */ @SuppressWarnings("unused") public final class ACRAConfiguration implements Serializable { - @Nullable - private final Class annotationType; - - // TODO Make all of these attributes final in ACRA 4.9 or 5.0 - // consider using immutable Collections for Arrays and Collections, so this can be truly final - private String[] additionalDropBoxTags; - private String[] additionalSharedPreferences; - private int connectionTimeout; - private Set reportContent; - private boolean deleteUnapprovedReportsOnApplicationStart; - private boolean deleteOldUnsentReportsOnApplicationStart; - private int dropboxCollectionMinutes; - private boolean forceCloseDialogAfterToast; - private String formUri; - private String formUriBasicAuthLogin; - private String formUriBasicAuthPassword; - private boolean includeDropBoxSystemTags; - - private String[] logcatArguments; - private String mailTo; - private ReportingInteractionMode reportingInteractionMode; - private Class reportDialogClass; - private Class reportPrimerClass; + private final ImmutableSet additionalDropBoxTags; + private final ImmutableSet additionalSharedPreferences; + private final int connectionTimeout; + private final ImmutableSet reportContent; + private final boolean deleteUnapprovedReportsOnApplicationStart; + private final boolean deleteOldUnsentReportsOnApplicationStart; + private final int dropboxCollectionMinutes; + private final boolean forceCloseDialogAfterToast; + private final String formUri; + private final String formUriBasicAuthLogin; + private final String formUriBasicAuthPassword; + private final boolean includeDropBoxSystemTags; + + private final ImmutableSet logcatArguments; + private final String mailTo; + private final ReportingInteractionMode reportingInteractionMode; + private final Class reportDialogClass; + private final Class reportPrimerClass; @StringRes - private int resDialogPositiveButtonText; + private final int resDialogPositiveButtonText; @StringRes - private int resDialogNegativeButtonText; + private final int resDialogNegativeButtonText; @StringRes - private int resDialogCommentPrompt; + private final int resDialogCommentPrompt; @StringRes - private int resDialogEmailPrompt; + private final int resDialogEmailPrompt; @DrawableRes - private int resDialogIcon; + private final int resDialogIcon; @StringRes - private int resDialogOkToast; + private final int resDialogOkToast; @StringRes - private int resDialogText; + private final int resDialogText; @StringRes - private int resDialogTitle; + private final int resDialogTitle; @StyleRes - private int resDialogTheme; + private final int resDialogTheme; @DrawableRes - private int resNotifIcon; + private final int resNotifIcon; @StringRes - private int resNotifText; + private final int resNotifText; @StringRes - private int resNotifTickerText; + private final int resNotifTickerText; @StringRes - private int resNotifTitle; + private final int resNotifTitle; @StringRes - private int resToastText; - private int sharedPreferencesMode; - private String sharedPreferencesName; - private int socketTimeout; - private boolean logcatFilterByPid; - private boolean sendReportsInDevMode; - - private String[] excludeMatchingSharedPreferencesKeys; - private String[] excludeMatchingSettingsKeys; + private final int resToastText; + private final int sharedPreferencesMode; + private final String sharedPreferencesName; + private final int socketTimeout; + private final boolean logcatFilterByPid; + private final boolean sendReportsInDevMode; + + private final ImmutableSet excludeMatchingSharedPreferencesKeys; + private final ImmutableSet excludeMatchingSettingsKeys; @Nullable - private Class buildConfigClass; - private String applicationLogFile; - private int applicationLogFileLines; - - private Method httpMethod; - private Type reportType; - private final Map httpHeaders = new HashMap(); - private Class keyStoreFactoryClass; - private Class[] reportSenderFactoryClasses; + private final Class buildConfigClass; + private final String applicationLogFile; + private final int applicationLogFileLines; + + private final Method httpMethod; + private final Type reportType; + private final ImmutableMap httpHeaders; + private final Class keyStoreFactoryClass; + private final ImmutableSet> reportSenderFactoryClasses; @RawRes - private int resCertificate; - private String certificatePath; - private String certificateType; + private final int resCertificate; + private final String certificatePath; + private final String certificateType; /** * @param builder ConfigurationBuilder with which to initialise this {@link ACRAConfiguration}. @@ -147,12 +124,10 @@ public final class ACRAConfiguration implements Serializable { throw new NullPointerException("A ConfigurationBuilder must be supplied to ACRAConfiguration"); } - annotationType = builder.annotationType; - - additionalDropBoxTags = copyArray(builder.additionalDropBoxTags()); - additionalSharedPreferences = copyArray(builder.additionalSharedPreferences()); + additionalDropBoxTags = new ImmutableSet(builder.additionalDropBoxTags()); + additionalSharedPreferences = new ImmutableSet(builder.additionalSharedPreferences()); connectionTimeout = builder.connectionTimeout(); - reportContent = new HashSet(builder.reportContent()); + reportContent = new ImmutableSet(builder.reportContent()); deleteUnapprovedReportsOnApplicationStart = builder.deleteUnapprovedReportsOnApplicationStart(); deleteOldUnsentReportsOnApplicationStart = builder.deleteOldUnsentReportsOnApplicationStart(); dropboxCollectionMinutes = builder.dropboxCollectionMinutes(); @@ -161,7 +136,7 @@ public final class ACRAConfiguration implements Serializable { formUriBasicAuthLogin = builder.formUriBasicAuthLogin(); formUriBasicAuthPassword = builder.formUriBasicAuthPassword(); includeDropBoxSystemTags = builder.includeDropBoxSystemTags(); - logcatArguments = copyArray(builder.logcatArguments()); + logcatArguments = new ImmutableSet(builder.logcatArguments()); mailTo = builder.mailTo(); reportingInteractionMode = builder.reportingInteractionMode(); resDialogIcon = builder.resDialogIcon(); @@ -183,42 +158,23 @@ public final class ACRAConfiguration implements Serializable { socketTimeout = builder.socketTimeout(); logcatFilterByPid = builder.logcatFilterByPid(); sendReportsInDevMode = builder.sendReportsInDevMode(); - excludeMatchingSharedPreferencesKeys = copyArray(builder.excludeMatchingSharedPreferencesKeys()); - excludeMatchingSettingsKeys = copyArray(builder.excludeMatchingSettingsKeys()); + excludeMatchingSharedPreferencesKeys = new ImmutableSet(builder.excludeMatchingSharedPreferencesKeys()); + excludeMatchingSettingsKeys = new ImmutableSet(builder.excludeMatchingSettingsKeys()); buildConfigClass = builder.buildConfigClass(); applicationLogFile = builder.applicationLogFile(); applicationLogFileLines = builder.applicationLogFileLines(); reportDialogClass = builder.reportDialogClass(); reportPrimerClass = builder.reportPrimerClass(); httpMethod = builder.httpMethod(); - httpHeaders.putAll(builder.httpHeaders()); + httpHeaders = new ImmutableMap(builder.httpHeaders()); reportType = builder.reportType(); - reportSenderFactoryClasses = copyArray(builder.reportSenderFactoryClasses()); + reportSenderFactoryClasses = new ImmutableSet>(builder.reportSenderFactoryClasses()); keyStoreFactoryClass = builder.keyStoreFactoryClass(); resCertificate = builder.resCertificate(); certificatePath = builder.certificatePath(); certificateType = builder.certificateType(); } - - /** - * Set custom HTTP headers to be sent by the provided {@link HttpSender}. - * This should be used also by third party senders. - * - * @param headers - * A map associating HTTP header names to their values. - * @return The updated ACRA configuration - * - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - @SuppressWarnings( "unused" ) - public ACRAConfiguration setHttpHeaders(@NonNull Map headers) { - this.httpHeaders.clear(); - this.httpHeaders.putAll(headers); - return this; - } - /** * Retrieve HTTP headers defined by the application developer. These should * be added to requests sent by any third-party sender (over HTTP of @@ -227,597 +183,32 @@ public ACRAConfiguration setHttpHeaders(@NonNull Map headers) { * @return A map associating http header names to their values. */ @NonNull - public Map getHttpHeaders() { - return Collections.unmodifiableMap(httpHeaders); + public ImmutableMap getHttpHeaders() { + return httpHeaders; } /** * @return List of ReportField that ACRA will provide to the server. */ @NonNull - public List getReportFields() { - return new ArrayList(reportContent); - } - - /** - * @param additionalDropboxTags the additionalDropboxTags to set - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - @SuppressWarnings( "unused" ) - public ACRAConfiguration setAdditionalDropboxTags(@NonNull String[] additionalDropboxTags) { - this.additionalDropBoxTags = copyArray(additionalDropboxTags); - return this; - } - - /** - * @param additionalSharedPreferences the additionalSharedPreferences to set - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - @SuppressWarnings( "unused" ) - public ACRAConfiguration setAdditionalSharedPreferences(@NonNull String[] additionalSharedPreferences) { - this.additionalSharedPreferences = copyArray(additionalSharedPreferences); - return this; - } - - /** - * @param connectionTimeout the connectionTimeout to set - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setConnectionTimeout(int connectionTimeout) { - this.connectionTimeout = connectionTimeout; - return this; - } - - /** - * @param customReportContent the customReportContent to set - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - @SuppressWarnings( "unused" ) - public ACRAConfiguration setCustomReportContent(@NonNull ReportField[] customReportContent) { - this.reportContent = new HashSet(Arrays.asList(customReportContent)); - return this; - } - - /** - * @param deleteUnapprovedReportsOnApplicationStart the deleteUnapprovedReportsOnApplicationStart to set - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setDeleteUnapprovedReportsOnApplicationStart(boolean deleteUnapprovedReportsOnApplicationStart) { - this.deleteUnapprovedReportsOnApplicationStart = deleteUnapprovedReportsOnApplicationStart; - return this; - } - - /** - * @param deleteOldUnsentReportsOnApplicationStart When to delete old (unsent) reports on startup. - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setDeleteOldUnsentReportsOnApplicationStart(boolean deleteOldUnsentReportsOnApplicationStart) { - this.deleteOldUnsentReportsOnApplicationStart = deleteOldUnsentReportsOnApplicationStart; - return this; - } - - /** - * @param dropboxCollectionMinutes the dropboxCollectionMinutes to set - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setDropboxCollectionMinutes(int dropboxCollectionMinutes) { - this.dropboxCollectionMinutes = dropboxCollectionMinutes; - return this; - } - - /** - * @param forceCloseDialogAfterToast the forceCloseDialogAfterToast to set - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setForceCloseDialogAfterToast(boolean forceCloseDialogAfterToast) { - this.forceCloseDialogAfterToast = forceCloseDialogAfterToast; - return this; - } - - /** - * Modify the formUri of your backend server receiving reports. - * - * @param formUri formUri to set. - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setFormUri(@Nullable String formUri) { - this.formUri = formUri; - return this; - } - - /** - * @param formUriBasicAuthLogin the formUriBasicAuthLogin to set - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setFormUriBasicAuthLogin(@Nullable String formUriBasicAuthLogin) { - this.formUriBasicAuthLogin = formUriBasicAuthLogin; - return this; - } - - /** - * @param formUriBasicAuthPassword the formUriBasicAuthPassword to set - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setFormUriBasicAuthPassword(@Nullable String formUriBasicAuthPassword) { - this.formUriBasicAuthPassword = formUriBasicAuthPassword; - return this; - } - - /** - * @param includeDropboxSystemTags the includeDropboxSystemTags to set - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setIncludeDropboxSystemTags(boolean includeDropboxSystemTags) { - this.includeDropBoxSystemTags = includeDropboxSystemTags; - return this; - } - - /** - * @param logcatArguments the logcatArguments to set - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setLogcatArguments(@NonNull String[] logcatArguments) { - this.logcatArguments = copyArray(logcatArguments); - return this; - } - - /** - * Modify the mailTo of the mail account receiving reports. - * - * @param mailTo mailTo to set. - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setMailTo(@Nullable String mailTo) { - this.mailTo = mailTo; - return this; - } - - /** - * Change the current {@link ReportingInteractionMode}. You must set - * required configuration items first. - * - * @param mode the new mode to set. - * @return The updated ACRA configuration - * @throws ACRAConfigurationException if a configuration item is missing for this mode. - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setMode(@NonNull ReportingInteractionMode mode) throws ACRAConfigurationException { - this.reportingInteractionMode = mode; - checkCrashResources(); - return this; - } - - /** - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setResDialogPositiveButtonText(@StringRes int resId) { - resDialogPositiveButtonText = resId; - return this; - } - - /** - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setResDialogNegativeButtonText(@StringRes int resId) { - resDialogNegativeButtonText = resId; - return this; - } - - /** - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setReportDialogClass(@NonNull Class reportDialogClass) { - this.reportDialogClass = reportDialogClass; - return this; - } - - /** - * Use this method if the id you wanted to give to - * {@link ReportsCrashes#resDialogCommentPrompt()} comes from an Android - * Library Project. - * - * @param resId The resource id, see - * {@link ReportsCrashes#resDialogCommentPrompt()} - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setResDialogCommentPrompt(@StringRes int resId) { - resDialogCommentPrompt = resId; - return this; - } - - /** - * Use this method if the id you wanted to give to - * {@link ReportsCrashes#resDialogEmailPrompt()} comes from an Android - * Library Project. - * - * @param resId The resource id, see - * {@link ReportsCrashes#resDialogEmailPrompt()} - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setResDialogEmailPrompt(@StringRes int resId) { - resDialogEmailPrompt = resId; - return this; - } - - /** - * Use this method if the id you wanted to give to - * {@link ReportsCrashes#resDialogIcon()} comes from an Android Library - * Project. - * - * @param resId The resource id, see {@link ReportsCrashes#resDialogIcon()} - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setResDialogIcon(@DrawableRes int resId) { - resDialogIcon = resId; - return this; - } - - /** - * Use this method BEFORE if the id you wanted to give to - * {@link ReportsCrashes#resDialogOkToast()} comes from an Android Library - * Project. - * - * @param resId The resource id, see {@link ReportsCrashes#resDialogOkToast()} - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setResDialogOkToast(@StringRes int resId) { - resDialogOkToast = resId; - return this; - } - - /** - * Use this method if the id you wanted to give to - * {@link ReportsCrashes#resDialogText()} comes from an Android Library - * Project. - * - * @param resId The resource id, see {@link ReportsCrashes#resDialogText()} - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setResDialogText(@StringRes int resId) { - resDialogText = resId; - return this; - } - - /** - * Use this method if the id you wanted to give to - * {@link ReportsCrashes#resDialogTitle()} comes from an Android Library - * Project. - * - * @param resId The resource id, see {@link ReportsCrashes#resDialogTitle()} - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setResDialogTitle(@StringRes int resId) { - resDialogTitle = resId; - return this; - } - - /** - * Use this method if the id you wanted to give to - * {@link ReportsCrashes#resNotifIcon()} comes from an Android Library - * Project. - * - * @param resId The resource id, see {@link ReportsCrashes#resNotifIcon()} - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setResNotifIcon(@DrawableRes int resId) { - resNotifIcon = resId; - return this; + public ImmutableSet getReportFields() { + return reportContent; } - /** - * Use this method if the id you wanted to give to - * {@link ReportsCrashes#resNotifText()} comes from an Android Library - * Project. - * - * @param resId The resource id, see {@link ReportsCrashes#resNotifText()} - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ @NonNull - public ACRAConfiguration setResNotifText(@StringRes int resId) { - resNotifText = resId; - return this; + public ImmutableSet additionalDropBoxTags() { + return additionalDropBoxTags; } - /** - * Use this method if the id you wanted to give to - * {@link ReportsCrashes#resNotifTickerText()} comes from an Android Library - * Project. - * - * @param resId The resource id, see - * {@link ReportsCrashes#resNotifTickerText()} - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ @NonNull - public ACRAConfiguration setResNotifTickerText(@StringRes int resId) { - resNotifTickerText = resId; - return this; - } - - /** - * Use this method if the id you wanted to give to - * {@link ReportsCrashes#resNotifTitle()} comes from an Android Library - * Project. - * - * @param resId The resource id, see {@link ReportsCrashes#resNotifTitle()} - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setResNotifTitle(@StringRes int resId) { - resNotifTitle = resId; - return this; - } - - /** - * Use this method if the id you wanted to give to - * {@link ReportsCrashes#resToastText()} comes from an Android Library - * Project. - * - * @param resId The resource id, see {@link ReportsCrashes#resToastText()} - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setResToastText(@StringRes int resId) { - resToastText = resId; - return this; - } - - /** - * @param sharedPreferenceMode the sharedPreferenceMode to set - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setSharedPreferenceMode(int sharedPreferenceMode) { - this.sharedPreferencesMode = sharedPreferenceMode; - return this; - } - - /** - * @param sharedPreferenceName the sharedPreferenceName to set - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setSharedPreferenceName(@NonNull String sharedPreferenceName) { - this.sharedPreferencesName = sharedPreferenceName; - return this; - } - - /** - * @param socketTimeout the socketTimeout to set - * @return The updated ACRA configuration - * - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setSocketTimeout(int socketTimeout) { - this.socketTimeout = socketTimeout; - return this; - } - - /** - * - * @param filterByPid - * true if you want to collect only logcat lines related to your - * application process. - * @return The updated ACRA configuration - * - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setLogcatFilterByPid(boolean filterByPid) { - logcatFilterByPid = filterByPid; - return this; - } - - /** - * @param sendReportsInDevMode - * false if you want to disable sending reports in development - * mode. Reports will be sent only on signed applications. - * @return The updated ACRA configuration - * - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setSendReportsInDevMode(boolean sendReportsInDevMode) { - this.sendReportsInDevMode = sendReportsInDevMode; - return this; - } - - /** - * @deprecated since 4.8.1 no replacement. Now that we are using the SenderService in a separate process it is always safe to send at shutdown. - */ - @NonNull - @SuppressWarnings( "unused" ) - public ACRAConfiguration setSendReportsAtShutdown(boolean sendReportsAtShutdown) { - return this; - } - - /** - * - * @param excludeMatchingSharedPreferencesKeys - * an array of Strings containing regexp defining - * SharedPreferences keys that should be excluded from the data - * collection. - * @return The updated ACRA configuration - * - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - @SuppressWarnings( "unused" ) - public ACRAConfiguration setExcludeMatchingSharedPreferencesKeys(@NonNull String[] excludeMatchingSharedPreferencesKeys) { - this.excludeMatchingSharedPreferencesKeys = copyArray(excludeMatchingSharedPreferencesKeys); - return this; - } - - /** - * @param excludeMatchingSettingsKeys - * an array of Strings containing regexp defining - * Settings.System, Settings.Secure and Settings.Global keys that - * should be excluded from the data collection. - * @return The updated ACRA configuration - * - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - @SuppressWarnings( "unused" ) - public ACRAConfiguration setExcludeMatchingSettingsKeys(@NonNull String[] excludeMatchingSettingsKeys) { - this.excludeMatchingSettingsKeys = copyArray(excludeMatchingSettingsKeys); - return this; - } - - /** - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setBuildConfigClass(@Nullable Class buildConfigClass) { - this.buildConfigClass = buildConfigClass; - return this; - } - - /** - * @param applicationLogFile The path and file name of your application log file, to be - * used with {@link ReportField#APPLICATION_LOG}. - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setApplicationLogFile(@NonNull String applicationLogFile) { - this.applicationLogFile = applicationLogFile; - return this; - } - - /** - * @param applicationLogFileLines The number of lines of your application log to be collected, - * to be used with {@link ReportField#APPLICATION_LOG} and - * {@link ReportsCrashes#applicationLogFile()}. - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setApplicationLogFileLines(int applicationLogFileLines) { - this.applicationLogFileLines = applicationLogFileLines; - return this; - } - - /** - * @param httpMethod The method to be used to send data to the server. - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setHttpMethod(@NonNull Method httpMethod) { - this.httpMethod = httpMethod; - return this; - } - - /** - * @param type The type of content encoding to be used to send data to the server. - * @return The updated ACRA configuration - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - @NonNull - public ACRAConfiguration setReportType(@NonNull Type type) { - reportType = type; - return this; - } - - /** - * @param keyStore Set this to the keystore that contains the trusted certificates - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - public void setKeyStore(@Nullable KeyStore keyStore) { - throw new UnsupportedOperationException("This method is not supported anymore"); - } - - /** - * @deprecated since 4.8.1 - configure using {@link ConfigurationBuilder} instead. ACRAConfiguration will become immutable in the near future. - */ - public void setReportSenderFactoryClasses(@NonNull Class[] reportSenderFactoryClasses) { - this.reportSenderFactoryClasses = copyArray(reportSenderFactoryClasses); - } - - @NonNull - public String[] additionalDropBoxTags() { - return copyArray(additionalDropBoxTags); - } - - @NonNull - public String[] additionalSharedPreferences() { - return copyArray(additionalSharedPreferences); - } - - /** - * @deprecated since 4.8.1 no replacement. - */ - @Nullable - public Class annotationType() { - return annotationType; // Why would this ever be needed? + public ImmutableSet additionalSharedPreferences() { + return additionalSharedPreferences; } public int connectionTimeout() { return connectionTimeout; } - /** - * @deprecated since 4.8.6 use {@link #getReportFields()} instead - * TODO remove with setters in 4.9 / 5.0 - */ - @NonNull - public ReportField[] customReportContent() { - return reportContent.toArray(new ReportField[reportContent.size()]); - } - public boolean deleteUnapprovedReportsOnApplicationStart() { return deleteUnapprovedReportsOnApplicationStart; } @@ -854,8 +245,8 @@ public boolean includeDropBoxSystemTags() { } @NonNull - public String[] logcatArguments() { - return copyArray(logcatArguments); + public ImmutableSet logcatArguments() { + return logcatArguments; } @Nullable @@ -960,13 +351,13 @@ public boolean sendReportsInDevMode() { } @NonNull - public String[] excludeMatchingSharedPreferencesKeys() { - return copyArray(excludeMatchingSharedPreferencesKeys); + public ImmutableSet excludeMatchingSharedPreferencesKeys() { + return excludeMatchingSharedPreferencesKeys; } @NonNull - public String[] excludeMatchingSettingsKeys() { - return copyArray(excludeMatchingSettingsKeys); + public ImmutableSet excludeMatchingSettingsKeys() { + return excludeMatchingSettingsKeys; } /** @@ -1008,8 +399,8 @@ public Type reportType() { } @NonNull - public Class[] reportSenderFactoryClasses() { - return copyArray(reportSenderFactoryClasses); + public ImmutableSet> reportSenderFactoryClasses() { + return reportSenderFactoryClasses; } @NonNull @@ -1063,15 +454,4 @@ public void checkCrashResources() throws ACRAConfigurationException { break; } } - - @NonNull - private static T[] copyArray(@NonNull T[] source) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { - return Arrays.copyOf(source, source.length); - } - //noinspection unchecked - T[] result = (T[]) Array.newInstance(source.getClass().getComponentType(), source.length); - System.arraycopy(source, 0, result, 0, source.length); - return result; - } } diff --git a/src/main/java/org/acra/sender/SenderServiceStarter.java b/src/main/java/org/acra/sender/SenderServiceStarter.java index 24b57136f..71ee6dd2f 100644 --- a/src/main/java/org/acra/sender/SenderServiceStarter.java +++ b/src/main/java/org/acra/sender/SenderServiceStarter.java @@ -8,7 +8,6 @@ import org.acra.config.ACRAConfiguration; import java.util.ArrayList; -import java.util.Arrays; import static org.acra.ACRA.LOG_TAG; @@ -37,7 +36,7 @@ public void startService(boolean onlySendSilentReports, boolean approveReportsFi intent.putExtra(SenderService.EXTRA_ONLY_SEND_SILENT_REPORTS, onlySendSilentReports); intent.putExtra(SenderService.EXTRA_APPROVE_REPORTS_FIRST, approveReportsFirst); - intent.putExtra(SenderService.EXTRA_REPORT_SENDER_FACTORIES, new ArrayList>(Arrays.asList(config.reportSenderFactoryClasses()))); + intent.putExtra(SenderService.EXTRA_REPORT_SENDER_FACTORIES, new ArrayList>(config.reportSenderFactoryClasses())); intent.putExtra(SenderService.EXTRA_ACRA_CONFIG, config); context.startService(intent); diff --git a/src/main/java/org/acra/util/ImmutableList.java b/src/main/java/org/acra/util/ImmutableList.java new file mode 100644 index 000000000..dc6302b36 --- /dev/null +++ b/src/main/java/org/acra/util/ImmutableList.java @@ -0,0 +1,160 @@ +/* + * Copyright 2016 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.acra.util; + +import android.support.annotation.NonNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +/** + * Naive (not optimized) implementation of an Immutable List + * + * @author F43nd1r + * @since 4.9.0 + */ +public final class ImmutableList implements List { + private List mList; + + public ImmutableList(Collection collection) { + this.mList = new ArrayList(collection); + } + + @Override + public void add(int location, E object) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean add(E object) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(int location, @NonNull Collection collection) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(@NonNull Collection collection) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean contains(Object object) { + return mList.contains(object); + } + + @Override + public boolean containsAll(@NonNull Collection collection) { + return mList.containsAll(collection); + } + + @Override + public E get(int location) { + return mList.get(location); + } + + @Override + public int indexOf(Object object) { + return mList.indexOf(object); + } + + @Override + public boolean isEmpty() { + return mList.isEmpty(); + } + + @NonNull + @Override + public Iterator iterator() { + return new UnmodifiableIteratorWrapper(mList.iterator()); + } + + @Override + public int lastIndexOf(Object object) { + return mList.lastIndexOf(object); + } + + @Override + public ListIterator listIterator() { + return new UnmodifiableListIteratorWrapper(mList.listIterator()); + } + + @NonNull + @Override + public ListIterator listIterator(int location) { + return new UnmodifiableListIteratorWrapper(mList.listIterator(location)); + } + + @Override + public E remove(int location) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean remove(Object object) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeAll(@NonNull Collection collection) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(@NonNull Collection collection) { + throw new UnsupportedOperationException(); + } + + @Override + public E set(int location, E object) { + throw new UnsupportedOperationException(); + } + + @Override + public int size() { + return mList.size(); + } + + @NonNull + @Override + public List subList(int start, int end) { + throw new UnsupportedOperationException(); + } + + @NonNull + @Override + public Object[] toArray() { + return mList.toArray(); + } + + @NonNull + @Override + public T[] toArray(@NonNull T[] array) { + //noinspection SuspiciousToArrayCall + return mList.toArray(array); + } + +} diff --git a/src/main/java/org/acra/util/ImmutableMap.java b/src/main/java/org/acra/util/ImmutableMap.java new file mode 100644 index 000000000..b74ce7301 --- /dev/null +++ b/src/main/java/org/acra/util/ImmutableMap.java @@ -0,0 +1,129 @@ +/* + * Copyright 2016 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.acra.util; + +import android.support.annotation.NonNull; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * Naive (not optimized) implementation of an Immutable Map + * + * @author F43nd1r + * @since 4.9.0 + */ +public class ImmutableMap implements Map { + private Map mMap; + + public ImmutableMap(Map map) { + this.mMap = new HashMap(map); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean containsKey(Object key) { + return mMap.containsKey(key); + } + + @Override + public boolean containsValue(Object value) { + return mMap.containsValue(value); + } + + @NonNull + @Override + public Set> entrySet() { + Set> original = mMap.entrySet(); + ImmutableSet.Builder> builder = new ImmutableSet.Builder>(); + for (Entry entry : original) { + builder.add(new ImmutableEntryWrapper(entry)); + } + return builder.build(); + } + + @Override + public V get(Object key) { + return mMap.get(key); + } + + @Override + public boolean isEmpty() { + return mMap.isEmpty(); + } + + @NonNull + @Override + public Set keySet() { + return new ImmutableSet(mMap.keySet()); + } + + @Override + public V put(K key, V value) { + throw new UnsupportedOperationException(); + } + + @Override + public void putAll(@NonNull Map map) { + throw new UnsupportedOperationException(); + } + + @Override + public V remove(Object object) { + throw new UnsupportedOperationException(); + } + + @Override + public int size() { + return mMap.size(); + } + + @NonNull + @Override + public Collection values() { + return new ImmutableList(mMap.values()); + } + + static class ImmutableEntryWrapper implements Map.Entry { + private final Map.Entry mEntry; + + ImmutableEntryWrapper(Entry mEntry) { + this.mEntry = mEntry; + } + + @Override + public K getKey() { + return mEntry.getKey(); + } + + @Override + public V getValue() { + return mEntry.getValue(); + } + + @Override + public V setValue(Object object) { + throw new UnsupportedOperationException(); + } + } + +} diff --git a/src/main/java/org/acra/util/ImmutableSet.java b/src/main/java/org/acra/util/ImmutableSet.java new file mode 100644 index 000000000..78a95a8f8 --- /dev/null +++ b/src/main/java/org/acra/util/ImmutableSet.java @@ -0,0 +1,128 @@ +/* + * Copyright 2016 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.acra.util; + +import android.support.annotation.NonNull; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * Naive (not optimized) implementation of an Immutable Set + * + * @author F43nd1r + * @since 4.9.0 + */ +public final class ImmutableSet implements Set { + private Set mSet; + + public ImmutableSet(E... elements) { + this(Arrays.asList(elements)); + } + + public ImmutableSet(Collection collection) { + this.mSet = new HashSet(collection); + } + + @Override + public boolean add(E object) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(@NonNull Collection collection) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean contains(Object object) { + return mSet.contains(object); + } + + @Override + public boolean containsAll(@NonNull Collection collection) { + return mSet.containsAll(collection); + } + + @Override + public boolean isEmpty() { + return mSet.isEmpty(); + } + + @NonNull + @Override + public Iterator iterator() { + return new UnmodifiableIteratorWrapper(mSet.iterator()); + } + + @Override + public boolean remove(Object object) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeAll(@NonNull Collection collection) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(@NonNull Collection collection) { + throw new UnsupportedOperationException(); + } + + @Override + public int size() { + return mSet.size(); + } + + @NonNull + @Override + public Object[] toArray() { + return mSet.toArray(); + } + + @NonNull + @Override + public T[] toArray(@NonNull T[] array) { + //noinspection SuspiciousToArrayCall + return mSet.toArray(array); + } + + public final static class Builder { + private final Set mSet; + + public Builder() { + mSet = new HashSet(); + } + + public void add(E element) { + mSet.add(element); + } + + public ImmutableSet build() { + return new ImmutableSet(mSet); + } + } + +} diff --git a/src/main/java/org/acra/util/UnmodifiableIteratorWrapper.java b/src/main/java/org/acra/util/UnmodifiableIteratorWrapper.java new file mode 100644 index 000000000..35ebd4b59 --- /dev/null +++ b/src/main/java/org/acra/util/UnmodifiableIteratorWrapper.java @@ -0,0 +1,47 @@ +/* + * Copyright 2016 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.acra.util; + +import java.util.Iterator; + +/** + * Wrapper around an Iterator which prevents modifications + * + * @author F43nd1r + * @since 4.9.0 + */ +class UnmodifiableIteratorWrapper implements Iterator { + private final Iterator mIterator; + + UnmodifiableIteratorWrapper(Iterator mIterator) { + this.mIterator = mIterator; + } + + @Override + public boolean hasNext() { + return mIterator.hasNext(); + } + + @Override + public E next() { + return mIterator.next(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/org/acra/util/UnmodifiableListIteratorWrapper.java b/src/main/java/org/acra/util/UnmodifiableListIteratorWrapper.java new file mode 100644 index 000000000..dae410657 --- /dev/null +++ b/src/main/java/org/acra/util/UnmodifiableListIteratorWrapper.java @@ -0,0 +1,78 @@ +/* + * Copyright 2016 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.acra.util; + +import java.util.ListIterator; + +/** + * Wrapper around a ListIterator which prevents modifications + * + * @author F43nd1r + * @since 4.9.0 + */ +class UnmodifiableListIteratorWrapper implements ListIterator { + private final ListIterator mIterator; + + UnmodifiableListIteratorWrapper(ListIterator mIterator) { + this.mIterator = mIterator; + } + + @Override + public void add(E object) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean hasNext() { + return mIterator.hasNext(); + } + + @Override + public boolean hasPrevious() { + return mIterator.hasPrevious(); + } + + @Override + public E next() { + return mIterator.next(); + } + + @Override + public int nextIndex() { + return mIterator.nextIndex(); + } + + @Override + public E previous() { + return mIterator.previous(); + } + + @Override + public int previousIndex() { + return mIterator.previousIndex(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public void set(E object) { + throw new UnsupportedOperationException(); + } +} + From a874150f51181e7272e03ebb08ae2ba03238761a Mon Sep 17 00:00:00 2001 From: F43nd1r Date: Wed, 20 Apr 2016 20:05:13 +0200 Subject: [PATCH 2/5] replace 4.8.6 with 4.9.0 --- src/main/java/org/acra/security/KeyStoreHelper.java | 2 +- src/main/java/org/acra/security/NoKeyStoreFactory.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/acra/security/KeyStoreHelper.java b/src/main/java/org/acra/security/KeyStoreHelper.java index 89460b6b7..569b5b4ea 100644 --- a/src/main/java/org/acra/security/KeyStoreHelper.java +++ b/src/main/java/org/acra/security/KeyStoreHelper.java @@ -31,7 +31,7 @@ * Helper to get a KeyStore from a configuration * * @author F43nd1r - * @since 4.8.6 + * @since 4.9.0 */ public final class KeyStoreHelper { private static final String ASSET_PREFIX = "asset://"; diff --git a/src/main/java/org/acra/security/NoKeyStoreFactory.java b/src/main/java/org/acra/security/NoKeyStoreFactory.java index 404381056..da8334246 100644 --- a/src/main/java/org/acra/security/NoKeyStoreFactory.java +++ b/src/main/java/org/acra/security/NoKeyStoreFactory.java @@ -25,7 +25,7 @@ * Default KeyStoreFactory. Does not provide any KeyStore * * @author F43nd1r - * @since 4.8.6 + * @since 4.9.0 */ public class NoKeyStoreFactory implements KeyStoreFactory { @Nullable From ae8de2c387d65e8cf780f59b8419e125cb0212ce Mon Sep 17 00:00:00 2001 From: F43nd1r Date: Wed, 20 Apr 2016 20:10:54 +0200 Subject: [PATCH 3/5] remove redundant local variable --- .../java/org/acra/collector/SharedPreferencesCollector.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/org/acra/collector/SharedPreferencesCollector.java b/src/main/java/org/acra/collector/SharedPreferencesCollector.java index 2189cefcc..b2d87bae6 100644 --- a/src/main/java/org/acra/collector/SharedPreferencesCollector.java +++ b/src/main/java/org/acra/collector/SharedPreferencesCollector.java @@ -25,7 +25,6 @@ import org.acra.config.ACRAConfiguration; import java.util.Map; -import java.util.Set; import java.util.TreeMap; import static org.acra.ACRA.LOG_TAG; @@ -63,8 +62,7 @@ public String collect() { sharedPrefs.put("default", PreferenceManager.getDefaultSharedPreferences(context)); // Add in any additional SharedPreferences - final Set sharedPrefIds = config.additionalSharedPreferences(); - for (final String sharedPrefId : sharedPrefIds) { + for (final String sharedPrefId : config.additionalSharedPreferences()) { sharedPrefs.put(sharedPrefId, context.getSharedPreferences(sharedPrefId, Context.MODE_PRIVATE)); } From a69bffbf033c16031af198b4756b9eda9bb95b19 Mon Sep 17 00:00:00 2001 From: F43nd1r Date: Thu, 21 Apr 2016 12:20:56 +0200 Subject: [PATCH 4/5] remove unused suppress on configuration: this should not contain anything unused --- src/main/java/org/acra/config/ACRAConfiguration.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/acra/config/ACRAConfiguration.java b/src/main/java/org/acra/config/ACRAConfiguration.java index 95a950a78..58fe21bb3 100644 --- a/src/main/java/org/acra/config/ACRAConfiguration.java +++ b/src/main/java/org/acra/config/ACRAConfiguration.java @@ -42,7 +42,6 @@ * * Use {@link ConfigurationBuilder} to programmatically construct an ACRAConfiguration. */ -@SuppressWarnings("unused") public final class ACRAConfiguration implements Serializable { private final ImmutableSet additionalDropBoxTags; From 15e9c927455eb30437c8ebe849d07a393f8a3283 Mon Sep 17 00:00:00 2001 From: F43nd1r Date: Thu, 21 Apr 2016 12:24:24 +0200 Subject: [PATCH 5/5] remove null check: no need to check on a package-local constructor. --- src/main/java/org/acra/config/ACRAConfiguration.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/org/acra/config/ACRAConfiguration.java b/src/main/java/org/acra/config/ACRAConfiguration.java index 58fe21bb3..f83c7050d 100644 --- a/src/main/java/org/acra/config/ACRAConfiguration.java +++ b/src/main/java/org/acra/config/ACRAConfiguration.java @@ -118,11 +118,6 @@ public final class ACRAConfiguration implements Serializable { * @param builder ConfigurationBuilder with which to initialise this {@link ACRAConfiguration}. */ ACRAConfiguration(@NonNull ConfigurationBuilder builder) { - //noinspection ConstantConditions (don't rely on annotations alone) - if (builder == null) { - throw new NullPointerException("A ConfigurationBuilder must be supplied to ACRAConfiguration"); - } - additionalDropBoxTags = new ImmutableSet(builder.additionalDropBoxTags()); additionalSharedPreferences = new ImmutableSet(builder.additionalSharedPreferences()); connectionTimeout = builder.connectionTimeout();