diff --git a/checkstyle-suppressions.xml b/checkstyle-suppressions.xml index aa5c9d5..224dacd 100644 --- a/checkstyle-suppressions.xml +++ b/checkstyle-suppressions.xml @@ -8,4 +8,6 @@ + + diff --git a/jh-sun-eclipse-checkstyle.xml b/jh-sun-eclipse-checkstyle.xml index 3f0175a..ccf9447 100644 --- a/jh-sun-eclipse-checkstyle.xml +++ b/jh-sun-eclipse-checkstyle.xml @@ -5,8 +5,9 @@ This configuration file was written by the eclipse-cs plugin configuration editor --> @@ -35,7 +36,9 @@ - + + + diff --git a/static-jsfexpression-validator-core/README b/static-jsfexpression-validator-core/README index 57c669f..333f8a7 100644 --- a/static-jsfexpression-validator-core/README +++ b/static-jsfexpression-validator-core/README @@ -28,6 +28,7 @@ TODO '#{bean.listProperty[0].elementProperty}': PropertyNotFoundException - Property 'elementProperty' not found on class net.jakubholy.jeeutils.jsfelcheck.validator.MockObjectOfUnknownType]; expression=#{bean.listProperty[0].elementProperty}, file=/mypage.jsp, tagLine=126] - better error msg. for PropertyNotFoundException on class Error_YouMustDelcareTypeForThisVariable => include advice how to solve it => make it clear the solution is st. like propertyTypeOverrides.put("bean.listProperty.*", TheElementType.class); +- analyzer: replace the map arguments with method like declareLocalVariable ... (more readable, understandable) ... - don't mock implementations of Map/Collection, instantiate them instead (eg ArrayList) diff --git a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/beanfinder/ManagedBeanFinder.java b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/beanfinder/ManagedBeanFinder.java index 1687c1b..bf747f6 100644 --- a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/beanfinder/ManagedBeanFinder.java +++ b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/beanfinder/ManagedBeanFinder.java @@ -24,11 +24,19 @@ */ public interface ManagedBeanFinder { + /** + * Definition of a managed bean. + */ public static class ManagedBeanDescriptor { private final String name; private final Class type; + /** + * New descriptor. + * @param name (required) the managed bean's name + * @param type (required) the managed bean's class + */ public ManagedBeanDescriptor(final String name, final Class type) { if (name == null) { throw new IllegalArgumentException("name: String must be set"); @@ -59,6 +67,7 @@ public int hashCode() { @Override public boolean equals(Object obj) { + // CHECKSTYLE:OFF if (this == obj) return true; if (obj == null) @@ -77,6 +86,7 @@ public boolean equals(Object obj) { } else if (!type.equals(other.type)) return false; return true; + // CHECKSTYLE:ON } @Override @@ -85,6 +95,11 @@ public String toString() { } } - public Collection findDefinedBackingBeans(); + /** + * Find all managed beans defined in the application + * (those this particular finder can discover). + * @return possibly empty collection + */ + Collection findDefinedBackingBeans(); } diff --git a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/beanfinder/SpringContextBeanFinder.java b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/beanfinder/SpringContextBeanFinder.java index ec85900..ae55f2f 100644 --- a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/beanfinder/SpringContextBeanFinder.java +++ b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/beanfinder/SpringContextBeanFinder.java @@ -37,22 +37,27 @@ public class SpringContextBeanFinder implements ManagedBeanFinder { private final Collection springContextFiles; + /** + * New finder reading Spring beans from the given applicationContext XML files. + * @param springContextFiles (optional) nothing done if empty/null + */ public SpringContextBeanFinder(final Collection springContextFiles) { if (springContextFiles == null || springContextFiles.isEmpty()) { - throw new IllegalArgumentException("springContextFiles: Collection cannot be null/empty, is: " + springContextFiles); + throw new IllegalArgumentException( + "springContextFiles: Collection cannot be null/empty, is: " + springContextFiles); } for (File file : springContextFiles) { if (!file.canRead()) { - throw new IllegalArgumentException("The supplied Spring application context XML file " + - "cannot be opened for reading: " + file); + throw new IllegalArgumentException("The supplied Spring application context XML file " + + "cannot be opened for reading: " + file); } } this.springContextFiles = new LinkedList(springContextFiles); } - //@Override + /** {@inheritDoc} */ public Collection findDefinedBackingBeans() { Collection allBeans = new LinkedList(); @@ -80,11 +85,11 @@ private Class loadBeanClass(String beanName, String beanClassName) { } } - private Resource[] toResources(Collection springContextFiles) { - Resource[] locations = new Resource[springContextFiles.size()]; + private Resource[] toResources(Collection resourceFiles) { + Resource[] locations = new Resource[resourceFiles.size()]; int index = 0; - for (File configFile : springContextFiles) { + for (File configFile : resourceFiles) { locations[index++] = new FileSystemResource(configFile); } diff --git a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/AttributesValidationResult.java b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/AttributesValidationResult.java index 63a89c3..2e9e97e 100644 --- a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/AttributesValidationResult.java +++ b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/AttributesValidationResult.java @@ -31,12 +31,24 @@ public class AttributesValidationResult extends ValidationResult { private Map results = new Hashtable(); private boolean error = false; + /** + * Add results of validation of the given attribute. + * @param attribute (required) the name of the tag's attribute + * @param result (required) + */ public void add(String attribute, ValidationResult result) { - if (result == null) throw new IllegalArgumentException("result: ValidationResult may not be null"); + if (result == null) { + throw new IllegalArgumentException("result: ValidationResult may not be null"); + } results.put(attribute, result); error |= result.hasErrors(); } + /** + * Get results of validating EL in the given attribute. + * @param attribute (required) + * @return null if the attribute had no EL + */ public ValidationResult get(String attribute) { return results.get(attribute); } @@ -46,6 +58,10 @@ public boolean hasErrors() { return error; } + /** + * True if any attribute's value contained an EL. + * @return see above + */ public boolean jsfExpressionsFound() { return !results.isEmpty(); } diff --git a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/CollectedValidationResultsImpl.java b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/CollectedValidationResultsImpl.java index 5646cce..0b60d54 100644 --- a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/CollectedValidationResultsImpl.java +++ b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/CollectedValidationResultsImpl.java @@ -22,7 +22,7 @@ import java.util.List; import net.jakubholy.jeeutils.jsfelcheck.CollectedValidationResults; -import net.jakubholy.jeeutils.jsfelcheck.expressionfinder.impl.jasper.variables.MissingLocalVariableTypeDeclarationException; +import net.jakubholy.jeeutils.jsfelcheck.expressionfinder.impl.jasper.variables.MissingLocalVariableTypeDeclarationException; // SUPPRESS CHECKSTYLE import net.jakubholy.jeeutils.jsfelcheck.validator.results.JsfExpressionDescriptor; import net.jakubholy.jeeutils.jsfelcheck.validator.results.MultipleValidationResults; import net.jakubholy.jeeutils.jsfelcheck.validator.results.ValidationResult; @@ -48,20 +48,30 @@ protected void postAddSingleResult(ValidationResult singleResult) { descriptor.setTagLineNumber(currentTagLineNumber); } - public void addAllFromTagLineNr(int currentTagLineNumber, + /** + * Add results of validating ELs in attributes of a tag that appeared at a particular line. + * @param currentTagLine number of the line in the source file where the tag starts + * @param allResults (required) the results to add + */ + public void addAllFromTagLineNr(int currentTagLine, Collection allResults) { - this.currentTagLineNumber = currentTagLineNumber; + this.currentTagLineNumber = currentTagLine; super.addAll(allResults); } + /** + * Report a local variable for which there was no type declaration. + * @param e (required) + */ public void reportContextVariableNeedingTypeDeclaration( MissingLocalVariableTypeDeclarationException e) { getVariablesNeedingTypeDeclaration().add(e); } /* (non-Javadoc) - * @see net.jakubholy.jeeutils.jsfelcheck.expressionfinder.impl.jasper.CollectedValidationResults#getVariablesNeedingTypeDeclaration() + * @see net.jakubholy.jeeutils.jsfelcheck.expressionfinder.impl.jasper.CollectedValidationResults + * #getVariablesNeedingTypeDeclaration() */ //@Override public Collection getVariablesNeedingTypeDeclaration() { diff --git a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/JsfElValidatingPageNodeListener.java b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/JsfElValidatingPageNodeListener.java index 7b8fc0f..6973a5d 100644 --- a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/JsfElValidatingPageNodeListener.java +++ b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/JsfElValidatingPageNodeListener.java @@ -21,14 +21,14 @@ import java.util.logging.Logger; import net.jakubholy.jeeutils.jsfelcheck.expressionfinder.impl.jasper.variables.ContextVariableRegistry; -import net.jakubholy.jeeutils.jsfelcheck.expressionfinder.impl.jasper.variables.MissingLocalVariableTypeDeclarationException; +import net.jakubholy.jeeutils.jsfelcheck.expressionfinder.impl.jasper.variables.MissingLocalVariableTypeDeclarationException; // SUPPRESS CHECKSTYLE import net.jakubholy.jeeutils.jsfelcheck.validator.JsfElValidator; import net.jakubholy.jeeutils.jsfelcheck.validator.exception.InternalValidatorFailureException; import net.jakubholy.jeeutils.jsfelcheck.validator.results.JsfExpressionDescriptor; /** * The main processing class for the Jasper-based implementation: retrieves information about - * JSP tags of interest and JSF EL extraction and validation while maintaining the local variable stack. + * JSP tags of interest and triggers JSF EL extraction and validation while maintaining the local variable stack. */ public class JsfElValidatingPageNodeListener implements PageNodeListener { @@ -39,17 +39,23 @@ public class JsfElValidatingPageNodeListener implements PageNodeListener { private final CollectedValidationResultsImpl validationResults = new CollectedValidationResultsImpl(); private Stack jspFileInclusionStack = new Stack(); - private String jspFile; - - public JsfElValidatingPageNodeListener(JsfElValidator expressionValidator, ContextVariableRegistry contextVarRegistry) { + private String currentJspFile; + + /** + * New listener using the given validator and resolving local variables via the given registry. + * @param expressionValidator (required) + * @param contextVarRegistry (required) + */ + public JsfElValidatingPageNodeListener( + JsfElValidator expressionValidator, ContextVariableRegistry contextVarRegistry) { this.contextVarRegistry = contextVarRegistry; this.nodeValidator = new PageNodeExpressionValidator(expressionValidator); } - //@Override + /** {@inheritDoc} */ public void nodeEntered(PageNode jspTag) { - LOG.fine("PROCESSING " + jspTag.getqName() + " at " + - jspTag.getLineNumber() + " id " + jspTag.getId() + LOG.fine("PROCESSING " + jspTag.getQName() + " at " + + jspTag.getLineNumber() + " id " + jspTag.getId() + ", class: " + jspTag.getTagHandlerClass().getName() + ", attrs: " + jspTag.getAttributes()); @@ -65,44 +71,44 @@ public void nodeEntered(PageNode jspTag) { contextVarRegistry.extractContextVariables(jspTag, resolvedJsfExpressions); } catch (MissingLocalVariableTypeDeclarationException e) { e.setTagLineNumber(jspTag.getLineNumber()); - e.setJspFile(jspFile); + e.setJspFile(currentJspFile); validationResults.reportContextVariableNeedingTypeDeclaration(e); } catch (InternalValidatorFailureException e) { - e.setExpressionDescriptor(new JsfExpressionDescriptor(jspTag.getLineNumber(), jspFile)); + e.setExpressionDescriptor(new JsfExpressionDescriptor(jspTag.getLineNumber(), currentJspFile)); throw e; } } - //@Override + /** {@inheritDoc} */ public void nodeLeft(PageNode jspTag) { LOG.fine("DONE WITH " + jspTag.getId()); contextVarRegistry.discardContextFor(jspTag); } - //@Override - public void fileEntered(String jspFile) { - setCurrentJspFile(jspFile); - LOG.info(">>> STARTED FOR '" + jspFile + " #############################################"); + /** {@inheritDoc} */ + public void fileEntered(String newJspFile) { + setCurrentJspFile(newJspFile); + LOG.info(">>> STARTED FOR '" + newJspFile + " #############################################"); } public CollectedValidationResultsImpl getValidationResults() { return validationResults; } - //@Override + /** {@inheritDoc} */ public void includedFileEntered(String includedFileName) { - jspFileInclusionStack.push(jspFile); + jspFileInclusionStack.push(currentJspFile); setCurrentJspFile(includedFileName); } - //@Override + /** {@inheritDoc} */ public void includedFileLeft(String includedFileName) { setCurrentJspFile(jspFileInclusionStack.pop()); } - private void setCurrentJspFile(String jspFile) { - this.jspFile = jspFile; - this.validationResults.setCurrentJspFile(jspFile); + private void setCurrentJspFile(String currentJspFile) { + this.currentJspFile = currentJspFile; + this.validationResults.setCurrentJspFile(currentJspFile); } } diff --git a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/JspCParsingToNodesOnly.java b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/JspCParsingToNodesOnly.java index 5825dcd..03540ca 100644 --- a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/JspCParsingToNodesOnly.java +++ b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/JspCParsingToNodesOnly.java @@ -25,7 +25,10 @@ */ public class JspCParsingToNodesOnly extends JspC { - /** Overriden to return the class of ours (default = null => JdtCompiler)*/ + /** + * {@inheritDoc} + * Overriden to return the class of ours (default = null => JdtCompiler. + */ @Override public String getCompilerClassName() { return OnlyReadingJspPseudoCompiler.class.getName(); diff --git a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/PageNode.java b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/PageNode.java index b63a443..295a6ec 100644 --- a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/PageNode.java +++ b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/PageNode.java @@ -19,6 +19,7 @@ import java.util.Map; +/** Represents a tag in a JSP/JSF page, in other words a node of the page. */ public class PageNode { private static long counter = 0; @@ -29,6 +30,17 @@ public class PageNode { private final Class tagHandlerClass; private final int lineNumber; + /** + * Create new page node describing a custom JSP tag. + * @param qName (required) + * qualified name of the tag, ex.: h:dataTable + * @param tagHandlerClass (required) + * the handler used for the tag, ex.: org.apache.myfaces.taglib.html.HtmlDataTableTag + * @param lineNumber (required) + * the line where the tag starts in the page source code + * @param attributeMap (required) + * map with attributes of the tag: name -> value + */ public PageNode(String qName, Class tagHandlerClass, int lineNumber, Map attributeMap) { this.qName = qName; @@ -41,7 +53,7 @@ public Map getAttributes() { return attributes; } - public String getqName() { + public String getQName() { return qName; } diff --git a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/variables/ContextVariableRegistry.java b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/variables/ContextVariableRegistry.java index b49005e..3765df9 100644 --- a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/variables/ContextVariableRegistry.java +++ b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/variables/ContextVariableRegistry.java @@ -101,7 +101,7 @@ public Class resolveVariable(String name) { public void extractContextVariables(PageNode jspTag, AttributesValidationResult resolvedJsfExpressions) throws MissingLocalVariableTypeDeclarationException { - TagJsfVariableResolver resolverForTag = resolvers.get(jspTag.getqName()); + TagJsfVariableResolver resolverForTag = resolvers.get(jspTag.getQName()); if (resolverForTag != null) { try { diff --git a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/validator/MockingPropertyResolver.java b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/validator/MockingPropertyResolver.java index 8d202b4..70ec37b 100644 --- a/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/validator/MockingPropertyResolver.java +++ b/static-jsfexpression-validator-core/src/main/java/net/jakubholy/jeeutils/jsfelcheck/validator/MockingPropertyResolver.java @@ -114,11 +114,11 @@ private void appendCurrentPropertyToExpression(final String property) { * actually is a variable) * @param property (required) the property name such as 'property' in the EL #{bean.property} * @return the type of the property or null if it cannot be detected - * @throws EvaluationException - * @throws PropertyNotFoundException + * @throws PropertyNotFoundException there is no such property on the target object + * @throws EvaluationException other problem */ - private Class getTypeOfCollectionOrBean(Object target, Object property) throws EvaluationException, - PropertyNotFoundException { + public Class getTypeOfCollectionOrBean(Object target, Object property) + throws PropertyNotFoundException, EvaluationException { // Would normally throw an exception for empty arrays/list not having the given index if (target.getClass().isArray()) { diff --git a/static-jsfexpression-validator-core/src/test/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/CollectedValidationResultsImplTest.java b/static-jsfexpression-validator-core/src/test/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/CollectedValidationResultsImplTest.java index 8479d69..7435ca1 100644 --- a/static-jsfexpression-validator-core/src/test/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/CollectedValidationResultsImplTest.java +++ b/static-jsfexpression-validator-core/src/test/java/net/jakubholy/jeeutils/jsfelcheck/expressionfinder/impl/jasper/CollectedValidationResultsImplTest.java @@ -1,3 +1,20 @@ +/* + * 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 net.jakubholy.jeeutils.jsfelcheck.expressionfinder.impl.jasper; import static org.junit.Assert.*; @@ -7,7 +24,6 @@ import org.junit.Before; import org.junit.Test; - public class CollectedValidationResultsImplTest { private CollectedValidationResultsImpl results; diff --git a/static-jsfexpression-validator-jsf12/src/test/java/net/jakubholy/jeeutils/jsfelcheck/validator/jsf12/Jsf12ElValidatorImplTest.java b/static-jsfexpression-validator-jsf12/src/test/java/net/jakubholy/jeeutils/jsfelcheck/validator/jsf12/Jsf12ElValidatorImplTest.java deleted file mode 100644 index 2037c0b..0000000 --- a/static-jsfexpression-validator-jsf12/src/test/java/net/jakubholy/jeeutils/jsfelcheck/validator/jsf12/Jsf12ElValidatorImplTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package net.jakubholy.jeeutils.jsfelcheck.validator.jsf12; - -import static org.junit.Assert.assertEquals; - -import java.util.Collections; - -import javax.el.ValueExpression; - -import org.junit.Before; -import org.junit.Test; - - -public class Jsf12ElValidatorImplTest { - - private static interface MyVariable { - public int getIntProperty(); - } - - private Jsf12ValidatingElResolver validator; - - @Before - public void setUp() throws Exception { - validator = new Jsf12ValidatingElResolver(); - } - - @Test - public void should_evaluate_value_expression() throws Exception { - - /* - getExpressionFactory().createValueExpression(elContext, expression, expectedType).getValue(elContext); - • Expr.Factory - use org.apache.el.ExpressionFactoryImpl - • ELContext - see how JsfElContext is initialized - ‣ VariableMapper- either custom or unset & use custom ELResolver - • Mockito with default Answer = deep mock - ‣ FunctionMapper - either unset or find out how Japser sets & initializes it - • ELResolver - use composed & the default ones, see ResolverBuilderForFaces - ‣ opt. modify BeanResolver not to invoke method but mock its return type (x deep Mocks) - - + impl's faces-config parsing; annotated managed bean discovery??? - */ - - validator.declareVariable("bean", Collections.EMPTY_MAP); - validator.definePropertyTypeOverride("bean.*", MyVariable.class); - - ValueExpression valueExpression = validator.expressionFactory.createValueExpression( - validator.elContext - , "#{bean['key'].intProperty != 0}" - , Object.class); - - Object result = valueExpression.getValue(validator.elContext); - - //verify(context, times(2)).getExternalContext(); - assertEquals(true, result); - } - -}