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.util.Map;
22
23 import org.apache.rat.analysis.IHeaderMatcher;
24
25 /**
26 * A reference matching Matcher builder.
27 * <p>
28 * This class stores a matcher id as a reference to the matcher. It also has a map of matcher ids to the matcher
29 * instances. When build is called the matcher reference is looked up in the map. If it is found then it is returned
30 * value from the {@code build()} call. If the reference is not located then a IHeaderMatcherProxy is returned.
31 * the IHeaderMatcherProxy is resolved in a later configuration construction phase.
32 */
33 public class MatcherRefBuilder extends AbstractBuilder {
34 private String referenceId;
35 private Map<String, IHeaderMatcher> matchers;
36
37 /**
38 * Constructs the MatcherReferenceBuilder using the provided reference id.
39 * @param refId the reverence to the matcher id.
40 * @return this builder for chaining.
41 */
42 public MatcherRefBuilder setRefId(String refId) {
43 this.referenceId = refId;
44 return this;
45 }
46
47 /**
48 * Set the Map of matcher ids to matcher instances.
49 * @param matchers the Map of ids to instances.
50 * @return this builder for chaining.
51 */
52 public MatcherRefBuilder setMatchers(Map<String, IHeaderMatcher> matchers) {
53 this.matchers = matchers;
54 return this;
55 }
56
57 @Override
58 public IHeaderMatcher build() {
59 IHeaderMatcher result = matchers.get(referenceId);
60 return result != null ? result : new IHeaderMatcherProxy(referenceId, matchers);
61 }
62
63 @Override
64 public String toString() {
65 return "MathcerRefBuilder: "+referenceId;
66 }
67
68 /**
69 * A class that is a proxy to the actual matcher. It retrieves the actual matcher from the map of
70 * matcher ids to matcher instances one the first use of the matcher. This allows earlier read matchers
71 * to reference later constructed matchers as long as all the matchers are constructed before the earlier one is
72 * used.
73 */
74 private class IHeaderMatcherProxy implements IHeaderMatcher {
75 private final String proxyId;
76 private IHeaderMatcher wrapped;
77 private Map<String, IHeaderMatcher> matchers;
78
79 private IHeaderMatcherProxy(String proxyId, Map<String, IHeaderMatcher> matchers) {
80 this.proxyId = proxyId;
81 this.matchers = matchers;
82 }
83
84 private void checkProxy() {
85 if (wrapped == null) {
86 wrapped = matchers.get(proxyId);
87 if (wrapped == null) {
88 throw new IllegalStateException(String.format("%s is not a valid matcher id", proxyId));
89 }
90 matchers = null;
91 }
92 }
93
94 @Override
95 public String getId() {
96 checkProxy();
97 return wrapped.getId();
98 }
99
100 @Override
101 public void reset() {
102 checkProxy();
103 wrapped.reset();
104 }
105
106 @Override
107 public State matches(String line) {
108 checkProxy();
109 return wrapped.matches(line);
110 }
111
112 @Override
113 public State currentState() {
114 checkProxy();
115 return wrapped.currentState();
116 }
117
118 @Override
119 public State finalizeState() {
120 checkProxy();
121 return wrapped.finalizeState();
122 }
123 }
124
125 }