blob: d5c83a86ce63b4f04629bdd4b3aa52a2ef5437b5 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.myfaces.resource;
import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
import javax.faces.application.ResourceVisitOption;
import javax.faces.context.FacesContext;
/**
*
*/
public class ExternalContextResourceLoaderIterator implements Iterator<String>
{
private FacesContext facesContext;
private String basePath;
private int maxDepth;
private ResourceVisitOption[] options;
private Deque<String> stack;
public ExternalContextResourceLoaderIterator(FacesContext facesContext, String path,
int maxDepth, ResourceVisitOption... options)
{
this.facesContext = facesContext;
this.basePath = path;
this.maxDepth = maxDepth;
this.options = options;
Set<String> paths = facesContext.getExternalContext().getResourcePaths(basePath);
if (paths == null)
{
//empty stack means empty iterator.
}
else
{
for (String p : paths)
{
if (p.startsWith("/WEB-INF") && isTopLevelViewsOnly(options))
{
// skip
}
else if (p.startsWith("/META-INF") && isTopLevelViewsOnly(options))
{
// skip
}
else
{
if (stack == null)
{
stack = new LinkedList<>();
}
stack.add(p);
}
}
}
}
private boolean isTopLevelViewsOnly(ResourceVisitOption... options)
{
boolean isTopLevelViewsOnly = false;
for (ResourceVisitOption option : options)
{
if(option == ResourceVisitOption.TOP_LEVEL_VIEWS_ONLY)
{
isTopLevelViewsOnly = true;
break;
}
}
return isTopLevelViewsOnly;
}
@Override
public boolean hasNext()
{
if (stack == null || stack.isEmpty())
{
return false;
}
String path = stack.peek();
do
{
if (ResourceLoaderUtils.isDirectory(path))
{
path = stack.pop();
int depth = ResourceLoaderUtils.getDepth(path);
if (depth < maxDepth)
{
Set<String> list = facesContext.getExternalContext().getResourcePaths(path);
if (list != null)
{
stack.addAll(list);
}
}
if (!stack.isEmpty())
{
path = stack.peek();
}
else
{
path = null;
}
}
}
while (path != null && ResourceLoaderUtils.isDirectory(path) && !stack.isEmpty());
return !stack.isEmpty();
}
@Override
public String next()
{
if (stack == null || stack.isEmpty())
{
return null;
}
String path = stack.pop();
do
{
if (ResourceLoaderUtils.isDirectory(path))
{
int depth = ResourceLoaderUtils.getDepth(path);
if (depth < maxDepth)
{
Set<String> list = facesContext.getExternalContext().getResourcePaths(path);
if (list != null)
{
stack.addAll(list);
}
}
if (!stack.isEmpty())
{
path = stack.pop();
}
else
{
path = null;
}
}
}
while (path != null && ResourceLoaderUtils.isDirectory(path) && !stack.isEmpty());
if (path != null)
{
// Calculate name based on url, basePath.
return path;
}
return null;
}
@Override
public void remove()
{
}
}