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

Unified Diff: adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/engine/DefaultSubscriptions.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/DefaultSubscriptions.java
===================================================================
new file mode 100644
--- /dev/null
+++ b/adblockplussbrowser/src/main/java/org/adblockplus/sbrowser/contentblocker/engine/DefaultSubscriptions.java
@@ -0,0 +1,293 @@
+/*
+ * 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.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+final class DefaultSubscriptions
+{
+ private final List<DefaultSubscriptionInfo> subscriptions = new ArrayList<>();
+ private final List<DefaultSubscriptionInfo> linearSubscriptions = new ArrayList<>();
+ private final HashMap<String, DefaultSubscriptionInfo> urlMap = new HashMap<>();
+ private final List<DefaultSubscriptionInfo> adsSubscriptions = new ArrayList<>();
+ private final List<DefaultSubscriptionInfo> otherSubscriptions = new ArrayList<>();
+
+ private DefaultSubscriptions initialize()
+ {
+ this.listSubscriptions(this.linearSubscriptions);
+
+ for (final DefaultSubscriptionInfo s : this.linearSubscriptions)
+ {
+ final String url = s.getUrl();
+ final String type = s.getType();
+
+ if (url.length() > 0)
+ {
+ this.urlMap.put(url, s);
+ }
+
+ if (type.length() == 0 || type.equals("ads"))
+ {
+ this.adsSubscriptions.add(s);
+ }
+ else if (type.equals("other"))
+ {
+ this.otherSubscriptions.add(s);
+ }
+ }
+
+ return this;
+ }
+
+ public List<Subscription> createSubscriptions() throws IOException
+ {
+ final ArrayList<Subscription> subs = new ArrayList<>();
+ for (DefaultSubscriptionInfo info : this.linearSubscriptions)
+ {
+ if (!info.getUrl().isEmpty())
+ {
+ final Subscription sub = Subscription.create(info.getUrl());
+ sub.putMeta(Subscription.KEY_TITLE, info.getTitle());
+ subs.add(sub);
+ }
+ }
+ return subs;
+ }
+
+ public DefaultSubscriptionInfo getForUrl(final String url)
+ {
+ return this.urlMap.get(url);
+ }
+
+ public DefaultSubscriptionInfo getForUrl(final URL url)
+ {
+ return url != null ? this.getForUrl(url.toString()) : null;
+ }
+
+ public List<DefaultSubscriptionInfo> getAdsSubscriptions()
+ {
+ return adsSubscriptions;
+ }
+
+ private void listSubscriptions(final List<DefaultSubscriptionInfo> output)
+ {
+ for (final DefaultSubscriptionInfo s : this.subscriptions)
+ {
+ this.listSubscriptions(s, output);
+ }
+ }
+
+ private void listSubscriptions(final DefaultSubscriptionInfo parent,
+ final List<DefaultSubscriptionInfo> output)
+ {
+ output.add(parent);
+ for (final DefaultSubscriptionInfo s : parent.variants)
+ {
+ this.listSubscriptions(s, output);
+ }
+ for (final DefaultSubscriptionInfo s : parent.supplements)
+ {
+ this.listSubscriptions(s, output);
+ }
+ }
+
+ public static DefaultSubscriptions fromStream(final InputStream in) throws IOException
+ {
+ try
+ {
+ final SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setValidating(false);
+ final SAXParser parser = factory.newSAXParser();
+ final SubscriptionParser handler = new SubscriptionParser();
+ parser.parse(in, handler);
+ return handler.subscriptions.initialize();
+ }
+ catch (final ParserConfigurationException | SAXException e)
+ {
+ throw new IOException(e.getClass().getSimpleName() + ": " + e.getMessage());
+ }
+ }
+
+ private static class SubscriptionParser extends DefaultHandler
+ {
+ private boolean inSubscriptions = false;
+ private boolean inVariants = false;
+
+ private final static String KEY_SUPPLEMENTS = "supplements";
+ private final static String KEY_SUBSCRIPTIONS = "subscriptions";
+ private final static String KEY_SUBSCRIPTION = "subscription";
+ private final static String KEY_VARIANTS = "variants";
+ private final static String KEY_VARIANT = "variant";
+
+ private final DefaultSubscriptions subscriptions = new DefaultSubscriptions();
+ private final LinkedList<DefaultSubscriptionInfo> subscriptionStack = new LinkedList<>();
+ private DefaultSubscriptionInfo subscription = null;
+ private DefaultSubscriptionInfo variant = null;
+
+ @Override
+ public void startElement(final String uri, final String localName, final String qName,
+ final Attributes attributes) throws SAXException
+ {
+ super.startElement(uri, localName, qName, attributes);
+
+ if (KEY_SUBSCRIPTIONS.equals(qName))
+ {
+ this.inSubscriptions = true;
+ }
+ else if (KEY_SUBSCRIPTION.equals(qName))
+ {
+ if (!this.inSubscriptions)
+ {
+ throw new SAXException("<subscription> outside <subscriptions>");
+ }
+ if (this.subscription != null)
+ {
+ throw new SAXException("nested <subscription>");
+ }
+ this.subscription = new DefaultSubscriptionInfo();
+ for (int i = 0; i < attributes.getLength(); i++)
+ {
+ this.subscription.attributes.put(attributes.getQName(i), attributes.getValue(i));
+ }
+ }
+ else if (KEY_VARIANTS.equals(qName))
+ {
+ this.inVariants = true;
+ }
+ else if (KEY_VARIANT.equals(qName))
+ {
+ if (!this.inVariants)
+ {
+ throw new SAXException("<variant> outside <variants>");
+ }
+ if (!this.inSubscriptions)
+ {
+ throw new SAXException("<variant> outside <subscriptions>");
+ }
+ if (this.subscription == null)
+ {
+ throw new SAXException("<variant> outside <subscription>");
+ }
+ if (this.variant != null)
+ {
+ throw new SAXException("nested <variant>");
+ }
+ this.variant = new DefaultSubscriptionInfo();
+ this.variant.attributes.putAll(this.subscription.attributes);
+ for (int i = 0; i < attributes.getLength(); i++)
+ {
+ this.variant.attributes.put(attributes.getQName(i), attributes.getValue(i));
+ }
+ }
+ else if (KEY_SUPPLEMENTS.equals(qName))
+ {
+ if (!this.inSubscriptions)
+ {
+ throw new SAXException("<supplements> outside <subscriptions>");
+ }
+ if (this.subscription == null)
+ {
+ throw new SAXException("<supplements> outside <subscription>");
+ }
+ this.subscriptionStack.addFirst(this.subscription);
+ this.subscription = null;
+ }
+ }
+
+ @Override
+ public void endElement(final String uri, final String localName, final String qName)
+ throws SAXException
+ {
+ super.endElement(uri, localName, qName);
+
+ if (KEY_SUBSCRIPTIONS.equals(qName))
+ {
+ if (!this.inSubscriptions)
+ {
+ throw new SAXException("</subscriptions> without <subscriptions>");
+ }
+ this.inSubscriptions = false;
+ }
+ else if (KEY_SUBSCRIPTION.equals(qName))
+ {
+ if (this.subscription == null)
+ {
+ throw new SAXException("</subscription> without <subscription>");
+ }
+ if (!this.subscriptionStack.isEmpty())
+ {
+ this.subscription.parent = this.subscriptionStack.getFirst();
+ this.subscription.parent.supplements.add(this.subscription);
+ }
+ else
+ {
+ this.subscriptions.subscriptions.add(this.subscription);
+ }
+ this.subscription = null;
+ }
+ else if (KEY_VARIANTS.equals(qName))
+ {
+ if (!this.inVariants)
+ {
+ throw new SAXException("</variants> without </variants>");
+ }
+ this.inVariants = false;
+ }
+ else if (KEY_VARIANT.equals(qName))
+ {
+ if (this.variant == null)
+ {
+ throw new SAXException("</variant> without </variant>");
+ }
+
+ this.variant.parent = this.subscription;
+ this.subscription.variants.add(this.variant);
+
+ this.variant = null;
+ }
+ else if (KEY_SUPPLEMENTS.equals(qName))
+ {
+ if (this.subscriptionStack.isEmpty())
+ {
+ throw new SAXException("</supplements> without </supplements>");
+ }
+ this.subscription = this.subscriptionStack.removeFirst();
+ }
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.linearSubscriptions.toString();
+ }
+}

Powered by Google App Engine
This is Rietveld