You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2007/10/21 20:58:04 UTC
svn commit: r586932 - in /tapestry/tapestry5/trunk:
tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/
tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/
tapestry-core/src/site/ tapestry-core/src/site/apt/guide/ tapestry-co...
Author: hlship
Date: Sun Oct 21 11:58:02 2007
New Revision: 586932
URL: http://svn.apache.org/viewvc?rev=586932&view=rev
Log:
TAPESTRY-1848: Make status of Tapestry IoC services available programattically and via a simple user interface
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/ServiceStatus.java
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/ServiceStatus.tml
tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/servicestatus.apt
tapestry/tapestry5/trunk/tapestry-core/src/site/resources/images/servicestatus.png (with props)
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceActivityTracker.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceActivityTrackerImpl.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceActivity.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceActivityScoreboard.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Status.java
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ModuleImpl.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/JustInTimeObjectCreator.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleImplTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/JustInTimeObjectCreatorTest.java
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/ServiceStatus.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/ServiceStatus.java?rev=586932&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/ServiceStatus.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/pages/ServiceStatus.java Sun Oct 21 11:58:02 2007
@@ -0,0 +1,88 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed 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.tapestry.corelib.pages;
+
+import java.util.List;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.beaneditor.BeanModel;
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.annotations.Inject;
+import org.apache.tapestry.ioc.services.ServiceActivity;
+import org.apache.tapestry.ioc.services.ServiceActivityScoreboard;
+import org.apache.tapestry.services.BeanModelSource;
+
+/**
+ * Page used to see the status of all services defined by the {@link Registry}.
+ * <p>
+ * TODO: Add filters to control which services are displayed.
+ * <p>
+ * TODO: Disable this page if in production mode (or not, as it does no harm).
+ */
+public class ServiceStatus
+{
+ @Inject
+ private ServiceActivityScoreboard _scoreboard;
+
+ private List<ServiceActivity> _activity;
+
+ private ServiceActivity _row;
+
+ @Inject
+ private BeanModelSource _source;
+
+ private final BeanModel _model;
+
+ @Inject
+ private ComponentResources _resources;
+
+ public ServiceStatus()
+ {
+ _model = _source.create(ServiceActivity.class, false, _resources);
+
+ _model.add("serviceInterface", null);
+
+ // There's no line number information for interfaces, so we'll reorder the
+ // propreties manually.
+
+ _model.reorder("serviceId", "serviceInterface", "scope", "status");
+ }
+
+ public ServiceActivity getRow()
+ {
+ return _row;
+ }
+
+ public void setRow(ServiceActivity row)
+ {
+ _row = row;
+ }
+
+ void setupRender()
+ {
+ _activity = _scoreboard.getServiceActivity();
+ }
+
+ public List<ServiceActivity> getActivity()
+ {
+ return _activity;
+ }
+
+ public BeanModel getModel()
+ {
+ return _model;
+ }
+
+}
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/ServiceStatus.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/ServiceStatus.tml?rev=586932&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/ServiceStatus.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/corelib/pages/ServiceStatus.tml Sun Oct 21 11:58:02 2007
@@ -0,0 +1,72 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+ <head>
+ <title>Tapestry IoC Services Status</title>
+ <style>
+TR.defined {
+ color: #666666;
+ font-style: italic;
+}
+
+TR.virtual
+{
+ color: blue;
+}
+
+TR.real
+{
+ color: green;
+}
+
+
+ </style>
+ </head>
+ <body>
+
+ <h1>Tapestry IoC Services Status</h1>
+
+ <p>${activity.size()} services defined in the IoC Registry.</p>
+
+ <t:grid rowsperpage="100" model="model" pagerposition="top" rowClass="row.status"
+ source="activity" row="row">
+
+ <t:parameter name="serviceInterfaceCell">
+ ${row.serviceInterface}
+ </t:parameter>
+
+ </t:grid>
+
+ <p>
+ Explanation of status:
+ <dl>
+ <dt>Builtin</dt>
+ <dd>
+ A fundamental service that exists even before the Registry is
+ created.
+ </dd>
+
+ <dt>Defined</dt>
+ <dd>
+ The service is defined, but has not yet been referenced.
+ </dd>
+
+ <dt>Virtual</dt>
+ <dd>
+ The service has been referenced (usually for injection into
+ another service) but has not yet been
+ <em>realized</em>
+ into an instantiated service. Realization occurs with the
+ first method invocation on the proxy.
+ </dd>
+
+ <dt>Real</dt>
+ <dd>
+ The service has been realized: instantiated, dependencies
+ injected, decorated with interceptors and is fully in
+ operation.
+ </dd>
+
+ </dl>
+ </p>
+
+ </body>
+</html>
\ No newline at end of file
Added: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/servicestatus.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/servicestatus.apt?rev=586932&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/servicestatus.apt (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/servicestatus.apt Sun Oct 21 11:58:02 2007
@@ -0,0 +1,25 @@
+ ----
+ IoC Services Status
+ ----
+
+IoC Services Status
+
+ Using Tapestry there will often be a large number of services defined in the registry; a mix of the builtin services provided by the framework
+ and your own.
+
+ Built in to every Tapestry application is a page, ServiceStatus, that can present this information to you.
+
+ The page "ServiceStatus" presents the list of services within the appication's Registry.
+
+[../images/servicestatus.png] Service Status Page
+
+ Services may be builtin, defined, virtual or real.
+
+ Builtin only applies to a few special services that are part of Tapestry IoC.
+
+ Defined services are defined in some module, but have not yet been referenced in any way.
+
+ Virtual services have been referenced and have gotten as far as creating a service proxy.
+
+ Real services have had methods invoked, this forces the <realization> of the service which includes
+ instantiating the service, injecting dependencies, and decorating with any applicable interceptors.
\ No newline at end of file
Added: tapestry/tapestry5/trunk/tapestry-core/src/site/resources/images/servicestatus.png
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/resources/images/servicestatus.png?rev=586932&view=auto
==============================================================================
Binary file - no diff available.
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/site/resources/images/servicestatus.png
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml?rev=586932&r1=586931&r2=586932&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml Sun Oct 21 11:58:02 2007
@@ -77,7 +77,8 @@
<item name="DOM" href="guide/dom.html"/>
<item name="Class Reloading" href="guide/reload.html"/>
<item name="Unit testing pages/components" href="guide/unit-testing-pages.html"/>
- <item name="Logging" href="guide/logging.html"/>
+ <item name="Logging" href="guide/logging.html"/>
+ <item name="Service Status" href="guide/servicestatus.html"/>
</menu>
<menu ref="reports"/>
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?rev=586932&r1=586931&r2=586932&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Sun Oct 21 11:58:02 2007
@@ -1158,4 +1158,13 @@
assertTextPresent("Howard Lewis Ship", "Dec 24, 1966");
}
+
+ /** This basically checks that the services status page does not error. */
+ @Test
+ public void services_status()
+ {
+ open(BASE_URL + "servicestatus");
+
+ assertTextPresent("Tapestry IoC Services Status");
+ }
}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java?rev=586932&r1=586931&r2=586932&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java Sun Oct 21 11:58:02 2007
@@ -144,4 +144,9 @@
expect(registry.getService(serviceId, serviceInterface)).andReturn(service);
}
+ protected ServiceActivityTracker mockServiceActivityTracker()
+ {
+ return newMock(ServiceActivityTracker.class);
+ }
+
}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ModuleImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ModuleImpl.java?rev=586932&r1=586931&r2=586932&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ModuleImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ModuleImpl.java Sun Oct 21 11:58:02 2007
@@ -46,6 +46,7 @@
import org.apache.tapestry.ioc.services.ClassFab;
import org.apache.tapestry.ioc.services.ClassFactory;
import org.apache.tapestry.ioc.services.MethodSignature;
+import org.apache.tapestry.ioc.services.Status;
import org.apache.tapestry.ioc.services.TapestryIOCModule;
import org.slf4j.Logger;
@@ -53,6 +54,8 @@
{
private final InternalRegistry _registry;
+ private final ServiceActivityTracker _tracker;
+
private final ModuleDef _moduleDef;
private final ClassFactory _classFactory;
@@ -77,10 +80,11 @@
/** Keyed on fully qualified service id; values are instantiated services (proxies). */
private final Map<String, Object> _services = newCaseInsensitiveMap();
- public ModuleImpl(InternalRegistry registry, ModuleDef moduleDef, ClassFactory classFactory,
- Logger logger)
+ public ModuleImpl(InternalRegistry registry, ServiceActivityTracker tracker,
+ ModuleDef moduleDef, ClassFactory classFactory, Logger logger)
{
_registry = registry;
+ _tracker = tracker;
_moduleDef = moduleDef;
_classFactory = classFactory;
_logger = logger;
@@ -242,7 +246,8 @@
creator = new RecursiveServiceCreationCheckWrapper(def, creator, logger);
- JustInTimeObjectCreator delegate = new JustInTimeObjectCreator(creator, serviceId);
+ JustInTimeObjectCreator delegate = new JustInTimeObjectCreator(_tracker, creator,
+ serviceId);
Object proxy = createProxy(resources, delegate);
@@ -255,6 +260,8 @@
// is being realized anyway.
if (def.isEagerLoad() && eagerLoadProxies != null) eagerLoadProxies.add(delegate);
+
+ _tracker.setStatus(serviceId, Status.VIRTUAL);
return proxy;
}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java?rev=586932&r1=586931&r2=586932&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java Sun Oct 21 11:58:02 2007
@@ -55,6 +55,8 @@
import org.apache.tapestry.ioc.services.RegistryShutdownHub;
import org.apache.tapestry.ioc.services.RegistryShutdownListener;
import org.apache.tapestry.ioc.services.ServiceLifecycleSource;
+import org.apache.tapestry.ioc.services.ServiceActivityScoreboard;
+import org.apache.tapestry.ioc.services.Status;
import org.apache.tapestry.ioc.services.SymbolSource;
import org.apache.tapestry.ioc.services.TapestryIOCModule;
import org.apache.tapestry.ioc.services.ThreadCleanupHub;
@@ -70,6 +72,8 @@
static final String THREAD_CLEANUP_HUB_SERVICE_ID = "ThreadCleanupHub";
+ private static final String SERVICE_ACTIVITY_SCOREBOARD_SERVICE_ID = "ServiceActivityScoreboard";
+
/**
* Used to obtain the {@link org.apache.tapestry.ioc.services.ClassFactory} service, which is
* crucial when creating runtime classes for proxies and the like.
@@ -99,6 +103,8 @@
private final ClassFactory _classFactory;
+ private final ServiceActivityTracker _tracker;
+
private SymbolSource _symbolSource;
private final List<Module> _modules = newList();
@@ -139,11 +145,51 @@
{
_loggerSource = loggerSource;
+ final ServiceActivityTrackerImpl scoreboardAndTracker = new ServiceActivityTrackerImpl();
+
+ _tracker = scoreboardAndTracker;
+
+ addBuiltin(
+ SERVICE_ACTIVITY_SCOREBOARD_SERVICE_ID,
+ ServiceActivityScoreboard.class,
+ scoreboardAndTracker);
+
+ addBuiltin(LOG_SOURCE_SERVICE_ID, LoggerSource.class, _loggerSource);
+
+ _classFactory = classFactory;
+
+ addBuiltin(CLASS_FACTORY_SERVICE_ID, ClassFactory.class, _classFactory);
+
+ Logger logger = loggerForBuiltinService(THREAD_CLEANUP_HUB_SERVICE_ID);
+
+ _cleanupHub = new ThreadCleanupHubImpl(logger);
+
+ addBuiltin(THREAD_CLEANUP_HUB_SERVICE_ID, ThreadCleanupHub.class, _cleanupHub);
+
+ logger = loggerForBuiltinService(REGISTRY_SHUTDOWN_HUB_SERVICE_ID);
+
+ _registryShutdownHub = new RegistryShutdownHubImpl(logger);
+
+ addBuiltin(
+ REGISTRY_SHUTDOWN_HUB_SERVICE_ID,
+ RegistryShutdownHub.class,
+ _registryShutdownHub);
+
+ _lifecycles.put("singleton", new SingletonServiceLifecycle());
+
+ _registryShutdownHub.addRegistryShutdownListener(new RegistryShutdownListener()
+ {
+ public void registryDidShutdown()
+ {
+ scoreboardAndTracker.shutdown();
+ }
+ });
+
for (ModuleDef def : moduleDefs)
{
- Logger logger = _loggerSource.getLogger(def.getLoggerName());
+ logger = _loggerSource.getLogger(def.getLoggerName());
- Module module = new ModuleImpl(this, def, classFactory, logger);
+ Module module = new ModuleImpl(this, _tracker, def, classFactory, logger);
_modules.add(module);
@@ -159,6 +205,9 @@
_serviceIdToModule.put(serviceId, module);
+ // The service is defined but will not have gone further than that.
+ _tracker.define(serviceDef, Status.DEFINED);
+
Class marker = serviceDef.getMarker();
if (marker != null)
@@ -167,28 +216,7 @@
}
}
- addBuiltin(LOG_SOURCE_SERVICE_ID, LoggerSource.class, _loggerSource);
-
- _classFactory = classFactory;
-
- addBuiltin(CLASS_FACTORY_SERVICE_ID, ClassFactory.class, _classFactory);
-
- Logger logger = loggerForBuiltinService(THREAD_CLEANUP_HUB_SERVICE_ID);
-
- _cleanupHub = new ThreadCleanupHubImpl(logger);
-
- addBuiltin(THREAD_CLEANUP_HUB_SERVICE_ID, ThreadCleanupHub.class, _cleanupHub);
-
- logger = loggerForBuiltinService(REGISTRY_SHUTDOWN_HUB_SERVICE_ID);
-
- _registryShutdownHub = new RegistryShutdownHubImpl(logger);
-
- addBuiltin(
- REGISTRY_SHUTDOWN_HUB_SERVICE_ID,
- RegistryShutdownHub.class,
- _registryShutdownHub);
-
- _lifecycles.put("singleton", new SingletonServiceLifecycle());
+ scoreboardAndTracker.startup();
}
/**
@@ -265,6 +293,8 @@
};
InternalUtils.addToMapList(_markerToServiceDef, serviceDef.getMarker(), serviceDef);
+
+ _tracker.define(serviceDef, Status.BUILTIN);
}
public synchronized void shutdown()
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceActivityTracker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceActivityTracker.java?rev=586932&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceActivityTracker.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceActivityTracker.java Sun Oct 21 11:58:02 2007
@@ -0,0 +1,46 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed 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.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.ioc.services.ServiceActivityScoreboard;
+import org.apache.tapestry.ioc.services.Status;
+
+/**
+ * Used to update the status of services defined by the {@link ServiceActivityScoreboard}.
+ */
+public interface ServiceActivityTracker
+{
+
+ /**
+ * Defines a service in the tracker with an initial status.
+ *
+ * @param serviceDef
+ * the service being defined
+ * @param initialStatus
+ * typically {@link Status#BUILTIN} or {@link Status#DEFINED}
+ */
+ void define(ServiceDef serviceDef, Status initialStatus);
+
+ /**
+ * Updates the status for the service.
+ *
+ * @param serviceId
+ * identifies the service, which must be previously defined
+ * @param status
+ * the new status value
+ */
+ void setStatus(String serviceId, Status status);
+}
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceActivityTrackerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceActivityTrackerImpl.java?rev=586932&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceActivityTrackerImpl.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceActivityTrackerImpl.java Sun Oct 21 11:58:02 2007
@@ -0,0 +1,110 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed 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.tapestry.ioc.internal;
+
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.services.ServiceActivity;
+import org.apache.tapestry.ioc.services.ServiceActivityScoreboard;
+import org.apache.tapestry.ioc.services.Status;
+
+public class ServiceActivityTrackerImpl implements ServiceActivityScoreboard,
+ ServiceActivityTracker
+{
+ public static class MutableServiceActivity implements ServiceActivity
+ {
+ private final ServiceDef _serviceDef;
+
+ private Status _status;
+
+ public MutableServiceActivity(ServiceDef serviceDef, Status status)
+ {
+ _serviceDef = serviceDef;
+ _status = status;
+ }
+
+ public String getServiceId()
+ {
+ return _serviceDef.getServiceId();
+ }
+
+ public Class getServiceInterface()
+ {
+ return _serviceDef.getServiceInterface();
+ }
+
+ public String getScope()
+ {
+ return _serviceDef.getServiceScope();
+ }
+
+ // Mutable properties must be synchronized
+
+ public synchronized Status getStatus()
+ {
+ return _status;
+ }
+
+ synchronized void setStatus(Status status)
+ {
+ _status = status;
+ }
+ }
+
+ /** Tree map keeps everything in order by key (serviceId). */
+ private final Map<String, MutableServiceActivity> _serviceIdToServiceStatus = new TreeMap<String, MutableServiceActivity>();
+
+ public synchronized List<ServiceActivity> getServiceActivity()
+ {
+ // Need to wrap the values in a new list because
+ // a) we don't want people arbitrarily changing the internal state of
+ // _serviceIdtoServiceStatus
+ // b) values() is Collection and we want to return List
+
+ // Note: ugly code here to keep Sun compiler happy.
+
+ List<ServiceActivity> result = CollectionFactory.newList();
+
+ result.addAll(_serviceIdToServiceStatus.values());
+
+ return result;
+ }
+
+ void startup()
+ {
+ // Does nothing, first pass does not use a worker thread
+ }
+
+ void shutdown()
+ {
+ // Does nothing, first pass does not use a worker thread
+ }
+
+ public synchronized void define(ServiceDef serviceDef, Status initialStatus)
+ {
+ _serviceIdToServiceStatus.put(serviceDef.getServiceId(), new MutableServiceActivity(
+ serviceDef, initialStatus));
+ }
+
+ public synchronized void setStatus(String serviceId, Status status)
+ {
+ _serviceIdToServiceStatus.get(serviceId).setStatus(status);
+ }
+
+}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/JustInTimeObjectCreator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/JustInTimeObjectCreator.java?rev=586932&r1=586931&r2=586932&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/JustInTimeObjectCreator.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/services/JustInTimeObjectCreator.java Sun Oct 21 11:58:02 2007
@@ -16,7 +16,9 @@
import org.apache.tapestry.ioc.ObjectCreator;
import org.apache.tapestry.ioc.internal.EagerLoadServiceProxy;
+import org.apache.tapestry.ioc.internal.ServiceActivityTracker;
import org.apache.tapestry.ioc.services.RegistryShutdownListener;
+import org.apache.tapestry.ioc.services.Status;
/**
* Invoked from a fabricated service delegate to get or realize (instantiate and configure) the
@@ -28,6 +30,8 @@
public class JustInTimeObjectCreator implements ObjectCreator, EagerLoadServiceProxy,
RegistryShutdownListener
{
+ private final ServiceActivityTracker _tracker;
+
private ObjectCreator _creator;
private boolean _shutdown;
@@ -36,8 +40,10 @@
private final String _serviceId;
- public JustInTimeObjectCreator(ObjectCreator creator, String serviceId)
+ public JustInTimeObjectCreator(ServiceActivityTracker tracker, ObjectCreator creator,
+ String serviceId)
{
+ _tracker = tracker;
_creator = creator;
_serviceId = serviceId;
}
@@ -59,9 +65,11 @@
try
{
_object = _creator.createObject();
-
+
// And if that's successful ...
-
+
+ _tracker.setStatus(_serviceId, Status.REAL);
+
_creator = null;
}
catch (RuntimeException ex)
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceActivity.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceActivity.java?rev=586932&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceActivity.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceActivity.java Sun Oct 21 11:58:02 2007
@@ -0,0 +1,40 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed 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.tapestry.ioc.services;
+
+import org.apache.tapestry.ioc.def.ServiceDef;
+
+/**
+ * Provided by the {@link ServiceActivityScoreboard} to track a single service's state and activity.
+ *
+ * @see ServiceDef
+ */
+public interface ServiceActivity
+{
+ /** The unique id for the service. */
+ String getServiceId();
+
+ /**
+ * The interface implemented by the service (this may occasionally be a class, for non-proxied
+ * services).
+ */
+ Class getServiceInterface();
+
+ /** The scope of the service (typically "singleton" or "perthread"). */
+ String getScope();
+
+ /** Indicates the lifecycle status of the service. */
+ Status getStatus();
+}
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceActivityScoreboard.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceActivityScoreboard.java?rev=586932&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceActivityScoreboard.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/ServiceActivityScoreboard.java Sun Oct 21 11:58:02 2007
@@ -0,0 +1,27 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed 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.tapestry.ioc.services;
+
+import java.util.List;
+
+/**
+ * Provides access to the runtime details about services in the
+ * {@link org.apache.tapestry.ioc.Registry}.
+ */
+public interface ServiceActivityScoreboard
+{
+ /** Returns the status of all services, sorted alphabetically by service id. */
+ List<ServiceActivity> getServiceActivity();
+}
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Status.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Status.java?rev=586932&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Status.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/services/Status.java Sun Oct 21 11:58:02 2007
@@ -0,0 +1,36 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed 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.tapestry.ioc.services;
+
+import org.apache.tapestry.ioc.Registry;
+
+/**
+ * Used in {@link ServiceActivity} to identify the state of the service in terms of its overall
+ * lifecycle.
+ */
+public enum Status
+{
+ /** A builtin service that exists before the {@link Registry} is constructed. */
+ BUILTIN,
+
+ /** The service is defined in a module, but has not yet been referenced. */
+ DEFINED,
+
+ /** A proxy has been created for the service, but no methods of the proxy have been invoked. */
+ VIRTUAL,
+
+ /** A service implementation for the service has been created. */
+ REAL;
+}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java?rev=586932&r1=586931&r2=586932&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java Sun Oct 21 11:58:02 2007
@@ -23,6 +23,9 @@
import org.apache.tapestry.ioc.internal.ExceptionInConstructorModule;
import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry.ioc.services.ServiceActivity;
+import org.apache.tapestry.ioc.services.ServiceActivityScoreboard;
+import org.apache.tapestry.ioc.services.Status;
import org.apache.tapestry.ioc.services.TypeCoercer;
import org.apache.tapestry.ioc.services.TapestryIOCModule.Builtin;
import org.testng.Assert;
@@ -662,5 +665,44 @@
assertSame(tc1, tc2);
verify();
+ }
+
+ /**
+ * A cursory test for {@link ServiceActivityScoreboard}, just to see if any data has been
+ * collected.
+ */
+ @Test
+ public void service_activity_scoreboard()
+ {
+ Registry r = buildRegistry(GreeterModule.class);
+
+ ServiceActivityScoreboard scoreboard = r.getService(ServiceActivityScoreboard.class);
+
+ // Force the state of a few services.
+
+ TypeCoercer tc = r.getService("TypeCoercer", TypeCoercer.class);
+
+ tc.coerce("123", Integer.class);
+
+ r.getService("BlueGreeter", Greeter.class);
+
+ // Now get the activity list and poke around.
+
+ List<ServiceActivity> serviceActivity = scoreboard.getServiceActivity();
+
+ assertTrue(serviceActivity.size() > 0);
+
+ for (ServiceActivity a : serviceActivity)
+ {
+ String serviceId = a.getServiceId();
+
+ if (serviceId.equals("ClassFactory")) assertEquals(a.getStatus(), Status.BUILTIN);
+
+ if (serviceId.equals("RedGreeter1")) assertEquals(a.getStatus(), Status.DEFINED);
+
+ if (serviceId.equals("TypeCoercer")) assertEquals(a.getStatus(), Status.REAL);
+
+ if (serviceId.equals("BlueGreeter")) assertEquals(a.getStatus(), Status.VIRTUAL);
+ }
}
}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleImplTest.java?rev=586932&r1=586931&r2=586932&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleImplTest.java Sun Oct 21 11:58:02 2007
@@ -29,6 +29,7 @@
import org.apache.tapestry.ioc.internal.services.ClassFactoryImpl;
import org.apache.tapestry.ioc.services.ClassFactory;
import org.apache.tapestry.ioc.services.RegistryShutdownListener;
+import org.apache.tapestry.ioc.services.Status;
import org.slf4j.Logger;
import org.testng.annotations.Test;
@@ -40,30 +41,39 @@
InternalRegistry registry = mockInternalRegistry();
Logger logger = mockLogger();
ClassFactory factory = new ClassFactoryImpl();
+ ServiceActivityTracker tracker = mockServiceActivityTracker();
ModuleDef moduleDef = new DefaultModuleDefImpl(ModuleImplTestModule.class, logger,
getClassFactory());
- Module module = new ModuleImpl(registry, moduleDef, null, logger);
+ Module module = new ModuleImpl(registry, tracker, moduleDef, null, logger);
expect(registry.getServiceLogger("Upcase")).andReturn(logger);
train_isDebugEnabled(logger, true);
logger.debug("Creating service 'Upcase'.");
- train_getLifecycle(registry, "singleton", new SingletonServiceLifecycle());
+ tracker.setStatus("Upcase", Status.VIRTUAL);
train_newClass(registry, factory, UpcaseService.class);
registry.addRegistryShutdownListener(isA(RegistryShutdownListener.class));
+ replay();
+
+ UpcaseService service = module.getService("Upcase", UpcaseService.class);
+
+ verify();
+
+ train_getLifecycle(registry, "singleton", new SingletonServiceLifecycle());
+
train_isDebugEnabled(logger, false);
train_findDecoratorsForService(registry);
- replay();
+ tracker.setStatus("Upcase", Status.REAL);
- UpcaseService service = module.getService("Upcase", UpcaseService.class);
+ replay();
assertEquals(service.upcase("hello"), "HELLO");
@@ -84,7 +94,7 @@
ModuleDef moduleDef = new DefaultModuleDefImpl(ModuleImplTestModule.class, logger, null);
- Module module = new ModuleImpl(registry, moduleDef, null, logger);
+ Module module = new ModuleImpl(registry, null, moduleDef, null, logger);
replay();
@@ -119,7 +129,7 @@
replay();
- Module module = new ModuleImpl(registry, moduleDef, null, logger);
+ Module module = new ModuleImpl(registry, null, moduleDef, null, logger);
Set<DecoratorDef> defs = module.findMatchingDecoratorDefs(serviceDef);
@@ -138,7 +148,7 @@
replay();
- Module module = new ModuleImpl(registry, def, null, logger);
+ Module module = new ModuleImpl(registry, null, def, null, logger);
try
{
@@ -164,7 +174,7 @@
Logger logger = mockLogger();
ModuleDef def = new DefaultModuleDefImpl(ExtraPublicConstructorsModule.class, logger, null);
ClassFactory factory = newMock(ClassFactory.class);
- Module module = new ModuleImpl(registry, def, null, logger);
+ Module module = new ModuleImpl(registry, null, def, null, logger);
logger.warn(contains("contains more than one public constructor"));
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/JustInTimeObjectCreatorTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/JustInTimeObjectCreatorTest.java?rev=586932&r1=586931&r2=586932&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/JustInTimeObjectCreatorTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/JustInTimeObjectCreatorTest.java Sun Oct 21 11:58:02 2007
@@ -16,6 +16,8 @@
import org.apache.tapestry.ioc.ObjectCreator;
import org.apache.tapestry.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry.ioc.internal.ServiceActivityTracker;
+import org.apache.tapestry.ioc.services.Status;
import org.testng.annotations.Test;
public class JustInTimeObjectCreatorTest extends IOCInternalTestCase
@@ -29,7 +31,7 @@
replay();
- JustInTimeObjectCreator j = new JustInTimeObjectCreator(creator, SERVICE_ID);
+ JustInTimeObjectCreator j = new JustInTimeObjectCreator(null, creator, SERVICE_ID);
j.registryDidShutdown();
@@ -51,16 +53,19 @@
{
ObjectCreator creator = mockObjectCreator();
Object service = new Object();
+ ServiceActivityTracker tracker = mockServiceActivityTracker();
replay();
- JustInTimeObjectCreator j = new JustInTimeObjectCreator(creator, SERVICE_ID);
+ JustInTimeObjectCreator j = new JustInTimeObjectCreator(tracker, creator, SERVICE_ID);
verify();
// First access: use the creator to get the actual object.
train_createObject(creator, service);
+
+ tracker.setStatus(SERVICE_ID, Status.REAL);
replay();