| /******************************************************************************* |
| * Copyright (c) 2001, 2007 Oracle Corporation 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: |
| * Oracle Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jst.jsf.designtime.internal.symbols; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Properties; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IStorage; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jst.jsf.context.symbol.IComponentSymbol; |
| import org.eclipse.jst.jsf.context.symbol.IMapTypeDescriptor; |
| import org.eclipse.jst.jsf.context.symbol.ISymbol; |
| import org.eclipse.jst.jsf.context.symbol.SymbolFactory; |
| import org.eclipse.jst.jsf.context.symbol.source.AbstractSymbolSourceProviderFactory; |
| import org.eclipse.jst.jsf.context.symbol.source.ISymbolSourceProvider; |
| import org.eclipse.jst.jsf.core.IJSFCoreConstants; |
| import org.eclipse.jst.jsf.core.internal.JSFCorePlugin; |
| import org.eclipse.jst.jsf.core.internal.tld.LoadBundleUtil; |
| import org.eclipse.jst.jsf.core.jsfappconfig.JSFAppConfigUtils; |
| import org.eclipse.jst.jsf.core.jsfappconfig.internal.IJSFAppConfigManager; |
| import org.eclipse.jst.jsf.core.jsfappconfig.internal.JSFAppConfigManagerFactory; |
| import org.eclipse.jst.jsf.designtime.symbols.FileContextUtil; |
| import org.eclipse.jst.jsf.designtime.symbols.SymbolUtil; |
| import org.eclipse.jst.jsf.facesconfig.emf.BaseNameType; |
| import org.eclipse.jst.jsf.facesconfig.emf.ResourceBundleType; |
| import org.eclipse.jst.jsf.facesconfig.emf.VarType; |
| |
| /** |
| * WARNING: this is an interim solution to supporting Faces 1.2 resource |
| * bundle variables. This class will become obsolete by design once |
| * the dt framework for Unified EL symbol resolution is added |
| * |
| * DO NOT USE THIS CLASS EXTERNALLY, IT WILL BE REMOVED WITHOUT WARNING IN THE FUTURE |
| * WITH NO MIGRATION PATH |
| * |
| * Self-factory for symbol source providers that contribute symbols for |
| * the resource bundle variables declared in Faces 1.2 and greater |
| * app configuration files. |
| * |
| * @author cbateman |
| * |
| */ |
| public final class ResourceBundleSymbolSourceProvider extends |
| AbstractSymbolSourceProviderFactory implements ISymbolSourceProvider { |
| |
| protected final ISymbolSourceProvider create(IProject project) { |
| return this; |
| } |
| |
| public final ISymbol[] getSymbols(IAdaptable context, int symbolScopeMask) |
| { |
| if (isProvider(context)) |
| { |
| final List symbols = new ArrayList(); |
| final IFile fileContext = FileContextUtil.deriveIFileFromContext(context); |
| final IProject project = fileContext.getProject(); |
| |
| final IJSFAppConfigManager appconfigMgr = JSFAppConfigManagerFactory.getJSFAppConfigManagerInstance(project); |
| final List<ResourceBundleType> resourceBundles = appconfigMgr.getResourceBundles(); |
| |
| for (final ResourceBundleType resBundle : resourceBundles) |
| { |
| final String basename = getBaseName(resBundle); |
| final String name = getVarName(resBundle); |
| |
| if (basename != null && name != null) |
| { |
| try |
| { |
| symbols.add(createSymbolForResourceBundle(project, name, basename)); |
| } catch (JavaModelException e) { |
| JSFCorePlugin.log(e, "Error creating base name for: "+basename); //$NON-NLS-1$ |
| } catch (IOException e) { |
| //Bug 306811 - Invalid error "messages not found in classpath for project" |
| ISymbol symbol = createSymbolForResourceBundleInJAR(project, name, basename); |
| if (symbol != null) { |
| symbols.add(symbol); |
| } else { |
| JSFCorePlugin.log(e, "Error creating base name for: "+basename); //$NON-NLS-1$ |
| } |
| } catch (CoreException e) { |
| JSFCorePlugin.log(e, "Error creating base name for: "+basename); //$NON-NLS-1$ |
| } |
| } |
| } |
| return (ISymbol[]) symbols.toArray(ISymbol.EMPTY_SYMBOL_ARRAY); |
| } |
| return ISymbol.EMPTY_SYMBOL_ARRAY; |
| } |
| |
| private ISymbol createSymbolForResourceBundle(IProject project, |
| final String name, |
| final String basename) throws JavaModelException, IOException, CoreException |
| { |
| // TODO: push down into ResourceBundleMapSourceFactory and share |
| // with loadBundle |
| final Map mapSource = ResourceBundleMapSourceFactory |
| .getResourceBundleMapSource(project, basename); |
| final IMapTypeDescriptor typeDesc = |
| SymbolFactory.eINSTANCE.createIMapTypeDescriptor(); |
| typeDesc.setMapSource(mapSource); |
| final IComponentSymbol symbol = |
| SymbolFactory.eINSTANCE.createIComponentSymbol(); |
| symbol.setName(name); |
| symbol.setTypeDescriptor(typeDesc); |
| symbol.setDetailedDescription(Messages.getString("ResourceBundleSymbolSourceProvider.DetailedDescription")+basename+"</i>"); //$NON-NLS-1$//$NON-NLS-2$ |
| return symbol; |
| } |
| |
| //Bug 306811 - Invalid error "messages not found in classpath for project" |
| private ISymbol createSymbolForResourceBundleInJAR(IProject project, final String name, final String basename) { |
| IComponentSymbol symbol = null; |
| InputStream in = null; |
| try { |
| final IStorage storage = LoadBundleUtil.getLoadBundleResource(project, basename); |
| if (storage != null) { |
| in = storage.getContents(); |
| Properties props = new Properties(); |
| props.load(in); |
| final IMapTypeDescriptor typeDesc = SymbolFactory.eINSTANCE.createIMapTypeDescriptor(); |
| typeDesc.setMapSource(props); |
| symbol = SymbolFactory.eINSTANCE.createIComponentSymbol(); |
| symbol.setName(name); |
| symbol.setTypeDescriptor(typeDesc); |
| symbol.setDetailedDescription(Messages.getString("ResourceBundleSymbolSourceProvider.DetailedDescription") + basename + "</i>"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } catch(CoreException cex) { |
| //fall through with null symbol |
| } catch(IOException ioex) { |
| //fall through with null symbol |
| } finally { |
| if (in != null) { |
| try { |
| in.close(); |
| } catch(IOException ignored) { |
| //do nothing |
| } |
| } |
| } |
| return symbol; |
| } |
| |
| private String getBaseName(ResourceBundleType resBundle) |
| { |
| final BaseNameType baseNameType = resBundle.getBaseName(); |
| if (baseNameType != null) |
| { |
| return baseNameType.getTextContent(); |
| } |
| return null; |
| } |
| |
| private String getVarName(ResourceBundleType resBundle) |
| { |
| final VarType varName = resBundle.getVar(); |
| if (varName != null) |
| { |
| return varName.getTextContent(); |
| } |
| return null; |
| } |
| |
| public final ISymbol[] getSymbols(String prefix, IAdaptable context, |
| int symbolScopeMask) { |
| return SymbolUtil. |
| filterSymbolsByPrefix(getSymbols(context, symbolScopeMask), prefix); |
| } |
| |
| public final boolean isProvider(IAdaptable context) { |
| IFile file = FileContextUtil.deriveIFileFromContext(context); |
| |
| if (file != null) |
| { |
| final IProject project = file.getProject(); |
| |
| if (project != null && project.isAccessible()) |
| { |
| // to be valid, the jsf project must be at least version 1.2 |
| return JSFAppConfigUtils.isValidJSFProject(project, IJSFCoreConstants.FACET_VERSION_1_2); |
| } |
| } |
| |
| return false; |
| } |
| } |