Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/engine/Subscriptions.java

Issue 29603697: Issue 5931 - Create tests for util package (Closed)
Patch Set: Created Nov. 10, 2017, 2:23 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/engine/Subscriptions.java
===================================================================
new file mode 100644
--- /dev/null
+++ b/adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/engine/Subscriptions.java
@@ -0,0 +1,298 @@
+/*
+ * This file is part of Adblock Plus <https://adblockplus.org/>,
+ * Copyright (C) 2006-present eyeo GmbH
+ *
+ * Adblock Plus is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Adblock Plus is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.adblockplus.sbrowser.contentblocker.engine;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.adblockplus.sbrowser.contentblocker.engine.Subscription.Type;
+
+import android.util.Log;
+
+/**
+ * This class holds all listed subscriptions and manages the subscription
+ * aggregation cache folder.
+ */
+final class Subscriptions
+{
+ private static final String TAG = Subscriptions.class.getSimpleName();
+ private static final String[] USER_SUBSCRIPTIONS =
+ { Engine.USER_FILTERS_TITLE, Engine.USER_EXCEPTIONS_TITLE };
+ // Filters that begin with '|$' , '||$' , '@@|$' or '@@||$'
+ // See https://issues.adblockplus.org/ticket/4772
+ private static final String UNSUPPORTED_FILTERS_REGEX = "^(\\|\\$|\\|\\|\\$|@@\\|\\$|@@\\|\\|\\$).*";
+ private final HashMap<String, Subscription> subscriptions = new HashMap<>();
+
+ private final Engine engine;
+ private final File subscriptionFolder;
+ private final File cacheFolder;
+ private final boolean wasUninitialized;
+
+ private Subscriptions(final Engine engine, final File appFolder, final File cacheFolder)
+ {
+ this.engine = engine;
+ this.subscriptionFolder = appFolder;
+ this.wasUninitialized = !this.subscriptionFolder.exists();
+ this.cacheFolder = cacheFolder;
+ }
+
+ public boolean wasUnitialized()
+ {
+ return this.wasUninitialized;
+ }
+
+ public File createAndWriteFile() throws IOException
+ {
+ for (;;)
+ {
+ final File file = new File(this.cacheFolder, String.format(Locale.ENGLISH, "tmp-%d.txt",
+ (int) (Math.random() * 1e8)));
+ if (!file.exists())
+ {
+ Log.d(TAG, "Writing filters to " + file);
+ this.writeFile(file);
+ return file;
+ }
+ }
+ }
+
+ List<SubscriptionInfo> getSubscriptions(final Engine engine)
+ {
+ final ArrayList<SubscriptionInfo> subs = new ArrayList<>();
+ for (final Subscription sub : this.subscriptions.values())
+ {
+ subs.add(SubscriptionInfo.create(engine, sub));
+ }
+ return subs;
+ }
+
+ void loadSubscriptions(final List<Subscription> list)
+ {
+ list.addAll(this.subscriptions.values());
+ }
+
+ public boolean hasSubscription(final String id)
+ {
+ return this.subscriptions.containsKey(id);
+ }
+
+ public boolean isSubscriptionEnabled(final String id)
+ {
+ final Subscription sub = this.subscriptions.get(id);
+ return sub != null && sub.isEnabled();
+ }
+
+ public boolean changeSubscriptionState(final String id, final boolean enabled) throws IOException
+ {
+ final Subscription sub = this.subscriptions.get(id);
+ if (sub != null)
+ {
+ if (enabled != sub.isEnabled())
+ {
+ sub.setEnabled(enabled);
+ sub.serializeMetaData(this.getMetaFile(sub));
+ if (enabled)
+ {
+ this.engine.enqueueDownload(sub, true);
+ }
+
+ this.engine.subscriptionStateChanged();
+ this.engine.requestUpdateBroadcast();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ File getFiltersFile(final Subscription sub)
+ {
+ final File filtersFile;
+ if (sub.getType() == Type.USER)
+ {
+ filtersFile = new File(this.subscriptionFolder, "user_" + sub.getTitle() + ".sub");
+ }
+ else
+ {
+ filtersFile = new File(this.subscriptionFolder, "url_"
+ + new File(sub.getURL().getPath()).getName() + ".sub");
+ }
+ return filtersFile;
+ }
+
+ File getMetaFile(final Subscription sub)
+ {
+ return new File(getFiltersFile(sub).getAbsolutePath() + ".meta");
+ }
+
+ void persistSubscription(final Subscription sub) throws IOException
+ {
+ sub.serializeSubscription(this.getMetaFile(sub), this.getFiltersFile(sub));
+ }
+
+ void persistSubscriptions() throws IOException
+ {
+ for (final Subscription sub : this.subscriptions.values())
+ {
+ this.persistSubscription(sub);
+ }
+ }
+
+ /**
+ * This method combines all currently listed and enabled subscriptions into
+ * one text file.
+ *
+ * @param output
+ * @throws IOException
+ */
+ private void writeFile(final File output) throws IOException
+ {
+ final HashSet<String> filters = new HashSet<>();
+ for (final Subscription s : this.subscriptions.values())
+ {
+ if (s.isEnabled())
+ {
+ Log.d(TAG, "Adding filters for '" + s.getId() + "'");
+ s.deserializeFilters(this.getFiltersFile(s));
+ s.copyFilters(filters);
+ s.clearFilters();
+ }
+ if ((!s.isMetaDataValid() || !s.isFiltersValid()) && s.getURL() != null)
+ {
+ this.engine.enqueueDownload(s, true);
+ }
+ }
+
+ try (final BufferedWriter w = new BufferedWriter(
+ new OutputStreamWriter(new FileOutputStream(output), StandardCharsets.UTF_8)))
+ {
+ Log.d(TAG, "Writing " + filters.size() + " filters");
+ Engine.writeFilterHeaders(w);
+ for (final String filter : filters)
+ {
+ // This is a temporary fix to not write filters that might crash Samsung Internet
+ // See https://issues.adblockplus.org/ticket/4772
+ if (!filter.matches(UNSUPPORTED_FILTERS_REGEX))
+ {
+ w.write(filter);
+ w.write('\n');
+ }
+ else
+ {
+ Log.d(TAG, "Ignoring unsupported filter: " + filter);
+ }
+ }
+ }
+ }
+
+ public Subscription add(final Subscription sub)
+ {
+ final String id = sub.getId();
+ if (!this.subscriptions.containsKey(id))
+ {
+ this.subscriptions.put(id, sub);
+ return sub;
+ }
+ return this.subscriptions.get(id);
+ }
+
+ public boolean remove(final String id)
+ {
+ return this.subscriptions.remove(id) != null;
+ }
+
+ public static Subscriptions initialize(final Engine engine, final File appFolder,
+ final File cacheFolder)
+ {
+ final Subscriptions subs = new Subscriptions(engine, appFolder, cacheFolder);
+
+ subs.subscriptionFolder.mkdirs();
+ subs.cacheFolder.mkdirs();
+
+ final File[] files = subs.subscriptionFolder.listFiles();
+ for (File f : files)
+ {
+ if (f.getName().endsWith(".sub"))
+ {
+ final File metaFile = new File(f.getAbsolutePath() + ".meta");
+ if (metaFile.exists())
+ {
+ final Subscription sub = Subscription.deserializeSubscription(metaFile);
+ if (sub != null)
+ {
+ subs.subscriptions.put(sub.getId(), sub);
+ }
+ }
+ }
+ }
+
+ subs.createUserSubscriptions();
+
+ return subs;
+ }
+
+ /**
+ * Adds default user subscriptions if not exist.
+ */
+ private void createUserSubscriptions()
+ {
+ for (String title : USER_SUBSCRIPTIONS)
+ {
+ final Subscription userSub = Subscription.createUserSubscription(title);
+ if (!this.subscriptions.containsKey(userSub.getId()))
+ {
+ this.subscriptions.put(userSub.getId(), userSub);
+ }
+ }
+ }
+
+ public void checkForUpdates() throws IOException
+ {
+ for (Subscription sub : this.subscriptions.values())
+ {
+ if (sub.isEnabled())
+ {
+ this.engine.enqueueDownload(sub, false);
+ }
+ }
+ }
+
+ public void updateSubscription(final String id, final int responseCode, final String text,
+ final Map<String, String> httpHeaders)
+ throws IOException
+ {
+ final Subscription sub = this.subscriptions.get(id);
+ if (sub != null)
+ {
+ if (sub.updateSubscription(responseCode, text, httpHeaders, this.getMetaFile(sub),
+ this.getFiltersFile(sub)))
+ {
+ this.engine.requestUpdateBroadcast();
+ }
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld