blob: 572d7d55dbdaa0059523a6461b9b17eef85b89a5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 Oracle Corporation.
* 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:
* Cameron Bateman - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.jsf.facelet.core.internal.cm.attributevalues;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IDOMContextResolver;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.facelet.core.internal.FaceletCorePlugin;
import org.eclipse.jst.jsf.metadataprocessors.features.IPossibleValues;
import org.eclipse.jst.jsf.metadataprocessors.features.PossibleValue;
import org.eclipse.jst.jsf.taglibprocessing.attributevalues.WebPathType;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.resources.IVirtualContainer;
import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
import org.w3c.dom.Attr;
import org.w3c.dom.Node;
/**
* Web-path attribute value type that adds possible values support
*
* @author cbateman
*
*/
public class TemplateWebPathType extends WebPathType implements IPossibleValues
{
public List getPossibleValues()
{
final IStructuredDocumentContext context = getStructuredDocumentContext();
final IDOMContextResolver resolver = IStructuredDocumentContextResolverFactory.INSTANCE
.getDOMContextResolver(context);
if (resolver != null)
{
final Node node = resolver.getNode();
if (node instanceof Attr)
{
return createPossibleValues((Attr) node);
}
}
return Collections.EMPTY_LIST;
}
private List createPossibleValues(final Attr node)
{
String currentPathString = node.getNodeValue();
final List possibleValues = new ArrayList();
if (currentPathString == null || "".equals(currentPathString.trim())) //$NON-NLS-1$
{
currentPathString = "/"; //$NON-NLS-1$
}
final IPath currentPath = new Path(currentPathString);
final IVirtualContainer webRoot = getWebRoot();
final IVirtualResource deepestElement = findDeepestCommonElement(
currentPath, webRoot);
if (deepestElement == null)
{
// empty
return possibleValues;
}
final IResource[] allResources = deepestElement
.getUnderlyingResources();
for (final IResource res : allResources)
{
if (res instanceof IContainer)
{
try
{
for (final IResource child : ((IContainer) res).members())
{
if (child.exists())
{
IPath childPath = child.getProjectRelativePath();
int numLeadingSegments = webRoot
.getProjectRelativePath()
.matchingFirstSegments(childPath);
childPath = childPath
.removeFirstSegments(numLeadingSegments);
String pathName = null;
if (currentPath.isAbsolute())
{
pathName = childPath.makeAbsolute()
.toString();
}
else
{
pathName = childPath.makeRelative().toString();
}
final PossibleValue pv = new PossibleValue(
pathName, pathName);
possibleValues.add(pv);
}
}
}
catch (final CoreException ce)
{
FaceletCorePlugin.log("While trying possible values", ce); //$NON-NLS-1$
}
}
}
return possibleValues;
}
private IVirtualResource findDeepestCommonElement(
final IPath currentPath, final IVirtualContainer webRoot)
{
final String[] segments = currentPath.segments();
IVirtualResource deepestElement = null;
if (segments != null)
{
IPath longestSubPath = new Path(""); //$NON-NLS-1$
for (final String segment : segments)
{
longestSubPath = longestSubPath.append(segment);
deepestElement = webRoot.findMember(longestSubPath);
if (deepestElement == null)
{
longestSubPath = longestSubPath.removeLastSegments(1);
break;
}
}
deepestElement = webRoot.findMember(longestSubPath);
if (deepestElement == null)
{
deepestElement = webRoot;
}
else
{
int avoidInfiniteLoopCount = 0;
while(avoidInfiniteLoopCount < 1000 && // we timeout in cause of circular chains.
deepestElement != null &&
! (deepestElement.getUnderlyingResource() instanceof IContainer))
{
deepestElement = deepestElement.getParent();
}
if (avoidInfiniteLoopCount == 1000)
{
throw new IllegalStateException();
}
}
}
return deepestElement;
}
private IVirtualContainer getWebRoot()
{
final IVirtualContainer webRoot = ComponentCore.createComponent(
getProject()).getRootFolder();
return webRoot;
}
}