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 }