blob: 3ab047a1fbab893f0f44a8bb7096f185e462d9d4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2002, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are 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:
* IBM - Initial API and implementation
*******************************************************************************/
package org.eclipse.wst.wsi.internal.core.profile.validator.impl;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.TreeMap;
import java.util.Vector;
import org.eclipse.wst.wsi.internal.core.WSIException;
import org.eclipse.wst.wsi.internal.core.analyzer.AnalyzerContext;
import org.eclipse.wst.wsi.internal.core.profile.ProfileArtifact;
import org.eclipse.wst.wsi.internal.core.profile.TestAssertion;
import org.eclipse.wst.wsi.internal.core.profile.validator.BaseValidator;
import org.eclipse.wst.wsi.internal.core.profile.validator.EntryContext;
import org.eclipse.wst.wsi.internal.core.profile.validator.EnvelopeValidator;
import org.eclipse.wst.wsi.internal.core.report.AssertionResult;
import org.eclipse.wst.wsi.internal.core.report.Entry;
import org.eclipse.wst.wsi.internal.core.report.FailureDetail;
import org.eclipse.wst.wsi.internal.core.report.PrereqFailedList;
import org.eclipse.wst.wsi.internal.core.report.ReportArtifact;
import org.eclipse.wst.wsi.internal.core.report.Reporter;
import org.eclipse.wst.wsi.internal.core.report.impl.PrereqFailedListImpl;
import org.eclipse.wst.wsi.internal.core.util.EntryType;
import org.eclipse.wst.wsi.internal.core.xml.XMLDocumentCacheUser;
import org.eclipse.wst.wsi.internal.core.xml.dom.ElementLocation;
/**
* The WSDL validator will verify that the WSDL and associated XML schema definitions
* are in conformance with the profile.
*
* @version 1.0.1
* @author Peter Brittenham (peterbr@us.ibm.com)
* @author Graham Turrell (gturrell@uk.ibm.com)
*/
public abstract class BaseValidatorImpl
extends XMLDocumentCacheUser
implements BaseValidator
{
/**
* A hashtable that maps assertion results to their priorities, 0 is lowest
*/
private static final Hashtable resultPriority = new Hashtable(6);
static {
resultPriority.put(AssertionResult.RESULT_PASSED, new Integer(0));
resultPriority.put(AssertionResult.RESULT_NOT_APPLICABLE, new Integer(1));
resultPriority.put(AssertionResult.RESULT_MISSING_INPUT, new Integer(2));
resultPriority.put(AssertionResult.RESULT_WARNING, new Integer(3));
resultPriority.put(AssertionResult.RESULT_PREREQ_FAILED, new Integer(4));
resultPriority.put(AssertionResult.RESULT_FAILED, new Integer(5));
}
/**
* The highest priority value being passed when processing pre-requisites
*/
private static final int MAX_VALID_PRIORITY = 1;
/**
* Analyzer context.
*/
public AnalyzerContext analyzerContext;
/**
* Profile artifact.
*/
protected ProfileArtifact profileArtifact;
/**
* Reporter.
*/
protected Reporter reporter;
/**
* Entry.
*/
// protected Entry entry;
/**
* Report artifact.
*/
protected ReportArtifact reportArtifact;
/**
* Verbose option.
*/
public boolean verboseOption = false;
/**
* Test assertion processed count.
*/
protected int assertionCount = 0;
/**
* Constructor.
*/
public BaseValidatorImpl()
{
}
/**
* Initiailize validation test procedure.
* @param analyzerContext the analyzerContext.
* @param profileArtifact the profile artifiact.
* @param reportArtifact the report artifact.
* @param reporter a Reporter object.
* @throws WSIException if validator could not be initialized.
*/
public void init(
AnalyzerContext analyzerContext,
ProfileArtifact profileArtifact,
ReportArtifact reportArtifact,
Reporter reporter)
throws WSIException
{
// Save input references
this.analyzerContext = analyzerContext;
this.profileArtifact = profileArtifact;
this.reportArtifact = reportArtifact;
this.reporter = reporter;
// Get verbose option
verboseOption =
reporter
.getReport()
.getReportContext()
.getAnalyzer()
.getAnalyzerConfig()
.getVerboseOption();
}
/**
* Process all of the test assertions for one entry.
* @param classPrefix a class prefix.
* @param entryContext an entry context.
* @throws WSIException if serious problems occur while processing
* all of the test assertions for an entry.
*/
protected void processAssertions(
String classPrefix,
EntryContext entryContext)
throws WSIException
{
long startTime = 0;
HashMap processList = new HashMap();
TestAssertion testAssertion = null;
AssertionProcess assertionProcess;
AssertionResult assertionResult;
TreeMap preReqResults;
PrereqFailedList prereqFailedList;
String preReqId;
Class[] paramTypes = new Class[1];
// If this is an instance of MessageValidator or EnvelopeValidator
// then use BaseMessageValidator as a param type of assertions constructor
paramTypes[0] = this instanceof BaseMessageValidator ?
BaseMessageValidator.class : this.getClass();
Object[] params = new Object[1];
params[0] = this;
// Get entry from context
Entry entry = entryContext.getEntry();
// Add entry to artifact
this.reportArtifact.addEntry(entry);
// Add entry to report
if (this instanceof EnvelopeValidator)
this.reporter.setCurrentEnvelopeEntry(entry);
else this.reporter.setCurrentEntry(entry);
try
{
// Go through the list of test assertions for the artifact
Iterator iterator = profileArtifact.getTestAssertionList().iterator();
while (iterator.hasNext())
{
// Get next test assertion
testAssertion = (TestAssertion) iterator.next();
// Reset variables
assertionResult = null;
// If the test assertion is enabled, then continue
// if ((testAssertion.isEnabled()) &&
// testAssertion.getEntryTypeName().equals(targetContext.getEntry().getEntryType().getTypeName())) {
if (testAssertion.isEnabled()
&& isPrimaryEntryTypeMatch(testAssertion, entryContext))
{
try
{
// Add 1 to assertion processed count
assertionCount++;
// If the assertion process hasn't been created yet, then create it
if ((assertionProcess =
(AssertionProcess) processList.get(testAssertion.getId()))
== null)
{
// Create a new assertion process
Class assertionClass =
Class.forName(classPrefix + testAssertion.getId());
assertionProcess =
(AssertionProcess) assertionClass.getConstructor(
paramTypes).newInstance(
params);
// Add it to the list
processList.put(testAssertion.getId(), assertionProcess);
}
// Check whether entry is null
if (entry.getEntryDetail() == null)
{
assertionResult =
createAssertionResult(
testAssertion,
AssertionResult.RESULT_MISSING_INPUT,
(String) null);
}
// Check to see if the test assertion should be run
//if (isNotApplicable(testAssertion, entryContext)) {
else if (isNotApplicable(testAssertion))
{
assertionResult =
createAssertionResult(
testAssertion,
AssertionResult.RESULT_NOT_APPLICABLE,
(String) null);
}
else
{
// Processing all the assertion pre-requisites
preReqResults = null;
prereqFailedList = null;
// Get list of pre-reqs for specified assertion
Iterator i = testAssertion.getPrereqIdList().iterator();
while (i.hasNext())
{
if (preReqResults == null)
preReqResults = new TreeMap();
// Get next id
preReqId = (String) i.next();
// Get the prereq result
AssertionResult preReqResult = reporter.getAssertionResult(preReqId);
// Adding a result priority value to preReqResults
preReqResults.put(
resultPriority.get(preReqResult.getResult()),
preReqResult.getResult());
// If the prereq failed, then add it to the list
if (((Integer)resultPriority.get(preReqResult.getResult())).intValue()
> MAX_VALID_PRIORITY)
{
// Adding failed prereq ID to the list
if (prereqFailedList == null)
prereqFailedList = new PrereqFailedListImpl();
prereqFailedList.addTestAssertionID(preReqId);
}
}
if (prereqFailedList != null) {
// Getting the highest pre-requisites' result
Integer maxRes = (Integer)preReqResults.lastKey();
String resString = (String)preReqResults.get(maxRes);
if (resString.equals(AssertionResult.RESULT_FAILED)
||resString.equals(AssertionResult.RESULT_WARNING)) {
resString = AssertionResult.RESULT_PREREQ_FAILED;
}
// Create assertion result based on pre-requisites which are not passed
assertionResult = createAssertionResult(testAssertion, resString, prereqFailedList);
}
// Pre-requisites are passed, validate current assertion
else {
// Reset test assertion
assertionProcess.reset();
// VERBOSE
if (verboseOption)
{
System.err.println(
" Processing "
+ testAssertion.getId()
+ " for entry reference ID ["
+ entry.getReferenceID()
+ "] ...");
startTime = System.currentTimeMillis();
}
// Validate the target
assertionResult =
assertionProcess.validate(testAssertion, entryContext);
// VERBOSE
if (verboseOption)
{
System.err.println(
" Elapsed time: "
+ (System.currentTimeMillis() - startTime)
+ "ms");
}
}
}
// Add result to the report
reporter.addAssertionResult(assertionResult);
}
catch (ClassNotFoundException cnfe)
{
// DEBUG:
if (testAssertion != null)
{
reporter
.getReport()
.getReportContext()
.getAnalyzer()
.printMessage(
"WARNING: "
+ testAssertion.getId()
+ " is not supported currently.");
}
}
}
}
}
catch (Exception e)
{
System.err.println("EXECEPTION: " + e.getMessage());
if (verboseOption)
e.printStackTrace();
if (e instanceof WSIException)
throw (WSIException) e;
else
throw new WSIException(e.getMessage(), e);
}
finally
{
// Indicate that we are done with this assertion target
this.reporter.endCurrentEntry();
}
}
/**
* Determine if the test assertion should be processed for the current entry.
* @param testAssertion a test assertion.
* @param entryContext the entry context.
* @return true if the test assertion should be processed for the current entry.
*/
protected abstract boolean isPrimaryEntryTypeMatch(
TestAssertion testAssertion,
EntryContext entryContext);
/**
* Determine if the test assertion should be processed for the current entry.
* @param testAssertion a test assertion.
* @param entry an Entry object
* @return true if the test assertion should be processed for the current entry.
*/
protected boolean isPrimaryEntryTypeMatch(
TestAssertion testAssertion,
Entry entry)
{
boolean match = false;
// If the test assertion entry type matches the target context entry type, then contine
if (testAssertion
.getEntryTypeName()
.equals(entry.getEntryType().getTypeName()))
{
match = true;
}
return match;
}
/**
* Determine if the test assertion is not applicable.
* @param testAssertion a test assertion.
* @return true if the test assertion is not applicable.
*/
protected abstract boolean isNotApplicable(TestAssertion testAssertion);
/* (non-Javadoc)
* @see org.wsi.test.profile.validator.BaseValidator#cleanup()
*/
public void cleanup() throws WSIException
{
// If no assertions were processed, then set all missingInput
if (assertionCount == 0)
setAllMissingInput();
analyzerContext = null;
profileArtifact = null;
reportArtifact = null;
reporter = null;
}
/**
* Create assertion result.
* @param testAssertion a test assertion.
* @param result a String object.
* @param failureDetail a FailureDetail object.
* @return newly created test result.
*/
public AssertionResult createAssertionResult(
TestAssertion testAssertion,
String result,
FailureDetail failureDetail)
{
Vector failureDetailList = null;
// Create failure detail list
if (failureDetail != null)
{
failureDetailList = new Vector();
failureDetailList.add(failureDetail);
}
return createAssertionResult(testAssertion, result, failureDetailList);
}
/**
* Create assertion result.
* @param testAssertion a test assertion.
* @param result a String object.
* @param failureDetailMessage a failure detail message.
* @return newly created test result.
*/
public AssertionResult createAssertionResult(
TestAssertion testAssertion,
String result,
String failureDetailMessage)
{
return createAssertionResult(
testAssertion,
result,
failureDetailMessage,
null);
}
/**
* Create assertion result.
* @param testAssertion a test assertion.
* @param result a String object.
* @param failureDetailMessage a failure detail message.
* @param elementLocation element location.
* @return newly created test result.
*/
public AssertionResult createAssertionResult(
TestAssertion testAssertion,
String result,
String failureDetailMessage,
ElementLocation elementLocation)
{
// Create failure detail list
Vector failureDetailList = null;
if (failureDetailMessage != null)
{
failureDetailList = new Vector();
FailureDetail failureDetail = reporter.createFailureDetail();
failureDetail.setFailureMessage(failureDetailMessage);
failureDetail.setElementLocation(elementLocation);
failureDetailList.add(failureDetail);
}
return createAssertionResult(testAssertion, result, failureDetailList);
}
/**
* Create assertion result.
* @param testAssertion a test assertion.
* @param result a String object.
* @param failureDetailList a failure detail list.
* @return newly created test result.
*/
public AssertionResult createAssertionResult(
TestAssertion testAssertion,
String result,
Vector failureDetailList)
{
// Create assertion result
AssertionResult assertionResult = reporter.createAssertionResult();
// Set values in assertion result
assertionResult.setAssertion(testAssertion);
assertionResult.setResult(result);
assertionResult.setEntry(reporter.getReport().getCurrentEntry());
// Set failure detail list
assertionResult.setFailureDetailList(failureDetailList);
return assertionResult;
}
/**
* Create assertion result.
* @param testAssertion a test assertion.
* @param result a String object.
* @param prereqFailedList a list failed pre-requisite assertions.
* @return newly created test result.
*/
public AssertionResult createAssertionResult(
TestAssertion testAssertion,
String result,
PrereqFailedList prereqFailedList)
{
// Create assertion result
AssertionResult assertionResult = reporter.createAssertionResult();
// Set values in assertion result
assertionResult.setAssertion(testAssertion);
assertionResult.setResult(result);
assertionResult.setEntry(reporter.getReport().getCurrentEntry());
assertionResult.setPrereqFailedList(prereqFailedList);
return assertionResult;
}
/**
* Add assertion result to report.
* @param assertionId assertion id.
* @param result assertion result.
* @throws WSIException if the assertion result cannot be added to the report.
*/
protected void addAssertionResult(String assertionId, String result)
throws WSIException
{
// Create test assertion result
AssertionResult assertionResult = reporter.createAssertionResult();
// Set assertion, result and target
assertionResult.setAssertion(profileArtifact.getTestAssertion(assertionId));
assertionResult.setResult(result);
assertionResult.setEntry(reporter.getReport().getCurrentEntry());
// Add it to the report
reporter.addAssertionResult(assertionResult);
}
/**
* Add assertion result to report with an error detail message.
* @param assertionId assertion id.
* @param result assertion result.
* @param failureDetailMessage an error detail message.
* @throws WSIException if the assertion result cannot be added to the report.
*/
protected void addAssertionResult(
String assertionId,
String result,
String failureDetailMessage)
throws WSIException
{
// Convert message to vector
Vector failureDetailList = null;
if (failureDetailMessage != null)
{
failureDetailList = new Vector();
FailureDetail failureDetail = reporter.createFailureDetail();
failureDetailList.add(failureDetail);
}
// Add assertion result
addAssertionResult(assertionId, result, failureDetailList);
}
/**
* Add assertion result to report.
* @param assertionId assertion id.
* @param result assertion result.
* @param failureDetailList a list of error detail messages.
* @throws WSIException if the assertion result cannot be added to the report.
*/
protected void addAssertionResult(
String assertionId,
String result,
Vector failureDetailList)
throws WSIException
{
// Create test assertion result
AssertionResult assertionResult = reporter.createAssertionResult();
// Set assertion, result and target
assertionResult.setAssertion(profileArtifact.getTestAssertion(assertionId));
assertionResult.setResult(result);
assertionResult.setEntry(reporter.getReport().getCurrentEntry());
assertionResult.setFailureDetailList(failureDetailList);
// Add it to the report
reporter.addAssertionResult(assertionResult);
}
/**
* Add missingInput assertion result to report.
* @param testAssertion a test assertion.
* @throws WSIException if there is any problem adding missingInput
* assertion result to report.
*/
protected void addMissingInputResult(TestAssertion testAssertion)
throws WSIException
{
// Create test assertion result
AssertionResult assertionResult = reporter.createAssertionResult();
// Set assertion, result and target
assertionResult.setAssertion(testAssertion);
assertionResult.setResult(AssertionResult.RESULT_MISSING_INPUT);
assertionResult.setEntry(reporter.getReport().getCurrentEntry());
// Add it to the report
reporter.addAssertionResult(assertionResult);
}
/* (non-Javadoc)
* @see org.wsi.test.profile.validator.BaseValidator#setAllMissingInput()
*/
public void setAllMissingInput() throws WSIException
{
// If profile artifact is set
if (profileArtifact != null)
{
TestAssertion testAssertion;
// Create entry
Entry entry = this.reporter.getReport().createEntry();
entry.setArtifactName(this.reportArtifact.getType().getTypeName());
// Add entry to artifact
this.reportArtifact.addEntry(entry);
// Add entry to report
this.reporter.setCurrentEntry(entry);
// Go through the list of test assertions for the artifact
Iterator iterator = profileArtifact.getTestAssertionList().iterator();
while (iterator.hasNext())
{
// Get next test assertion
testAssertion = (TestAssertion) iterator.next();
// Add missingInput result
if (testAssertion.isEnabled())
addMissingInputResult(testAssertion);
}
// Indicate that we are done with this assertion target
this.reporter.endCurrentEntry();
}
}
/**
* Set all results for an entry type to missingInput.
* @param entryType an EntryType object.
* @throws WSIException if there is any problem while processing.
*/
protected void setMissingInput(EntryType entryType) throws WSIException
{
TestAssertion testAssertion;
// Create entry
Entry entry = this.reporter.getReport().createEntry();
entry.setEntryType(entryType);
entry.setReferenceID("[" + entryType.getTypeName() + "]");
// Add entry to artifact
this.reportArtifact.addEntry(entry);
// Add entry to report
this.reporter.setCurrentEntry(entry);
//try {
// Go through the list of test assertions for the artifact
Iterator iterator = profileArtifact.getTestAssertionList().iterator();
while (iterator.hasNext())
{
// Get next test assertion
testAssertion = (TestAssertion) iterator.next();
if (testAssertion.isEnabled()
&& isPrimaryEntryTypeMatch(testAssertion, entry))
{
addMissingInputResult(testAssertion);
}
}
// Indicate that we are done with this entry
this.reporter.endCurrentEntry();
}
}