001 // Copyright 2004, 2005 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.tapestry.services.impl; 016 017 import java.util.HashMap; 018 import java.util.Iterator; 019 import java.util.List; 020 import java.util.Map; 021 022 import org.apache.hivemind.ApplicationRuntimeException; 023 import org.apache.hivemind.ErrorLog; 024 import org.apache.tapestry.engine.IEngineService; 025 import org.apache.tapestry.services.ServiceMap; 026 027 /** 028 * Implementation of {@link org.apache.tapestry.services.ServiceMap}. 029 * 030 * @author Howard Lewis Ship 031 * @since 4.0 032 */ 033 public class ServiceMapImpl implements ServiceMap, EngineServiceSource 034 { 035 /** 036 * List of {@link EngineServiceContribution}. 037 */ 038 private List _applicationServices; 039 040 /** 041 * List of {@link EngineServiceContribution}. 042 */ 043 private List _factoryServices; 044 045 private ErrorLog _errorLog; 046 047 /** 048 * Map of {@link EngineServiceContribution} keyed on String name. 049 */ 050 private Map _services; 051 052 /** 053 * Map of {@link org.apache.tapestry.services.impl.EngineServiceOuterProxy}, keyed on String 054 * name. 055 */ 056 057 private Map _proxies = new HashMap(); 058 059 public void initializeService() 060 { 061 Map factoryMap = buildServiceMap(_factoryServices); 062 Map applicationMap = buildServiceMap(_applicationServices); 063 064 // Add services from the applicationMap to factoryMap, overwriting 065 // factoryMap entries with the same name. 066 067 factoryMap.putAll(applicationMap); 068 069 _services = factoryMap; 070 } 071 072 private Map buildServiceMap(List services) 073 { 074 Map result = new HashMap(); 075 076 Iterator i = services.iterator(); 077 while (i.hasNext()) 078 { 079 EngineServiceContribution contribution = (EngineServiceContribution) i.next(); 080 String name = contribution.getName(); 081 082 EngineServiceContribution existing = (EngineServiceContribution) result.get(name); 083 084 if (existing != null) 085 { 086 _errorLog.error( 087 ImplMessages.dupeService(name, existing), 088 existing.getLocation(), 089 null); 090 continue; 091 } 092 093 result.put(name, contribution); 094 } 095 096 return result; 097 } 098 099 public synchronized IEngineService getService(String name) 100 { 101 IEngineService result = (IEngineService) _proxies.get(name); 102 103 if (result == null) 104 { 105 result = buildProxy(name); 106 _proxies.put(name, result); 107 } 108 109 return result; 110 } 111 112 public boolean isValid(String name) 113 { 114 return _services.containsKey(name); 115 } 116 117 /** 118 * This returns the actual service, not the outer proxy. 119 */ 120 121 public IEngineService resolveEngineService(String name) 122 { 123 EngineServiceContribution contribution = (EngineServiceContribution) _services.get(name); 124 125 if (contribution == null) 126 throw new ApplicationRuntimeException(ImplMessages.noSuchService(name)); 127 128 IEngineService service = contribution.getService(); 129 String serviceName = service.getName(); 130 131 if (!name.equals(serviceName)) 132 throw new ApplicationRuntimeException(ImplMessages.serviceNameMismatch( 133 service, 134 name, 135 serviceName), contribution.getLocation(), null); 136 137 return service; 138 } 139 140 private IEngineService buildProxy(String name) 141 { 142 if (!_services.containsKey(name)) 143 throw new ApplicationRuntimeException(ImplMessages.noSuchService(name)); 144 145 EngineServiceOuterProxy outer = new EngineServiceOuterProxy(name); 146 147 EngineServiceInnerProxy inner = new EngineServiceInnerProxy(name, outer, this); 148 149 outer.installDelegate(inner); 150 151 return outer; 152 } 153 154 public void setApplicationServices(List applicationServices) 155 { 156 _applicationServices = applicationServices; 157 } 158 159 public void setFactoryServices(List factoryServices) 160 { 161 _factoryServices = factoryServices; 162 } 163 164 public void setErrorLog(ErrorLog errorLog) 165 { 166 _errorLog = errorLog; 167 } 168 }