X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=liblttng-ust-java-agent%2Fjava%2Flttng-ust-agent-common%2Forg%2Flttng%2Fust%2Fagent%2FEventNamePattern.java;fp=liblttng-ust-java-agent%2Fjava%2Flttng-ust-agent-common%2Forg%2Flttng%2Fust%2Fagent%2FEventNamePattern.java;h=f89d74f4c0384e0326ad1b7b97be9c9f58d4147c;hb=c0e418b5f350c9a4a70184c418f4a46ee299508b;hp=0000000000000000000000000000000000000000;hpb=f35c6aa089659c7d16867ce4eac740d30c2c0213;p=lttng-ust.git diff --git a/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/EventNamePattern.java b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/EventNamePattern.java new file mode 100644 index 00000000..f89d74f4 --- /dev/null +++ b/liblttng-ust-java-agent/java/lttng-ust-agent-common/org/lttng/ust/agent/EventNamePattern.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2017 - EfficiOS Inc., Philippe Proulx + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License, version 2.1 only, + * as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package org.lttng.ust.agent; + +import java.util.regex.Pattern; + +/** + * Class encapsulating an event name from the session daemon, and its + * corresponding {@link Pattern}. This allows referring back to the original + * event name, for example when we receive a disable command. + * + * @author Philippe Proulx + * @author Alexandre Montplaisir + */ +class EventNamePattern { + + private final String originalEventName; + + /* + * Note that two Patterns coming from the exact same String will not be + * equals()! As such, it would be confusing to make the pattern part of this + * class's equals/hashCode + */ + private final transient Pattern pattern; + + public EventNamePattern(String eventName) { + if (eventName == null) { + throw new IllegalArgumentException(); + } + + originalEventName = eventName; + pattern = patternFromEventName(eventName); + } + + public String getEventName() { + return originalEventName; + } + + public Pattern getPattern() { + return pattern; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + originalEventName.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + EventNamePattern other = (EventNamePattern) obj; + if (!originalEventName.equals(other.originalEventName)) { + return false; + } + return true; + } + + private static Pattern patternFromEventName(String eventName) { + /* + * The situation here is that `\*` means a literal `*` in the event + * name, and `*` is a wildcard star. We check the event name one + * character at a time and create a list of tokens to be converter to + * partial patterns. + */ + StringBuilder bigBuilder = new StringBuilder("^"); + StringBuilder smallBuilder = new StringBuilder(); + + for (int i = 0; i < eventName.length(); i++) { + char c = eventName.charAt(i); + + switch (c) { + case '*': + /* Add current quoted builder's string if not empty. */ + if (smallBuilder.length() > 0) { + bigBuilder.append(Pattern.quote(smallBuilder.toString())); + smallBuilder.setLength(0); + } + + /* Append the equivalent regex which is `.*`. */ + bigBuilder.append(".*"); + continue; + + case '\\': + /* We only escape `*` and `\` here. */ + if (i < (eventName.length() - 1)) { + char nextChar = eventName.charAt(i + 1); + + if (nextChar == '*' || nextChar == '\\') { + smallBuilder.append(nextChar); + } else { + smallBuilder.append(c); + smallBuilder.append(nextChar); + } + + i++; + continue; + } + break; + + default: + break; + } + + smallBuilder.append(c); + } + + /* Add current quoted builder's string if not empty. */ + if (smallBuilder.length() > 0) { + bigBuilder.append(Pattern.quote(smallBuilder.toString())); + } + + bigBuilder.append("$"); + + return Pattern.compile(bigBuilder.toString()); + } +}