2 * Copyright (C) 2015 - EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
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.
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
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
18 package org
.lttng
.ust
.agent
.context
;
20 import java
.io
.IOException
;
21 import java
.util
.HashMap
;
23 import java
.util
.concurrent
.ConcurrentHashMap
;
24 import java
.util
.regex
.Matcher
;
25 import java
.util
.regex
.Pattern
;
28 * The singleton manager of {@link IContextInfoRetriever} objects.
30 * @author Alexandre Montplaisir
32 public final class ContextInfoManager
{
34 private static final String SHARED_LIBRARY_NAME
= "lttng-ust-context-jni";
36 private static final Pattern VALID_CONTEXT_NAME_PATTERN
= Pattern
.compile("^[a-zA-Z0-9_\\.]+$");
38 private static ContextInfoManager instance
;
40 private final Map
<String
, IContextInfoRetriever
> contextInfoRetrievers
= new ConcurrentHashMap
<String
, IContextInfoRetriever
>();
41 private final Map
<String
, Long
> contextInforRetrieverRefs
= new HashMap
<String
, Long
>();
43 private final Object retrieverLock
= new Object();
45 /** Singleton class, constructor should not be accessed directly */
46 private ContextInfoManager() {
50 * Get the singleton instance.
53 * Usage of this class requires the "liblttng-ust-context-jni.so" native
54 * library to be present on the system and available (passing
55 * -Djava.library.path=path to the JVM may be needed).
58 * @return The singleton instance
60 * If the shared library cannot be found.
61 * @throws SecurityException
62 * We will forward any SecurityExcepion that may be thrown when
63 * trying to load the JNI library.
65 public static synchronized ContextInfoManager
getInstance() throws IOException
, SecurityException
{
66 if (instance
== null) {
68 System
.loadLibrary(SHARED_LIBRARY_NAME
);
69 } catch (UnsatisfiedLinkError e
) {
70 throw new IOException(e
);
72 instance
= new ContextInfoManager();
78 * Register a new context info retriever.
81 * Each context info retriever is registered with a given "retriever name",
82 * which specifies the namespace of the context elements. This name is
83 * specified separately from the retriever objects, which would allow
84 * register the same retriever under different namespaces for example.
88 * If the method returns false (indicating registration failure), then the
89 * retriever object will *not* be used for context information.
92 * @param retrieverName
93 * The name to register to the context retriever object with.
94 * @param contextInfoRetriever
95 * The context info retriever to register
96 * @return True if the retriever was successfully registered, false if there
97 * was an error, for example if a retriever is already registered
100 public boolean registerContextInfoRetriever(String retrieverName
, IContextInfoRetriever contextInfoRetriever
) {
101 synchronized (retrieverLock
) {
102 if (!validateRetrieverName(retrieverName
)) {
106 if (contextInfoRetrievers
.containsKey(retrieverName
)) {
108 * There is already a retriever registered with that name,
109 * refuse the new registration.
114 * Inform LTTng-UST of the new retriever. The names have to start
115 * with "$app." on the UST side!
117 long ref
= LttngContextApi
.registerProvider("$app." + retrieverName
);
122 contextInfoRetrievers
.put(retrieverName
, contextInfoRetriever
);
123 contextInforRetrieverRefs
.put(retrieverName
, Long
.valueOf(ref
));
130 * Unregister a previously added context info retriever.
132 * This method has no effect if the retriever was not already registered.
134 * @param retrieverName
135 * The context info retriever to unregister
136 * @return True if unregistration was successful, false if there was an
139 public boolean unregisterContextInfoRetriever(String retrieverName
) {
140 synchronized (retrieverLock
) {
141 if (!contextInfoRetrievers
.containsKey(retrieverName
)) {
143 * There was no retriever registered with that name.
147 contextInfoRetrievers
.remove(retrieverName
);
148 long ref
= contextInforRetrieverRefs
.remove(retrieverName
).longValue();
150 /* Unregister the retriever on the UST side too */
151 LttngContextApi
.unregisterProvider(ref
);
158 * Return the context info retriever object registered with the given name.
160 * @param retrieverName
161 * The retriever name to look for
162 * @return The corresponding retriever object, or <code>null</code> if there
165 public IContextInfoRetriever
getContextInfoRetriever(String retrieverName
) {
166 return contextInfoRetrievers
.get(retrieverName
);
170 * Validate that the given retriever name contains only the allowed
171 * characters, which are alphanumerical characters, period "." and
172 * underscore "_". The name must also not start with a number.
174 private static boolean validateRetrieverName(String contextName
) {
175 if (contextName
.isEmpty()) {
179 /* First character must not be a number */
180 if (Character
.isDigit(contextName
.charAt(0))) {
184 /* Validate the other characters of the string */
185 Matcher matcher
= VALID_CONTEXT_NAME_PATTERN
.matcher(contextName
);
186 return matcher
.matches();