/*******************************************************************************
* Copyright (c) 2011 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is 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:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.jsf.web.validation;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
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.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IType;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.validation.internal.core.ValidationException;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
import org.jboss.tools.common.EclipseUtil;
import org.jboss.tools.common.model.XModel;
import org.jboss.tools.common.model.XModelObject;
import org.jboss.tools.common.model.XModelObjectConstants;
import org.jboss.tools.common.model.filesystems.FileSystemsHelper;
import org.jboss.tools.common.model.impl.XModelImpl;
import org.jboss.tools.common.model.util.EclipseResourceUtil;
import org.jboss.tools.common.validation.ContextValidationHelper;
import org.jboss.tools.common.validation.IPreferenceInfo;
import org.jboss.tools.common.validation.IProjectValidationContext;
import org.jboss.tools.common.validation.IValidatingProjectSet;
import org.jboss.tools.common.validation.IValidatingProjectTree;
import org.jboss.tools.common.validation.IValidator;
import org.jboss.tools.common.validation.PreferenceInfoManager;
import org.jboss.tools.common.validation.ValidationErrorManager;
import org.jboss.tools.common.validation.ValidatorManager;
import org.jboss.tools.common.validation.internal.ProjectValidationContext;
import org.jboss.tools.common.validation.internal.SimpleValidatingProjectTree;
import org.jboss.tools.common.validation.internal.ValidatingProjectSet;
import org.jboss.tools.common.web.WebUtils;
import org.jboss.tools.jsf.JSFModelPlugin;
import org.jboss.tools.jsf.model.JSFConstants;
import org.jboss.tools.jsf.model.pv.JSFProjectsTree;
import org.jboss.tools.jsf.web.JSFWebHelper;
import org.jboss.tools.jsf.web.JSFWebProject;
import org.jboss.tools.jsf.web.pattern.JSFUrlPattern;
import org.jboss.tools.jsf.web.validation.composite.CompositeComponentValidator;
import org.jboss.tools.jst.web.WebModelPlugin;
import org.jboss.tools.jst.web.kb.IKbProject;
import org.jboss.tools.jst.web.kb.KbProjectFactory;
import org.jboss.tools.jst.web.model.helpers.WebAppHelper;
import org.jboss.tools.jst.web.model.pv.WebProjectNode;
import org.jboss.tools.jst.web.validation.Check;
import org.jboss.tools.jst.web.validation.CheckClass;
/**
* @author Viacheslav Kabanovich
*/
public class FacesConfigValidator extends ValidationErrorManager implements IValidator, JSFConstants {
public static final String ID = "org.jboss.tools.esb.validator.ESBCoreValidator"; //$NON-NLS-1$
public static final String PREFERENCE_PAGE_ID = CompositeComponentValidator.PREFERENCE_PAGE_ID;
public static final String PROPERTY_PAGE_ID = CompositeComponentValidator.PROPERTY_PAGE_ID;
public static String SHORT_ID = "jsf-verification"; //$NON-NLS-1$
static String XML_EXT = ".xml"; //$NON-NLS-1$
String projectName;
Map<IProject, IProjectValidationContext> contexts = new HashMap<IProject, IProjectValidationContext>();
Map<String, Set<Check>> checks = new HashMap<String, Set<Check>>();
public FacesConfigValidator() {
createChecks();
}
/*
* (non-Javadoc)
* @see org.jboss.tools.jst.web.kb.internal.validation.ValidationErrorManager#getPreference(org.eclipse.core.resources.IProject, java.lang.String)
*/
@Override
protected String getPreference(IProject project, String preferenceKey) {
return JSFSeverityPreferences.getInstance().getProjectPreference(project, preferenceKey);
}
/*
* (non-Javadoc)
* @see org.jboss.tools.jst.web.kb.internal.validation.ValidationErrorManager#getMaxNumberOfMarkersPerFile(org.eclipse.core.resources.IProject)
*/
@Override
public int getMaxNumberOfMarkersPerFile(IProject project) {
return JSFSeverityPreferences.getMaxNumberOfProblemMarkersPerFile(project);
}
private void addCheck(Check check, String... entities) {
for (String entity: entities) {
Set<Check> cs = checks.get(entity);
if(cs == null) {
cs = new HashSet<Check>();
checks.put(entity, cs);
}
cs.add(check);
}
}
static class JSFCheckClass extends CheckClass {
public JSFCheckClass(ValidationErrorManager manager, String preference, String attr, boolean allowsPrimitive, String implementsType, String extendsType) {
super(manager, preference, attr, allowsPrimitive, implementsType, extendsType);
}
protected String getShortId() {
return SHORT_ID;
}
}
void createChecks() {
String ENT_APP = "JSFApplication", ENT_APP_12 = ENT_APP + SUFF_12, ENT_APP_20 = ENT_APP + SUFF_20, ENT_APP_22 = ENT_APP + SUFF_22;
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_ACTION_LISTENER, "action-listener", false, "javax.faces.event.ActionListener", null), ENT_APP, ENT_APP_12, ENT_APP_20, ENT_APP_22);
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_NAVIGATION_HANDLER, "navigation-handler", false, null, "javax.faces.application.NavigationHandler"), ENT_APP, ENT_APP_12, ENT_APP_20, ENT_APP_22);
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_PROPERTY_RESOLVER, "class name", false, "javax.faces.el.PropertyResolver", null).setVisualAttribute("property-resolver"), "JSFPropertyResolver");
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_STATE_MANAGER, "state-manager", false, null, "javax.faces.application.StateManager"), ENT_APP, ENT_APP_12, ENT_APP_20, ENT_APP_22);
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_VARIABLE_RESOLVER, "class name", false, null, "javax.el.ELResolver").setVisualAttribute("el-resolver"), "JSFELResolver");
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_VARIABLE_RESOLVER, "class name", false, null, "javax.faces.el.VariableResolver").setVisualAttribute("variable-resolver"), "JSFVariableResolver");
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_VIEW_HANDLER, "view-handler", false, null, "javax.faces.application.ViewHandler"), ENT_APP, ENT_APP_12, ENT_APP_20, ENT_APP_22);
String ENT_COMPONENT = "JSFComponent", ENT_COMPONENT_11 = ENT_COMPONENT + SUFF_11;
addCheck(new CheckClass(this, JSFSeverityPreferences.INVALID_COMPONENT_CLASS, "component-class", false, null, "javax.faces.component.UIComponent"), ENT_COMPONENT, ENT_COMPONENT_11);
String ENT_CONVERTER = "JSFConverter";
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_CONVERTER_CLASS, "converter-class", false, "javax.faces.convert.Converter", null), ENT_CONVERTER);
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_CONVERTER_FOR_CLASS, "converter-for-class", true, null, null), ENT_CONVERTER);
String ENT_FACTORY = "JSFFactory", ENT_FACTORY_20 = ENT_FACTORY + SUFF_20;
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_APPLICATION_FACTORY, "application-factory", false, null, "javax.faces.application.ApplicationFactory"), ENT_FACTORY, ENT_FACTORY_20);
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_FACES_CONTEXT_FACTORY, "faces-context-factory", false, null, "javax.faces.context.FacesContextFactory"), ENT_FACTORY, ENT_FACTORY_20);
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_LIFECYCLE_FACTORY, "lifecycle-factory", false, null, "javax.faces.lifecycle.LifecycleFactory"), ENT_FACTORY, ENT_FACTORY_20);
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_RENDER_KIT_FACTORY, "render-kit-factory", false, null, "javax.faces.render.RenderKitFactory"), ENT_FACTORY, ENT_FACTORY_20);
String ENT_LIST_ENTRIES = "JSFListEntries", ENT_MAP_ENTRIES = "JSFMapEntries";
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_KEY_CLASS, "key-class", true, null, null), ENT_MAP_ENTRIES);
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_KEY_CLASS, "value-class", true, null, null), ENT_LIST_ENTRIES, ENT_MAP_ENTRIES);
String ENT_MANAGED_BEAN = "JSFManagedBean", ENT_MANAGED_BEAN_20 = ENT_MANAGED_BEAN + SUFF_20;
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_BEAN_CLASS, "managed-bean-class", false, null, null), ENT_MANAGED_BEAN, ENT_MANAGED_BEAN_20);
String ENT_MANAGED_PROPERTY = "JSFManagedProperty";
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_PROPERTY_CLASS, "property-class", false, null, null), ENT_MANAGED_PROPERTY);
String ENT_REFERENCED_BEAN = "JSFReferencedBean";
addCheck(new CheckClass(this, JSFSeverityPreferences.INVALID_BEAN_CLASS, "referenced-bean-class", false, null, null), ENT_REFERENCED_BEAN);
String ENT_PHASE_LISTENER = "JSFPhaseListener";
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_PHASE_LISTENER, "phase-listener", false, "javax.faces.event.PhaseListener", null), ENT_PHASE_LISTENER);
String ENT_RENDER_KIT = "JSFRenderKit", ENT_RENDER_KIT_11 = ENT_RENDER_KIT + SUFF_11, ENT_RENDER_KIT_12 = ENT_RENDER_KIT + SUFF_12, ENT_RENDER_KIT_20 = ENT_RENDER_KIT + SUFF_20;
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_RENDER_KIT_CLASS, "render-kit-class", false, null, "javax.faces.render.RenderKit"), ENT_RENDER_KIT, ENT_RENDER_KIT_11, ENT_RENDER_KIT_12, ENT_RENDER_KIT_20);
String ENT_RENDERER = "JSFRenderer", ENT_RENDERER_11 = ENT_RENDERER + SUFF_11;
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_RENDERER_CLASS, "renderer-class", false, null, "javax.faces.render.Renderer"), ENT_RENDERER, ENT_RENDERER_11);
String ENT_VALIDATOR = "JSFValidator", ENT_VALIDATOR_12 = ENT_VALIDATOR + SUFF_12;
addCheck(new JSFCheckClass(this, JSFSeverityPreferences.INVALID_VALIDATOR_CLASS, "validator-class", false, "javax.faces.validator.Validator", null), ENT_VALIDATOR, ENT_VALIDATOR_12);
addCheck(new JSFCheckFromViewId(this), new String[]{ENT_NAVIGATION_CASE, ENT_NAVIGATION_CASE_20, ENT_NAVIGATION_RULE, ENT_NAVIGATION_RULE_20});
addCheck(new JSFCheckToViewId(this), new String[]{ENT_NAVIGATION_CASE, ENT_NAVIGATION_CASE_20, ENT_NAVIGATION_RULE, ENT_NAVIGATION_RULE_20});
}
public String getId() {
return ID;
}
public String getBuilderId() {
return null;
}
public IValidatingProjectTree getValidatingProjects(IProject project) {
IProjectValidationContext rootContext = contexts.get(project);
if(rootContext == null) {
IKbProject kb = KbProjectFactory.getKbProject(project, true);
if(kb != null) {
rootContext = kb.getValidationContext();
} else {
rootContext = new ProjectValidationContext();
}
contexts.put(project, rootContext);
}
Set<IProject> projects = new HashSet<IProject>();
projects.add(project);
IValidatingProjectSet projectSet = new ValidatingProjectSet(project, projects, rootContext);
return new SimpleValidatingProjectTree(projectSet);
}
public boolean shouldValidate(IProject project) {
if(!project.isAccessible()) {
return false;
}
try {
IFacetedProject fp = ProjectFacetsManager.create(project);
IProjectFacet f = ProjectFacetsManager.getProjectFacet("jst.web");
if(fp != null && f != null && fp.getInstalledVersion(f) != null) {
return true;
}
} catch (CoreException e) {
WebModelPlugin.getDefault().logError(e);
}
return false;
}
/*
* (non-Javadoc)
* @see org.jboss.tools.jst.web.kb.internal.validation.ValidationErrorManager#init(org.eclipse.core.resources.IProject, org.jboss.tools.jst.web.kb.internal.validation.ContextValidationHelper, org.jboss.tools.jst.web.kb.validation.IProjectValidationContext, org.eclipse.wst.validation.internal.provisional.core.IValidator, org.eclipse.wst.validation.internal.provisional.core.IReporter)
*/
@Override
public void init(IProject project, ContextValidationHelper validationHelper, IProjectValidationContext context, org.eclipse.wst.validation.internal.provisional.core.IValidator manager, IReporter reporter) {
super.init(project, validationHelper, context, manager, reporter);
projectName = project.getName();
}
/*
* (non-Javadoc)
* @see org.jboss.tools.jst.web.kb.validation.IValidator#validate(java.util.Set, org.eclipse.core.resources.IProject, org.jboss.tools.jst.web.kb.internal.validation.ContextValidationHelper, org.jboss.tools.jst.web.kb.validation.IProjectValidationContext, org.jboss.tools.jst.web.kb.internal.validation.ValidatorManager, org.eclipse.wst.validation.internal.provisional.core.IReporter)
*/
public IStatus validate(Set<IFile> changedFiles, IProject project,
ContextValidationHelper validationHelper, IProjectValidationContext context, ValidatorManager manager,
IReporter reporter) throws ValidationException {
init(project, validationHelper, context, manager, reporter);
Set<IPath> resourcesToClean = new HashSet<IPath>(); // Resource which we should remove from validation context
for (IFile file: changedFiles) {
resourcesToClean.add(file.getFullPath());
}
changedFiles = collectFiles(project, changedFiles, context);
for(IFile file: changedFiles) {
removeAllMessagesFromResource(file);
resourcesToClean.add(file.getFullPath());
}
getValidationContext().removeLinkedCoreResources(SHORT_ID, resourcesToClean);
for (IFile file: changedFiles) {
if(file.getName().endsWith(XML_EXT)) {
XModelObject o = EclipseResourceUtil.createObjectForResource(file);
if(o != null) {
String entity = o.getModelEntity().getName();
if(entity.startsWith("FacesConfig")) {
validateFile(o, file);
} else if(entity.startsWith("FileWebApp")) {
new CheckContextParam(this).check(o);
}
}
}
}
return OK_STATUS;
}
private void validateFile(XModelObject object, IFile file) {
validateObject(object);
}
private void validateObject(XModelObject object) {
String entity = object.getModelEntity().getName();
Set<Check> ch = checks.get(entity);
if(ch != null) {
for (Check c: ch) {
c.check(object);
}
}
XModelObject[] cs = object.getChildren();
for (XModelObject c: cs) {
validateObject(c);
}
}
/*
* (non-Javadoc)
* @see org.jboss.tools.jst.web.kb.validation.IValidator#validateAll(org.eclipse.core.resources.IProject, org.jboss.tools.jst.web.kb.internal.validation.ContextValidationHelper, org.jboss.tools.jst.web.kb.validation.IProjectValidationContext, org.jboss.tools.jst.web.kb.internal.validation.ValidatorManager, org.eclipse.wst.validation.internal.provisional.core.IReporter)
*/
public IStatus validateAll(IProject project,
ContextValidationHelper validationHelper, IProjectValidationContext context, ValidatorManager manager,
IReporter reporter) throws ValidationException {
init(project, validationHelper, context, manager, reporter);
displaySubtask(JSFValidationMessage.VALIDATING_PROJECT, new String[]{projectName});
IPath webContentPath = WebUtils.getFirstWebContentPath(project);
if(webContentPath == null) {
return OK_STATUS;
}
IFolder webInf = null;
try {
// This code line never return null
webInf = project.getFolder(webContentPath.removeFirstSegments(1).append("WEB-INF")); //$NON-NLS-1$
// so never check it for null
if(webInf.isAccessible()) {
IResource[] rs = webInf.members();
// exception is not required here because if esbContent is not exist control
// never gets here
for (IResource r: rs) {
if(r instanceof IFile) {
IFile file = (IFile)r;
String name = file.getName();
if(name.endsWith(XML_EXT)) {
XModelObject o = EclipseResourceUtil.createObjectForResource(file);
if(o != null) {
String entity = o.getModelEntity().getName();
if(entity.startsWith("FacesConfig")) {
validateFile(o, file);
} else if(entity.startsWith("FileWebApp")) {
new CheckContextParam(this).check(o);
}
}
}
}
}
}
} catch (CoreException e) {
// hiding exceptions is the evil so lets return EROOR Status with exception
return new Status(IStatus.ERROR,WebModelPlugin.PLUGIN_ID,MessageFormat.format("Validation error for project {0}",project.getLocation().toString()),e);
}
return OK_STATUS;
}
public boolean isEnabled(IProject project) {
return JSFSeverityPreferences.isValidationEnabled(project);
}
private Set<IFile> collectFiles(IProject project, Set<IFile> changedFiles, IProjectValidationContext context) {
Set<IFile> files = new HashSet<IFile>();
if(context == null) {
files.addAll(changedFiles);
return files;
}
Set<IFile> direct = new HashSet<IFile>();
Set<IFile> dependent = new HashSet<IFile>();
for (IFile f: changedFiles) {
if(f != null && f.getProject() == project) {
Set<IPath> paths = context.getCoreResourcesByVariableName(SHORT_ID, f.getFullPath().toOSString(), true);
String name = f.getName();
if(name.endsWith(".java")) {
try {
ICompilationUnit unit = EclipseUtil.getCompilationUnit(f);
if(unit != null) {
IType[] ts = unit.getTypes();
for (IType t: ts) {
String type = t.getFullyQualifiedName();
Set<IPath> paths1 = context.getCoreResourcesByVariableName(SHORT_ID, type, true);
if(paths1 != null) {
if(paths != null) {
paths.addAll(paths1);
} else {
paths = paths1;
}
}
}
}
} catch (CoreException e) {
JSFModelPlugin.getDefault().logError(e);
}
} else {
IPath[] ps = WebUtils.getWebContentPaths(project);
for (IPath rootPath: ps) {
if(rootPath.isPrefixOf(f.getFullPath())) {
String s = f.getFullPath().removeFirstSegments(rootPath.segmentCount()).toString();
if(!s.startsWith("/")) s = "/" + s;
Set<IPath> paths1 = context.getCoreResourcesByVariableName(SHORT_ID, s, true);
if(paths1 != null) {
if(paths != null) {
paths.addAll(paths1);
} else {
paths = paths1;
}
}
}
}
}
if(name.endsWith(".xml") && f.exists()) { //$NON-NLS-1$
if(!direct.contains(f) && !dependent.contains(f)) {
files.add(f);
}
direct.add(f);
dependent.remove(f);
}
if(paths != null) {
for (IPath path: paths) {
IFile f1 = project.getParent().getFile(path);
if(f1.exists()) {
if(direct.contains(f1) || dependent.contains(f1)) continue;
dependent.add(f1);
files.add(f1);
}
}
}
}
}
return files;
}
@Override
public void registerPreferenceInfo() {
PreferenceInfoManager.register(getProblemType(), new JSFPreferenceInfo());
}
class JSFPreferenceInfo implements IPreferenceInfo{
@Override
public String getPreferencePageId() {
return PREFERENCE_PAGE_ID;
}
@Override
public String getPropertyPageId() {
return PROPERTY_PAGE_ID;
}
@Override
public String getPluginId() {
return JSFModelPlugin.PLUGIN_ID;
}
}
}
class JSFCheckFromViewId extends JSFCheckToViewId {
public JSFCheckFromViewId(ValidationErrorManager manager) {
super(manager, JSFSeverityPreferences.INVALID_FROM_VIEW_ID, JSFConstants.ATT_FROM_VIEW_ID);
}
public void check(XModelObject object) {
String value = object.getAttributeValue(attr);
if(value == null) {
return;
}
if(value != null && value.length() > 0 && !value.startsWith("*") && !value.startsWith("/")) {
fireMessage(object, JSFValidationMessage.VIEW_ID_NO_SLASH, attr);
}
if(value != null && value.length() > 0 && value.indexOf("*") < 0) {
checkEsists(object, value);
}
}
}
class JSFCheckToViewId extends Check {
public JSFCheckToViewId(ValidationErrorManager manager) {
super(manager, JSFSeverityPreferences.INVALID_TO_VIEW_ID, JSFConstants.ATT_TO_VIEW_ID);
}
public JSFCheckToViewId(ValidationErrorManager manager, String preference, String attr) {
super(manager, preference, attr);
}
public void check(XModelObject object) {
String value = object.getAttributeValue(attr);
if(value == null) {
return;
}
if(value.length() == 0) {
fireMessage(object, JSFValidationMessage.TO_VIEW_ID_EMPTY, attr);
} else if(!value.startsWith("/")) { //$NON-NLS-1$
if(value.startsWith("#{")) { //$NON-NLS-1$
//Ignore EL.
return;
}
fireMessage(object, JSFValidationMessage.VIEW_ID_NO_SLASH, attr);
} else if(value.indexOf("*") >= 0) {
fireMessage(object, JSFValidationMessage.TO_VIEW_ID_STAR, attr);
} else {
checkEsists(object, value);
}
}
void checkEsists(XModelObject object, String value) {
if(value.indexOf('?') >= 0) {
value = value.substring(0, value.indexOf('?'));
}
if(value.indexOf("#{") > 0) { //$NON-NLS-1$
//Ignore EL.
return;
}
XModel model = object.getModel();
XModelObject o = model.getByPath(value);
if(o == null) {
JSFUrlPattern pattern = JSFWebProject.getInstance(model).getUrlPattern();
if(pattern != null && pattern.isJSFUrl(value)) {
List<String> vs = pattern.getJSFPaths(value);
for (String v: vs) {
o = model.getByPath(v);
if(o != null) break;
}
if(o == null) {
o = model.getByPath(pattern.getJSFPath(value));
}
}
}
IFile f = (IFile)object.getAdapter(IFile.class);
if(f != null) {
IProjectValidationContext context = manager.getValidationContext();
if(context != null) {
context.addLinkedCoreResource(FacesConfigValidator.SHORT_ID, value, f.getFullPath(), true);
}
}
if(o != null) {
IFile f2 = (IFile)o.getAdapter(IFile.class);
if(f2 != null) {
String path = f2.getLocation().toOSString().replace('\\', '/');
IProjectValidationContext context = manager.getValidationContext();
if(context != null) {
context.addLinkedCoreResource(FacesConfigValidator.SHORT_ID, f2.getFullPath().toOSString(), f.getFullPath(), true);
}
if(path.endsWith(value)) {
return;
}
}
} else if(checkTiles(model, value)) {
return;
}
fireMessage(object, JSFValidationMessage.VIEW_NOT_EXISTS, attr, value);
}
private boolean checkTiles(XModel model, String path) {
XModelObject root = JSFProjectsTree.getProjectsRoot(model);
if(root == null) return false;
XModelObject tiles = root.getChildByPath("Tiles"); //$NON-NLS-1$
if(tiles == null) return false;
XModelObject[] ts = ((WebProjectNode)tiles).getTreeChildren();
if(ts.length == 0) return false;
int d = path.lastIndexOf('.');
if(d < 0) return false;
String tileName = path.substring(0, d + 1) + "tiles"; //$NON-NLS-1$
tileName = tileName.replace('/', '#');
for (int i = 0; i < ts.length; i++) {
if(ts[i].getChildByPath(tileName) != null) return true;
}
return false;
}
}
class CheckContextParam extends Check {
static String CONFIG_FILES_PARAM = JSFWebHelper.FACES_CONFIG_DATA.param;
public CheckContextParam(ValidationErrorManager manager) {
super(manager, JSFSeverityPreferences.INVALID_CONFIG_FILES, "param-value");
}
public void check(XModelObject webapp) {
XModelObject object = WebAppHelper.findWebAppContextParam(webapp, CONFIG_FILES_PARAM);
if(object == null) return;
// if(!CONFIG_FILES_PARAM.equals(object.getAttributeValue("param-name"))) return; //$NON-NLS-1$
String value = object.getAttributeValue("param-value"); //$NON-NLS-1$
if(value == null || value.length() == 0) return;
XModel model = object.getModel();
List<XModelObject> webRoots = new ArrayList<XModelObject>();
XModelObject[] fss = FileSystemsHelper.getFileSystems(model).getChildren();
for (XModelObject s: fss) {
String n = s.getAttributeValue(XModelObjectConstants.ATTR_NAME);
if("WEB-ROOT".equals(n) || n.startsWith("WEB-ROOT-")) {
webRoots.add(s);
}
}
if(webRoots.isEmpty()) return;
StringTokenizer st = new StringTokenizer(value, ","); //$NON-NLS-1$
while(st.hasMoreTokens()) {
String path = st.nextToken().trim();
if(path.length() == 0) continue;
XModelObject fc = XModelImpl.getByRelativePath(model, path);
if(fc == null) {
fireMessage(object, JSFValidationMessage.INVALID_FACES_CONFIG_REFERENCE, "param-value", path);
return;
}
String path2 = path.startsWith("/") ? path.substring(1) : path; //$NON-NLS-1$
XModelObject fc2 = null;
for (XModelObject s: webRoots) {
fc2 = s.getChildByPath(path2);
if(fc2 != null) break;
}
if(fc2 == null) {
fireMessage(object, JSFValidationMessage.INVALID_FACES_CONFIG_REFERENCE, "param-value", path);
return;
}
if(!fc2.getModelEntity().getName().startsWith("FacesConfig")) { //$NON-NLS-1$
fireMessage(object, JSFValidationMessage.INVALID_FACES_CONFIG_REFERENCE, "param-value", path);
return;
}
}
}
}