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 015package org.apache.tapestry5.ioc.internal; 016 017import org.apache.tapestry5.ioc.def.ServiceDef; 018import org.apache.tapestry5.ioc.services.ServiceActivity; 019import org.apache.tapestry5.ioc.services.ServiceActivityScoreboard; 020import org.apache.tapestry5.ioc.services.Status; 021 022import java.util.List; 023import java.util.Map; 024import java.util.Set; 025import java.util.TreeMap; 026 027import org.apache.tapestry5.commons.util.CollectionFactory; 028import org.apache.tapestry5.ioc.ScopeConstants; 029import org.apache.tapestry5.ioc.services.PerThreadValue; 030import org.apache.tapestry5.ioc.services.PerthreadManager; 031 032public class ServiceActivityTrackerImpl implements ServiceActivityScoreboard, 033 ServiceActivityTracker 034{ 035 public static class MutableServiceActivity implements ServiceActivity 036 { 037 private final ServiceDef serviceDef; 038 039 private Status status; 040 041 private final PerThreadValue<Status> perThreadStatus; 042 043 public MutableServiceActivity(ServiceDef serviceDef, PerthreadManager perthreadManager, Status status) 044 { 045 this.serviceDef = serviceDef; 046 if (serviceDef.getServiceScope().equals(ScopeConstants.PERTHREAD)) { 047 perThreadStatus = perthreadManager.createValue(); 048 perThreadStatus.set(status); 049 this.status = status; // this is now the default status 050 } else { 051 perThreadStatus = null; 052 this.status = status; 053 } 054 } 055 056 @Override 057 public String getServiceId() 058 { 059 return serviceDef.getServiceId(); 060 } 061 062 @Override 063 public Class getServiceInterface() 064 { 065 return serviceDef.getServiceInterface(); 066 } 067 068 @Override 069 public String getScope() 070 { 071 return serviceDef.getServiceScope(); 072 } 073 074 @Override 075 public Set<Class> getMarkers() 076 { 077 return serviceDef.getMarkers(); 078 } 079 080 // Mutable properties must be synchronized 081 082 @Override 083 public synchronized Status getStatus() 084 { 085 if (perThreadStatus != null) { 086 if (!perThreadStatus.exists()) perThreadStatus.set(status); 087 return perThreadStatus.get(); 088 } 089 else return status; 090 } 091 092 synchronized void setStatus(Status status) 093 { 094 if (perThreadStatus != null) perThreadStatus.set(status); 095 else this.status = status; 096 } 097 } 098 099 private final PerthreadManager perthreadManager; 100 101 public ServiceActivityTrackerImpl(PerthreadManager perthreadManager) { 102 this.perthreadManager = perthreadManager; 103 } 104 105 /** 106 * Tree map keeps everything in order by key (serviceId). 107 */ 108 private final Map<String, MutableServiceActivity> serviceIdToServiceStatus = new TreeMap<String, MutableServiceActivity>(); 109 110 @Override 111 public synchronized List<ServiceActivity> getServiceActivity() 112 { 113 // Need to wrap the values in a new list because 114 // a) we don't want people arbitrarily changing the internal state of 115 // _serviceIdtoServiceStatus 116 // b) values() is Collection and we want to return List 117 118 // Note: ugly code here to keep Sun compiler happy. 119 120 List<ServiceActivity> result = CollectionFactory.newList(); 121 122 result.addAll(serviceIdToServiceStatus.values()); 123 124 return result; 125 } 126 127 void startup() 128 { 129 // Does nothing, first pass does not use a worker thread 130 } 131 132 void shutdown() 133 { 134 // Does nothing, first pass does not use a worker thread 135 } 136 137 @Override 138 public synchronized void define(ServiceDef serviceDef, Status initialStatus) 139 { 140 serviceIdToServiceStatus.put(serviceDef.getServiceId(), new MutableServiceActivity( 141 serviceDef, perthreadManager, initialStatus)); 142 } 143 144 @Override 145 public synchronized void setStatus(String serviceId, Status status) 146 { 147 serviceIdToServiceStatus.get(serviceId).setStatus(status); 148 } 149 150}