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 }