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

Side by Side 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.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-present eyeo GmbH
4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 package org.adblockplus.sbrowser.contentblocker.engine;
19
20 import java.io.BufferedWriter;
21 import java.io.File;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.OutputStreamWriter;
25 import java.nio.charset.StandardCharsets;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Locale;
31 import java.util.Map;
32
33 import org.adblockplus.sbrowser.contentblocker.engine.Subscription.Type;
34
35 import android.util.Log;
36
37 /**
38 * This class holds all listed subscriptions and manages the subscription
39 * aggregation cache folder.
40 */
41 final class Subscriptions
42 {
43 private static final String TAG = Subscriptions.class.getSimpleName();
44 private static final String[] USER_SUBSCRIPTIONS =
45 { Engine.USER_FILTERS_TITLE, Engine.USER_EXCEPTIONS_TITLE };
46 // Filters that begin with '|$' , '||$' , '@@|$' or '@@||$'
47 // See https://issues.adblockplus.org/ticket/4772
48 private static final String UNSUPPORTED_FILTERS_REGEX = "^(\\|\\$|\\|\\|\\$|@ @\\|\\$|@@\\|\\|\\$).*";
49 private final HashMap<String, Subscription> subscriptions = new HashMap<>();
50
51 private final Engine engine;
52 private final File subscriptionFolder;
53 private final File cacheFolder;
54 private final boolean wasUninitialized;
55
56 private Subscriptions(final Engine engine, final File appFolder, final File ca cheFolder)
57 {
58 this.engine = engine;
59 this.subscriptionFolder = appFolder;
60 this.wasUninitialized = !this.subscriptionFolder.exists();
61 this.cacheFolder = cacheFolder;
62 }
63
64 public boolean wasUnitialized()
65 {
66 return this.wasUninitialized;
67 }
68
69 public File createAndWriteFile() throws IOException
70 {
71 for (;;)
72 {
73 final File file = new File(this.cacheFolder, String.format(Locale.ENGLISH, "tmp-%d.txt",
74 (int) (Math.random() * 1e8)));
75 if (!file.exists())
76 {
77 Log.d(TAG, "Writing filters to " + file);
78 this.writeFile(file);
79 return file;
80 }
81 }
82 }
83
84 List<SubscriptionInfo> getSubscriptions(final Engine engine)
85 {
86 final ArrayList<SubscriptionInfo> subs = new ArrayList<>();
87 for (final Subscription sub : this.subscriptions.values())
88 {
89 subs.add(SubscriptionInfo.create(engine, sub));
90 }
91 return subs;
92 }
93
94 void loadSubscriptions(final List<Subscription> list)
95 {
96 list.addAll(this.subscriptions.values());
97 }
98
99 public boolean hasSubscription(final String id)
100 {
101 return this.subscriptions.containsKey(id);
102 }
103
104 public boolean isSubscriptionEnabled(final String id)
105 {
106 final Subscription sub = this.subscriptions.get(id);
107 return sub != null && sub.isEnabled();
108 }
109
110 public boolean changeSubscriptionState(final String id, final boolean enabled) throws IOException
111 {
112 final Subscription sub = this.subscriptions.get(id);
113 if (sub != null)
114 {
115 if (enabled != sub.isEnabled())
116 {
117 sub.setEnabled(enabled);
118 sub.serializeMetaData(this.getMetaFile(sub));
119 if (enabled)
120 {
121 this.engine.enqueueDownload(sub, true);
122 }
123
124 this.engine.subscriptionStateChanged();
125 this.engine.requestUpdateBroadcast();
126 return true;
127 }
128 }
129 return false;
130 }
131
132 File getFiltersFile(final Subscription sub)
133 {
134 final File filtersFile;
135 if (sub.getType() == Type.USER)
136 {
137 filtersFile = new File(this.subscriptionFolder, "user_" + sub.getTitle() + ".sub");
138 }
139 else
140 {
141 filtersFile = new File(this.subscriptionFolder, "url_"
142 + new File(sub.getURL().getPath()).getName() + ".sub");
143 }
144 return filtersFile;
145 }
146
147 File getMetaFile(final Subscription sub)
148 {
149 return new File(getFiltersFile(sub).getAbsolutePath() + ".meta");
150 }
151
152 void persistSubscription(final Subscription sub) throws IOException
153 {
154 sub.serializeSubscription(this.getMetaFile(sub), this.getFiltersFile(sub));
155 }
156
157 void persistSubscriptions() throws IOException
158 {
159 for (final Subscription sub : this.subscriptions.values())
160 {
161 this.persistSubscription(sub);
162 }
163 }
164
165 /**
166 * This method combines all currently listed and enabled subscriptions into
167 * one text file.
168 *
169 * @param output
170 * @throws IOException
171 */
172 private void writeFile(final File output) throws IOException
173 {
174 final HashSet<String> filters = new HashSet<>();
175 for (final Subscription s : this.subscriptions.values())
176 {
177 if (s.isEnabled())
178 {
179 Log.d(TAG, "Adding filters for '" + s.getId() + "'");
180 s.deserializeFilters(this.getFiltersFile(s));
181 s.copyFilters(filters);
182 s.clearFilters();
183 }
184 if ((!s.isMetaDataValid() || !s.isFiltersValid()) && s.getURL() != null)
185 {
186 this.engine.enqueueDownload(s, true);
187 }
188 }
189
190 try (final BufferedWriter w = new BufferedWriter(
191 new OutputStreamWriter(new FileOutputStream(output), StandardCharsets.UT F_8)))
192 {
193 Log.d(TAG, "Writing " + filters.size() + " filters");
194 Engine.writeFilterHeaders(w);
195 for (final String filter : filters)
196 {
197 // This is a temporary fix to not write filters that might crash Samsung Internet
198 // See https://issues.adblockplus.org/ticket/4772
199 if (!filter.matches(UNSUPPORTED_FILTERS_REGEX))
200 {
201 w.write(filter);
202 w.write('\n');
203 }
204 else
205 {
206 Log.d(TAG, "Ignoring unsupported filter: " + filter);
207 }
208 }
209 }
210 }
211
212 public Subscription add(final Subscription sub)
213 {
214 final String id = sub.getId();
215 if (!this.subscriptions.containsKey(id))
216 {
217 this.subscriptions.put(id, sub);
218 return sub;
219 }
220 return this.subscriptions.get(id);
221 }
222
223 public boolean remove(final String id)
224 {
225 return this.subscriptions.remove(id) != null;
226 }
227
228 public static Subscriptions initialize(final Engine engine, final File appFold er,
229 final File cacheFolder)
230 {
231 final Subscriptions subs = new Subscriptions(engine, appFolder, cacheFolder) ;
232
233 subs.subscriptionFolder.mkdirs();
234 subs.cacheFolder.mkdirs();
235
236 final File[] files = subs.subscriptionFolder.listFiles();
237 for (File f : files)
238 {
239 if (f.getName().endsWith(".sub"))
240 {
241 final File metaFile = new File(f.getAbsolutePath() + ".meta");
242 if (metaFile.exists())
243 {
244 final Subscription sub = Subscription.deserializeSubscription(metaFile );
245 if (sub != null)
246 {
247 subs.subscriptions.put(sub.getId(), sub);
248 }
249 }
250 }
251 }
252
253 subs.createUserSubscriptions();
254
255 return subs;
256 }
257
258 /**
259 * Adds default user subscriptions if not exist.
260 */
261 private void createUserSubscriptions()
262 {
263 for (String title : USER_SUBSCRIPTIONS)
264 {
265 final Subscription userSub = Subscription.createUserSubscription(title);
266 if (!this.subscriptions.containsKey(userSub.getId()))
267 {
268 this.subscriptions.put(userSub.getId(), userSub);
269 }
270 }
271 }
272
273 public void checkForUpdates() throws IOException
274 {
275 for (Subscription sub : this.subscriptions.values())
276 {
277 if (sub.isEnabled())
278 {
279 this.engine.enqueueDownload(sub, false);
280 }
281 }
282 }
283
284 public void updateSubscription(final String id, final int responseCode, final String text,
285 final Map<String, String> httpHeaders)
286 throws IOException
287 {
288 final Subscription sub = this.subscriptions.get(id);
289 if (sub != null)
290 {
291 if (sub.updateSubscription(responseCode, text, httpHeaders, this.getMetaFi le(sub),
292 this.getFiltersFile(sub)))
293 {
294 this.engine.requestUpdateBroadcast();
295 }
296 }
297 }
298 }
OLDNEW

Powered by Google App Engine
This is Rietveld