/*
* Copyright 2011 Future Systems, Inc.
*
* 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.krakenapps.dom.api.impl;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Invalidate;
import org.apache.felix.ipojo.annotations.Provides;
import org.apache.felix.ipojo.annotations.Validate;
import org.krakenapps.dom.api.LocalizationApi;
import org.krakenapps.dom.api.ResourceKey;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Component(name = "dom-localization-api")
@Provides
public class LocalizationApiImpl implements LocalizationApi, BundleListener {
private final Logger logger = LoggerFactory.getLogger(LocalizationApiImpl.class.getName());
private BundleContext bc;
private Map<ResourceKey, String> templates;
public LocalizationApiImpl(BundleContext bc) {
this.bc = bc;
this.templates = new ConcurrentHashMap<ResourceKey, String>();
}
@Validate
public void start() {
bc.addBundleListener(this);
}
@Invalidate
public void stop() {
if (bc != null)
bc.removeBundleListener(this);
}
@Override
public String format(ResourceKey key, Object... args) {
String template = templates.get(key);
if (template == null)
return null;
return String.format(template, args);
}
@Override
public String get(ResourceKey key) {
return templates.get(key);
}
@Override
public void register(ResourceKey key, String template) {
templates.put(key, template);
}
@Override
public void unregister(ResourceKey key) {
templates.remove(key);
}
@Override
public void bundleChanged(BundleEvent event) {
if (event.getType() == BundleEvent.STARTED) {
Map<ResourceKey, String> m = getLocalizations(event);
if (m == null)
return;
for (ResourceKey key : m.keySet()) {
templates.put(key, m.get(key));
logger.trace("kraken dom: added [{}] resource key", key);
}
} else if (event.getType() == BundleEvent.STOPPED) {
Map<ResourceKey, String> m = getLocalizations(event);
if (m == null)
return;
for (ResourceKey key : m.keySet()) {
templates.remove(key);
logger.trace("kraken dom: removed [{}] resource key", key);
}
}
}
@SuppressWarnings("unchecked")
private Map<ResourceKey, String> getLocalizations(BundleEvent event) {
Map<ResourceKey, String> m = new HashMap<ResourceKey, String>();
Bundle bundle = event.getBundle();
Enumeration<String> e = bundle.getEntryPaths("/OSGI-INF/kraken-dom/");
if (e == null) {
logger.trace("kraken dom: localization not found for bundle {}", event.getBundle().getBundleId());
return null;
}
while (e.hasMoreElements()) {
String path = e.nextElement();
if (path.startsWith("OSGI-INF/kraken-dom/localization.") && path.endsWith(".properties")) {
String token = path.replace("OSGI-INF/kraken-dom/localization.", "").replace(".properties", "");
if (token.length() != 2)
continue;
Locale locale = new Locale(token);
InputStream is = null;
InputStreamReader reader = null;
try {
URL url = bundle.getEntry(path);
Properties p = new Properties();
is = url.openStream();
reader = new InputStreamReader(is, Charset.forName("utf-8"));
p.load(reader);
String group = p.getProperty("group");
for (Object key : p.keySet()) {
if (key.equals("group"))
continue;
ResourceKey resourceKey = new ResourceKey(group, (String) key, locale);
String template = p.getProperty((String) key);
m.put(resourceKey, template);
}
} catch (IOException ex) {
logger.error("kraken dom: cannot read localization properties", ex);
} finally {
if (reader != null)
try {
reader.close();
} catch (IOException e2) {
}
if (is != null)
try {
is.close();
} catch (IOException e1) {
}
}
}
}
return m;
}
}