Bug 306451 - [JSF2.0] Support for Implicit navigation
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/JSFAppConfigUtils.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/JSFAppConfigUtils.java
index 38dd45a..73c8004 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/JSFAppConfigUtils.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/jsfappconfig/JSFAppConfigUtils.java
@@ -23,13 +23,20 @@
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
+import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.core.runtime.content.IContentTypeManager;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
@@ -364,4 +371,69 @@
return JARsList;
}
+ //Bug 306451 - [JSF2.0] Support for Implicit navigation
+ /**
+ * Get all files that are possible destinations for implicit navigation (JSF 2.x or greater).
+ *
+ * @param fromFile IFile instance that navigation is from.
+ * @return List of IFile instances that are possible destinations.
+ */
+ public static List<IFile> getImplicitNavigationFiles(final IFile fromFile) {
+ List<IFile> files = new ArrayList<IFile>();
+ if (fromFile != null) {
+ final IProject project = fromFile.getProject();
+ if (isValidJSFProject(project, IJSFCoreConstants.JSF_VERSION_2_0)) {
+ final IVirtualFolder webContentFolder = new DefaultVirtualComponentQuery().getWebContentFolder(project);
+ if (webContentFolder != null) {
+ final IContainer[] rootContainers = webContentFolder.getUnderlyingFolders();
+ if (rootContainers != null && rootContainers.length > 0) {
+ for (int i = 0; i < rootContainers.length; i++) {
+ try {
+ rootContainers[i].accept(new JSFAppConfigUtils().new ImplicitNavigationResourceProxyVisitor(files), IResource.NONE);
+ } catch(CoreException cEx) {
+ JSFCorePlugin.log(IStatus.ERROR, cEx.getLocalizedMessage(), cEx);
+ }
+ }
+ files.remove(fromFile);
+ }
+ }
+ }
+ }
+ return files;
+ }
+
+
+
+ class ImplicitNavigationResourceProxyVisitor implements IResourceProxyVisitor {
+
+ private List<IFile> files;
+ private IContentTypeManager contentTypeMgr;
+ private IContentType jspSourceType;
+ private IContentType htmlSourceType;
+
+ public ImplicitNavigationResourceProxyVisitor(List<IFile> files) {
+ this.files = files;
+ this.contentTypeMgr = Platform.getContentTypeManager();
+ this.jspSourceType = contentTypeMgr.getContentType("org.eclipse.jst.jsp.core.jspsource"); //$NON-NLS-1$
+ this.htmlSourceType = contentTypeMgr.getContentType("org.eclipse.wst.html.core.htmlsource"); //$NON-NLS-1$
+ }
+
+ public boolean visit(IResourceProxy proxy) throws CoreException {
+ switch (proxy.getType()) {
+ case IResource.FOLDER:
+ return true;
+ case IResource.FILE:
+ IContentType contentType = contentTypeMgr.findContentTypeFor(proxy.getName());
+ if (contentType != null) {
+ if (contentType.isKindOf(jspSourceType) || contentType.isKindOf(htmlSourceType)) {
+ files.add((IFile)proxy.requestResource());
+ }
+ }
+ break;
+ }
+ return false;
+ }
+
+ }
+
}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/taglibprocessing/attributevalues/ActionType.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/taglibprocessing/attributevalues/ActionType.java
index 85a8c63..b773fca 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/taglibprocessing/attributevalues/ActionType.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/taglibprocessing/attributevalues/ActionType.java
@@ -19,6 +19,7 @@
import java.util.List;
import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
@@ -26,17 +27,20 @@
import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IWorkspaceContextResolver;
import org.eclipse.jst.jsf.core.JSFVersion;
+import org.eclipse.jst.jsf.core.jsfappconfig.JSFAppConfigUtils;
import org.eclipse.jst.jsf.core.jsfappconfig.internal.JSFAppConfigManagerFactory;
import org.eclipse.jst.jsf.facesconfig.FacesConfigPlugin;
import org.eclipse.jst.jsf.facesconfig.emf.DisplayNameType;
import org.eclipse.jst.jsf.facesconfig.emf.NavigationCaseType;
import org.eclipse.jst.jsf.facesconfig.emf.NavigationRuleType;
+import org.eclipse.jst.jsf.metadataprocessors.features.IPossibleValue;
import org.eclipse.jst.jsf.metadataprocessors.features.IPossibleValues;
import org.eclipse.jst.jsf.metadataprocessors.features.IValidationMessage;
import org.eclipse.jst.jsf.metadataprocessors.features.PossibleValue;
import org.eclipse.jst.jsf.metadataprocessors.features.ValidationMessage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.osgi.framework.Bundle;
@@ -126,7 +130,7 @@
* @see org.eclipse.jst.jsf.metadataprocessors.features.IPossibleValues#getPossibleValues()
*/
public List getPossibleValues() {
- final List<NavigationRuleType> ret = new ArrayList<NavigationRuleType>();
+ final List<IPossibleValue> ret = new ArrayList<IPossibleValue>();
if (getStructuredDocumentContext() == null)
return ret;
@@ -138,6 +142,8 @@
if (rule != null)
ret.addAll(createProposals(rule));
}
+ //Bug 306451 - [JSF2.0] Support for Implicit navigation
+ ret.addAll(createImplicitProposals(jsp));
}
return ret;
}
@@ -191,7 +197,64 @@
return pv;
}
-
+ //Bug 306451 - [JSF2.0] Support for Implicit navigation
+ private List createImplicitProposals(final IFile fromFile) {
+ List ret = new ArrayList();
+ if (fromFile != null) {
+ final IProject project = fromFile.getProject();
+ if (project != null) {
+ final IVirtualComponent component = ComponentCore.createComponent(project);
+ if (component != null) {
+ final IVirtualFolder folder = component.getRootFolder();
+ if (folder != null) {
+ final IPath webContentPath = folder.getUnderlyingFolder().getFullPath();
+ IPath fromPath = fromFile.getFullPath();
+ if (webContentPath.isPrefixOf(fromPath)) {
+ fromPath = fromPath.makeRelativeTo(webContentPath);
+ final IPath fromPathParent = fromPath.removeLastSegments(1);
+ final List<IFile> files =
+ JSFAppConfigUtils.getImplicitNavigationFiles(fromFile);
+ for (final IFile currentFile: files) {
+ IPath currentPath = currentFile.getFullPath();
+ if (webContentPath.isPrefixOf(currentPath)) {
+ currentPath = currentPath.makeRelativeTo(webContentPath);
+ final String toViewId = '/' + currentPath.toString();
+ boolean isRelative = false;
+ if (fromPathParent.isPrefixOf(currentPath)) {
+ currentPath = currentPath.makeRelativeTo(fromPathParent);
+ isRelative = true;
+ }
+ String value = currentPath.toString();
+ final String fromPathExt = fromPath.getFileExtension();
+ if (fromPathExt != null &&
+ fromPathExt.equals(currentPath.getFileExtension())) {
+ value = currentPath.removeFileExtension().toString();
+ }
+ if (!isRelative) {
+ value = '/' + value;
+ }
+ final String navDisplay =
+ NLS.bind(
+ Messages.ActionType_navcase_display,
+ new String[]{value, toViewId});
+ final PossibleValue possibleValue =
+ new PossibleValue(value, navDisplay);
+ possibleValue.setIcon(getNavCaseImageDescriptor());
+ possibleValue.setAdditionalInformation(
+ NLS.bind(
+ Messages.ActionType_implicit_navigation_additional_info,
+ toViewId));
+ ret.add(possibleValue);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return ret;
+ }
+
private ImageDescriptor getNavCaseImageDescriptor() {
ImageDescriptor ret = super.getImage();
if (ret != null && ret != MISSING_IMAGE)
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/taglibprocessing/attributevalues/Messages.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/taglibprocessing/attributevalues/Messages.java
index 447ef78..7b28196 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/taglibprocessing/attributevalues/Messages.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/taglibprocessing/attributevalues/Messages.java
@@ -40,6 +40,10 @@
/**
* see messages.properties
*/
+ public static String ActionType_implicit_navigation_additional_info;
+ /**
+ * see messages.properties
+ */
public static String BooleanType_invalid_values;
/**
* see messages.properties
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/taglibprocessing/attributevalues/messages.properties b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/taglibprocessing/attributevalues/messages.properties
index 22ddc87..e445525 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/taglibprocessing/attributevalues/messages.properties
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/taglibprocessing/attributevalues/messages.properties
@@ -270,6 +270,7 @@
ActionType_invalid_value=The action value does not match a navigation case outcome.
ActionType_invalid_empty_value=The action attribute must be a non-zero length String or a method binding matching a navigation case outcome.
ActionType_navcase_display={0}: goto {1}
+ActionType_implicit_navigation_additional_info=Implicit navigation to {0}
ContentType_MIME_not_empty=Content (MIME) type must not be empty
MethodBindingType_invalid_value=MethodBinding attribute values must be EL expressions.
JavaClassType_invalid_type=Value for type attribute must be valid Java class and not empty.