1 /*
2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 package jdk.tools.jlink.internal.plugins;
26 
27 import java.io.File;
28 import java.io.IOException;
29 import java.io.UncheckedIOException;
30 import java.nio.file.Files;
31 import java.nio.file.Path;
32 import java.nio.file.PathMatcher;
33 import java.util.ArrayList;
34 import java.util.Collections;
35 import java.util.List;
36 import java.util.Objects;
37 import java.util.function.Predicate;
38 import jdk.tools.jlink.internal.Utils;
39 
40 /**
41  *
42  * Filter resource resources using path matcher.
43  */
44 public class ResourceFilter implements Predicate<String> {
45     private final static List<String> EMPTY_LIST = Collections.emptyList();
46 
47     private final List<PathMatcher> matchers;
48     private final boolean include;
49     private final boolean otherwise;
50 
ResourceFilter(List<String> patterns, boolean exclude)51     private ResourceFilter(List<String> patterns, boolean exclude) {
52         Objects.requireNonNull(patterns);
53         this.matchers = new ArrayList<>();
54 
55         for (String pattern : patterns) {
56             if (pattern.startsWith("@")) {
57                 File file = new File(pattern.substring(1));
58 
59                 if (file.exists()) {
60                     List<String> lines;
61 
62                     try {
63                         lines = Files.readAllLines(file.toPath());
64                     } catch (IOException ex) {
65                         throw new UncheckedIOException(ex);
66                     }
67 
68                     lines.stream().forEach((line) -> {
69                         matchers.add(Utils.getJRTFSPathMatcher(line.trim()));
70                     });
71                 } else {
72                     System.err.println("warning - the filter file " + file +
73                                        " is empty or not present.");
74                 }
75             } else {
76                 matchers.add(Utils.getJRTFSPathMatcher(pattern));
77             }
78         }
79 
80         this.include = !exclude;
81         this.otherwise = exclude || this.matchers.isEmpty();
82     }
83 
includeFilter(List<String> patterns)84     public static ResourceFilter includeFilter(List<String> patterns) {
85         Objects.requireNonNull(patterns);
86         return new ResourceFilter(patterns, false);
87     }
88 
includeFilter(String patterns)89     public static ResourceFilter includeFilter(String patterns) {
90         if (patterns == null) {
91             return includeFilter(EMPTY_LIST);
92         }
93 
94         return includeFilter(Utils.parseList(patterns));
95     }
96 
excludeFilter(List<String> patterns)97     public static ResourceFilter excludeFilter(List<String> patterns) {
98         Objects.requireNonNull(patterns);
99         return new ResourceFilter(patterns, true);
100     }
101 
excludeFilter(String patterns)102     public static ResourceFilter excludeFilter(String patterns) {
103         if (patterns == null) {
104             return excludeFilter(EMPTY_LIST);
105         }
106 
107         return excludeFilter(Utils.parseList(patterns));
108     }
109 
110     @Override
test(String name)111     public boolean test(String name) {
112         Objects.requireNonNull(name);
113         Path path = Utils.getJRTFSPath(name);
114 
115         for (PathMatcher matcher : matchers) {
116             if (matcher.matches(path)) {
117                 return include;
118             }
119         }
120 
121         return otherwise;
122     }
123 }
124