This repository has been archived by the owner on May 7, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 789
/
RulePredicates.java
180 lines (164 loc) · 6.15 KB
/
RulePredicates.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/**
* Copyright (c) 2017 by Deutsche Telekom AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.smarthome.automation;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;
/**
* Add support for prefixes and provide default predicates for prefixes and tags.
*
* @author Victor Toni - initial contribution
*
*/
public class RulePredicates {
/**
* Constant defining separator between prefix and name.
*/
public static final String PREFIX_SEPARATOR = ":";
/**
* Gets the prefix of the {@link Rule}, if any exist. This property is either set by the {@link RuleEngine} when
* the {@link Rule} is added or by the creating party. It's an optional property.
* <br/>
* <br/>
* Implementation note
* <br/>
* The namespace is part of the UID and the prefix thereof.
* <br/>
* If the UID does not contain a {@link PREFIX_SEPARATOR} {@code null} will be returned.
* <br/>
* If the UID does contain a {@link PREFIX_SEPARATOR} the prefix until the first occurrence will be returned.
* <br/>
* If the prefix would have a zero length {@code null} will be returned.
*
* @return prefix of this {@link Rule}, or {@code null} if no prefix or an empty prefix is found
*/
public static String getPrefix(Rule rule) {
if (null != rule) {
final String uid = rule.getUID();
final int index = uid.indexOf(PREFIX_SEPARATOR);
// only when a delimiter was found and the prefix is not empty
if (0 < index) {
return uid.substring(0, index);
}
}
return null;
}
/**
* Creates a {@link Predicate} which can be used to filter {@link Rule}s for a given prefix or {@code null}
* prefix.
*
* @param prefix to search for
* @return created {@link Predicate}
*/
public static Predicate<Rule> hasPrefix(final String prefix) {
if (null == prefix) {
return r -> null == getPrefix(r);
} else {
return r -> prefix.equals(getPrefix(r));
}
}
/**
* Creates a {@link Predicate} which can be used to match {@link Rule}s for any of the given prefixes and even
* {@code null} prefix.
*
* @param prefixes to search for
* @return created {@link Predicate}
*/
public static Predicate<Rule> hasAnyOfPrefixes(String... prefixes) {
final HashSet<String> namespaceSet = new HashSet<String>(prefixes.length);
for (final String namespace : prefixes) {
namespaceSet.add(namespace);
}
// this will even work for null namepace
return r -> namespaceSet.contains(getPrefix(r));
}
/**
* Creates a {@link Predicate} which can be used to match {@link Rule}s with one or more tags.
*
* @param tags to search for
* @return created {@link Predicate}
*/
public static Predicate<Rule> hasTags() {
// everything with a tag is matching
// Rule.getTags() is never null
return r -> 0 < r.getTags().size();
}
/**
* Creates a {@link Predicate} which can be used to match {@link Rule}s without tags.
*
* @param tags to search for
* @return created {@link Predicate}
*/
public static Predicate<Rule> hasNoTags() {
// Rule.getTags() is never null
return r -> r.getTags().isEmpty();
}
/**
* Creates a {@link Predicate} which can be used to match {@link Rule}s with all given tags or no tags at all.
* All given tags must match, (the matched {@code Rule} might contain more).
*
* @param tags to search for
* @return created {@link Predicate}
*/
public static Predicate<Rule> hasAllTags(final Collection<String> tags) {
if (tags == null || tags.isEmpty()) {
return (Predicate<Rule>) r -> true;
} else {
final Set<String> tagSet = new HashSet<String>(tags);
// everything containing _all_ given tags is matching
// (Rule might might have more tags than the given set)
return r -> r.getTags().containsAll(tagSet);
}
}
/**
* Creates a {@link Predicate} which can be used to match {@link Rule}s for all given tags or no tags at all.
* All given tags must match, (the matched {@code Rule} might contain more).
*
* @param tags to search for
* @return created {@link Predicate}
*/
public static Predicate<Rule> hasAllTags(final String... tags) {
return hasAllTags(tags == null ? null : Arrays.asList(tags));
}
/**
* Creates a {@link Predicate} which can be used to match {@link Rule}s for any of the given tags or {@link Rule}s
* without tags.
*
* @param tags to search for
* @return created {@link Predicate}
*/
public static Predicate<Rule> hasAnyOfTags(final Collection<String> tags) {
if (null == tags || tags.isEmpty()) {
// everything without a tag is matching
return hasNoTags();
} else {
final Set<String> tagSet = new HashSet<String>(tags);
// everything containing _any_ of the given tags is matching (more than one tag might match)
// if the collections are NOT disjoint, they have something in common
return r -> !Collections.disjoint(r.getTags(), tagSet);
}
}
/**
* Creates a {@link Predicate} which can be used to match {@link Rule}s for any of the given tags or {@link Rule}s
* without tags.
*
* @param tags to search for
* @return created {@link Predicate}
*/
public static Predicate<Rule> hasAnyOfTags(final String... tags) {
if (null == tags || 0 == tags.length) {
// everything without a tag is matching
return hasNoTags();
} else {
return hasAnyOfTags(Arrays.asList(tags));
}
}
}