Author: akazakov
Date: 2007-07-19 11:53:48 -0400 (Thu, 19 Jul 2007)
New Revision: 2527
Modified:
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/SeamCoreValidationHelper.java
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/SeamCoreValidator.java
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/SeamValidationContext.java
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/messages.properties
Log:
http://jira.jboss.com/jira/browse/EXIN-327 component.xml validation
Modified:
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/SeamCoreValidationHelper.java
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/SeamCoreValidationHelper.java 2007-07-19
15:29:32 UTC (rev 2526)
+++
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/SeamCoreValidationHelper.java 2007-07-19
15:53:48 UTC (rev 2527)
@@ -10,12 +10,17 @@
******************************************************************************/
package org.jboss.tools.seam.internal.core.validation;
+import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
@@ -28,9 +33,12 @@
import org.jboss.tools.seam.core.SeamCorePlugin;
import org.jboss.tools.seam.internal.core.AbstractContextVariable;
import org.jboss.tools.seam.internal.core.SeamComponentDeclaration;
+import org.jboss.tools.seam.internal.core.SeamProject;
public class SeamCoreValidationHelper extends WorkbenchContext {
+ private SeamValidationContext validationContext;
+
/**
* @return Seam project
*/
@@ -116,6 +124,33 @@
* @return IType of component for <ComponentName>.component.xml
*/
public IType getClassTypeForComponentXml(IFile componentXmlFile) {
+ String className = getClassNameForComponentXml(componentXmlFile);
+ if(className==null) {
+ return null;
+ }
+ return findType(className);
+ }
+
+ /**
+ * @param type name
+ * @return IType
+ */
+ public IType findType(String fullyQualifiedName) {
+ IProject p = getProject().getProject();
+ try {
+ IJavaProject jp = EclipseResourceUtil.getJavaProject(p);
+ return jp.findType(fullyQualifiedName);
+ } catch (JavaModelException e) {
+ SeamCorePlugin.getDefault().logError(e);
+ return null;
+ }
+ }
+
+ /**
+ * @param componentXmlFile
+ * @return name of component class for <ComponentName>.component.xml
+ */
+ public String getClassNameForComponentXml(IFile componentXmlFile) {
String fileName = componentXmlFile.getName();
int firstDot = fileName.indexOf('.');
if(firstDot==-1) {
@@ -129,10 +164,99 @@
if(packageFragment==null) {
return null;
}
- return jp.findType(packageFragment.getElementName(), className);
+ return packageFragment.getElementName() + "." + className;
} catch (JavaModelException e) {
SeamCorePlugin.getDefault().logError(e);
return null;
}
}
+
+ /**
+ * Find setter for property
+ * @param type
+ * @param propertyName
+ * @return
+ */
+ public IMethod findSetter(IType type, String propertyName) {
+ if(propertyName == null || propertyName.length()==0) {
+ return null;
+ }
+ String firstLetter = propertyName.substring(0, 1).toUpperCase();
+ String nameWithoutFirstLetter = propertyName.substring(1);
+ String setterName = "set" + firstLetter + nameWithoutFirstLetter;
+ try {
+ return findSetterInHierarchy(type, setterName);
+ } catch (JavaModelException e) {
+ SeamCorePlugin.getDefault().logError(e);
+ }
+ return null;
+ }
+
+ private IMethod findSetterInHierarchy(IType type, String setterName) throws
JavaModelException {
+ IMethod[] methods = type.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ if(methods[i].getElementName().equals(setterName) &&
methods[i].getParameterNames().length==1) {
+ return methods[i];
+ }
+ }
+ String superclassName = type.getSuperclassName();
+ if(superclassName!=null) {
+ String[][] packages = type.resolveType(superclassName);
+ if(packages!=null) {
+ for (int i = 0; i < packages.length; i++) {
+ String packageName = packages[i][0];
+ if(packageName!=null && packageName.length()>0) {
+ packageName = packageName + ".";
+ } else {
+ packageName = "";
+ }
+ String qName = packageName + packages[i][1];
+ IType superclass = type.getJavaProject().findType(qName);
+ if(superclass!=null) {
+ IMethod method = findSetterInHierarchy(superclass, setterName);
+ if(method!=null) {
+ return method;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
org.eclipse.wst.validation.internal.operations.WorkbenchContext#registerResource(org.eclipse.core.resources.IResource)
+ */
+ @Override
+ public void registerResource(IResource resource) {
+ if(resource instanceof IFile) {
+ IFile file = (IFile)resource;
+ if(!file.exists()) {
+ getValidationContext().addRemovedFile(file);
+ }
+ }
+ }
+
+ /**
+ * @return Set of changed resources
+ */
+ public Set<IFile> getChangedFiles() {
+ Set<IFile> result = new HashSet<IFile>();
+ String[] uris = getURIs();
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ for (int i = 0; i < uris.length; i++) {
+ IFile currentFile = root.getFile(new Path(uris[i]));
+ result.add(currentFile);
+ }
+ result.addAll(getValidationContext().getRemovedFiles());
+ return result;
+ }
+
+ public SeamValidationContext getValidationContext() {
+ if(validationContext==null) {
+ validationContext = ((SeamProject)getSeamProject()).getValidationContext();
+ }
+ return validationContext;
+ }
}
\ No newline at end of file
Modified:
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/SeamCoreValidator.java
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/SeamCoreValidator.java 2007-07-19
15:29:32 UTC (rev 2526)
+++
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/SeamCoreValidator.java 2007-07-19
15:53:48 UTC (rev 2527)
@@ -23,12 +23,9 @@
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
-import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.wst.validation.internal.core.ValidationException;
@@ -46,6 +43,7 @@
import org.jboss.tools.seam.core.ISeamFactory;
import org.jboss.tools.seam.core.ISeamJavaComponentDeclaration;
import org.jboss.tools.seam.core.ISeamProject;
+import org.jboss.tools.seam.core.ISeamProperty;
import org.jboss.tools.seam.core.ISeamTextSourceReference;
import org.jboss.tools.seam.core.ISeamXmlComponentDeclaration;
import org.jboss.tools.seam.core.ISeamXmlFactory;
@@ -67,7 +65,7 @@
private static final String NONUNIQUE_COMPONENT_NAME_MESSAGE_ID =
"NONUNIQUE_COMPONENT_NAME_MESSAGE";
private static final String UNKNOWN_INJECTION_NAME_MESSAGE_ID =
"UNKNOWN_INJECTION_NAME";
- private static final String STATEFUL_COMPONENT_DOES_NOT_CONTENT_METHOD_SUFIX_MESSAGE_ID
= "STATEFUL_COMPONENT_DOES_NOT_CONTENT_";
+ private static final String STATEFUL_COMPONENT_DOES_NOT_CONTAIN_METHOD_SUFIX_MESSAGE_ID
= "STATEFUL_COMPONENT_DOES_NOT_CONTAIN_";
private static final String DUPLICATE_METHOD_PREFIX_MESSAGE_ID =
"DUPLICATE_";
private static final String REMOVE_METHOD_SUFIX_MESSAGE_ID = "REMOVE";
private static final String DESTROY_METHOD_SUFIX_MESSAGE_ID = "DESTROY";
@@ -82,6 +80,7 @@
private static final String DUPLICATE_VARIABLE_NAME_MESSAGE_ID =
"DUPLICATE_VARIABLE_NAME";
private static final String UNKNOWN_DATA_MODEL_MESSAGE_ID =
"UNKNOWN_DATA_MODEL";
private static final String UNKNOWN_COMPONENT_CLASS_NAME_MESSAGE_ID =
"UNKNOWN_COMPONENT_CLASS_NAME";
+ private static final String UNKNOWN_COMPONENT_PROPERTY_MESSAGE_ID =
"UNKNOWN_COMPONENT_PROPERTY";
private SeamValidationContext validationContext;
private ISeamProject project;
@@ -92,21 +91,22 @@
public IStatus validateInJob(IValidationContext helper, IReporter reporter) throws
ValidationException {
super.validateInJob(helper, reporter);
- String[] uris = coreHelper.getURIs();
project = coreHelper.getSeamProject();
validationContext = ((SeamProject)project).getValidationContext();
- if (uris.length > 0) {
+ Set<IFile> changedFiles = coreHelper.getChangedFiles();
+ validationContext.getRemovedFiles().clear();
+ if(changedFiles.size()>0) {
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
- IFile currentFile = null;
Set<ISeamComponent> checkedComponents = new HashSet<ISeamComponent>();
Set<String> markedDuplicateFactoryNames = new HashSet<String>();
// Collect all resources which we must validate.
Set<IPath> resources = new HashSet<IPath>(); // Resources which we have to
validate.
Set<IPath> newResources = new HashSet<IPath>(); // New (unlinked)
resources file
- for (int i = 0; i < uris.length && !reporter.isCancelled(); i++) {
- currentFile = root.getFile(new Path(uris[i]));
- // Don't handle one resource twice.
- if (currentFile != null && currentFile.exists()) {
+ for(IFile currentFile : changedFiles) {
+ if(reporter.isCancelled()) {
+ break;
+ }
+ if (currentFile != null) {
// Get all variable names that were linked with this resource.
Set<String> oldVariablesNamesOfChangedFile =
validationContext.getVariableNamesByResource(currentFile.getFullPath());
if(oldVariablesNamesOfChangedFile!=null) {
@@ -337,9 +337,7 @@
boolean sourceJavaDeclaration = !((IType)jd.getSourceMember()).isBinary();
if(sourceJavaDeclaration) {
// Save link between component name and java source file.
- validationContext.addLinkedResource(declaration.getName(),
declaration.getSourcePath());
- // Validate all elements in declaration but @Name.
- validateJavaDeclaration(firstJavaDeclaration);
+ validationContext.addLinkedResource(component.getName(),
declaration.getSourcePath());
}
if(declaration!=firstJavaDeclaration) {
// Validate @Name
@@ -374,9 +372,8 @@
}
boolean source = !((IType)firstJavaDeclaration.getSourceMember()).isBinary();
if(source) {
- validateStatefulComponent(component);
- validateDuplicateComponentMethods(component);
- validateEntityComponent(component);
+ // Validate all elements in first java declaration but @Name.
+ validateJavaDeclaration(component, firstJavaDeclaration);
}
}
validateXmlComponentDeclarations(component);
@@ -391,19 +388,47 @@
return;
}
validationContext.addLinkedResource(componentName, declaration.getSourcePath());
- // validate class name
String className = declaration.getClassName();
if(className!=null) {
+ // validate class name
try {
IProject p = project.getProject();
IType type = EclipseResourceUtil.getJavaProject(p).findType(className);
if(type==null) {
// Mark wrong class name
- addError(UNKNOWN_COMPONENT_CLASS_NAME_MESSAGE_ID, new String[]{className},
coreHelper.getLocationOfAttribute(declaration, ISeamXmlComponentDeclaration.CLASS),
declaration.getResource(), MARKED_SEAM_RESOURCE_MESSAGE_GROUP);
+ ISeamTextSourceReference location =
((SeamComponentDeclaration)declaration).getLocationFor(ISeamXmlComponentDeclaration.CLASS);
+ if(location==null) {
+ location =
((SeamComponentDeclaration)declaration).getLocationFor(ISeamXmlComponentDeclaration.NAME);
+ }
+ if(location==null) {
+ location = declaration;
+ }
+ addError(UNKNOWN_COMPONENT_CLASS_NAME_MESSAGE_ID, new String[]{className},
location, declaration.getResource(), MARKED_SEAM_RESOURCE_MESSAGE_GROUP);
}
} catch (JavaModelException e) {
SeamCorePlugin.getDefault().logError(e);
}
+ // validate properties
+ Collection<ISeamProperty> properties = declaration.getProperties();
+ for (ISeamProperty property : properties) {
+ if(coreHelper.isJar(property)) {
+ return;
+ }
+ String name = property.getName();
+ if(name==null) {
+ return;
+ }
+ ISeamJavaComponentDeclaration javaDeclaration = component.getJavaDeclaration();
+ if(javaDeclaration==null) {
+ return;
+ }
+
+ IType type = (IType)javaDeclaration.getSourceMember();
+ boolean ok = type.isBinary() || coreHelper.findSetter(type, name)!=null;
+ if(!ok) {
+ addError(UNKNOWN_COMPONENT_PROPERTY_MESSAGE_ID, new
String[]{type.getElementName(), componentName, name}, property, declaration.getResource(),
MARKED_SEAM_RESOURCE_MESSAGE_GROUP);
+ }
+ }
}
}
}
@@ -459,7 +484,7 @@
ISeamTextSourceReference classNameLocation = getClassNameLocation(javaDeclaration);
Set<ISeamComponentMethod> methods =
javaDeclaration.getMethodsByType(methodType);
if(methods==null || methods.size()==0) {
- addError(STATEFUL_COMPONENT_DOES_NOT_CONTENT_METHOD_SUFIX_MESSAGE_ID +
postfixMessageId, new String[]{component.getName()}, classNameLocation,
javaDeclaration.getResource(), MARKED_SEAM_RESOURCE_MESSAGE_GROUP);
+ addError(STATEFUL_COMPONENT_DOES_NOT_CONTAIN_METHOD_SUFIX_MESSAGE_ID +
postfixMessageId, new String[]{component.getName()}, classNameLocation,
javaDeclaration.getResource(), MARKED_SEAM_RESOURCE_MESSAGE_GROUP);
}
}
@@ -482,9 +507,12 @@
}
}
- private void validateJavaDeclaration(ISeamJavaComponentDeclaration declaration) {
+ private void validateJavaDeclaration(ISeamComponent component,
ISeamJavaComponentDeclaration declaration) {
validateBijections(declaration);
- // TODO
+ validateStatefulComponent(component);
+ validateDuplicateComponentMethods(component);
+ validateEntityComponent(component);
+
}
private void validateBijections(ISeamJavaComponentDeclaration declaration) {
@@ -514,7 +542,6 @@
Set<ISeamContextVariable> variables = project.getVariablesByName(name);
if(variables==null || variables.size()<1) {
// Injection has unknown name. Mark it.
- // TODO check preferences to mark it as Error or Warning or ignore it.
IResource declarationResource = declaration.getResource();
addError(UNKNOWN_INJECTION_NAME_MESSAGE_ID, new String[]{name}, bijection,
declarationResource, MARKED_SEAM_RESOURCE_MESSAGE_GROUP);
}
Modified:
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/SeamValidationContext.java
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/SeamValidationContext.java 2007-07-19
15:29:32 UTC (rev 2526)
+++
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/SeamValidationContext.java 2007-07-19
15:53:48 UTC (rev 2527)
@@ -15,6 +15,7 @@
import java.util.Map;
import java.util.Set;
+import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.jboss.tools.common.xml.XMLUtilities;
@@ -31,12 +32,19 @@
private Map<String, Set<IPath>> resourcesByVariableName = new
HashMap<String, Set<IPath>>();
private Map<IPath, Set<String>> variableNamesByResource = new
HashMap<IPath, Set<String>>();
private Set<IPath> unnamedResources = new HashSet<IPath>();
+ private Set<IFile> removedFiles = new HashSet<IFile>();
/**
* Save link between resource and variable name.
* It's needed for incremental validation because we must save all linked resources
of changed java file.
*/
public void addLinkedResource(String variableName, IPath linkedResourcePath) {
+ if(linkedResourcePath==null) {
+ throw new RuntimeException("Linked resource path must not be null!");
+ }
+ if(variableName==null) {
+ throw new RuntimeException("Variable name must not be null!");
+ }
Set<IPath> linkedResources = resourcesByVariableName.get(variableName);
if(linkedResources==null) {
// create set of linked resources with variable name.
@@ -128,6 +136,7 @@
resourcesByVariableName.clear();
variableNamesByResource.clear();
unnamedResources.clear();
+ removedFiles.clear();
}
public void store(Element root) {
@@ -175,4 +184,12 @@
}
}
}
+
+ public Set<IFile> getRemovedFiles() {
+ return removedFiles;
+ }
+
+ public void addRemovedFile(IFile file) {
+ removedFiles.add(file);
+ }
}
\ No newline at end of file
Modified:
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/messages.properties
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/messages.properties 2007-07-19
15:29:32 UTC (rev 2526)
+++
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/messages.properties 2007-07-19
15:53:48 UTC (rev 2527)
@@ -10,10 +10,11 @@
******************************************************************************/
#Components
NONUNIQUE_COMPONENT_NAME_MESSAGE=Duplicate component name: {0}
-STATEFUL_COMPONENT_DOES_NOT_CONTENT_REMOVE=Stateful component "{0}" must have a
method marked @Remove
-STATEFUL_COMPONENT_DOES_NOT_CONTENT_DESTROY=Stateful component "{0}" must have
a method marked @Destroy
+STATEFUL_COMPONENT_DOES_NOT_CONTAIN_REMOVE=Stateful component "{0}" must have a
method marked @Remove
+STATEFUL_COMPONENT_DOES_NOT_CONTAIN_DESTROY=Stateful component "{0}" must have
a method marked @Destroy
STATEFUL_COMPONENT_WRONG_SCOPE=Stateful component "{0}" should not have
org.jboss.seam.ScopeType.PAGE, nor org.jboss.seam.ScopeType.STATELESS
-UNKNOWN_COMPONENT_CLASS_NAME={0} cannot be resolved to a type
+UNKNOWN_COMPONENT_CLASS_NAME="{0}" cannot be resolved to a type
+UNKNOWN_COMPONENT_PROPERTY=Class "{0}" of component "{1}" does not
contain setter for property "{2}"
#Entities
ENTITY_COMPONENT_WRONG_SCOPE=Entity component "{0}" should not have
org.jboss.seam.ScopeType.STATELESS