blob: 830780693f28138f9fb46e0ba7325ec010cf05b3 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2013 Oracle Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* 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.IProject;
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.common.internal.componentcore.AbstractCompCoreQueryFactory;
import org.eclipse.jst.jsf.common.internal.componentcore.AbstractVirtualComponentQuery;
import org.eclipse.jst.jsf.context.IModelContext;
import org.eclipse.jst.jsf.context.resolver.structureddocument.internal.IStructuredDocumentContextResolverFactory2;
import org.eclipse.jst.jsf.context.resolver.structureddocument.internal.IXMLNodeContextResolver;
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;
/**
* Web-path attribute value type that adds possible values support
*
* @author cbateman
*
*/
public class TemplateWebPathType extends WebPathType implements IPossibleValues {
public List getPossibleValues() {
final IModelContext context = getModelContext();
if (context != null)
{
final IXMLNodeContextResolver resolver = IStructuredDocumentContextResolverFactory2.INSTANCE
.getXMLNodeContextResolver(context);
if (resolver != null) {
if (resolver.isAttribute()) {
return createPossibleValues(resolver.getValue());
}
}
}
return Collections.EMPTY_LIST;
}
private List createPossibleValues(final String attrValue) {
String currentPathString = attrValue;
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 IContainer webRoot = getWebRoot();
if (webRoot == null)
{
return possibleValues;
}
final IResource deepestElement = findDeepestCommonElement(currentPath, webRoot);
if (deepestElement == null) {
// empty
return possibleValues;
}
if (deepestElement instanceof IContainer) {
try {
for (final IResource child : ((IContainer) deepestElement).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 IResource findDeepestCommonElement(final IPath currentPath, final IContainer webRoot) {
final String[] segments = currentPath.segments();
IResource 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 instanceof IContainer)) {
deepestElement = deepestElement.getParent();
}
if (avoidInfiniteLoopCount == 1000) {
throw new IllegalStateException();
}
}
}
return deepestElement;
}
@Override
protected IContainer getWebRoot()
{
IProject project = getProject2();
if (project != null)
{
AbstractCompCoreQueryFactory compCoreQueryFactory = FaceletCorePlugin.getDefault().getCompCoreQueryFactory();
AbstractVirtualComponentQuery virtualComponentQuery = compCoreQueryFactory.createVirtualComponentQuery(project);
if (virtualComponentQuery != null)
{
return virtualComponentQuery.getWebContentFolder(project).getUnderlyingFolder();
}
}
return null;
}
}