001 // Copyright 2006, 2007, 2008, 2009, 2010, 2011 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.internal.services; 016 017 import java.util.Arrays; 018 import java.util.Collections; 019 import java.util.List; 020 import java.util.Locale; 021 022 import org.apache.tapestry5.SymbolConstants; 023 import org.apache.tapestry5.func.Worker; 024 import org.apache.tapestry5.ioc.Messages; 025 import org.apache.tapestry5.ioc.Resource; 026 import org.apache.tapestry5.ioc.annotations.Symbol; 027 import org.apache.tapestry5.ioc.internal.util.CollectionFactory; 028 import org.apache.tapestry5.ioc.internal.util.URLChangeTracker; 029 import org.apache.tapestry5.ioc.services.ClasspathURLConverter; 030 import org.apache.tapestry5.model.ComponentModel; 031 import org.apache.tapestry5.services.InvalidationEventHub; 032 import org.apache.tapestry5.services.UpdateListener; 033 import org.apache.tapestry5.services.messages.ComponentMessagesSource; 034 import org.apache.tapestry5.services.messages.PropertiesFileParser; 035 import org.apache.tapestry5.services.pageload.ComponentResourceLocator; 036 import org.apache.tapestry5.services.pageload.ComponentResourceSelector; 037 038 public class ComponentMessagesSourceImpl implements ComponentMessagesSource, UpdateListener 039 { 040 private final MessagesSource messagesSource; 041 042 private final MessagesBundle appCatalogBundle; 043 044 private class ComponentModelBundle implements MessagesBundle 045 { 046 private final ComponentModel model; 047 048 public ComponentModelBundle(ComponentModel model) 049 { 050 this.model = model; 051 } 052 053 public Resource getBaseResource() 054 { 055 return model.getBaseResource(); 056 } 057 058 public Object getId() 059 { 060 return model.getComponentClassName(); 061 } 062 063 public MessagesBundle getParent() 064 { 065 ComponentModel parentModel = model.getParentModel(); 066 067 if (parentModel == null) 068 return appCatalogBundle; 069 070 return new ComponentModelBundle(parentModel); 071 } 072 } 073 074 public ComponentMessagesSourceImpl(@Symbol(SymbolConstants.PRODUCTION_MODE) 075 boolean productionMode, List<Resource> appCatalogResources, PropertiesFileParser parser, 076 ComponentResourceLocator resourceLocator, ClasspathURLConverter classpathURLConverter) 077 { 078 this(productionMode, appCatalogResources, resourceLocator, parser, new URLChangeTracker(classpathURLConverter)); 079 } 080 081 ComponentMessagesSourceImpl(boolean productionMode, Resource appCatalogResource, 082 ComponentResourceLocator resourceLocator, PropertiesFileParser parser, URLChangeTracker tracker) 083 { 084 this(productionMode, Arrays.asList(appCatalogResource), resourceLocator, parser, tracker); 085 } 086 087 ComponentMessagesSourceImpl(boolean productionMode, List<Resource> appCatalogResources, 088 ComponentResourceLocator resourceLocator, PropertiesFileParser parser, URLChangeTracker tracker) 089 { 090 messagesSource = new MessagesSourceImpl(productionMode, productionMode ? null : tracker, resourceLocator, 091 parser); 092 093 appCatalogBundle = createAppCatalogBundle(appCatalogResources); 094 } 095 096 public void checkForUpdates() 097 { 098 messagesSource.checkForUpdates(); 099 } 100 101 public Messages getMessages(ComponentModel componentModel, Locale locale) 102 { 103 return getMessages(componentModel, new ComponentResourceSelector(locale)); 104 } 105 106 public Messages getMessages(ComponentModel componentModel, ComponentResourceSelector selector) 107 { 108 MessagesBundle bundle = new ComponentModelBundle(componentModel); 109 110 return messagesSource.getMessages(bundle, selector); 111 } 112 113 public Messages getApplicationCatalog(Locale locale) 114 { 115 return messagesSource.getMessages(appCatalogBundle, new ComponentResourceSelector(locale)); 116 } 117 118 private MessagesBundle createAppCatalogBundle(List<Resource> resources) 119 { 120 MessagesBundle current = null; 121 122 for (Resource r : resources) 123 { 124 current = createMessagesBundle(r, current); 125 } 126 127 return current; 128 } 129 130 private MessagesBundle createMessagesBundle(final Resource resource, final MessagesBundle parent) 131 { 132 return new MessagesBundle() 133 { 134 public Resource getBaseResource() 135 { 136 return resource; 137 } 138 139 public Object getId() 140 { 141 return resource.getPath(); 142 } 143 144 public MessagesBundle getParent() 145 { 146 return parent; 147 } 148 }; 149 } 150 151 public InvalidationEventHub getInvalidationEventHub() 152 { 153 return messagesSource; 154 } 155 }