/*-
* Copyright (C) 2011-2014 by Iwao AVE!
* This program is made available under the terms of the MIT License.
*/
package org.eclipselabs.stlipse.cache;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.TypeNameRequestor;
import org.eclipse.jst.j2ee.common.ParamValue;
import org.eclipse.jst.j2ee.web.componentcore.util.WebArtifactEdit;
import org.eclipse.jst.j2ee.webapplication.Filter;
import org.eclipse.jst.j2ee.webapplication.WebApp;
import org.eclipselabs.stlipse.Activator;
/**
* @author Iwao AVE!
*/
public class BeanClassCache
{
private static final Map<IProject, List<BeanClassInfo>> beanCache = new ConcurrentHashMap<IProject, List<BeanClassInfo>>();
public static List<BeanClassInfo> getBeanClassInfo(IJavaProject project)
{
return getBeanClassCache(project);
}
public static boolean actionBeanExists(IJavaProject project, String beanclass)
{
List<BeanClassInfo> beanClassList = getBeanClassCache(project);
for (BeanClassInfo beanClassInfo : beanClassList)
{
if (beanClassInfo.matches(beanclass))
return true;
}
return false;
}
public static void add(IProject project, String packageName, String simpleTypeName)
{
List<BeanClassInfo> beanClassList = getBeanClassCache(JavaCore.create(project));
BeanClassInfo beanClassInfo = new BeanClassInfo(packageName, simpleTypeName);
beanClassList.remove(beanClassInfo);
beanClassList.add(0, beanClassInfo);
}
public static void remove(IProject project, String packageName, String simpleTypeName)
{
List<BeanClassInfo> beanClassList = beanCache.get(project);
if (beanClassList != null)
beanClassList.remove(new BeanClassInfo(packageName, simpleTypeName));
}
public static void clear(IProject project)
{
beanCache.remove(project);
}
public static void clear()
{
beanCache.clear();
}
private static synchronized List<BeanClassInfo> getBeanClassCache(IJavaProject javaProject)
{
final IProject project = javaProject.getProject();
if (beanCache.containsKey(project))
return beanCache.get(project);
final List<BeanClassInfo> beanClassList = new CopyOnWriteArrayList<BeanClassInfo>();
beanCache.put(project, beanClassList);
try
{
IType actionBeanInterface = TypeCache.getActionBean(javaProject);
if (actionBeanInterface == null)
{
// It wouldn't be a Stripes project.
return beanClassList;
}
final List<String> packageList = getActionResolverPackages(project);
IJavaSearchScope scope = SearchEngine.createHierarchyScope(actionBeanInterface);
TypeNameRequestor requestor = new TypeNameRequestor()
{
@Override
public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName,
char[][] enclosingTypeNames, String path)
{
// Ignore abstract classes.
if (Flags.isAbstract(modifiers))
return;
// Should be in action resolver packages if specified.
if (!packageList.isEmpty()
&& !isInTargetPackage(packageList, String.valueOf(packageName)))
return;
BeanClassInfo beanClass = new BeanClassInfo(packageName, simpleTypeName);
beanClassList.add(beanClass);
}
private boolean isInTargetPackage(List<String> targetPackages, String packageToTest)
{
if (targetPackages == null || packageToTest == null)
return false;
for (String targetPackage : targetPackages)
{
if (packageToTest.startsWith(targetPackage))
return true;
}
return false;
}
};
SearchEngine searchEngine = new SearchEngine();
searchEngine.searchAllTypeNames(null, SearchPattern.R_EXACT_MATCH, null,
SearchPattern.R_EXACT_MATCH, IJavaSearchConstants.DECLARATIONS
| IJavaSearchConstants.IMPLEMENTORS, scope, requestor,
IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, null);
}
catch (CoreException e)
{
Activator.log(Status.ERROR, "Error occurred while creating proposals.", e);
}
return beanClassList;
}
/**
* @param project
* @return Packages listed in ActionResolver.Packages<br>
* Returns an empty list if ActionResolver.Packages is not set in web.xml.
*/
private static List<String> getActionResolverPackages(IProject project)
{
List<String> packageList = new ArrayList<String>();
WebArtifactEdit artifactEdit = WebArtifactEdit.getWebArtifactEditForRead(project);
WebApp webApp = artifactEdit.getWebApp();
@SuppressWarnings("unchecked")
EList<Filter> filters = webApp.getFilters();
for (Filter filter : filters)
{
@SuppressWarnings("unchecked")
EList<ParamValue> initParamValues = filter.getInitParamValues();
for (ParamValue paramValue : initParamValues)
{
if ("ActionResolver.Packages".equals(paramValue.getName()))
{
String packages = paramValue.getValue();
if (packages != null)
{
String[] pkgArray = packages.split(",");
for (String pkg : pkgArray)
{
String trimmed = pkg.trim();
if (trimmed.length() > 0)
packageList.add(trimmed);
}
}
}
}
}
if (packageList.size() == 0)
{
Activator.log(Status.WARNING,
"The filter init-param 'ActionResolver.Packages' was not found in your web.xml. ");
}
return packageList;
}
}