/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* This repository does not support persistency.
*
* @since 1.5
*/
public class Repository {
/**
* An interface that allows the caller to get some control
* over the registration.
* @see #addMBean
* @see #remove
*/
public interface RegistrationContext {
/**
* Called by {@link #addMBean}.
* Can throw a RuntimeOperationsException to cancel the
* registration.
*/
public void registering();
/**
* Called by {@link #remove}.
* Any exception thrown by this method will be ignored.
*/
public void unregistered();
}
// Private fields -------------------------------------------->
/**
* The structure for storing the objects is very basic.
* A Hashtable is used for storing the different domains
* For each domain, a hashtable contains the instances with
* canonical key property list string as key and named object
* aggregated from given object name and mbean instance as value.
*/
/**
* Number of elements contained in the Repository
*/
/**
* Domain name of the server the repository is attached to.
* It is quicker to store the information in the repository rather
* than querying the framework each time the info is required.
*/
/**
* We use a global reentrant read write lock to protect the repository.
* This seems safer and more efficient: we are using Maps of Maps,
* Guaranteing consistency while using Concurent objects at each level
* may be more difficult.
**/
// Private fields <=============================================
// Private methods --------------------------------------------->
/* This class is used to match an ObjectName against a pattern. */
private final static class ObjectNamePattern {
private final boolean isPropertyListPattern;
private final boolean isPropertyValuePattern;
/**
* The ObjectName pattern against which ObjectNames are matched.
**/
/**
* Builds a new ObjectNamePattern object from an ObjectName pattern.
* @param pattern The ObjectName pattern under examination.
**/
this(pattern.isPropertyListPattern(),
pattern);
}
/**
* Builds a new ObjectNamePattern object from an ObjectName pattern
* constituents.
* @param propertyListPattern pattern.isPropertyListPattern().
* @param propertyValuePattern pattern.isPropertyValuePattern().
* @param canonicalProps pattern.getCanonicalKeyPropertyListString().
* @param keyPropertyList pattern.getKeyPropertyList().
* @param pattern The ObjectName pattern under examination.
**/
boolean propertyValuePattern,
this.properties = canonicalProps;
int i = 0;
i++;
}
}
/**
* Return true if the given ObjectName matches the ObjectName pattern
* for which this object has been built.
* WARNING: domain name is not considered here because it is supposed
* not to be wildcard when called. PropertyList is also
* supposed not to be zero-length.
* @param name The ObjectName we want to match against the pattern.
* @return true if <code>name</code> matches the pattern.
**/
// If key property value pattern but not key property list
// pattern, then the number of key properties must be equal
//
if (isPropertyValuePattern &&
return false;
// If key property value pattern or key property list pattern,
// then every property inside pattern should exist in name
//
if (isPropertyValuePattern || isPropertyListPattern) {
// Find value in given object name for key at current
// index in receiver
//
// Did we find a value for this key ?
//
if (v == null) return false;
// If this property is ok (same key, same value), go to next
//
if (isPropertyValuePattern &&
// wildmatch key property values
// values[i] is the pattern;
// v is the string
continue;
else
return false;
}
return false;
}
return true;
}
// If no pattern, then canonical names must be equal
//
}
}
/**
* Add all the matching objects from the given hashtable in the
* result set for the given ObjectNamePattern
* Do not check whether the domains match (only check for matching
* key property lists - see <i>matchKeys()</i>)
**/
final ObjectNamePattern pattern) {
synchronized (moiTb) {
// if all couples (property, value) are contained
}
}
}
final ObjectName name,
final RegistrationContext context) {
nbElements++;
}
try {
} catch (RuntimeOperationsException x) {
throw x;
} catch (RuntimeException x) {
throw new RuntimeOperationsException(x);
}
}
try {
} catch (Exception x) {
// shouldn't come here...
"Unexpected exception while unregistering "+name,
x);
}
}
final ObjectName name,
final RegistrationContext context) {
}
/**
* Retrieves the named object contained in repository
* from the given objectname.
*/
// No patterns inside reposit
// Extract the domain name.
// Default domain case
}
return null; // No domain containing registered object names
}
}
// Private methods <=============================================
// Protected methods --------------------------------------------->
// Protected methods <=============================================
// Public methods --------------------------------------------->
/**
* Construct a new repository with the given default domain.
*/
this(domain,true);
}
/**
* Construct a new repository with the given default domain.
*/
else
// Creates a new hashtable for the default domain
}
/**
* Returns the list of domains in which any MBean is currently
* registered.
*
*/
try {
// Temporary list
// Skip domains that are in the table but have no
// MBean registered in them
// in particular the default domain may be like this
}
} finally {
}
// Make an array from result.
}
/**
* Stores an MBean associated with its object name in the repository.
*
* @param object MBean to be stored in the repository.
* @param name MBean object name.
* @param context A registration context. If non null, the repository
* will call {@link RegistrationContext#registering()
* context.registering()} from within the repository
* lock, when it has determined that the {@code object}
* can be stored in the repository with that {@code name}.
* If {@link RegistrationContext#registering()
* context.registering()} throws an exception, the
* operation is abandonned, the MBean is not added to the
* repository, and a {@link RuntimeOperationsException}
* is thrown.
*/
final RegistrationContext context)
throws InstanceAlreadyExistsException {
}
// Extract the domain name.
boolean to_default_domain = false;
// Set domain to default if domain is empty and not already set
// Do we have default domain ?
to_default_domain = true;
} else {
to_default_domain = false;
}
// Validate name for an object
throw new RuntimeOperationsException(
new IllegalArgumentException("Repository: cannot add mbean for " +
}
try {
// Domain cannot be JMImplementation if entry does not exist
if ( !to_default_domain &&
throw new RuntimeOperationsException(
"Repository: domain name cannot be JMImplementation"));
}
// If domain does not already exist, add it to the hash table
return;
} else {
// Add instance if not already present
} else {
nbElements++;
}
}
} finally {
}
}
/**
* Checks whether an MBean of the name specified is already stored in
* the repository.
*
* @param name name of the MBean to find.
*
* @return true if the MBean is stored in the repository,
* false otherwise.
*/
}
try {
} finally {
}
}
/**
* Retrieves the MBean of the name specified from the repository. The
* object name must match exactly.
*
* @param name name of the MBean to retrieve.
*
* @return The retrieved MBean if it is contained in the repository,
* null otherwise.
*/
}
// Calls internal retrieve method to get the named object
try {
} finally {
}
}
/**
* Selects and retrieves the list of MBeans whose names match the specified
* object name pattern and which match the specified query expression
* (optionally).
*
* @param pattern The name of the MBean(s) to retrieve - may be a specific
* object or a name pattern allowing multiple MBeans to be selected.
* @param query query expression to apply when selecting objects - this
* parameter will be ignored when the Repository Service does not
* support filtering.
*
* @return The list of MBeans selected. There may be zero, one or many
* MBeans returned in the set.
*/
// The following filter cases are considered:
// null, "", "*:*" : names in all domains
// ":*", ":[key=value],*" : names in defaultDomain
// "domain:*", "domain:[key=value],*" : names in the specified domain
// Surely one of the most frequent cases ... query on the whole world
try {
// If pattern is not a pattern, retrieve this mbean !
return result;
}
// All names in all domains
}
return result;
}
final boolean allNames =
final ObjectNamePattern namePattern =
// All names in default domain
if (allNames)
else
return result;
}
if (!name.isDomainPattern()) {
if (allNames)
else
return result;
}
// Pattern matching in the domain name (*, ?)
if (allNames)
else
}
}
return result;
} finally {
}
}
/**
* Removes an MBean from the repository.
*
* @param name name of the MBean to remove.
* @param context A registration context. If non null, the repository
* will call {@link RegistrationContext#unregistered()
* context.unregistered()} from within the repository
* lock, just after the mbean associated with
* {@code name} is removed from the repository.
* If {@link RegistrationContext#unregistered()
* context.unregistered()} is not expected to throw any
* exception. If it does, the exception is logged
* and swallowed.
*
* @exception InstanceNotFoundException The MBean does not exist in
* the repository.
*/
final RegistrationContext context)
throws InstanceNotFoundException {
// Debugging stuff
}
// Extract domain name.
// Default domain case
try {
// Find the domain subtable
}
// Remove the corresponding element
}
// We removed it !
nbElements--;
// No more object for this domain, we remove this domain hashtable
// set a new default domain table (always present)
// need to reinstantiate a hashtable because of possible
// big buckets array size inside table, never cleared,
// thus the new !
}
} finally {
}
}
/**
* Gets the number of MBeans stored in the repository.
*
* @return Number of MBeans.
*/
return nbElements;
}
/**
* Gets the name of the domain currently used by default in the
* repository.
*
* @return A string giving the name of the default domain name.
*/
return domain;
}
// Public methods <=============================================
}