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