/******************************************************************************* * 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; } } }