blob: e9c2d8877f207b4b67473a65f6edbd2684dacd11 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.osgi.framework.internal.core;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;
import org.eclipse.osgi.framework.util.Headers;
import org.osgi.framework.Constants;
/**
* This class is used by the Bundle Class to localize manifest headers.
*/
public class ManifestLocalization {
private Bundle bundle = null;
private Dictionary rawHeaders = null;
private Headers defaultLocaleHeaders = null;
public ManifestLocalization(Bundle bundle, Dictionary rawHeaders) {
this.bundle = bundle;
this.rawHeaders = rawHeaders;
}
protected Dictionary getHeaders(String localeString) {
boolean defaultLocale = false;
if (localeString == "") {
return (rawHeaders);
}
if (localeString.equals(Locale.getDefault().toString())) {
if (defaultLocaleHeaders != null) {
return (defaultLocaleHeaders);
} else {
defaultLocale = true;
}
}
try {
bundle.checkValid();
} catch (IllegalStateException ex) {
return (rawHeaders);
}
ResourceBundle localeProperties = null;
localeProperties = getResourceBundle(localeString);
if (localeProperties == null) {
// TODO Need to strip off leading percents. Can do it when
//Eclipse no uses Bundle.getHeaders("") instead of
// Bundle.getHeaders()
// Dictionary localeHeaders = stripPercents(new Hashtable(
// this.rawHeaders.size()));
//if (defaultLocale) {
// defaultLocaleHeaders = localeHeaders;
//}
//return (localeHeaders);
return (rawHeaders);
}
Enumeration e = this.rawHeaders.keys();
Headers localeHeaders = new Headers(this.rawHeaders.size());
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
String value = (String) this.rawHeaders.get(key);
if (value.startsWith("%") && (value.length() > 1)) { //$NON-NLS-1$
String propertiesKey = value.substring(1);
String transValue = (String) localeProperties.getObject(propertiesKey);
if (transValue != null) {
value = transValue;
}
//strip the leading percent and return the raw value
else {
value = propertiesKey;
}
}
localeHeaders.set(key, value);
}
if (defaultLocale) {
defaultLocaleHeaders = localeHeaders;
}
return (localeHeaders);
}
private String[] buildNLVariants(String nl) {
ArrayList result = new ArrayList();
int lastSeparator;
while ((lastSeparator = nl.lastIndexOf('_')) != -1) {
result.add(nl);
if (lastSeparator != -1) {
nl = nl.substring(0, lastSeparator);
}
}
result.add(nl);
return (String[]) result.toArray(new String[result.size()]);
}
/*
* This method find the appropiate Manifest Localization file inside the bundle. If not found, return null.
*/
protected ResourceBundle getResourceBundle(String localeString) {
URL resourceURL = null;
String propertiesLocation = (String) rawHeaders.get(Constants.BUNDLE_MANIFEST_LOCALIZATION);
if (propertiesLocation == null) {
propertiesLocation = Constants.BUNDLE_DEFAULT_MANIFEST_LOCALIZATION;
}
resourceURL = findProperties(localeString, propertiesLocation);
if (resourceURL == null) {
return null;
}
ResourceBundle resourceBundle = null;
InputStream resourceStream = null;
try {
resourceStream = resourceURL.openStream();
resourceBundle = new PropertyResourceBundle(resourceStream);
} catch (IOException e2) {
if (resourceStream != null) {
try {
resourceStream.close();
} catch (IOException e3) {
//Ignore exception
}
}
return null;
}
return resourceBundle;
}
/*
* This method searchs for properties file the same way the ResourceBundle algorithm
*/
private URL findProperties(String localeString, String path) {
String[] nlVariants = buildNLVariants(localeString);
URL result = null;
for (int i = 0; i < nlVariants.length; i++) {
String filePath = path.concat("_" + nlVariants[i] + ".properties");
result = findInBundle(filePath);
if (result != null)
return result;
result = findInFragments(filePath);
if (result != null)
return result;
}
// If we get to this point, we haven't found it yet.
// Look in the plugin and fragment root directories
String filename = path + ".properties";
result = findInBundle(filename);
if (result != null)
return result;
return findInFragments(filename);
}
private URL findInBundle(String filePath) {
return this.bundle.getEntry(filePath);
}
private URL findInFragments(String filePath) {
org.osgi.framework.Bundle[] fragments = this.bundle.getFragments();
URL fileURL = null;
int i = 0;
while (fragments != null && i < fragments.length && fileURL == null) {
fileURL = fragments[i].getEntry(filePath);
i++;
}
return fileURL;
}
private Dictionary stripPercents(Dictionary dictionary) {
//strip out the '%'s and return the raw headers without '%'s
Enumeration e = rawHeaders.keys();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
String value = (String) rawHeaders.get(key);
if (value.startsWith("%")) //$NON-NLS-1$
{
if (value.length() > 1) {
value = value.substring(1);
} else {
value = "";
}
}
dictionary.put(key, value);
}
return (dictionary);
}
}