001 // Copyright 2007 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.tapestry5.ioc.internal;
016
017 import org.apache.tapestry5.ioc.def.ServiceDef;
018 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
019 import org.apache.tapestry5.ioc.services.ServiceActivity;
020 import org.apache.tapestry5.ioc.services.ServiceActivityScoreboard;
021 import org.apache.tapestry5.ioc.services.Status;
022
023 import java.util.List;
024 import java.util.Map;
025 import java.util.Set;
026 import java.util.TreeMap;
027 import org.apache.tapestry5.ioc.ScopeConstants;
028 import org.apache.tapestry5.ioc.services.PerThreadValue;
029 import org.apache.tapestry5.ioc.services.PerthreadManager;
030
031 public class ServiceActivityTrackerImpl implements ServiceActivityScoreboard,
032 ServiceActivityTracker
033 {
034 public static class MutableServiceActivity implements ServiceActivity
035 {
036 private final ServiceDef serviceDef;
037
038 private Status status;
039
040 private final PerThreadValue<Status> perThreadStatus;
041
042 public MutableServiceActivity(ServiceDef serviceDef, PerthreadManager perthreadManager, Status status)
043 {
044 this.serviceDef = serviceDef;
045 if (serviceDef.getServiceScope().equals(ScopeConstants.PERTHREAD)) {
046 perThreadStatus = perthreadManager.createValue();
047 perThreadStatus.set(status);
048 this.status = status; // this is now the default status
049 } else {
050 perThreadStatus = null;
051 this.status = status;
052 }
053 }
054
055 public String getServiceId()
056 {
057 return serviceDef.getServiceId();
058 }
059
060 public Class getServiceInterface()
061 {
062 return serviceDef.getServiceInterface();
063 }
064
065 public String getScope()
066 {
067 return serviceDef.getServiceScope();
068 }
069
070 public Set<Class> getMarkers()
071 {
072 return serviceDef.getMarkers();
073 }
074
075 // Mutable properties must be synchronized
076
077 public synchronized Status getStatus()
078 {
079 if (perThreadStatus != null) {
080 if (!perThreadStatus.exists()) perThreadStatus.set(status);
081 return perThreadStatus.get();
082 }
083 else return status;
084 }
085
086 synchronized void setStatus(Status status)
087 {
088 if (perThreadStatus != null) perThreadStatus.set(status);
089 else this.status = status;
090 }
091 }
092
093 private final PerthreadManager perthreadManager;
094
095 public ServiceActivityTrackerImpl(PerthreadManager perthreadManager) {
096 this.perthreadManager = perthreadManager;
097 }
098
099 /**
100 * Tree map keeps everything in order by key (serviceId).
101 */
102 private final Map<String, MutableServiceActivity> serviceIdToServiceStatus = new TreeMap<String, MutableServiceActivity>();
103
104 public synchronized List<ServiceActivity> getServiceActivity()
105 {
106 // Need to wrap the values in a new list because
107 // a) we don't want people arbitrarily changing the internal state of
108 // _serviceIdtoServiceStatus
109 // b) values() is Collection and we want to return List
110
111 // Note: ugly code here to keep Sun compiler happy.
112
113 List<ServiceActivity> result = CollectionFactory.newList();
114
115 result.addAll(serviceIdToServiceStatus.values());
116
117 return result;
118 }
119
120 void startup()
121 {
122 // Does nothing, first pass does not use a worker thread
123 }
124
125 void shutdown()
126 {
127 // Does nothing, first pass does not use a worker thread
128 }
129
130 public synchronized void define(ServiceDef serviceDef, Status initialStatus)
131 {
132 serviceIdToServiceStatus.put(serviceDef.getServiceId(), new MutableServiceActivity(
133 serviceDef, perthreadManager, initialStatus));
134 }
135
136 public synchronized void setStatus(String serviceId, Status status)
137 {
138 serviceIdToServiceStatus.get(serviceId).setStatus(status);
139 }
140
141 }