commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nico...@apache.org
Subject svn commit: r721657 [2/3] - in /commons/sandbox/monitoring/branches/modules: core/src/ core/src/main/ core/src/main/java/ core/src/main/java/org/ core/src/main/java/org/apache/ core/src/main/java/org/apache/commons/ core/src/main/java/org/apache/common...
Date Sat, 29 Nov 2008 09:08:44 GMT
Added: commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/AbstractMonitor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/AbstractMonitor.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/AbstractMonitor.java (added)
+++ commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/AbstractMonitor.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.monitors;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.commons.monitoring.Counter;
+import org.apache.commons.monitoring.Gauge;
+import org.apache.commons.monitoring.Metric;
+import org.apache.commons.monitoring.Monitor;
+import org.apache.commons.monitoring.Role;
+
+/**
+ * Abstract {@link Monitor} with implementation for base methods
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public abstract class AbstractMonitor implements Monitor
+{
+
+    @SuppressWarnings("unchecked")
+    private final ConcurrentMap<Role, Metric<?>> metrics;
+    private final Key key;
+
+    public AbstractMonitor( Key key )
+    {
+        super();
+        this.key = key;
+        this.metrics = createConcurrentMap();
+    }
+
+    /**
+     * User with very specific requirements or fine knowledge of Java Concurrency may override this method and use
+     * another implementation of ConcurrentMap. In such case, please post feedback to apache-commons dev list !
+     *
+     * @return the ConcurrentMap implementation to use for storing metrics
+     */
+    @SuppressWarnings("unchecked")
+    protected ConcurrentHashMap<Role, Metric<?>> createConcurrentMap()
+    {
+        return new ConcurrentHashMap<Role, Metric<?>>();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final Key getKey()
+    {
+        return key;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final Metric<?> getMetric( String role )
+    {
+        return metrics.get( role );
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T extends Metric<?>> T getMetric( Role<T> role )
+    {
+        return (T) metrics.get( role );
+    }
+
+    @SuppressWarnings("unchecked")
+    public final Collection<Role> getRoles()
+    {
+        return Collections.unmodifiableCollection( metrics.keySet() );
+    }
+
+    public Collection<Metric<?>> getMetrics()
+    {
+        return Collections.unmodifiableCollection( metrics.values() );
+    }
+
+    /**
+     * Register a new Metric in the monitor
+     *
+     * @param metric Metric instance to get registered
+     * @return a previously registered Metric if existed, or <code>null</code> if the metric has been successfully
+     * registered
+     */
+    @SuppressWarnings("unchecked")
+    protected <M extends Metric<?>> M register( M metric )
+    {
+        metric.setMonitor( this );
+        return (M) metrics.putIfAbsent( metric.getRole(), metric );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void reset()
+    {
+        for ( Metric<?> metric : metrics.values() )
+        {
+            metric.reset();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public Counter getCounter( String role )
+    {
+        return getCounter( (Role<Counter>) Role.getRole( role ) );
+    }
+
+    @SuppressWarnings("unchecked")
+    public Gauge getGauge( String role )
+    {
+        return getGauge( (Role<Gauge>) Role.getRole( role ) );
+    }
+
+    public Counter getCounter( Role<Counter> role )
+    {
+        return (Counter) getMetric( role );
+    }
+
+    public Gauge getGauge( Role<Gauge> role )
+    {
+        return (Gauge) getMetric( role );
+    }
+
+}
\ No newline at end of file

Added: commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/CreateMetricsOnDemandMonitor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/CreateMetricsOnDemandMonitor.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/CreateMetricsOnDemandMonitor.java (added)
+++ commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/CreateMetricsOnDemandMonitor.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.monitors;
+
+import org.apache.commons.monitoring.Counter;
+import org.apache.commons.monitoring.Gauge;
+import org.apache.commons.monitoring.Role;
+
+/**
+ * implementation of the <code>Monitor</code> interface that creates Metrics on
+ * demand. The application can request for Counters/Gauges without having to
+ * handle instantiation of monitors with all required Metrics pre-registered.
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public abstract class CreateMetricsOnDemandMonitor
+    extends AbstractMonitor
+{
+
+    public CreateMetricsOnDemandMonitor( Key key )
+    {
+        super( key );
+    }
+
+    public Counter getCounter( Role<Counter> role )
+    {
+        Counter counter = getMetric( role );
+        if ( counter != null )
+        {
+            return counter;
+        }
+        counter = newCounterInstance( role );
+        Counter previous = register( counter );
+        return previous != null ? previous : counter;
+    }
+
+    public Gauge getGauge( Role<Gauge> role )
+    {
+        Gauge gauge = getMetric( role );
+        if ( gauge != null )
+        {
+            return gauge;
+        }
+        gauge = newGaugeInstance( role );
+        Gauge previous = register( gauge );
+        return previous != null ? previous : gauge;
+    }
+
+    /**
+     * Create a new Counter instance
+     * <p>
+     * As the monitor can be used by multiple threads, this method MAY be
+     * executed to create more than one instance for the same role, so DON'T
+     * assume unicity here.
+     */
+    protected abstract Counter newCounterInstance( Role<Counter> role );
+
+    /**
+     * Create a new Gauge instance
+     * <p>
+     * As the monitor can be used by multiple threads, this method MAY be
+     * executed to create more than one instance for the same role, so DON'T
+     * assume unicity here.
+     */
+    protected abstract Gauge newGaugeInstance( Role<Gauge> role );
+}

Added: commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/DefaultMonitor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/DefaultMonitor.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/DefaultMonitor.java (added)
+++ commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/DefaultMonitor.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.monitors;
+
+import org.apache.commons.monitoring.Counter;
+import org.apache.commons.monitoring.Gauge;
+import org.apache.commons.monitoring.Role;
+import org.apache.commons.monitoring.metrics.RentrantLockCounter;
+import org.apache.commons.monitoring.metrics.RentrantLockGauge;
+
+/**
+ * A Monitor implementation that creates
+ * {@link org.apache.commons.monitoring.Composite} Gauges and Counters.
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public class DefaultMonitor
+    extends ObservableMonitor
+{
+
+    public DefaultMonitor( Key key )
+    {
+        super( key );
+    }
+
+    @Override
+    protected Counter newCounterInstance( Role<Counter> role )
+    {
+        return new RentrantLockCounter( role );
+    }
+
+    @Override
+    protected Gauge newGaugeInstance( Role<Gauge> role )
+    {
+        return new RentrantLockGauge( role );
+    }
+
+}

Added: commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/NullMonitor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/NullMonitor.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/NullMonitor.java (added)
+++ commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/NullMonitor.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,84 @@
+package org.apache.commons.monitoring.monitors;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.apache.commons.monitoring.Counter;
+import org.apache.commons.monitoring.Gauge;
+import org.apache.commons.monitoring.Metric;
+import org.apache.commons.monitoring.Monitor;
+import org.apache.commons.monitoring.Role;
+import org.apache.commons.monitoring.Unit;
+import org.apache.commons.monitoring.metrics.NoOpCounter;
+import org.apache.commons.monitoring.metrics.NoOpGauge;
+
+/**
+ * Monitor implementation that does nothing, and return NoOp metrics when requested. Designed for test purpose or to
+ * disable monitoring to compare monitored to unmonitored performances.
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+@SuppressWarnings( "unchecked" )
+public class NullMonitor
+    implements Monitor
+{
+    private static Role NOOP = new Role( "NoOp", Unit.UNARY, Metric.class );
+
+    private static NoOpCounter counter = new NoOpCounter( NOOP );
+
+    private static NoOpGauge gauge = new NoOpGauge( NOOP );
+
+    private Collection<Metric<?>> metrics = Arrays.asList( new Metric<?>[] { counter, gauge } );
+
+    public Counter getCounter( String role )
+    {
+        return counter;
+    }
+
+    public Counter getCounter( Role<Counter> role )
+    {
+        return counter;
+    }
+
+    public Gauge getGauge( String role )
+    {
+        return gauge;
+    }
+
+    public Gauge getGauge( Role<Gauge> role )
+    {
+        return gauge;
+    }
+
+    public Key getKey()
+    {
+        return new Key( "noOp", null, null );
+    }
+
+    public Metric getMetric( String role )
+    {
+        return counter;
+    }
+
+    public <M extends Metric<?>> M getMetric( Role<M> role )
+    {
+        return (M) counter;
+    }
+
+    public Collection<Metric<?>> getMetrics()
+    {
+        return metrics;
+    }
+
+    public Collection<Role> getRoles()
+    {
+        return Collections.singletonList( NOOP );
+    }
+
+    public void reset()
+    {
+        // NoOp
+    }
+
+}

Added: commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/ObservableMonitor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/ObservableMonitor.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/ObservableMonitor.java (added)
+++ commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/ObservableMonitor.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.monitors;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.commons.monitoring.Metric;
+import org.apache.commons.monitoring.Monitor;
+
+/**
+ * Implements <tt>Observale</tt> pattern on the Monitor
+ * <p>
+ * Use a CopyOnWriteArrayList to avoid synchronization
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public abstract class ObservableMonitor
+    extends CreateMetricsOnDemandMonitor
+    implements Monitor.Observable
+{
+
+    private List<Listener> listeners;
+
+    /**
+     * Constructor
+     *
+     * @param key the monitor identifier
+     */
+    public ObservableMonitor( Key key )
+    {
+        super( key );
+        this.listeners = new CopyOnWriteArrayList<Listener>();
+    }
+
+    /**
+     * Notify listeners of a new metric beeing registered.
+     *
+     * @param metric
+     * @param role
+     * @return the registered metric, or a previously existing one for the role
+     */
+    @Override
+    protected <T extends Metric<?>> T register( T metric )
+    {
+        T previous = (T) super.register( metric );
+        if ( previous != null )
+        {
+            return previous;
+        }
+        for ( Listener listener : listeners )
+        {
+            listener.onMetricRegistered( this, metric );
+        }
+        return null;
+    }
+
+    public void addListener( Listener listener )
+    {
+        listeners.add( listener );
+    }
+
+    public void removeListener( Listener listener )
+    {
+        listeners.remove( listener );
+    }
+}
\ No newline at end of file

Added: commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/ObserverMonitor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/ObserverMonitor.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/ObserverMonitor.java (added)
+++ commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/monitors/ObserverMonitor.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,83 @@
+package org.apache.commons.monitoring.monitors;
+
+import org.apache.commons.monitoring.Counter;
+import org.apache.commons.monitoring.Detachable;
+import org.apache.commons.monitoring.Gauge;
+import org.apache.commons.monitoring.Metric;
+import org.apache.commons.monitoring.Monitor;
+import org.apache.commons.monitoring.metrics.ObserverCounter;
+import org.apache.commons.monitoring.metrics.ObserverGauge;
+
+public class ObserverMonitor
+    extends AbstractMonitor
+    implements Monitor.Listener, Detachable
+{
+    /**
+     * The monitor beeing observed. All event/data gathered by this monitor will be duplicated here
+     */
+    private Monitor.Observable observable;
+
+    private boolean detached;
+
+    private long attachedAt;
+
+    private long detachedAt;
+
+    public ObserverMonitor( Monitor.Observable observable )
+    {
+        super( observable.getKey() );
+        this.observable = observable;
+        this.attachedAt = System.currentTimeMillis();
+        this.detached = false;
+        this.observable.addListener( this );
+        for ( Metric<?> metric : observable.getMetrics() )
+        {
+            onMetricRegistered( observable, metric );
+        }
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public void onMetricRegistered( Monitor.Observable monitor, Metric metric )
+    {
+        if ( metric instanceof Counter.Observable )
+        {
+            register( new ObserverCounter( (Counter.Observable) metric ) );
+        }
+        else if ( metric instanceof Gauge.Observable )
+        {
+            register( new ObserverGauge( (Gauge.Observable) metric ) );
+        }
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public void detach()
+    {
+        detached = true;
+        for ( Metric<?> metric : observable.getMetrics() )
+        {
+            if ( metric instanceof Metric.Observable<?> )
+            {
+                Metric.Observable<?> observableMetric = (Metric.Observable<?>) metric;
+                Metric.Listener observer = (Metric.Listener) getMetric( metric.getRole() );
+                observableMetric.removeListener( observer );
+            }
+        }
+        detachedAt = System.currentTimeMillis();
+    }
+
+    public boolean isDetached()
+    {
+        return detached;
+    }
+
+    public long getAttachedAt()
+    {
+        return attachedAt;
+    }
+
+    public long getDetachedAt()
+    {
+        return detachedAt;
+    }
+
+}

Added: commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/AbstractRepository.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/AbstractRepository.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/AbstractRepository.java (added)
+++ commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/AbstractRepository.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.repositories;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.commons.monitoring.Monitor;
+import org.apache.commons.monitoring.Repository;
+import org.apache.commons.monitoring.Monitor.Key;
+
+/**
+ * Abstract implementation of {@link Repository} with support for base methods.
+ * <p>
+ * Only implements the convenient <code>getMonitor( * )</code> methods.
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public abstract class AbstractRepository
+    implements Repository
+{
+    private final ConcurrentMap<Monitor.Key, Monitor> monitors;
+
+    public AbstractRepository()
+    {
+        super();
+        this.monitors = createConcurrentMap();
+    }
+
+    /**
+     * User with very specific requirements or fine knowledge of Java Concurrency may override this method and use
+     * another implementation of ConcurrentMap. In such case, please post feedback to apache-commons dev list !
+     *
+     * @return the ConcurrentMap implementation to use for storing monitors
+     */
+    protected ConcurrentMap<Monitor.Key, Monitor> createConcurrentMap()
+    {
+        return new ConcurrentHashMap<Monitor.Key, Monitor>( 50 );
+    }
+
+    public Monitor getMonitor( String name )
+    {
+        return getMonitor( name, Key.DEFAULT, Key.DEFAULT );
+    }
+
+    public Monitor getMonitor( String name, String category )
+    {
+        return getMonitor( name, category, Key.DEFAULT );
+    }
+
+    public Monitor getMonitor( String name, String category, String subsystem )
+    {
+        return getMonitor( new Monitor.Key( name, category, subsystem ) );
+    }
+
+    public Monitor getMonitor( Key key )
+    {
+        Monitor monitor = monitors.get( key );
+        if ( monitor == null )
+        {
+            monitor = newMonitorInstance( key );
+            Monitor previous = register( monitor );
+            if ( previous != null )
+            {
+                monitor = previous;
+            }
+        }
+        return monitor;
+    }
+
+    /**
+     * Create a new monitor instance for the dedicated Key.
+     * <p>
+     * As the repository can be used by multiple threads, this method MAY be
+     * executed to create more than one instance for the same key, so DON'T
+     * assume unicity here.
+     * @param key
+     * @return
+     */
+    protected abstract Monitor newMonitorInstance( Key key );
+
+    /**
+     * Register a new monitor in the repository
+     *
+     * @param monitor Monitor instance to get registered
+     * @return a previously registered monitor if existed, or <code>null</code>
+     * if monitor has been successfully registered
+     */
+    protected Monitor register( Monitor monitor )
+    {
+        return monitors.putIfAbsent( monitor.getKey(), monitor );
+    }
+
+    public Set<String> getCategories()
+    {
+        Set<String> categories = new HashSet<String>();
+        for ( Key key : monitors.keySet() )
+        {
+            categories.add( key.getCategory() );
+        }
+        return categories;
+    }
+
+    public Set<String> getSubSystems()
+    {
+        Set<String> subsystems = new HashSet<String>();
+        for ( Key key : monitors.keySet() )
+        {
+            subsystems.add( key.getSubsystem() );
+        }
+        return subsystems;
+    }
+
+    public Collection<Monitor> getMonitors()
+    {
+        return Collections.unmodifiableCollection( monitors.values() );
+    }
+
+    public Collection<Monitor> getMonitorsFromCategory( String category )
+    {
+        Collection<Monitor> filtered = new LinkedList<Monitor>();
+        for ( Monitor monitor : monitors.values() )
+        {
+            if ( category.equals( monitor.getKey().getCategory() ) )
+            {
+                filtered.add( monitor );
+            }
+        }
+        return filtered;
+    }
+
+    public Collection<Monitor> getMonitorsFromSubSystem( String subsystem )
+    {
+        Collection<Monitor> filtered = new LinkedList<Monitor>();
+        for ( Monitor monitor : monitors.values() )
+        {
+            if ( subsystem.equals( monitor.getKey().getSubsystem() ) )
+            {
+                filtered.add( monitor );
+            }
+        }
+        return filtered;
+    }
+
+    public void clear()
+    {
+        monitors.clear();
+    }
+
+    public void reset()
+    {
+        for ( Monitor monitor : monitors.values() )
+        {
+            monitor.reset();
+        }
+    }
+
+}
\ No newline at end of file

Added: commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/ConfigurableImplementationsRepository.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/ConfigurableImplementationsRepository.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/ConfigurableImplementationsRepository.java (added)
+++ commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/ConfigurableImplementationsRepository.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.repositories;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.commons.monitoring.Monitor;
+import org.apache.commons.monitoring.StopWatch;
+import org.apache.commons.monitoring.Monitor.Key;
+
+/**
+ * Implementation of the Repository that can be used to configure custom
+ * {@link StopWatch} or {@link Monitor} implementation.
+ * <p>
+ * Uses reflection to invoke constructor on the specified implementation classes.
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public class ConfigurableImplementationsRepository
+    extends ObservableRepository
+{
+    private Constructor<? extends StopWatch> stopWatchConstructor;
+
+    private Constructor<? extends Monitor> monitorConstructor;
+
+    /**
+     * Constructor
+     * @param stopWatchImplementation the StopWatch implementation to use
+     * @param monitorImplementation the Monitor implementation to use
+     */
+    public ConfigurableImplementationsRepository( Class<? extends StopWatch> stopWatchImplementation,
+                                                  Class<? extends Monitor> monitorImplementation )
+    {
+        super();
+        setStopWatchImplementation( stopWatchImplementation );
+        setMonitorImplementation( monitorImplementation );
+    }
+
+    protected void setStopWatchImplementation( Class<? extends StopWatch> implementation )
+    {
+        try
+        {
+            stopWatchConstructor = implementation.getConstructor( Monitor.class );
+        }
+        catch ( Exception e )
+        {
+            throw new IllegalStateException( "Invalid StopWatch implemenation. Constructor <init>(Monitor) required" );
+        }
+    }
+
+    protected void setMonitorImplementation( Class<? extends Monitor> implementation )
+    {
+        try
+        {
+            monitorConstructor = implementation.getConstructor( Monitor.Key.class );
+        }
+        catch ( Exception e )
+        {
+            throw new IllegalStateException(
+                "Invalid StopWatch implemenation. Constructor <init>(Monitor.Key) required" );
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see org.apache.commons.monitoring.repositories.AbstractRepository#newMonitorInstance(org.apache.commons.monitoring.Monitor.Key)
+     */
+    @Override
+    protected Monitor newMonitorInstance( Key key )
+    {
+        try
+        {
+            return monitorConstructor.newInstance( key );
+        }
+        catch ( InvocationTargetException e )
+        {
+            throw new IllegalStateException( "Failed to invoke configured stopWatchConstructor ", e.getTargetException() );
+        }
+        catch ( Exception e )
+        {
+            throw new IllegalStateException( "Invalid stopWatchConstructor configured in repository "
+                + stopWatchConstructor );
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see org.apache.commons.monitoring.Repository#start(org.apache.commons.monitoring.Monitor)
+     */
+    public StopWatch start( Monitor monitor )
+    {
+        try
+        {
+            return stopWatchConstructor.newInstance( monitor );
+        }
+        catch ( InvocationTargetException e )
+        {
+            throw new IllegalStateException( "Failed to invoke configured stopWatchConstructor ", e.getTargetException() );
+        }
+        catch ( Exception e )
+        {
+            throw new IllegalStateException( "Invalid stopWatchConstructor configured in repository "
+                + stopWatchConstructor, e );
+        }
+    }
+}

Added: commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/DefaultRepository.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/DefaultRepository.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/DefaultRepository.java (added)
+++ commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/DefaultRepository.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.repositories;
+
+import org.apache.commons.monitoring.Monitor;
+import org.apache.commons.monitoring.StopWatch;
+import org.apache.commons.monitoring.Monitor.Key;
+import org.apache.commons.monitoring.monitors.DefaultMonitor;
+import org.apache.commons.monitoring.stopwatches.DefaultStopWatch;
+
+
+/**
+ * Default Repository implementation
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public class DefaultRepository extends ObservableRepository
+{
+
+    @Override
+    protected Monitor newMonitorInstance( Key key )
+    {
+        return new DefaultMonitor( key );
+    }
+
+    public StopWatch start( Monitor monitor )
+    {
+        return new DefaultStopWatch( monitor );
+    }
+
+}

Added: commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/ObservableRepository.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/ObservableRepository.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/ObservableRepository.java (added)
+++ commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/ObservableRepository.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.repositories;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.commons.monitoring.Monitor;
+
+/**
+ * Implements <tt>Observale</tt> pattern on the repository
+ * <p>
+ * Use a CopyOnWriteArrayList to avoid synchronization
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public abstract class ObservableRepository
+    extends AbstractRepository
+{
+
+    protected List<Listener> listeners;
+
+    public ObservableRepository()
+    {
+        super();
+        listeners = new CopyOnWriteArrayList<Listener>();
+    }
+
+
+    public void addListener( Listener listener )
+    {
+        listeners.add( listener );
+    }
+
+    public void removeListener( Listener listener )
+    {
+        listeners.remove( listener );
+    }
+
+    /**
+     * Dispatch a <tt>newMonitorInstance</tt> event to listener when a new monitor instance is registered to the
+     * repository. Note that unused monitors that may have been created in multi-threaded environements are not
+     * considered.
+     *
+     * @see org.apache.commons.monitoring.repositories.AbstractRepository#register(org.apache.commons.monitoring.Monitor)
+     */
+    @Override
+    protected Monitor register( Monitor monitor )
+    {
+        Monitor previous = super.register( monitor );
+        if ( previous != null )
+        {
+            return previous;
+        }
+        for ( Listener listener : listeners )
+        {
+            listener.newMonitorInstance( monitor );
+        }
+        return null;
+    }
+
+}

Added: commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/ObserverRepository.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/ObserverRepository.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/ObserverRepository.java (added)
+++ commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/repositories/ObserverRepository.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.repositories;
+
+import org.apache.commons.monitoring.Detachable;
+import org.apache.commons.monitoring.Monitor;
+import org.apache.commons.monitoring.Repository;
+import org.apache.commons.monitoring.StopWatch;
+import org.apache.commons.monitoring.Monitor.Key;
+import org.apache.commons.monitoring.monitors.NullMonitor;
+import org.apache.commons.monitoring.monitors.ObserverMonitor;
+
+/**
+ * A repository implementation that registers as a <tt>Listener</tt> to an
+ * <tt>Observable</tt> repository and maintains a set of Monitors in sync with
+ * the observed repository.
+ * <p>
+ * As a <tt>Detachable</tt> implementation, the SecondaryRepository can be
+ * detached from the observed repository and used to build a report for the
+ * observed period.
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public class ObserverRepository
+    extends AbstractRepository
+    implements Repository.Listener, Detachable
+{
+    private Repository.Observable repository;
+
+    private boolean detached;
+
+    private long attachedAt;
+
+    private long detachedAt;
+
+    public ObserverRepository( Repository.Observable repository )
+    {
+        super();
+        this.repository = repository;
+        this.attachedAt = System.currentTimeMillis();
+        this.detached = false;
+        for ( Monitor monitor : repository.getMonitors() )
+        {
+            if ( monitor instanceof Monitor.Observable )
+            {
+                register( new ObserverMonitor( (Monitor.Observable) monitor ) );
+            }
+        }
+        repository.addListener( this );
+    }
+
+    public void detach()
+    {
+        detached = true;
+        repository.removeListener( this );
+        for ( Monitor monitor : getMonitors() )
+        {
+            ( (Detachable) monitor ).detach();
+        }
+        this.detachedAt = System.currentTimeMillis();
+    }
+
+    /**
+     * @see org.apache.commons.monitoring.Repository.Listener#newMonitorInstance(org.apache.commons.monitoring.Monitor)
+     */
+    public void newMonitorInstance( Monitor monitor )
+    {
+        if ( !detached && monitor instanceof Monitor.Observable )
+        {
+            register( new ObserverMonitor( (Monitor.Observable) monitor ) );
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see org.apache.commons.monitoring.Repository#start(org.apache.commons.monitoring.Monitor)
+     */
+    public StopWatch start( Monitor monitor )
+    {
+        throw new UnsupportedOperationException( "Not available on an Observer repository" );
+    }
+
+    /**
+     * @return When (as a System.currentTimeMillis() time) the
+     * SecondaryRepository started to observe the repository
+     */
+    public long getAttachedAt()
+    {
+        return attachedAt;
+    }
+
+    /**
+     * @return When (as a System.currentTimeMillis() time) the
+     * SecondaryRepository stopped observing the repository
+     */
+    public long getDetachedAt()
+    {
+        return detachedAt;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see org.apache.commons.monitoring.listeners.Detachable#isDetached()
+     */
+    public boolean isDetached()
+    {
+        return detached;
+    }
+
+    @Override
+    protected Monitor newMonitorInstance( Key key )
+    {
+        /*
+         * A monitor was requested for a key that has not beeing used when the
+         * ObserverRepository was connecter to the observed repository. To avoid
+         * NullPointer we return a No-op Monitor
+         */
+        return new NullMonitor();
+    }
+
+}

Added: commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/stopwatches/CpuTimeStopWatch.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/stopwatches/CpuTimeStopWatch.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/stopwatches/CpuTimeStopWatch.java (added)
+++ commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/stopwatches/CpuTimeStopWatch.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.stopwatches;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadMXBean;
+
+import org.apache.commons.monitoring.Monitor;
+import org.apache.commons.monitoring.Unit;
+
+/**
+ * Extend DefaultStopWatch to add support for CPU time estimate based on ThreadMXBean
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public class CpuTimeStopWatch
+    extends DefaultStopWatch
+{
+    private long cpuStartedAt;
+
+    /**
+     * Constructor.
+     * <p>
+     * The monitor can be set to null to use the StopWatch without the monitoring infrastructure.
+     *
+     * @param monitor the monitor associated with the process to be monitored
+     */
+    public CpuTimeStopWatch( Monitor monitor )
+    {
+        super( monitor );
+    }
+
+    @Override
+    protected void doStart( Monitor monitor )
+    {
+        super.doStart( monitor );
+        ThreadMXBean mx = ManagementFactory.getThreadMXBean();
+        if ( mx.isCurrentThreadCpuTimeSupported() )
+        {
+            cpuStartedAt = mx.getCurrentThreadCpuTime();
+        }
+    }
+
+    @Override
+    protected void doStop()
+    {
+        super.doStop();
+        ThreadMXBean mx = ManagementFactory.getThreadMXBean();
+        if ( mx.isCurrentThreadCpuTimeSupported() )
+        {
+            long cpu = mx.getCurrentThreadCpuTime() - cpuStartedAt;
+            monitor.getCounter( Monitor.CPU ).add( cpu, Unit.NANOS );
+        }
+    }
+}

Added: commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/stopwatches/DefaultStopWatch.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/stopwatches/DefaultStopWatch.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/stopwatches/DefaultStopWatch.java (added)
+++ commons/sandbox/monitoring/branches/modules/core/src/main/java/org/apache/commons/monitoring/stopwatches/DefaultStopWatch.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,252 @@
+package org.apache.commons.monitoring.stopwatches;
+
+import org.apache.commons.monitoring.Monitor;
+import org.apache.commons.monitoring.StopWatch;
+import org.apache.commons.monitoring.Unit;
+
+/**
+ * Simple implementation of StopWatch that estimate monitored element execution time.
+ * 
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public class DefaultStopWatch
+    implements StopWatch
+{
+
+    /** Time the probe was started */
+    protected final long startedAt;
+
+    /** Time the probe was stopped */
+    private long stopedAt;
+
+    /** Time the probe was paused */
+    private long pauseDelay;
+
+    /** flag for stopped probe */
+    private boolean stoped;
+
+    /** flag for paused probe */
+    private boolean paused;
+
+    /** Monitor that is notified of process execution state */
+    protected final Monitor monitor;
+
+    /**
+     * Constructor.
+     * <p>
+     * The monitor can be set to null to use the StopWatch without the monitoring infrastructure.
+     * 
+     * @param monitor the monitor associated with the process to be monitored
+     */
+    public DefaultStopWatch( Monitor monitor )
+    {
+        super();
+        this.monitor = monitor;
+        startedAt = nanotime();
+        doStart( monitor );
+    }
+
+    protected void doStart( Monitor monitor )
+    {
+        monitor.getGauge( Monitor.CONCURRENCY ).increment( Unit.UNARY );
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.apache.commons.monitoring.StopWatch#getElapsedTime()
+     */
+    public long getElapsedTime()
+    {
+        if ( stoped || paused )
+        {
+            return stopedAt - startedAt - pauseDelay;
+        }
+        else
+        {
+            // Still running !
+            return nanotime() - startedAt - pauseDelay;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.apache.commons.monitoring.StopWatch#pause()
+     */
+    public void pause()
+    {
+        if ( !paused && !stoped )
+        {
+            stopedAt = nanotime();
+            paused = true;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.apache.commons.monitoring.StopWatch#resume()
+     */
+    public void resume()
+    {
+        if ( paused && !stoped )
+        {
+            pauseDelay = nanotime() - stopedAt;
+            paused = false;
+            stopedAt = 0;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.apache.commons.monitoring.StopWatch#stop()
+     */
+    public void stop()
+    {
+        if ( !stoped )
+        {
+            long t = nanotime();
+            if ( paused )
+            {
+                pauseDelay = t - stopedAt;
+            }
+            stopedAt = t;
+            stoped = true;
+            doStop();
+        }
+    }
+
+    protected void doStop()
+    {
+        monitor.getGauge( Monitor.CONCURRENCY ).decrement( Unit.UNARY );
+        monitor.getCounter( Monitor.PERFORMANCES ).add( getElapsedTime(), Unit.NANOS );
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.apache.commons.monitoring.StopWatch#stop(boolean)
+     */
+    public void stop( boolean canceled )
+    {
+        if ( canceled )
+        {
+            cancel();
+        }
+        else
+        {
+            stop();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.apache.commons.monitoring.StopWatch#cancel()
+     */
+    public void cancel()
+    {
+        if ( !stoped )
+        {
+            stoped = true;
+            doCancel();
+        }
+    }
+
+    protected void doCancel()
+    {
+        monitor.getGauge( Monitor.CONCURRENCY ).decrement( Unit.UNARY );
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * Monitored application should use a <code>try/finally</code> block to ensure on of {@link #stop()} or
+     * {@link #cancel()} method is invoked, even when an exception occurs. To avoid StopWatches to keep running if the
+     * application didn't follow this recommendation, the finalizer is used to cancel the StopWatch and will log a
+     * educational warning.
+     * 
+     * @see java.lang.Object#finalize()
+     */
+    protected void finalize()
+    {
+        // This probe is reclaimed by garbage-collector and still running,
+        // the monitored code "forgot" to stop/cancel it properly.
+        if ( !stoped && ( monitor != null ) )
+        {
+            System.err.println( "WARNING : Execution for " + monitor.getKey().toString() +
+                " was not stoped properly. " + "This can result in wrong concurrency monitoring. " +
+                "Use try/finally blocks to avoid this warning" );
+        }
+    }
+
+    /**
+     * Returns the current value of the most precise available system timer, in nanoseconds. The real precision depends
+     * on the JVM and the underlying system. On JRE before java5, <tt>backport-util-concurrent</tt> provides some
+     * limited support for equivalent timer.
+     * 
+     * @see System#nanoTime()
+     * @return time in nanosecond
+     */
+    protected long nanotime()
+    {
+        return System.nanoTime();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.apache.commons.monitoring.StopWatch#isStoped()
+     */
+    public boolean isStoped()
+    {
+        return stoped;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.apache.commons.monitoring.StopWatch#isPaused()
+     */
+    public boolean isPaused()
+    {
+        return paused;
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuffer stb = new StringBuffer();
+        if ( monitor != null )
+        {
+            stb.append( "Execution for " ).append( monitor.getKey().toString() ).append( " " );
+        }
+        if ( paused )
+        {
+            stb.append( "paused after " ).append( getElapsedTime() ).append( "ns" );
+        }
+        else if ( stoped )
+        {
+            stb.append( "stoped after " ).append( getElapsedTime() ).append( "ns" );
+        }
+        else
+        {
+            stb.append( "running for " ).append( getElapsedTime() ).append( "ns" );
+        }
+        return stb.toString();
+
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.apache.commons.monitoring.StopWatch#getMonitor()
+     */
+    public Monitor getMonitor()
+    {
+        return monitor;
+    }
+
+}
\ No newline at end of file

Added: commons/sandbox/monitoring/branches/modules/core/src/test/java/org/apache/commons/monitoring/UnitTest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/core/src/test/java/org/apache/commons/monitoring/UnitTest.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/core/src/test/java/org/apache/commons/monitoring/UnitTest.java (added)
+++ commons/sandbox/monitoring/branches/modules/core/src/test/java/org/apache/commons/monitoring/UnitTest.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring;
+
+import static junit.framework.Assert.assertEquals;
+
+import org.junit.Test;
+
+/**
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public class UnitTest
+{
+    @Test
+    public void derived()
+    {
+        assertEquals( Unit.NANOS, Unit.HOUR.getPrimary() );
+        assertEquals( Unit.NANOS, Unit.NANOS.getDerived( "ns" ) );
+        assertEquals( Unit.MICROS, Unit.NANOS.getDerived( "┬Ás" ) );
+        assertEquals( Unit.MILLIS, Unit.NANOS.getDerived( "ms" ) );
+        assertEquals( Unit.SECOND, Unit.NANOS.getDerived( "s" ) );
+    }
+
+    @Test
+    public void scales()
+    {
+        assertEquals( 1L, Unit.NANOS.getScale() );
+        assertEquals( 1000L, Unit.MICROS.getScale() );
+        assertEquals( 1000000L, Unit.MILLIS.getScale() );
+        assertEquals( 1000000000L, Unit.SECOND.getScale() );
+    }
+}

Added: commons/sandbox/monitoring/branches/modules/core/src/test/java/org/apache/commons/monitoring/metrics/CounterBench.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/core/src/test/java/org/apache/commons/monitoring/metrics/CounterBench.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/core/src/test/java/org/apache/commons/monitoring/metrics/CounterBench.java (added)
+++ commons/sandbox/monitoring/branches/modules/core/src/test/java/org/apache/commons/monitoring/metrics/CounterBench.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,63 @@
+package org.apache.commons.monitoring.metrics;
+import static junit.framework.Assert.assertEquals;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.monitoring.Counter;
+import org.apache.commons.monitoring.Monitor;
+import org.apache.commons.monitoring.Unit;
+import org.apache.commons.monitoring.metrics.RentrantLockCounter;
+import org.apache.commons.monitoring.metrics.SynchronizedCounter;
+import org.junit.Test;
+
+public class CounterBench implements Runnable
+{
+    private static final int THREADS = 5;
+
+    private static final int LOOPS = 100;
+
+    private Counter counter;
+
+    private String mode;
+
+
+    @Test
+    public void synchronizedCounter() throws Exception
+    {
+        mode = "SynchronizedCounter";
+        counter = new SynchronizedCounter( Monitor.FAILURES );
+        runConcurrent();
+    }
+
+    @Test
+    public void rentrantLockCounter() throws Exception
+    {
+        mode = "RentrantLockCounter";
+        counter = new RentrantLockCounter( Monitor.FAILURES );
+        runConcurrent();
+    }
+
+
+    private void runConcurrent()
+        throws InterruptedException
+    {
+        long start = System.nanoTime();
+        ExecutorService pool = Executors.newFixedThreadPool( THREADS );
+        for (int i = 0 ; i < LOOPS; i++)
+        {
+            pool.submit( this );
+        }
+        pool.awaitTermination( 60, TimeUnit.SECONDS );
+        assertEquals( LOOPS, counter.getSum() );
+        System.out.printf( "%s : %,d ns/operation %n", mode, ( System.nanoTime() - start ) /LOOPS);
+
+    }
+
+    public void run()
+    {
+        counter.add( 1, Unit.UNARY );
+    }
+}
+
+

Added: commons/sandbox/monitoring/branches/modules/core/src/test/java/org/apache/commons/monitoring/repositories/DefaultRepositoryTest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/core/src/test/java/org/apache/commons/monitoring/repositories/DefaultRepositoryTest.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/core/src/test/java/org/apache/commons/monitoring/repositories/DefaultRepositoryTest.java (added)
+++ commons/sandbox/monitoring/branches/modules/core/src/test/java/org/apache/commons/monitoring/repositories/DefaultRepositoryTest.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.repositories;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertSame;
+import static junit.framework.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.apache.commons.monitoring.Monitor;
+import org.apache.commons.monitoring.Repository;
+import org.apache.commons.monitoring.Monitor.Key;
+import org.apache.commons.monitoring.repositories.DefaultRepository;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public class DefaultRepositoryTest
+{
+    @Test
+    public void categories()
+        throws Exception
+    {
+        Repository repository = new DefaultRepository();
+        Monitor foo = repository.getMonitor( "foo", "test" );
+        repository.getMonitor( "bar", "junit" );
+        repository.getMonitor( "just-a-name" );
+
+        Set<String> categories = repository.getCategories();
+        assertTrue( categories.contains( "test" ) );
+        assertTrue( categories.contains( "junit" ) );
+        assertTrue( categories.contains( Key.DEFAULT ) );
+        assertEquals( 3, categories.size() );
+
+        Collection<Monitor> monitors = repository.getMonitorsFromCategory( "test" );
+        assertEquals( 1, monitors.size() );
+        assertSame( foo, monitors.iterator().next() );
+    }
+
+    @Test
+    public void subsystem()
+        throws Exception
+    {
+        Repository repository = new DefaultRepository();
+        Monitor foo = repository.getMonitor( "foo", "test", "test" );
+        repository.getMonitor( "bar", "junit", "fake" );
+        repository.getMonitor( "just-a-name" );
+
+        Set<String> subsystems = repository.getSubSystems();
+        assertTrue( subsystems.contains( "test" ) );
+        assertTrue( subsystems.contains( "fake" ) );
+        assertTrue( subsystems.contains( Key.DEFAULT ) );
+        assertEquals( 3, subsystems.size() );
+
+        Collection<Monitor> monitors = repository.getMonitorsFromSubSystem( "test" );
+        assertEquals( 1, monitors.size() );
+        assertSame( foo, monitors.iterator().next() );
+    }
+
+}

Added: commons/sandbox/monitoring/branches/modules/core/src/test/java/org/apache/commons/monitoring/stopwatches/DefaultStopWatchTest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/core/src/test/java/org/apache/commons/monitoring/stopwatches/DefaultStopWatchTest.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/core/src/test/java/org/apache/commons/monitoring/stopwatches/DefaultStopWatchTest.java (added)
+++ commons/sandbox/monitoring/branches/modules/core/src/test/java/org/apache/commons/monitoring/stopwatches/DefaultStopWatchTest.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.stopwatches;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
+import org.apache.commons.monitoring.Monitor;
+import org.apache.commons.monitoring.StopWatch;
+import org.apache.commons.monitoring.monitors.NullMonitor;
+import org.apache.commons.monitoring.stopwatches.DefaultStopWatch;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public class DefaultStopWatchTest
+{
+    private long time;
+
+    /**
+     * assert the StopWatch computes the time elapsed during the monitored
+     * process execution. User a MockTimeWatch to make timing predictable
+     *
+     * @throws Exception
+     */
+    @Test
+    public void computeTime()
+        throws Exception
+    {
+        time = 0;
+        StopWatch stopWatch = new MockTimeWatch();
+        time++;
+        stopWatch.pause();
+        assertTrue( stopWatch.isPaused() );
+        System.out.println( stopWatch.toString() );
+        time++;
+        stopWatch.resume();
+        assertTrue( !stopWatch.isPaused() );
+        System.out.println( stopWatch.toString() );
+        time++;
+        stopWatch.stop();
+        assertEquals( 2, stopWatch.getElapsedTime() );
+        assertTrue( stopWatch.isStoped() );
+        System.out.println( stopWatch.toString() );
+    }
+
+    /**
+     * Check that the elapsed time computed by the WtopWatch is not affected by
+     * unexpected method calls.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void supportUnexpectedCalls()
+        throws Exception
+    {
+        time = 0;
+        StopWatch stopWatch = new MockTimeWatch();
+
+        // resume the non-paused watch
+        assertTrue( !stopWatch.isPaused() );
+        stopWatch.resume();
+        assertTrue( !stopWatch.isPaused() );
+
+        // pause the watch multiple times
+        time++;
+        stopWatch.pause();
+        assertEquals( 1, stopWatch.getElapsedTime() );
+        assertTrue( stopWatch.isPaused() );
+        time++;
+        stopWatch.pause();
+        assertEquals( 1, stopWatch.getElapsedTime() );
+        assertTrue( stopWatch.isPaused() );
+
+        stopWatch.stop();
+        assertEquals( 1, stopWatch.getElapsedTime() );
+        assertTrue( stopWatch.isStoped() );
+
+        // Unexpected use after stopped
+        stopWatch.resume();
+        assertEquals( 1, stopWatch.getElapsedTime() );
+        assertTrue( stopWatch.isStoped() );
+        stopWatch.pause();
+        assertEquals( 1, stopWatch.getElapsedTime() );
+        assertTrue( stopWatch.isStoped() );
+        stopWatch.stop();
+        assertEquals( 1, stopWatch.getElapsedTime() );
+        assertTrue( stopWatch.isStoped() );
+    }
+
+
+    private class MockTimeWatch
+        extends DefaultStopWatch
+    {
+        public MockTimeWatch()
+        {
+            super( new NullMonitor() );
+        }
+
+        @Override
+        protected long nanotime()
+        {
+            return time;
+        }
+    }
+}

Added: commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/AbstractPerformanceInterceptor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/AbstractPerformanceInterceptor.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/AbstractPerformanceInterceptor.java (added)
+++ commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/AbstractPerformanceInterceptor.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.instrumentation.aop;
+
+import java.lang.reflect.Method;
+
+import org.apache.commons.monitoring.Monitor;
+import org.apache.commons.monitoring.Repository;
+import org.apache.commons.monitoring.StopWatch;
+import org.apache.commons.monitoring.Unit;
+
+/**
+ * A method interceptor that compute method invocation performances.
+ * <p>
+ * Concrete implementation will adapt the method interception API to
+ * this class requirement.
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public abstract class AbstractPerformanceInterceptor<T>
+{
+
+    protected Repository repository;
+
+    protected String category;
+
+    protected String subsystem;
+
+    protected MonitorNameExtractor monitorNameExtractor = new DefaultMonitorNameExtractor();
+
+    public AbstractPerformanceInterceptor()
+    {
+        super();
+    }
+
+    /**
+     * API neutral method invocation
+     */
+    protected Object doInvoke( T invocation )
+        throws Throwable
+    {
+        String name = getMonitorName( invocation );
+        if ( name == null )
+        {
+            return proceed( invocation );
+        }
+        Monitor monitor = repository.getMonitor( name, category, subsystem );
+        StopWatch stopwatch = repository.start( monitor );
+        Throwable error = null;
+        try
+        {
+            return proceed( invocation );
+        }
+        catch ( Throwable t )
+        {
+            error = t;
+            throw t;
+        }
+        finally
+        {
+            stopwatch.stop();
+            beforeReturning( monitor, error, stopwatch.getElapsedTime() );
+        }
+    }
+
+    /**
+     * @param invocation
+     * @return
+     */
+    protected abstract Object proceed( T invocation )
+        throws Throwable;
+
+    /**
+     * @param invocation
+     * @return
+     */
+    protected abstract String getMonitorName( T invocation );
+
+    /**
+     * Compute the monitor name associated to this method invocation
+     *
+     * @param method method being invoked
+     * @return monitor name. If <code>null</code>, nothing will be monitored
+     */
+    protected String getMonitorName( Method method )
+    {
+        return monitorNameExtractor.getMonitorName( method );
+    }
+
+    /**
+     * @param monitor the monitor associated to the method invocation
+     * @param error Throwable thrown by the method invocation if any
+     * @param duration the duration of the method invocation
+     */
+    protected void beforeReturning( Monitor monitor, Throwable error, long duration )
+    {
+        if ( error != null )
+        {
+            monitor.getCounter( Monitor.FAILURES ).add( duration, Unit.NANOS );
+        }
+    }
+
+    /**
+     * Set a custom application-defined repository
+     *
+     * @param repository
+     */
+    public void setRepository( Repository repository )
+    {
+        this.repository = repository;
+    }
+
+    public void setCategory( String category )
+    {
+        this.category = category;
+    }
+
+    public void setSubsystem( String subsystem )
+    {
+        this.subsystem = subsystem;
+    }
+
+    /**
+     * @param monitorNameExtractor the monitorNameExtractor to set
+     */
+    public void setMonitorNameExtractor( MonitorNameExtractor monitorNameExtractor )
+    {
+        this.monitorNameExtractor = monitorNameExtractor;
+    }
+}
\ No newline at end of file

Added: commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/AopaliancePerformanceInterceptor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/AopaliancePerformanceInterceptor.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/AopaliancePerformanceInterceptor.java (added)
+++ commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/AopaliancePerformanceInterceptor.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.instrumentation.aop;
+
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+
+/**
+ * Spring-aop implementation of PerformanceInterceptor.
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public class AopaliancePerformanceInterceptor
+    extends AbstractPerformanceInterceptor<MethodInvocation>
+    implements MethodInterceptor
+{
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
+     */
+    public Object invoke( MethodInvocation invocation )
+        throws Throwable
+    {
+        return doInvoke( invocation );
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see org.apache.commons.monitoring.instrument.AbstractPerformanceInterceptor#getMonitorName(java.lang.Object)
+     */
+    @Override
+    protected String getMonitorName( MethodInvocation invocation )
+    {
+        return getMonitorName( invocation.getMethod() );
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see org.apache.commons.monitoring.instrument.AbstractPerformanceInterceptor#proceed(java.lang.Object)
+     */
+    @Override
+    protected Object proceed( MethodInvocation invocation )
+    throws Throwable
+    {
+        return invocation.proceed();
+    }
+
+}
\ No newline at end of file

Added: commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/CommonsProxyPerformanceInterceptor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/CommonsProxyPerformanceInterceptor.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/CommonsProxyPerformanceInterceptor.java (added)
+++ commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/CommonsProxyPerformanceInterceptor.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.instrumentation.aop;
+
+import org.apache.commons.proxy.Interceptor;
+import org.apache.commons.proxy.Invocation;
+
+/**
+ * Commons-proxy implementation of PerformanceInterceptor.
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public class CommonsProxyPerformanceInterceptor
+    extends AbstractPerformanceInterceptor<Invocation>
+    implements Interceptor
+{
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see org.apache.commons.proxy.Interceptor#intercept(org.apache.commons.proxy.Invocation)
+     */
+    public Object intercept( Invocation invocation )
+        throws Throwable
+    {
+        return doInvoke( invocation );
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see org.apache.commons.monitoring.instrument.AbstractPerformanceInterceptor#getMonitorName(java.lang.Object)
+     */
+    @Override
+    protected String getMonitorName( Invocation invocation )
+    {
+        return getMonitorName( invocation.getMethod() );
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see org.apache.commons.monitoring.instrument.AbstractPerformanceInterceptor#proceed(java.lang.Object)
+     */
+    @Override
+    protected Object proceed( Invocation invocation )
+        throws Throwable
+    {
+        return invocation.proceed();
+    }
+}

Added: commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/DefaultMonitorNameExtractor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/DefaultMonitorNameExtractor.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/DefaultMonitorNameExtractor.java (added)
+++ commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/DefaultMonitorNameExtractor.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.instrumentation.aop;
+
+import java.lang.reflect.Method;
+
+/**
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public class DefaultMonitorNameExtractor
+    implements MonitorNameExtractor
+{
+
+    /**
+     * {@inheritDoc}
+     * @see org.apache.commons.monitoring.instrumentation.aop.MonitorNameExtractor#getMonitorName(java.lang.reflect.Method)
+     */
+    public String getMonitorName( Method method )
+    {
+        return method.getDeclaringClass().getSimpleName() + "." + method.getName();
+    }
+
+}

Added: commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/JavaProxyPerformanceInterceptor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/JavaProxyPerformanceInterceptor.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/JavaProxyPerformanceInterceptor.java (added)
+++ commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/JavaProxyPerformanceInterceptor.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.instrumentation.aop;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/**
+ * Spring-aop implementation of PerformanceInterceptor.
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public class JavaProxyPerformanceInterceptor
+    extends AbstractPerformanceInterceptor<Invocation>
+{
+
+    /**
+     * Create a java.lang.reflect.Proxy around the target object and monitor it's methods execution.
+     */
+    public Object proxy( final Object target, Class<?>... interfaces )
+    {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        if ( cl == null )
+        {
+            cl = getClass().getClassLoader();
+        }
+        return Proxy.newProxyInstance( cl, interfaces, new InvocationHandler()
+        {
+            public Object invoke( Object proxy, Method method, Object[] args )
+                throws Throwable
+            {
+                return doInvoke( new Invocation( target, method, args ) );
+            }
+        } );
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see org.apache.commons.monitoring.instrument.AbstractPerformanceInterceptor#getMonitorName(java.lang.Object)
+     */
+    @Override
+    protected String getMonitorName( Invocation invocation )
+    {
+        return getMonitorName( invocation.method );
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see org.apache.commons.monitoring.instrument.AbstractPerformanceInterceptor#proceed(java.lang.Object)
+     */
+    @Override
+    protected Object proceed( Invocation invocation )
+        throws Throwable
+    {
+        return invocation.method.invoke( null, invocation.args );
+    }
+}
+
+class Invocation
+{
+    public Invocation( Object proxy, Method method, Object[] args )
+    {
+        super();
+        this.proxy = proxy;
+        this.method = method;
+        this.args = args;
+    }
+
+    public Object proxy;
+
+    public Method method;
+
+    public Object[] args;
+}
\ No newline at end of file

Added: commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/MonitorNameExtractor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/MonitorNameExtractor.java?rev=721657&view=auto
==============================================================================
--- commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/MonitorNameExtractor.java (added)
+++ commons/sandbox/monitoring/branches/modules/instrumentation/src/main/java/org/apache/commons/monitoring/instrumentation/aop/MonitorNameExtractor.java Sat Nov 29 01:08:42 2008
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.monitoring.instrumentation.aop;
+
+import java.lang.reflect.Method;
+
+/**
+ *
+ * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
+ */
+public interface MonitorNameExtractor
+{
+
+    /**
+     * Compute the monitor name associated to this method invocation
+     *
+     * @param method method being invoked
+     * @return monitor name. If <code>null</code>, nothing will be monitored
+     */
+    String getMonitorName( Method method );
+}



Mime
View raw message