/* $$ Clover has instrumented this file $$ */// Copyright 2004 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.services.impl;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.Messages;
import org.apache.hivemind.Resource;
import org.apache.tapestry.IComponent;
import org.apache.tapestry.Tapestry;
import org.apache.tapestry.engine.ComponentMessages;
import org.apache.tapestry.engine.DefaultComponentPropertySource;
import org.apache.tapestry.engine.IPropertySource;
import org.apache.tapestry.event.ResetEventListener;
import org.apache.tapestry.services.ComponentMessagesSource;
import org.apache.tapestry.util.MultiKey;
import org.apache.tapestry.util.text.LocalizedProperties;
/**
* Service used to access localized properties for a component.
*
* @author Howard Lewis Ship
* @since 2.0.4
*/
public class ComponentMessagesSourceImpl implements ComponentMessagesSource, ResetEventListener
{public static com.cortexeb.tools.clover.d __CLOVER_305_0 = com.cortexeb.tools.clover.aq.getRecorder(new char[] {67,58,92,119,111,114,107,115,112,97,99,101,92,106,97,107,97,114,116,97,45,116,97,112,101,115,116,114,121,92,102,114,97,109,101,119,111,114,107,92,116,97,114,103,101,116,92,99,108,111,118,101,114,45,100,98},1096998272901L);
private Properties _emptyProperties = new Properties();
private static final String SUFFIX = ".properties";
/**
* The name of the component/application/etc property that will be used to determine the
* encoding to use when loading the messages
*/
public static final String MESSAGES_ENCODING_PROPERTY_NAME = "org.apache.tapestry.messages-encoding";
/**
* Map of {@link Properties}, keyed on a {@link MultiKey}of component specification path and
* locale.
*/
private Map _cache = new HashMap();
private IPropertySource _applicationPropertySource;
public void setApplicationPropertySource(IPropertySource source)
{try { __CLOVER_305_0.M[1457]++;
__CLOVER_305_0.S[7036]++;_applicationPropertySource = source;
} finally { }}
/**
* Returns an instance of {@link Properties}containing the properly localized messages for the
* component, in the {@link Locale}identified by the component's containing page.
*/
protected synchronized Properties getLocalizedProperties(IComponent component)
{try { __CLOVER_305_0.M[1458]++;
__CLOVER_305_0.S[7037]++;Tapestry.notNull(component, "component");
__CLOVER_305_0.S[7038]++;Resource specificationLocation = component.getSpecification().getSpecificationLocation();
__CLOVER_305_0.S[7039]++;Locale locale = component.getPage().getLocale();
// Check to see if already in the cache
__CLOVER_305_0.S[7040]++;MultiKey key = buildKey(specificationLocation, locale);
__CLOVER_305_0.S[7041]++;Properties result = (Properties) _cache.get(key);
__CLOVER_305_0.S[7042]++;if ((((result != null) && (++__CLOVER_305_0.CT[1226] != 0)) || (++__CLOVER_305_0.CF[1226] == 0))){
__CLOVER_305_0.S[7043]++;return result;}
// Not found, create it now.
__CLOVER_305_0.S[7044]++;result = assembleProperties(component, specificationLocation, locale);
__CLOVER_305_0.S[7045]++;_cache.put(key, result);
__CLOVER_305_0.S[7046]++;return result;
} finally { }}
private Properties assembleProperties(IComponent component, Resource baseResourceLocation,
Locale locale)
{try { __CLOVER_305_0.M[1459]++;
__CLOVER_305_0.S[7047]++;String name = baseResourceLocation.getName();
__CLOVER_305_0.S[7048]++;int dotx = name.indexOf('.');
__CLOVER_305_0.S[7049]++;String baseName = name.substring(0, dotx);
__CLOVER_305_0.S[7050]++;String language = locale.getLanguage();
__CLOVER_305_0.S[7051]++;String country = locale.getCountry();
__CLOVER_305_0.S[7052]++;String variant = locale.getVariant();
__CLOVER_305_0.S[7053]++;Properties parent = (Properties) _cache.get(baseResourceLocation);
__CLOVER_305_0.S[7054]++;if ((((parent == null) && (++__CLOVER_305_0.CT[1227] != 0)) || (++__CLOVER_305_0.CF[1227] == 0))){
{
__CLOVER_305_0.S[7055]++;parent = readProperties(component, baseResourceLocation, baseName, null, null);
__CLOVER_305_0.S[7056]++;if ((((parent == null) && (++__CLOVER_305_0.CT[1228] != 0)) || (++__CLOVER_305_0.CF[1228] == 0))){
{
__CLOVER_305_0.S[7057]++;parent = _emptyProperties;
__CLOVER_305_0.S[7058]++;_cache.put(baseResourceLocation, parent);
}}
}}
__CLOVER_305_0.S[7059]++;Properties result = parent;
__CLOVER_305_0.S[7060]++;if ((((!Tapestry.isBlank(language)) && (++__CLOVER_305_0.CT[1229] != 0)) || (++__CLOVER_305_0.CF[1229] == 0))){
{
__CLOVER_305_0.S[7061]++;Locale l = new Locale(language, "");
__CLOVER_305_0.S[7062]++;MultiKey key = buildKey(baseResourceLocation, l);
__CLOVER_305_0.S[7063]++;result = (Properties) _cache.get(key);
__CLOVER_305_0.S[7064]++;if ((((result == null) && (++__CLOVER_305_0.CT[1230] != 0)) || (++__CLOVER_305_0.CF[1230] == 0))){
{
__CLOVER_305_0.S[7065]++;result = readProperties(component, baseResourceLocation, baseName, l, parent);
__CLOVER_305_0.S[7066]++;_cache.put(key, result);
}}
__CLOVER_305_0.S[7067]++;parent = result;
}}
else{
__CLOVER_305_0.S[7068]++;language = "";}
__CLOVER_305_0.S[7069]++;if ((((Tapestry.isNonBlank(country)) && (++__CLOVER_305_0.CT[1231] != 0)) || (++__CLOVER_305_0.CF[1231] == 0))){
{
__CLOVER_305_0.S[7070]++;Locale l = new Locale(language, country);
__CLOVER_305_0.S[7071]++;MultiKey key = buildKey(baseResourceLocation, l);
__CLOVER_305_0.S[7072]++;result = (Properties) _cache.get(key);
__CLOVER_305_0.S[7073]++;if ((((result == null) && (++__CLOVER_305_0.CT[1232] != 0)) || (++__CLOVER_305_0.CF[1232] == 0))){
{
__CLOVER_305_0.S[7074]++;result = readProperties(component, baseResourceLocation, baseName, l, parent);
__CLOVER_305_0.S[7075]++;_cache.put(key, result);
}}
__CLOVER_305_0.S[7076]++;parent = result;
}}
else{
__CLOVER_305_0.S[7077]++;country = "";}
__CLOVER_305_0.S[7078]++;if ((((Tapestry.isNonBlank(variant)) && (++__CLOVER_305_0.CT[1233] != 0)) || (++__CLOVER_305_0.CF[1233] == 0))){
{
__CLOVER_305_0.S[7079]++;Locale l = new Locale(language, country, variant);
__CLOVER_305_0.S[7080]++;MultiKey key = buildKey(baseResourceLocation, l);
__CLOVER_305_0.S[7081]++;result = (Properties) _cache.get(key);
__CLOVER_305_0.S[7082]++;if ((((result == null) && (++__CLOVER_305_0.CT[1234] != 0)) || (++__CLOVER_305_0.CF[1234] == 0))){
{
__CLOVER_305_0.S[7083]++;result = readProperties(component, baseResourceLocation, baseName, l, parent);
__CLOVER_305_0.S[7084]++;_cache.put(key, result);
}}
}}
__CLOVER_305_0.S[7085]++;return result;
} finally { }}
private MultiKey buildKey(Resource location, Locale locale)
{try { __CLOVER_305_0.M[1460]++;
__CLOVER_305_0.S[7086]++;return new MultiKey(new Object[]
{ location, locale.toString() }, false);
} finally { }}
private Properties readProperties(IComponent component, Resource baseLocation, String baseName,
Locale locale, Properties parent)
{try { __CLOVER_305_0.M[1461]++;
__CLOVER_305_0.S[7087]++;StringBuffer buffer = new StringBuffer(baseName);
__CLOVER_305_0.S[7088]++;if ((((locale != null) && (++__CLOVER_305_0.CT[1235] != 0)) || (++__CLOVER_305_0.CF[1235] == 0))){
{
__CLOVER_305_0.S[7089]++;buffer.append('_');
__CLOVER_305_0.S[7090]++;buffer.append(locale.toString());
}}
__CLOVER_305_0.S[7091]++;buffer.append(SUFFIX);
__CLOVER_305_0.S[7092]++;Resource localized = baseLocation.getRelativeResource(buffer.toString());
__CLOVER_305_0.S[7093]++;URL propertiesURL = localized.getResourceURL();
__CLOVER_305_0.S[7094]++;if ((((propertiesURL == null) && (++__CLOVER_305_0.CT[1236] != 0)) || (++__CLOVER_305_0.CF[1236] == 0))){
__CLOVER_305_0.S[7095]++;return parent;}
__CLOVER_305_0.S[7096]++;Properties result = null;
__CLOVER_305_0.S[7097]++;if ((((parent == null) && (++__CLOVER_305_0.CT[1237] != 0)) || (++__CLOVER_305_0.CF[1237] == 0))){
__CLOVER_305_0.S[7098]++;result = new Properties();}
else{
__CLOVER_305_0.S[7099]++;result = new Properties(parent);}
__CLOVER_305_0.S[7100]++;LocalizedProperties localizedResult = new LocalizedProperties(result);
__CLOVER_305_0.S[7101]++;String encoding = getMessagesEncoding(component, locale);
__CLOVER_305_0.S[7102]++;try
{
__CLOVER_305_0.S[7103]++;InputStream input = propertiesURL.openStream();
__CLOVER_305_0.S[7104]++;if ((((encoding == null) && (++__CLOVER_305_0.CT[1238] != 0)) || (++__CLOVER_305_0.CF[1238] == 0))){
__CLOVER_305_0.S[7105]++;localizedResult.load(input);}
else{
__CLOVER_305_0.S[7106]++;localizedResult.load(input, encoding);}
__CLOVER_305_0.S[7107]++;input.close();
}
catch (IOException ex)
{
__CLOVER_305_0.S[7108]++;throw new ApplicationRuntimeException(ImplMessages.unableToLoadProperties(
propertiesURL,
ex), ex);
}
__CLOVER_305_0.S[7109]++;return result;
} finally { }}
/**
* Clears the cache of read properties files.
*/
public synchronized void resetEventDidOccur()
{try { __CLOVER_305_0.M[1462]++;
__CLOVER_305_0.S[7110]++;_cache.clear();
} finally { }}
public Messages getMessages(IComponent component)
{try { __CLOVER_305_0.M[1463]++;
__CLOVER_305_0.S[7111]++;return new ComponentMessages(component.getPage().getLocale(),
getLocalizedProperties(component));
} finally { }}
private String getMessagesEncoding(IComponent component, Locale locale)
{try { __CLOVER_305_0.M[1464]++;
__CLOVER_305_0.S[7112]++;IPropertySource source = new DefaultComponentPropertySource(component,
_applicationPropertySource, locale);
__CLOVER_305_0.S[7113]++;String encoding = source.getPropertyValue(MESSAGES_ENCODING_PROPERTY_NAME);
__CLOVER_305_0.S[7114]++;if ((((encoding == null) && (++__CLOVER_305_0.CT[1239] != 0)) || (++__CLOVER_305_0.CF[1239] == 0))){
__CLOVER_305_0.S[7115]++;encoding = source.getPropertyValue(TemplateSourceImpl.TEMPLATE_ENCODING_PROPERTY_NAME);}
__CLOVER_305_0.S[7116]++;return encoding;
} finally { }}
}