Commit | Line | Data |
---|---|---|
c0e418b5 AM |
1 | /* |
2 | * Copyright (C) 2017 - EfficiOS Inc., Philippe Proulx <pproulx@efficios.com> | |
3 | * | |
4 | * This library is free software; you can redistribute it and/or modify it | |
5 | * under the terms of the GNU Lesser General Public License, version 2.1 only, | |
6 | * as published by the Free Software Foundation. | |
7 | * | |
8 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License | |
11 | * for more details. | |
12 | * | |
13 | * You should have received a copy of the GNU Lesser General Public License | |
14 | * along with this library; if not, write to the Free Software Foundation, | |
15 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
16 | */ | |
17 | ||
18 | package org.lttng.ust.agent; | |
19 | ||
20 | import java.util.regex.Pattern; | |
21 | ||
22 | /** | |
23 | * Class encapsulating an event name from the session daemon, and its | |
24 | * corresponding {@link Pattern}. This allows referring back to the original | |
25 | * event name, for example when we receive a disable command. | |
26 | * | |
27 | * @author Philippe Proulx | |
28 | * @author Alexandre Montplaisir | |
29 | */ | |
30 | class EventNamePattern { | |
31 | ||
32 | private final String originalEventName; | |
33 | ||
34 | /* | |
35 | * Note that two Patterns coming from the exact same String will not be | |
36 | * equals()! As such, it would be confusing to make the pattern part of this | |
37 | * class's equals/hashCode | |
38 | */ | |
39 | private final transient Pattern pattern; | |
40 | ||
41 | public EventNamePattern(String eventName) { | |
42 | if (eventName == null) { | |
43 | throw new IllegalArgumentException(); | |
44 | } | |
45 | ||
46 | originalEventName = eventName; | |
47 | pattern = patternFromEventName(eventName); | |
48 | } | |
49 | ||
50 | public String getEventName() { | |
51 | return originalEventName; | |
52 | } | |
53 | ||
54 | public Pattern getPattern() { | |
55 | return pattern; | |
56 | } | |
57 | ||
58 | @Override | |
59 | public int hashCode() { | |
60 | final int prime = 31; | |
61 | int result = 1; | |
62 | result = prime * result + originalEventName.hashCode(); | |
63 | return result; | |
64 | } | |
65 | ||
66 | @Override | |
67 | public boolean equals(Object obj) { | |
68 | if (this == obj) { | |
69 | return true; | |
70 | } | |
71 | if (obj == null) { | |
72 | return false; | |
73 | } | |
74 | if (getClass() != obj.getClass()) { | |
75 | return false; | |
76 | } | |
77 | EventNamePattern other = (EventNamePattern) obj; | |
78 | if (!originalEventName.equals(other.originalEventName)) { | |
79 | return false; | |
80 | } | |
81 | return true; | |
82 | } | |
83 | ||
84 | private static Pattern patternFromEventName(String eventName) { | |
85 | /* | |
86 | * The situation here is that `\*` means a literal `*` in the event | |
87 | * name, and `*` is a wildcard star. We check the event name one | |
88 | * character at a time and create a list of tokens to be converter to | |
89 | * partial patterns. | |
90 | */ | |
91 | StringBuilder bigBuilder = new StringBuilder("^"); | |
92 | StringBuilder smallBuilder = new StringBuilder(); | |
93 | ||
94 | for (int i = 0; i < eventName.length(); i++) { | |
95 | char c = eventName.charAt(i); | |
96 | ||
97 | switch (c) { | |
98 | case '*': | |
99 | /* Add current quoted builder's string if not empty. */ | |
100 | if (smallBuilder.length() > 0) { | |
101 | bigBuilder.append(Pattern.quote(smallBuilder.toString())); | |
102 | smallBuilder.setLength(0); | |
103 | } | |
104 | ||
105 | /* Append the equivalent regex which is `.*`. */ | |
106 | bigBuilder.append(".*"); | |
107 | continue; | |
108 | ||
109 | case '\\': | |
110 | /* We only escape `*` and `\` here. */ | |
111 | if (i < (eventName.length() - 1)) { | |
112 | char nextChar = eventName.charAt(i + 1); | |
113 | ||
114 | if (nextChar == '*' || nextChar == '\\') { | |
115 | smallBuilder.append(nextChar); | |
116 | } else { | |
117 | smallBuilder.append(c); | |
118 | smallBuilder.append(nextChar); | |
119 | } | |
120 | ||
121 | i++; | |
122 | continue; | |
123 | } | |
124 | break; | |
125 | ||
126 | default: | |
127 | break; | |
128 | } | |
129 | ||
130 | smallBuilder.append(c); | |
131 | } | |
132 | ||
133 | /* Add current quoted builder's string if not empty. */ | |
134 | if (smallBuilder.length() > 0) { | |
135 | bigBuilder.append(Pattern.quote(smallBuilder.toString())); | |
136 | } | |
137 | ||
138 | bigBuilder.append("$"); | |
139 | ||
140 | return Pattern.compile(bigBuilder.toString()); | |
141 | } | |
142 | } |