| /******************************************************************************* |
| * 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(); |
| } |
| } |