1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one *
3 * or more contributor license agreements. See the NOTICE file *
4 * distributed with this work for additional information *
5 * regarding copyright ownership. The ASF licenses this file *
6 * to you under the Apache License, Version 2.0 (the *
7 * "License"); you may not use this file except in compliance *
8 * with the License. You may obtain a copy of the License at *
9 * *
10 * http://www.apache.org/licenses/LICENSE-2.0 *
11 * *
12 * Unless required by applicable law or agreed to in writing, *
13 * software distributed under the License is distributed on an *
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
15 * KIND, either express or implied. See the License for the *
16 * specific language governing permissions and limitations *
17 * under the License. *
18 */
19 package org.apache.rat.configuration.builders;
20
21 import java.io.BufferedReader;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.InputStreamReader;
25 import java.net.URL;
26 import java.nio.charset.StandardCharsets;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.List;
31 import java.util.stream.Collectors;
32
33 import org.apache.commons.lang3.StringUtils;
34 import org.apache.rat.ConfigurationException;
35 import org.apache.rat.analysis.IHeaderMatcher;
36
37 /**
38 * Constructs a builder that contains other builders.
39 */
40 public abstract class ChildContainerBuilder extends AbstractBuilder {
41
42 /** The list of builders that will build the enclosed matchers. */
43 protected final List<IHeaderMatcher.Builder> children = new ArrayList<>();
44
45 /** The resource the builders came from if it was read from a resource */
46 protected String resource;
47
48 /**
49 * Empty default constructor.
50 */
51 protected ChildContainerBuilder() {
52 }
53
54 /**
55 * Reads a text file. Each line becomes a text matcher in the resulting list.
56 *
57 * @param resourceName the name of the resource to read.
58 * @return a List of Matchers, one for each non-empty line in the input file.
59 */
60 public AbstractBuilder setResource(final String resourceName) {
61 // this method is called by reflection
62 URL url = this.getClass().getResource(resourceName);
63 if (url == null) {
64 throw new ConfigurationException("Unable to read matching text file: " + resourceName);
65 }
66
67 try (InputStream in = url.openStream();
68 BufferedReader buffer = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
69 String txt;
70 while (null != (txt = buffer.readLine())) {
71 txt = txt.trim();
72 if (StringUtils.isNotBlank(txt)) {
73 children.add(new TextBuilder().setSimpleText(txt));
74 }
75 }
76 this.resource = resourceName;
77 return this;
78 } catch (IOException e) {
79 throw new ConfigurationException("Unable to read matching text file: " + resourceName, e);
80 }
81 }
82
83 /**
84 * Adds a builder to the list of builders.
85 *
86 * @param child the child builder to add.
87 * @return this for chaining.
88 */
89 public AbstractBuilder addEnclosed(final IHeaderMatcher.Builder child) {
90 children.add(child);
91 return this;
92 }
93
94 /**
95 * Adds a collection of builders to the list of child builders.
96 *
97 * @param children the children to add.
98 * @return this for chaining.
99 */
100 public AbstractBuilder addEnclosed(final Collection<IHeaderMatcher.Builder> children) {
101 // this method is called by reflection
102 this.children.addAll(children);
103 return this;
104 }
105
106 public List<IHeaderMatcher.Builder> getEnclosedBuilders() {
107 // this method is called by reflection
108 return Collections.unmodifiableList(children);
109 }
110 /**
111 * @return the list of child builders for this builder.
112 */
113 public List<IHeaderMatcher> getEnclosed() {
114 return children.stream().map(IHeaderMatcher.Builder::build).collect(Collectors.toList());
115 }
116
117 @Override
118 public String toString() {
119 StringBuilder sb = new StringBuilder(this.getClass().getSimpleName()).append(":");
120 children.stream().map(Object::toString).forEach(x -> sb.append(System.lineSeparator()).append(x));
121 return sb.toString();
122 }
123 }