Author: beckerdo
Date: Fri Jan 30 15:52:55 2009
New Revision: 739312
URL: http://svn.apache.org/viewvc?rev=739312&view=rev
Log:
TUSCANY-2776 The JMSBindingProcessor does not perform validation of binding
properties
Modified:
tuscany/branches/sca-java-1.x/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingProcessor.java
tuscany/branches/sca-java-1.x/modules/binding-jms/src/main/resources/binding-jms-validation-messages.properties
tuscany/branches/sca-java-1.x/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingProcessorTestCase.java
Modified:
tuscany/branches/sca-java-1.x/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingProcessor.java
URL:
http://svn.apache.org/viewvc/tuscany/branches/sca-java-1.x/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingProcessor.java?rev=739312&r1=739311&r2=739312&view=diff
==============================================================================
---
tuscany/branches/sca-java-1.x/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingProcessor.java
(original)
+++
tuscany/branches/sca-java-1.x/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingProcessor.java
Fri Jan 30 15:52:55 2009
@@ -117,6 +117,9 @@
* </operationProperties>*
* </binding.jms>
*
+ * Parsing error messages are recorded locally and reported as validation
exceptions. Parsing
+ * warnings do not cause validation exceptions.
+ *
* @version $Rev$ $Date$
*/
@@ -126,12 +129,14 @@
private PolicyAttachPointProcessor policyProcessor;
protected StAXArtifactProcessor<Object> extensionProcessor;
private Monitor monitor;
+ protected String validationMessage;
public JMSBindingProcessor(ModelFactoryExtensionPoint modelFactories,
StAXArtifactProcessor<Object> extensionProcessor, Monitor monitor) {
this.policyFactory = modelFactories.getFactory(PolicyFactory.class);
this.policyProcessor = new PolicyAttachPointProcessor(policyFactory);
this.extensionProcessor = extensionProcessor;
this.monitor = monitor;
+ this.validationMessage = null;
}
/**
@@ -149,7 +154,8 @@
}
/**
- * Report a error.
+ * Report an error.
+ * One side effect is that error messages are saved for future validation
calls.
*
* @param problems
* @param message
@@ -158,6 +164,7 @@
private void error(String message, Object model, Object...
messageParameters) {
if (monitor != null) {
Problem problem = new ProblemImpl(this.getClass().getName(),
"binding-jms-validation-messages", Severity.ERROR, model, message,
(Object[])messageParameters);
+ validationMessage = problem.toString(); // Record error message
for use in validation.
monitor.problem(problem);
}
}
@@ -172,6 +179,8 @@
public JMSBinding read(XMLStreamReader reader) throws
ContributionReadException, XMLStreamException {
JMSBinding jmsBinding = new JMSBinding();
+ // Reset validation message to keep track of validation issues.
+ this.validationMessage = null;
// Read policies
policyProcessor.readPolicies(jmsBinding, reader);
@@ -304,7 +313,7 @@
jmsBinding.setResponseWireFormat(jmsBinding.getRequestWireFormat());
}
- validate();
+ validate( jmsBinding );
return jmsBinding;
}
@@ -323,7 +332,6 @@
jmsBinding.setConnectionFactoryName(s.substring(22));
} else {
error("UnknownTokenInURI", jmsBinding, s, uri);
- //throw new JMSBindingException("unknown token '" + s +
"' in uri: " + uri);
return;
}
}
@@ -377,13 +385,13 @@
String type = reader.getAttributeValue(null, "type");
if (type != null && type.length() > 0) {
- warning("DoesntProcessDestinationType", jmsBinding);
+ warning("DoesntProcessDestinationType", jmsBinding);
if
(JMSBindingConstants.DESTINATION_TYPE_QUEUE.equalsIgnoreCase(type)) {
jmsBinding.setDestinationType(JMSBindingConstants.DESTINATION_TYPE_QUEUE);
} else if
(JMSBindingConstants.DESTINATION_TYPE_TOPIC.equalsIgnoreCase(type)) {
jmsBinding.setDestinationType(JMSBindingConstants.DESTINATION_TYPE_TOPIC);
} else {
- warning("InvalidDestinationType", reader, type);
+ error("InvalidDestinationType", reader, type);
}
}
@@ -398,17 +406,17 @@
if (name != null && name.length() > 0) {
jmsBinding.setConnectionFactoryName(name);
} else {
- error("MissingConnectionFactoryName", reader);
+ error("MissingConnectionFactoryName", reader);
}
}
private void parseActivationSpec(XMLStreamReader reader, JMSBinding
jmsBinding) {
String name = reader.getAttributeValue(null, "name");
if (name != null && name.length() > 0) {
- warning("DoesntProcessActivationSpec", jmsBinding);
+ warning("DoesntProcessActivationSpec", jmsBinding);
jmsBinding.setActivationSpecName(name);
} else {
- warning("MissingActivationSpecName", reader);
+ warning("MissingActivationSpecName", reader);
}
}
@@ -420,14 +428,14 @@
String type = reader.getAttributeValue(null, "type");
if (type != null && type.length() > 0) {
- warning("DoesntProcessResponseDestinationType", jmsBinding);
- if
(JMSBindingConstants.DESTINATION_TYPE_QUEUE.equalsIgnoreCase(type)) {
+ warning("DoesntProcessResponseDestinationType", jmsBinding);
+ if
(JMSBindingConstants.DESTINATION_TYPE_QUEUE.equalsIgnoreCase(type)) {
jmsBinding.setResponseDestinationType(JMSBindingConstants.DESTINATION_TYPE_QUEUE);
} else if
(JMSBindingConstants.DESTINATION_TYPE_TOPIC.equalsIgnoreCase(type)) {
jmsBinding.setResponseDestinationType(JMSBindingConstants.DESTINATION_TYPE_TOPIC);
} else {
- warning("InvalidResponseDestinationType", reader, type);
- }
+ error("InvalidResponseDestinationType", reader, type);
+ }
}
String create = reader.getAttributeValue(null, "create");
@@ -439,20 +447,20 @@
private void parseResponseConnectionFactory(XMLStreamReader reader,
JMSBinding jmsBinding) {
String name = reader.getAttributeValue(null, "name");
if (name != null && name.length() > 0) {
- warning("DoesntProcessResponseConnectionFactory", jmsBinding);
+ warning("DoesntProcessResponseConnectionFactory", jmsBinding);
jmsBinding.setResponseConnectionFactoryName(name);
} else {
- warning("MissingResponseConnectionFactory", reader);
+ warning("MissingResponseConnectionFactory", reader);
}
}
private void parseResponseActivationSpec(XMLStreamReader reader,
JMSBinding jmsBinding) {
String name = reader.getAttributeValue(null, "name");
if (name != null && name.length() > 0) {
- warning("DoesntProcessResponseActivationSpec", jmsBinding);
+ warning("DoesntProcessResponseActivationSpec", jmsBinding);
jmsBinding.setResponseActivationSpecName(name);
} else {
- warning("MissingResponseActivationSpec", reader);
+ warning("MissingResponseActivationSpec", reader);
}
}
@@ -514,7 +522,7 @@
} else if ("NON_PERSISTENT".equalsIgnoreCase(jmsDeliveryMode)) {
jmsBinding.setJMSDeliveryMode(false);
} else {
- warning("InvalidJMSDeliveryMode", jmsBinding, jmsDeliveryMode);
+ error("InvalidJMSDeliveryMode", jmsBinding, jmsDeliveryMode);
}
}
@@ -636,7 +644,7 @@
} else if ("NON_PERSISTENT".equalsIgnoreCase(jmsDeliveryMode)) {
jmsBinding.setOperationJMSDeliveryMode(opName, false);
} else {
- warning("InvalidOPJMSDeliveryMode", jmsBinding,
jmsDeliveryMode);
+ error("InvalidOPJMSDeliveryMode", jmsBinding, jmsDeliveryMode);
}
}
@@ -707,20 +715,78 @@
}
/**
- * The validation rules for the JMS model are relatively complicated to
they all live together here
+ * Preserve an existing public method. The method validate() is a legacy
method
+ * that was called from reading am XML stream via the
read(XMLStreamReader) method above.
+ * However read(XMLStreamReader) now calls validate(JMSBinding jmsBinding)
and
+ * passes in the jmsBinding model.
+ * The older validate() now calls validate(JMSBinding jmsBinding) with a
null model.
*/
public void validate() throws JMSBindingException {
- /*
- * first fix up anything now the model has been read
- */
-
- /*
- * Now some cross field validation
- */
-
- // connection factory doesn't contradict destination type
- // connection factory and activation Specification are mutually
exclusive
- // TODO check Specification for all validations
+ validate( null );
}
+
+ /**
+ * Validates JMS parsing and JMSBinding model.
+ * Validation rules are taken from the binding schema and the OSOA and
OASIS specs:
+ *
http://www.oasis-open.org/committees/documents.php?wg_abbrev=sca-bindings
+ * (sca-binding-jms-1.1-spec-cd01-rev4.pdf)
+ *
http://www.osoa.org/display/Main/Service+Component+Architecture+Specifications
+ * (SCA JMS Binding V1.00 )
+ * @param jmsBinding an optional JMS binding model to check for validity.
+ * @since 1.4
+ */
+ protected void validate( JMSBinding jmsBinding ) {
+ // Check validation message for issues that arise from parsing errors.
+ if ( validationMessage != null ) {
+ throw new JMSBindingException( validationMessage );
+ }
+
+ // If no JMSBinding model is provided, that is all the validation we
can do.
+ if ( jmsBinding == null ) {
+ return;
+ }
+ // Connection factory should not contradict destination type.
+ String connectionFactoryName = jmsBinding.getConnectionFactoryName();
+ if (( connectionFactoryName != null ) && (
connectionFactoryName.length() > 0 )) {
+ if (JMSBindingConstants.DESTINATION_TYPE_QUEUE ==
jmsBinding.getDestinationType()) {
+ if ( connectionFactoryName.contains( "topic" )) {
+ error("DestinationQueueContradiction", jmsBinding,
connectionFactoryName );
+ }
+ }
+ if (JMSBindingConstants.DESTINATION_TYPE_TOPIC ==
jmsBinding.getDestinationType()) {
+ if ( connectionFactoryName.contains( "queue" )) {
+ error("DestinationTopicContradiction", jmsBinding,
connectionFactoryName );
+ }
+ }
+ }
+
+ // Connection factory and activation Specification are mutually
exclusive.
+ if (( connectionFactoryName != null ) && (
connectionFactoryName.length() > 0 )) {
+ String activationSpecName = jmsBinding.getActivationSpecName();
+ if ((activationSpecName != null) && (activationSpecName.length() >
0 )) {
+ error("ConnectionFactoryActivationSpecContradiction",
jmsBinding, connectionFactoryName, activationSpecName );
+ }
+ }
+
+ // Given a response connection name attribute, there must not be a
response element.
+ // 156 /binding.jms/@responseConnection identifies a binding.jms
element that is present in a
+ // 157 definition document, whose response child element is used to
define the values for this binding. In
+ // 158 this case this binding.jms element MUST NOT contain a response
element.
+ String responseConnectionName = jmsBinding.getResponseConnectionName();
+ if (( responseConnectionName != null ) && (
responseConnectionName.length() > 0 )) {
+ String responseDestinationName =
jmsBinding.getResponseDestinationName();
+ if (( responseDestinationName != null ) &&
(responseDestinationName.length() > 0)) {
+ error("ResponseAttrElement", jmsBinding,
responseConnectionName, responseDestinationName );
+ }
+ }
+
+ // Other jmsBinding model validation may be added here.
+
+ // Check validation message for issues that arise from internal model
validation errors.
+ if ( validationMessage != null ) {
+ throw new JMSBindingException( validationMessage );
+ }
+
+ }
}
Modified:
tuscany/branches/sca-java-1.x/modules/binding-jms/src/main/resources/binding-jms-validation-messages.properties
URL:
http://svn.apache.org/viewvc/tuscany/branches/sca-java-1.x/modules/binding-jms/src/main/resources/binding-jms-validation-messages.properties?rev=739312&r1=739311&r2=739312&view=diff
==============================================================================
---
tuscany/branches/sca-java-1.x/modules/binding-jms/src/main/resources/binding-jms-validation-messages.properties
(original)
+++
tuscany/branches/sca-java-1.x/modules/binding-jms/src/main/resources/binding-jms-validation-messages.properties
Fri Jan 30 15:52:55 2009
@@ -42,6 +42,7 @@
MissingJMSOperationPropertyName = Missing JMSOperationProperty Name
InvalidOPJMSDeliveryMode = Invalid OPJMSDeliveryMode: {0}
InvalidOPJMSPriority = Invalid OPJMSPriority: {0}
-
-
-
+DestinationQueueContradiction = Destination type queue contradicts connection
factory name: {0}
+DestinationTopicContradiction = Destination type topic contradicts connection
factory name: {0}
+ConnectionFactoryActivationSpecContradiction = Connection factory \"{0}\" and
activation specification \"{0}\" are mutually exclusive
+ResponseAttrElement = Response connection \"{0}\" and response element \"{1}\"
are mutually exclusive
Modified:
tuscany/branches/sca-java-1.x/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingProcessorTestCase.java
URL:
http://svn.apache.org/viewvc/tuscany/branches/sca-java-1.x/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingProcessorTestCase.java?rev=739312&r1=739311&r2=739312&view=diff
==============================================================================
---
tuscany/branches/sca-java-1.x/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingProcessorTestCase.java
(original)
+++
tuscany/branches/sca-java-1.x/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingProcessorTestCase.java
Fri Jan 30 15:52:55 2009
@@ -121,6 +121,33 @@
+ " </component>"
+ "</composite>";
+ private static final String COMPOSITE_INVALID_URI =
+ "<?xml version=\"1.0\" encoding=\"ASCII\"?>"
+ + "<composite xmlns=\"http://www.osoa.org/xmlns/sca/1.0\"
targetNamespace=\"http://binding-jms\" name=\"binding-jms\">"
+ + " <component name=\"HelloWorldComponent\">"
+ + " <implementation.java class=\"services.HelloWorld\"/>"
+ + " <service name=\"HelloWorldService\">"
+ + " <binding.jms uri=\"invalidjms:testQueue\" />"
+ + " </service>"
+ + " </component>"
+ + "</composite>";
+
+ // Invalid: contains both a response attribute and a response element.
+ private static final String COMPOSITE_INVALID_RESPONSE_ATTR_ELEMENT =
+ "<?xml version=\"1.0\" encoding=\"ASCII\"?>"
+ + "<composite xmlns=\"http://www.osoa.org/xmlns/sca/1.0\"
targetNamespace=\"http://binding-jms\" name=\"binding-jms\">"
+ + " <component name=\"HelloWorldComponent\">"
+ + " <implementation.java class=\"services.HelloWorld\"/>"
+ + " <service name=\"HelloWorldService\">"
+ + " <binding.jms uri=\"jms:testQueue\"
responseConnection=\"responseConnectionAttrName\">"
+ + " <response>"
+ + " <destination
name=\"responseConnectionElementName\"/>"
+ + " </response>"
+ + " </binding.jms>"
+ + " </service>"
+ + " </component>"
+ + "</composite>";
+
private XMLInputFactory inputFactory;
private StAXArtifactProcessor<Object> staxProcessor;
private Monitor monitor;
@@ -208,4 +235,36 @@
assertEquals("prop1 = 2", binding.getJMSSelector());
}
+
+ /** Test various parsing validation requirements. */
+ public void testParsingValidationErrors1() throws Exception {
+ // Composite with malformed URI.
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(new
StringReader(COMPOSITE_INVALID_URI));
+
+ try {
+ Composite composite = (Composite)staxProcessor.read(reader);
+ } catch(Exception e) {
+ // JMSBindingExceptions are expected with invalid composite.
+ if ( !e.getClass().isAssignableFrom( JMSBindingException.class ) )
+ throw e;
+ // Do assertion to make sure test registers results.
+ assertTrue( e.getClass().isAssignableFrom(
JMSBindingException.class ) );
+ }
+ }
+
+ /** Test various model validation requirements. */
+ public void testValidationErrors1() throws Exception {
+ // Composite with response connection attr and element.
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(new
StringReader(COMPOSITE_INVALID_RESPONSE_ATTR_ELEMENT));
+
+ try {
+ Composite composite = (Composite)staxProcessor.read(reader);
+ } catch(Exception e) {
+ // JMSBindingExceptions are expected with invalid composite.
+ if ( !e.getClass().isAssignableFrom( JMSBindingException.class ) )
+ throw e;
+ // Do assertion to make sure test registers results.
+ assertTrue( e.getClass().isAssignableFrom(
JMSBindingException.class ) );
+ }
+ }
}