blob: 0b7ed141adbd74c6745f2cb57ef832a7c1332a7d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006 Sybase, Inc. and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sybase, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.jsf.core.internal.tld;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
/**
* @author mengbo
*/
public class LoadBundleUtil {
private LoadBundleUtil() {
// no external instantiation
}
/**
* @param project
* @param baseName
* @return an IStorage pointing to the request bundle or null if not found
* @throws CoreException if the search for the file encounters a problem
*/
public static IStorage getLoadBundleResource(final IProject project,
final String baseName) throws CoreException {
if (project == null || baseName == null) {
return null;
}
IStorage loadBundleResource = null;
if (project.hasNature(JavaCore.NATURE_ID)) {
IJavaProject javaProject = JavaCore.create(project);
IFile sourceFile = getSourceFile(javaProject, baseName);
if (sourceFile == null || !sourceFile.exists()) {
loadBundleResource = getJarFile(javaProject, baseName);
} else {
loadBundleResource = sourceFile;
}
}
return loadBundleResource;
}
private static IFile getSourceFile(IJavaProject javaProject, String baseName)
throws JavaModelException {
IClasspathEntry[] classpathEntries = javaProject.getRawClasspath();
for (int i = 0; i < classpathEntries.length; i++) {
if (classpathEntries[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) {
final IFile file = getFile(javaProject, baseName,
classpathEntries, i);
if (file.exists()) {
return file;
}
} else if (classpathEntries[i].getEntryKind() == IClasspathEntry.CPE_PROJECT) {
IProject project = ResourcesPlugin.getWorkspace().getRoot()
.getProject(classpathEntries[i].getPath().toString());
IJavaProject javaProject3 = JavaCore.create(project);
final IFile file = getSourceFile(javaProject3, baseName);
if (file != null && file.exists()) {
return file;
}
}
else if (classpathEntries[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER && classpathEntries[i].getPath().equals(new Path("org.eclipse.jst.j2ee.internal.module.container"))) //$NON-NLS-1$
{
IClasspathContainer container = JavaCore.getClasspathContainer(classpathEntries[i].getPath(), javaProject);
IClasspathEntry[] classpathEntries2 = container.getClasspathEntries();
for (int j = 0; j < classpathEntries2.length; j++)
{
if (classpathEntries2[j].getEntryKind() == IClasspathEntry.CPE_PROJECT)
{
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(classpathEntries2[j].getPath().toString());
IJavaProject javaProject3 = JavaCore.create(project);
final IFile file = getSourceFile(javaProject3, baseName);
if (file != null && file.exists())
{
return file;
}
}
}
}
}
return null;
}
private static IFile getFile(IJavaProject javaProject, String baseName,
IClasspathEntry[] classpathEntries, int i) {
IPath path = classpathEntries[i].getPath()
.append(getFilePath(baseName)).removeFirstSegments(1);
path = javaProject.getProject().getFullPath().append(path);
return ResourcesPlugin.getWorkspace().getRoot().getFile(path);
}
private static IPath getFilePath(String baseName) {
IPath path = new Path(baseName.replace('.', '/'));
path = path.addFileExtension("properties");//$NON-NLS-1$
return path;
}
private static IStorage getJarFile(IJavaProject javaProject, String baseName)
throws JavaModelException {
IClasspathEntry[] roots = javaProject.getRawClasspath();
return getJarFile(javaProject, baseName, roots);
}
private static IStorage getJarFile(IJavaProject javaProject, String baseName,
IClasspathEntry[] roots) throws JavaModelException
{
for (int i = 0; i < roots.length; i++) {
if (roots[i].getEntryKind() == IClasspathEntry.CPE_LIBRARY ||
roots[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER)
{
IStorage storage = getResourceFromLibrary(
javaProject, baseName, roots[i]);
if (storage != null)
{
return storage;
}
}
// else if ( roots[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER)
// {
// IClasspathContainer classpathContainer = JavaCore.getClasspathContainer(roots[i].getPath(), javaProject);
// final IClasspathEntry[] classpathEntries =
// classpathContainer.getClasspathEntries();
// IStorage storage = getJarFile(javaProject, baseName, classpathEntries);
// if (storage != null)
// {
// return storage;
// }
// }
}
return null;
}
private static IStorage getResourceFromLibrary(
IJavaProject javaProject, String baseName, IClasspathEntry entry) throws JavaModelException
{
IPackageFragmentRoot[] packageFragmentRoots = javaProject
.findPackageFragmentRoots(entry);
for (int j = 0; j < packageFragmentRoots.length; j++) {
String packageName = getPackageName(baseName);
Object[] resources = null;
if (packageName.length() == 0) {
resources = packageFragmentRoots[j].getNonJavaResources();
} else {
IPackageFragment fragment = packageFragmentRoots[j]
.getPackageFragment(getPackageName(baseName));
if (fragment != null && fragment.exists()) {
resources = fragment.getNonJavaResources();
}
}
if (resources != null && resources.length > 0) {
for (int k = 0; k < resources.length; k++) {
if (resources[k] instanceof IStorage) {
IStorage storage = (IStorage) resources[k];
if (getFileName(baseName).equalsIgnoreCase(
storage.getName())) {
return storage;
}
}
}
}
}
return null;
}
private static String getPackageName(String baseName) {
int index = baseName.lastIndexOf('.');
if (index == -1) {
return "";//$NON-NLS-1$
}
return baseName.substring(0, index);
}
private static String getFileName(String baseName) {
int index = baseName.lastIndexOf('.');
if (index == -1) {
return baseName + ".properties"; //$NON-NLS-1$
}
return baseName.substring(index + 1).concat(".properties");//$NON-NLS-1$
}
/**
* Encapsulates the hiearchy of bundle data sources in the hierarchy
* for a ResourceBundle base name. In practice this is often simply
* a single IFile for a
* @author cbateman
*
*/
// public static class BundleHierarchy
// {
// // list in order from most specific (first queried) to least,
// // front to back
// //private final List _hierarchy;
//
// /**
// * Takes the list *by reference*. Does not take a copy.
// * @param hierarchy
// */
// public BundleHierarchy(List hierarchy)
// {
// _hierarchy = hierarchy;
// }
//
// public BundleHierarchy()
// {
// _hierarchy = new ArrayList();
// }
// }
/**
* Used to describe the design time approximation of the locale lookup precendence
* that will be used by ResourceBundle to find a localized resource bundle.
*
* See the official JavaDoc for java.util.ResourceBundle.getBundle for docs on search
* order.
*
* @author cbateman
*
*/
public static class LocaleDescriptor
{
private Locale _locale;
private List _possibleSuffices;
/**
* @param language -- must not be null
*/
public LocaleDescriptor(String language)
{
_locale = new Locale(language);
}
/**
* All arguments must be non-null. To set a language only descriptor,
* see others.
*
* @param language -- must not be null
* @param country -- must not be null
*/
public LocaleDescriptor(String language,
String country)
{
_locale = new Locale(language, country);
}
/**
* All arguments must be non-null. Null arguments will cause an exception.
* To create descriptor without variant and/or country set, see other constructors
* @param language -- must not be null
* @param country -- must not be null
* @param variant -- must not be null
*/
public LocaleDescriptor(String language,
String country, String variant)
{
_locale = new Locale(language, country, variant);
}
/**
* @param baseName
* @return an iterator through all possible bundle names starting with the most
* specific and becoming more general for base name based on this locale.
*
* i.e. if baseName is "bundle" and the local is en_US_1 then in order the
* iterator will produce:
*
* bundle_en_US_1
* bundle_en_US
* bundle_en
* bundle
*
* per the ResourceBundle API
*
*/
public Iterator getBundleNameIterator(final String baseName)
{
return new Iterator()
{
final Iterator it = getPossibleBaseNameSuffices().iterator();
public boolean hasNext() {
return it.hasNext();
}
public Object next() {
return baseName+it.next();
}
public void remove() {
// delegate; should throw exception
it.remove();
}
};
}
private synchronized List getPossibleBaseNameSuffices()
{
if (_possibleSuffices == null)
{
List possibleSuffices = new ArrayList(3);
final String language = _locale.getLanguage();
final String country = _locale.getCountry();
final String variant = _locale.getVariant();
possibleSuffices.add(""); //$NON-NLS-1$
possibleSuffices.add("_"+language); //$NON-NLS-1$
if (country != null)
{
possibleSuffices.add(0, "_"+language + "_" + country); //$NON-NLS-1$ //$NON-NLS-2$
if (variant != null)
{
possibleSuffices.add(0, "_"+language+"_"+country+"_"+variant); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
_possibleSuffices = Collections.unmodifiableList(possibleSuffices);
}
return _possibleSuffices;
}
/**
* @return the local information as a standard locale object
*/
public Locale getLocale()
{
return _locale;
}
}
}