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