001 // Copyright 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.ArrayList; 018 import java.util.HashMap; 019 import java.util.List; 020 import java.util.Locale; 021 import java.util.Map; 022 023 import org.apache.hivemind.Resource; 024 import org.apache.hivemind.lib.chain.ChainBuilder; 025 import org.apache.tapestry.IComponent; 026 import org.apache.tapestry.INamespace; 027 import org.apache.tapestry.engine.IPropertySource; 028 import org.apache.tapestry.event.ResetEventListener; 029 import org.apache.tapestry.services.ComponentPropertySource; 030 import org.apache.tapestry.spec.IComponentSpecification; 031 import org.apache.tapestry.util.PropertyHolderPropertySource; 032 033 /** 034 * TODO: Figure out a testing strategy for this beast! 035 * 036 * @author Howard M. Lewis Ship 037 * @since 4.0 038 */ 039 public class ComponentPropertySourceImpl implements ComponentPropertySource, ResetEventListener 040 { 041 private IPropertySource _globalProperties; 042 043 private ChainBuilder _chainBuilder; 044 045 private Map _componentSources = new HashMap(); 046 047 private Map _localizedComponentSources = new HashMap(); 048 049 private Map _namespaceSources = new HashMap(); 050 051 private Map _localizedNamespaceSources = new HashMap(); 052 053 public synchronized void resetEventDidOccur() 054 { 055 _componentSources.clear(); 056 _localizedComponentSources.clear(); 057 _namespaceSources.clear(); 058 _localizedNamespaceSources.clear(); 059 } 060 061 private synchronized IPropertySource getSourceForNamespace(INamespace namespace) 062 { 063 Resource key = namespace.getSpecificationLocation(); 064 065 IPropertySource result = (IPropertySource) _namespaceSources.get(key); 066 067 if (result == null) 068 { 069 result = createSourceForNamespace(namespace); 070 _namespaceSources.put(key, result); 071 } 072 073 return result; 074 } 075 076 private synchronized IPropertySource getSourceForComponent(IComponent component) 077 { 078 Resource key = component.getSpecification().getSpecificationLocation(); 079 080 IPropertySource result = (IPropertySource) _componentSources.get(key); 081 082 if (result == null) 083 { 084 result = createSourceForComponent(component); 085 _componentSources.put(key, result); 086 } 087 088 return result; 089 } 090 091 private synchronized LocalizedPropertySource getLocalizedSourceForComponent(IComponent component) 092 { 093 Resource key = component.getSpecification().getSpecificationLocation(); 094 095 LocalizedPropertySource result = (LocalizedPropertySource) _localizedComponentSources 096 .get(key); 097 098 if (result == null) 099 { 100 result = new LocalizedPropertySource(getSourceForComponent(component)); 101 102 _localizedComponentSources.put(key, result); 103 } 104 105 return result; 106 } 107 108 private synchronized LocalizedPropertySource getLocalizedSourceForNamespace(INamespace namespace) 109 { 110 Resource key = namespace.getSpecificationLocation(); 111 112 LocalizedPropertySource result = (LocalizedPropertySource) _localizedNamespaceSources 113 .get(key); 114 115 if (result == null) 116 { 117 result = new LocalizedPropertySource(getSourceForNamespace(namespace)); 118 119 _localizedNamespaceSources.put(key, result); 120 } 121 122 return result; 123 } 124 125 private IPropertySource createSourceForComponent(IComponent component) 126 { 127 IComponentSpecification specification = component.getSpecification(); 128 129 List sources = new ArrayList(); 130 131 sources.add(new PropertyHolderPropertySource(specification)); 132 sources.add(getSourceForNamespace(component.getNamespace())); 133 134 return (IPropertySource) _chainBuilder.buildImplementation( 135 IPropertySource.class, 136 sources, 137 ImplMessages.componentPropertySourceDescription(specification)); 138 } 139 140 private IPropertySource createSourceForNamespace(INamespace namespace) 141 { 142 List sources = new ArrayList(); 143 144 sources.add(new PropertyHolderPropertySource(namespace.getSpecification())); 145 sources.add(_globalProperties); 146 147 return (IPropertySource) _chainBuilder.buildImplementation( 148 IPropertySource.class, 149 sources, 150 ImplMessages.namespacePropertySourceDescription(namespace)); 151 } 152 153 public String getComponentProperty(IComponent component, String propertyName) 154 { 155 return getSourceForComponent(component).getPropertyValue(propertyName); 156 } 157 158 public String getLocalizedComponentProperty(IComponent component, Locale locale, 159 String propertyName) 160 { 161 return getLocalizedSourceForComponent(component).getPropertyValue(propertyName, locale); 162 } 163 164 public String getNamespaceProperty(INamespace namespace, String propertyName) 165 { 166 return getSourceForNamespace(namespace).getPropertyValue(propertyName); 167 } 168 169 public String getLocalizedNamespaceProperty(INamespace namespace, Locale locale, 170 String propertyName) 171 { 172 return getLocalizedSourceForNamespace(namespace).getPropertyValue(propertyName, locale); 173 } 174 175 public void setChainBuilder(ChainBuilder chainBuilder) 176 { 177 _chainBuilder = chainBuilder; 178 } 179 180 public void setGlobalProperties(IPropertySource globalProperties) 181 { 182 _globalProperties = globalProperties; 183 } 184 }