001/*
002 * ====================================================================
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *   http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied.  See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 * ====================================================================
020 *
021 * This software consists of voluntary contributions made by many
022 * individuals on behalf of the Apache Software Foundation.  For more
023 * information on the Apache Software Foundation, please see
024 * <http://www.apache.org/>.
025 *
026 */
027package org.apache.http.conn.util;
028
029import java.io.File;
030import java.io.FileInputStream;
031import java.io.IOException;
032import java.io.InputStream;
033import java.io.InputStreamReader;
034import java.net.URL;
035import java.util.Arrays;
036import java.util.List;
037
038import org.apache.commons.logging.Log;
039import org.apache.commons.logging.LogFactory;
040import org.apache.http.Consts;
041import org.apache.http.annotation.Contract;
042import org.apache.http.annotation.ThreadingBehavior;
043import org.apache.http.util.Args;
044
045/**
046 * {@link org.apache.http.conn.util.PublicSuffixMatcher} loader.
047 *
048 * @since 4.4
049 */
050@Contract(threading = ThreadingBehavior.SAFE)
051public final class PublicSuffixMatcherLoader {
052
053    private static PublicSuffixMatcher load(final InputStream in) throws IOException {
054        final List<PublicSuffixList> lists = new PublicSuffixListParser().parseByType(
055                new InputStreamReader(in, Consts.UTF_8));
056        return new PublicSuffixMatcher(lists);
057    }
058
059    public static PublicSuffixMatcher load(final URL url) throws IOException {
060        Args.notNull(url, "URL");
061        final InputStream in = url.openStream();
062        try {
063            return load(in);
064        } finally {
065            in.close();
066        }
067    }
068
069    public static PublicSuffixMatcher load(final File file) throws IOException {
070        Args.notNull(file, "File");
071        final InputStream in = new FileInputStream(file);
072        try {
073            return load(in);
074        } finally {
075            in.close();
076        }
077    }
078
079    private static volatile PublicSuffixMatcher DEFAULT_INSTANCE;
080
081    public static PublicSuffixMatcher getDefault() {
082        if (DEFAULT_INSTANCE == null) {
083            synchronized (PublicSuffixMatcherLoader.class) {
084                if (DEFAULT_INSTANCE == null){
085                    final URL url = PublicSuffixMatcherLoader.class.getResource(
086                            "/mozilla/public-suffix-list.txt");
087                    if (url != null) {
088                        try {
089                            DEFAULT_INSTANCE = load(url);
090                        } catch (final IOException ex) {
091                            // Should never happen
092                            final Log log = LogFactory.getLog(PublicSuffixMatcherLoader.class);
093                            if (log.isWarnEnabled()) {
094                                log.warn("Failure loading public suffix list from default resource", ex);
095                            }
096                        }
097                    } else {
098                        DEFAULT_INSTANCE = new PublicSuffixMatcher(Arrays.asList("com"), null);
099                    }
100                }
101            }
102        }
103        return DEFAULT_INSTANCE;
104    }
105
106}