/* * 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 org.apache.tuscany.sca.binding.jms; import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; import org.apache.tuscany.sca.assembly.Base; import org.apache.tuscany.sca.assembly.ConfiguredOperation; import org.apache.tuscany.sca.assembly.OperationSelector; import org.apache.tuscany.sca.assembly.OperationsConfigurator; import org.apache.tuscany.sca.assembly.WireFormat; import org.apache.tuscany.sca.assembly.xml.ConfiguredOperationProcessor; import org.apache.tuscany.sca.assembly.xml.Constants; import org.apache.tuscany.sca.assembly.xml.PolicySubjectProcessor; import org.apache.tuscany.sca.binding.jms.operationselector.OperationSelectorJMSDefault; import org.apache.tuscany.sca.binding.jms.wireformat.WireFormatJMSDefault; import org.apache.tuscany.sca.binding.jms.wireformat.WireFormatJMSObject; import org.apache.tuscany.sca.binding.jms.wireformat.WireFormatJMSText; import org.apache.tuscany.sca.binding.jms.wireformat.WireFormatJMSTextXML; import org.apache.tuscany.sca.common.xml.stax.StAXHelper; import org.apache.tuscany.sca.contribution.processor.BaseStAXArtifactProcessor; import org.apache.tuscany.sca.contribution.processor.ContributionReadException; import org.apache.tuscany.sca.contribution.processor.ContributionResolveException; import org.apache.tuscany.sca.contribution.processor.ContributionWriteException; import org.apache.tuscany.sca.contribution.processor.ProcessorContext; import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; import org.apache.tuscany.sca.contribution.resolver.ModelResolver; import org.apache.tuscany.sca.core.FactoryExtensionPoint; import org.apache.tuscany.sca.monitor.Monitor; import org.apache.tuscany.sca.monitor.Problem; import org.apache.tuscany.sca.monitor.Problem.Severity; import org.apache.tuscany.sca.policy.PolicyFactory; /** * A processor to read the XML that describes the JMS binding... * * <binding.jms correlationScheme="string"? * initialContextFactory="xs:anyURI"? * jndiURL="xs:anyURI"? * requestConnection="QName"? * responseConnection="QName"? * operationProperties="QName"? * ...> * * <headers type="string"? * deliveryMode="string"? * timeToLive="int"? * priority="string"?> * <property name="NMTOKEN" type="NMTOKEN">* * </headers>? * * <destination jndiName="xs:anyURI" type="string"? create="string"?> * <property name="NMTOKEN" type="NMTOKEN">* * </destination>? * * <connectionFactory jndiName="xs:anyURI" create="string"?> * <property name="NMTOKEN" type="NMTOKEN">* * </connectionFactory>? * * <activationSpec name="xs:anyURI" create="string"?> * <property name="NMTOKEN" type="NMTOKEN">* * </activationSpec>? * * <response> * <destination jndiName="xs:anyURI" type="string"? create="string"?> * <property name="NMTOKEN" type="NMTOKEN">* * </destination>? * * <connectionFactory jndiName="xs:anyURI" create="string"?> * <property name="NMTOKEN" type="NMTOKEN">* * </connectionFactory>? * * <activationSpec name="xs:anyURI" create="string"?> * <property name="NMTOKEN" type="NMTOKEN">* * </activationSpec>? * * <wireFormat.someWireFormat/>? * </response>? * * <complexType name="SubscriptionHeaders"> * <attribute name="JMSSelector" type="string"/> * </complexType> * * <resourceAdapter name="NMTOKEN">? * <property name="NMTOKEN" type="NMTOKEN">* * </resourceAdapter>? * * <operationProperties name="string" selectedOperation="string"?> * <property name="NMTOKEN" type="NMTOKEN">* * <headers type="string"? * deliveryMode="string"? * timeToLive="int"? * priority="string"?> * <property name="NMTOKEN" type="NMTOKEN">* * </headers>? * </operationProperties>* * * <wireFormat.someWireFormat/>? * </binding.jms> * * Parsing error messages are recorded locally and reported as validation exceptions. Parsing * warnings do not cause validation exceptions. * * @version $Rev$ $Date$ */ public class JMSBindingProcessor extends BaseStAXArtifactProcessor implements StAXArtifactProcessor<JMSBinding> { private PolicyFactory policyFactory; private PolicySubjectProcessor policyProcessor; private ConfiguredOperationProcessor configuredOperationProcessor; protected StAXArtifactProcessor<Object> extensionProcessor; public JMSBindingProcessor(FactoryExtensionPoint modelFactories, StAXArtifactProcessor<Object> extensionProcessor) { this.policyFactory = modelFactories.getFactory(PolicyFactory.class); this.policyProcessor = new PolicySubjectProcessor(policyFactory); this.configuredOperationProcessor = new ConfiguredOperationProcessor(modelFactories); this.extensionProcessor = extensionProcessor; } /** * Report a error. * * @param problems * @param message * @param model */ private void warning(Monitor monitor, String message, Object model, Object... messageParameters) { if (monitor != null) { Problem problem = monitor.createProblem(this.getClass().getName(), "binding-jms-validation-messages", Severity.WARNING, model, message, (Object[])messageParameters); monitor.problem(problem); } } /** * Report an error. * One side effect is that error messages are saved for future validation calls. * * @param problems * @param message * @param model */ private void error(Monitor monitor, String message, Object model, Object... messageParameters) { if (monitor != null) { Problem problem = monitor.createProblem(this.getClass().getName(), "binding-jms-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters); monitor.problem(problem); } } public QName getArtifactType() { return JMSBindingConstants.BINDING_JMS_QNAME; } public Class<JMSBinding> getModelType() { return JMSBinding.class; } public JMSBinding read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException { Monitor monitor = context.getMonitor(); JMSBinding jmsBinding = new JMSBinding(); // Reset validation message to keep track of validation issues. // Read policies policyProcessor.readPolicies(jmsBinding, reader); // Read binding name String name = reader.getAttributeValue(null, "name"); if (name != null) { jmsBinding.setName(name); } // Read binding URI String uri = reader.getAttributeValue(null, "uri"); if (uri != null && uri.length() > 0) { parseURI(uri, jmsBinding, monitor); } // Read correlation scheme QName correlationScheme = StAXHelper.getAttributeAsQName(reader, "correlationScheme"); if (correlationScheme != null) { if (Base.SCA11_NS.equals(correlationScheme.getNamespaceURI()) && JMSBindingConstants.VALID_CORRELATION_SCHEMES.contains(correlationScheme.getLocalPart())) { jmsBinding.setCorrelationScheme(correlationScheme.getLocalPart()); } else { error(monitor, "InvalidCorrelationScheme", reader, correlationScheme); } } // Read initial context factory String initialContextFactory = getURIString(reader, "initialContextFactory"); if (initialContextFactory != null && initialContextFactory.length() > 0) { jmsBinding.setInitialContextFactoryName(initialContextFactory); } // Read JNDI URL String jndiURL = getURIString(reader, "jndiURL"); if (jndiURL != null && jndiURL.length() > 0) { jmsBinding.setJndiURL(jndiURL); } // Read message processor class name // TODO - maintain this for the time being but move over to // configuring wire formats instead of message processors String messageProcessorName = reader.getAttributeValue(null, "messageProcessor"); if (messageProcessorName != null && messageProcessorName.length() > 0) { if ("XMLTextMessage".equalsIgnoreCase(messageProcessorName)) { // may be overwritten be real wire format later jmsBinding.setRequestWireFormat(new WireFormatJMSTextXML()); jmsBinding.setResponseWireFormat(jmsBinding.getRequestWireFormat()); } else if ("TextMessage".equalsIgnoreCase(messageProcessorName)) { // may be overwritten be real wire format later jmsBinding.setRequestWireFormat(new WireFormatJMSText()); jmsBinding.setResponseWireFormat(jmsBinding.getRequestWireFormat()); } else if ("ObjectMessage".equalsIgnoreCase(messageProcessorName)) { // may be overwritten be real wire format later jmsBinding.setRequestWireFormat(new WireFormatJMSObject()); jmsBinding.setResponseWireFormat(jmsBinding.getRequestWireFormat()); } else { jmsBinding.setRequestMessageProcessorName(messageProcessorName); jmsBinding.setResponseMessageProcessorName(messageProcessorName); // exploit the text wire format code to drive the user selected // message processor jmsBinding.setRequestWireFormat(new WireFormatJMSText()); jmsBinding.setResponseWireFormat(jmsBinding.getRequestWireFormat()); } } String requestConnectionName = reader.getAttributeValue(null, "requestConnection"); if (requestConnectionName != null && requestConnectionName.length() > 0) { jmsBinding.setRequestConnectionName(getQNameValue(reader, requestConnectionName)); } String responseConnectionName = reader.getAttributeValue(null, "responseConnection"); if (responseConnectionName != null && responseConnectionName.length() > 0) { jmsBinding.setResponseConnectionName(getQNameValue(reader, responseConnectionName)); } String operationPropertiesName = reader.getAttributeValue(null, "operationProperties"); if (operationPropertiesName != null && operationPropertiesName.length() > 0) { jmsBinding.setOperationPropertiesName(getQNameValue(reader, operationPropertiesName)); } // Read sub-elements of binding.jms boolean endFound = false; while (!endFound) { int fg = reader.next(); switch (fg) { case START_ELEMENT: String elementName = reader.getName().getLocalPart(); if ("destination".equals(elementName)) { parseDestination(reader, jmsBinding, monitor); } else if ("connectionFactory".equals(elementName)) { parseConnectionFactory(reader, jmsBinding, monitor); } else if ("activationSpec".equals(elementName)) { parseActivationSpec(reader, jmsBinding, monitor); } else if ("response".equals(elementName)) { parseResponse(reader, jmsBinding, context); } else if ("resourceAdapter".equals(elementName)) { parseResourceAdapter(reader, jmsBinding, monitor); } else if ("headers".equals(elementName)) { parseHeaders(reader, jmsBinding, monitor); } else if ("operationProperties".equals(elementName)) { parseOperationProperties(reader, jmsBinding, monitor); } else if ("messageSelection".equals(elementName)) { parseSubscriptionHeaders(reader, jmsBinding); } else if (Constants.OPERATION_QNAME.equals(reader.getName())) { ConfiguredOperation confOp = configuredOperationProcessor.read(reader, context); if (confOp != null) { ((OperationsConfigurator)jmsBinding).getConfiguredOperations().add(confOp); } } else { Object extension = extensionProcessor.read(reader, context); if (extension != null) { if (extension instanceof WireFormat) { if (jmsBinding.getRequestWireFormat() == null) { jmsBinding.setRequestWireFormat((WireFormat) extension); } else { error(monitor, "WireFormatAlreadyDefined", reader, extension.toString()); } } else if (extension instanceof OperationSelector) { if (jmsBinding.getOperationSelector() == null) { jmsBinding.setOperationSelector((OperationSelector) extension); } else { error(monitor, "OpSelectorAlreadyDefined", reader, extension.toString()); } } else { error(monitor, "UnexpectedElement", reader, extension.toString()); } } } //reader.next(); break; case END_ELEMENT: QName x = reader.getName(); if (Constants.OPERATION.equals(x.getLocalPart())) break; // This assumption is not captured in schema, which isn't good, but will probably be fine for now. // A better solution might be to require each processor to advance to its own END_ELEMENT. if (x.getLocalPart().startsWith("wireFormat.") || x.getLocalPart().startsWith("operationSelector.")) { break; } if (x.equals(JMSBindingConstants.BINDING_JMS_QNAME)) { endFound = true; } else { error(monitor, "UnexpectedElement: expected " + JMSBindingConstants.BINDING_JMS_QNAME + ", found " + x.toString(), reader, x.toString()); } } } // if no operation selector is specified then assume the default if (jmsBinding.getOperationSelector() == null){ jmsBinding.setOperationSelector(new OperationSelectorJMSDefault()); } // if no request wire format specified then assume the default if (jmsBinding.getRequestWireFormat() == null){ jmsBinding.setRequestWireFormat(new WireFormatJMSDefault()); } // if no response wire format specific then assume the same as the request if (jmsBinding.getResponseWireFormat() == null){ jmsBinding.setResponseWireFormat(jmsBinding.getRequestWireFormat()); } validate( jmsBinding, monitor ); return jmsBinding; } protected void parseURI(String uri, JMSBinding jmsBinding, Monitor monitor) { if (!(uri.startsWith("jms:jndi:") || uri.startsWith("jms:queue:") || uri.startsWith("jms:topic:"))) { error(monitor, "MustStartWithSchema", jmsBinding, uri); return; } int i = uri.indexOf('?'); if (i >= 0) { StringTokenizer st = new StringTokenizer(uri.substring(i+1),"&"); while (st.hasMoreTokens()) { String s = st.nextToken(); if (s.startsWith("jndiConnectionFactoryName=")) { jmsBinding.setConnectionFactoryName(s.substring(26)); } else if (s.startsWith("deliveryMode=")) { jmsBinding.setURIJMSDeliveryMode("persistent".equals(s.substring(13))); } else if (s.startsWith("priority=")) { jmsBinding.setURIJMSPriority(Integer.parseInt(s.substring(9))); } else if (s.startsWith("timeToLive=")) { jmsBinding.setURIJMSTimeToLive(Long.parseLong(s.substring(11))); } else if (s.startsWith("selector='")) { String selector = s.substring(10); if (selector.startsWith("\"") || selector.startsWith("'")) { selector = selector.substring(1, selector.length()); } if (selector.endsWith("\"") || selector.endsWith("'")) { selector = selector.substring(0, selector.length() - 1); } jmsBinding.setURIJMSSelector(selector); } else if (s.startsWith("type")) { String type = s.substring(5); jmsBinding.setJMSURIType(type); } else { error(monitor, "UnknownTokenInURI", jmsBinding, s, uri); return; } } int j=uri.indexOf(':', 4); jmsBinding.setDestinationName(uri.substring(j+1, i)); jmsBinding.setDestinationType(uri.substring(4, j)); } else { int j=uri.indexOf(':', 4); jmsBinding.setDestinationName(uri.substring(j+1)); jmsBinding.setDestinationType(uri.substring(4, j)); } jmsBinding.setJMSURI(uri); } public void resolve(JMSBinding model, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException { if (model.getRequestConnectionName() != null) { model.setRequestConnectionBinding(getConnectionBinding(model, "requestConnection", model.getRequestConnectionName(), resolver, context)); } if (model.getResponseConnectionName() != null) { model.setResponseConnectionBinding(getConnectionBinding(model, "responseConnection", model.getResponseConnectionName(), resolver, context)); } if (model.getOperationPropertiesName() != null) { model.setOperationPropertiesBinding(getConnectionBinding(model, "operationProperties", model.getOperationPropertiesName(), resolver, context)); } } private JMSBinding getConnectionBinding(JMSBinding model, String attrName, QName bindingName, ModelResolver resolver, ProcessorContext context) { JMSBinding binding = new JMSBinding(); binding.setTargetNamespace(bindingName.getNamespaceURI()); binding.setName(bindingName.getLocalPart()); binding.setUnresolved(true); binding = resolver.resolveModel(JMSBinding.class, binding, context); if (binding.isUnresolved()) error(context.getMonitor(), "BindingNotFound", model, attrName, bindingName); return binding; } private void parseDestination(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException { jmsBinding.setIsDestinationSpecified(true); String name = getURIString(reader, "jndiName"); if (name != null && name.length() > 0) { jmsBinding.setDestinationName(name); } String type = reader.getAttributeValue(null, "type"); if (type != null && type.length() > 0) { 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 { error(monitor, "InvalidDestinationType", reader, type); } } String create = reader.getAttributeValue(null, "create"); if (create != null && create.length() > 0) { validateCreate(create, reader, monitor); jmsBinding.setDestinationCreate(create); } jmsBinding.getDestinationProperties().putAll(parseBindingProperties(reader, monitor)); if (jmsBinding.getDestinationCreate().equals(JMSBindingConstants.CREATE_IF_NOT_EXIST)) { if (name == null || name.length() < 1) { error(monitor, "MissingNameForCREATE_IF_NOT_EXIST", reader); } } if (jmsBinding.getDestinationCreate().equals(JMSBindingConstants.CREATE_NEVER)) { if (name == null || name.length() < 1) { error(monitor, "MissingNameForCREATE_NEVER", reader); } } } private void parseConnectionFactory(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException { String name = getURIString(reader, "jndiName"); if (name != null && name.length() > 0) { jmsBinding.setConnectionFactoryName(name); } else { error(monitor, "MissingConnectionFactoryName", reader); } String create = reader.getAttributeValue(null, "create"); if (create != null && create.length() > 0) { validateCreate(create, reader, monitor); jmsBinding.setConnectionFactoryCreate(create); } if (jmsBinding.getConnectionFactoryCreate().equals(JMSBindingConstants.CREATE_IF_NOT_EXIST)) { if (name == null || name.length() < 1) { error(monitor, "MissingNameForCREATE_IF_NOT_EXIST", reader); } } if (jmsBinding.getConnectionFactoryCreate().equals(JMSBindingConstants.CREATE_NEVER)) { if (name == null || name.length() < 1) { error(monitor, "MissingNameForCREATE_NEVER", reader); } } jmsBinding.getConnectionFactoryProperties().putAll(parseBindingProperties(reader, monitor)); } private void parseActivationSpec(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException { String name = reader.getAttributeValue(null, "jndiName"); if (name != null && name.length() > 0) { jmsBinding.setActivationSpecName(name); } String create = reader.getAttributeValue(null, "create"); if (create != null && create.length() > 0) { validateCreate(create, reader, monitor); jmsBinding.setActivationSpecCreate(create); } if (jmsBinding.getActivationSpecCreate().equals(JMSBindingConstants.CREATE_IF_NOT_EXIST)) { if (name == null || name.length() < 1) { error(monitor, "MissingNameForCREATE_IF_NOT_EXIST", reader); } } if (jmsBinding.getActivationSpecCreate().equals(JMSBindingConstants.CREATE_NEVER)) { if (name == null || name.length() < 1) { error(monitor, "MissingNameForCREATE_NEVER", reader); } } jmsBinding.getActivationSpecProperties().putAll(parseBindingProperties(reader, monitor)); } private void parseResponseDestination(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException { String name = getURIString(reader, "jndiName"); if (name != null && name.length() > 0) { jmsBinding.setResponseDestinationName(name); } String type = reader.getAttributeValue(null, "type"); if (type != null && type.length() > 0) { warning(monitor, "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 { error(monitor, "InvalidResponseDestinationType", reader, type); } } String create = reader.getAttributeValue(null, "create"); if (create != null && create.length() > 0) { validateCreate(create, reader, monitor); jmsBinding.setResponseDestinationCreate(create); } if (jmsBinding.getResponseDestinationCreate().equals(JMSBindingConstants.CREATE_IF_NOT_EXIST)) { if (name == null || name.length() < 1) { error(monitor, "MissingNameForCREATE_IF_NOT_EXIST", reader); } } if (jmsBinding.getResponseDestinationCreate().equals(JMSBindingConstants.CREATE_NEVER)) { if (name == null || name.length() < 1) { error(monitor, "MissingNameForCREATE_NEVER", reader); } } jmsBinding.getResponseDestinationProperties().putAll(parseBindingProperties(reader, monitor)); } private void parseResponseConnectionFactory(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException { String name = getURIString(reader, "jndiName"); if (name != null && name.length() > 0) { jmsBinding.setResponseConnectionFactoryName(name); } else { warning(monitor, "MissingResponseConnectionFactory", reader); } String create = reader.getAttributeValue(null, "create"); if (create != null && create.length() > 0) { validateCreate(create, reader, monitor); jmsBinding.setResponseConnectionFactoryCreate(create); } if (jmsBinding.getResponseConnectionFactoryCreate().equals(JMSBindingConstants.CREATE_IF_NOT_EXIST)) { if (name == null || name.length() < 1) { error(monitor, "MissingNameForCREATE_IF_NOT_EXIST", reader); } } if (jmsBinding.getResponseConnectionFactoryCreate().equals(JMSBindingConstants.CREATE_NEVER)) { if (name == null || name.length() < 1) { error(monitor, "MissingNameForCREATE_NEVER", reader); } } jmsBinding.getResponseConnectionFactoryProperties().putAll(parseBindingProperties(reader, monitor)); } private void parseResponseActivationSpec(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException { String name = reader.getAttributeValue(null, "jndiName"); if (name != null && name.length() > 0) { jmsBinding.setResponseActivationSpecName(name); } String create = reader.getAttributeValue(null, "create"); if (create != null && create.length() > 0) { validateCreate(create, reader, monitor); jmsBinding.setResponseActivationSpecCreate(create); } if (jmsBinding.getResponseActivationSpecCreate().equals(JMSBindingConstants.CREATE_IF_NOT_EXIST)) { if (name == null || name.length() < 1) { error(monitor, "MissingNameForCREATE_IF_NOT_EXIST", reader); } } if (jmsBinding.getResponseActivationSpecCreate().equals(JMSBindingConstants.CREATE_NEVER)) { if (name == null || name.length() < 1) { error(monitor, "MissingNameForCREATE_NEVER", reader); } } jmsBinding.getResponseActivationSpecProperties().putAll(parseBindingProperties(reader, monitor)); } private void validateCreate(String create, XMLStreamReader reader, Monitor monitor) { if (JMSBindingConstants.CREATE_ALWAYS.equals(create)) { return; } if (JMSBindingConstants.CREATE_NEVER.equals(create)) { return; } if (JMSBindingConstants.CREATE_IF_NOT_EXIST.equals(create)) { return; } error(monitor, "InvalidCreate", reader, create); } private void parseResponse(XMLStreamReader reader, JMSBinding jmsBinding, ProcessorContext context) throws ContributionReadException, XMLStreamException { // Read sub-elements of response Monitor monitor = context.getMonitor(); while (true) { switch (reader.next()) { case START_ELEMENT: String elementName = reader.getName().getLocalPart(); if ("destination".equals(elementName)) { parseResponseDestination(reader, jmsBinding, context.getMonitor()); } else if ("connectionFactory".equals(elementName)) { parseResponseConnectionFactory(reader, jmsBinding, monitor); } else if ("activationSpec".equals(elementName)) { parseResponseActivationSpec(reader, jmsBinding, monitor); } else { Object extension = extensionProcessor.read(reader, context); if (extension != null) { if (extension instanceof WireFormat) { if (jmsBinding.getResponseWireFormat() == null) { jmsBinding.setResponseWireFormat((WireFormat)extension); } else { error(context.getMonitor(), "ResponseWireformatAlreadyDefined", reader, extension.toString()); } } else { error(context.getMonitor(), "UnexpectedElement", reader, extension.toString()); } } reader.next(); } //reader.next(); break; case END_ELEMENT: QName x = reader.getName(); if (x.getLocalPart().equals("response")) { return; } else { error(context.getMonitor(), "UnexpectedResponseElement", reader, x.toString()); } } } } private void parseResourceAdapter(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException { String name = reader.getAttributeValue(null, "name"); if (name != null && name.length() > 0) { jmsBinding.setResourceAdapterName(name); } else { error(monitor, "MissingResourceAdapterName", reader); } jmsBinding.getResourceAdapterProperties().putAll(parseBindingProperties(reader, monitor)); } /** * <headers JMSType="string"? * JMSCorrelationID="string"? * JMSDeliveryMode="PERSISTENT or NON_PERSISTENT"? * timeToLive="long"? * JMSPriority="0 .. 9"?> * <property name="NMTOKEN" type="NMTOKEN"?>* * </headers>? */ private void parseHeaders(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException { String jmsType = reader.getAttributeValue(null, "type"); if (jmsType != null && jmsType.length() > 0) { jmsBinding.setJMSHeaderType(jmsType); } String jmsDeliveryMode = reader.getAttributeValue(null, "deliveryMode"); if (jmsDeliveryMode != null && jmsDeliveryMode.length() > 0) { if ("persistent".equalsIgnoreCase(jmsDeliveryMode)) { jmsBinding.setJMSHeaderDeliveryMode(true); } else if ("nonpersistent".equalsIgnoreCase(jmsDeliveryMode)) { jmsBinding.setJMSHeaderDeliveryMode(false); } else { error(monitor, "InvalidJMSDeliveryMode", jmsBinding, jmsDeliveryMode); } } String jmsTimeToLive = reader.getAttributeValue(null, "timeToLive"); if (jmsTimeToLive != null && jmsTimeToLive.length() > 0) { jmsBinding.setJMSHeaderTimeToLive(Long.parseLong(jmsTimeToLive)); } String jmsPriority = reader.getAttributeValue(null, "priority"); if (jmsPriority != null && jmsPriority.length() > 0) { try { int p = Integer.parseInt(jmsPriority); if (p >= 0 && p <= 9) { jmsBinding.setJMSHeaderPriority(p); } else { warning(monitor, "InvalidJMSPriority", jmsBinding, jmsPriority); } } catch (NumberFormatException ex) { error(monitor, "InvalidJMSPriority", jmsBinding, jmsPriority); } } while (true) { switch (reader.next()) { case START_ELEMENT: if (reader.getName().getLocalPart().equals("property")) { parseProperty(reader, jmsBinding); } break; case END_ELEMENT: QName x = reader.getName(); if (x.getLocalPart().equals("headers")) { return; } else { error(monitor, "UnexpectedResponseElement", reader, x.toString()); } } } } private void parseProperty(XMLStreamReader reader, JMSBinding jmsBinding) throws XMLStreamException { jmsBinding.setHeaders( true ); String name = reader.getAttributeValue(null, "name"); QName typeName = StAXHelper.getAttributeAsQName(reader, "type"); String type = typeName == null ? null : typeName.getLocalPart(); if (name != null && name.length() > 0) { Object value = reader.getElementText(); if ("boolean".equalsIgnoreCase(type)) { value = Boolean.parseBoolean((String)value); } else if ("byte".equalsIgnoreCase(type)) { value = Byte.parseByte(((String)value)); } else if ("short".equalsIgnoreCase(type)) { value = Short.parseShort((String)value); } else if ("int".equalsIgnoreCase(type)) { value = Integer.parseInt((String)value); } else if ("long".equalsIgnoreCase(type)) { value = Long.parseLong((String)value); } else if ("float".equalsIgnoreCase(type)) { value = Float.parseFloat((String)value); } else if ("double".equalsIgnoreCase(type)) { value = Double.parseDouble((String)value); } else if ("String".equalsIgnoreCase(type)) { // its already a string } jmsBinding.setProperty(name, value); } } /** * <operationProperties name="string" selectedOperation="string"?> * <property name="NMTOKEN" type="NMTOKEN"?>* * <headers JMSType="string"? * JMSCorrelationID="string"? * JMSDeliveryMode="PERSISTENT or NON_PERSISTENT"? * timeToLive="long"? * JMSPriority="0 .. 9"?> * <property name="NMTOKEN" type="NMTOKEN"?>* * </headers>? * </operationProperties>* */ private void parseOperationProperties(XMLStreamReader reader, JMSBinding jmsBinding, Monitor monitor) throws XMLStreamException { if (jmsBinding.getOperationPropertiesName() != null) { error(monitor, "DuplicateOperationProperties", jmsBinding); } String opName = reader.getAttributeValue(null, "name"); if (opName == null || opName.length() < 1) { error(monitor, "MissingJMSOperationPropertyName", jmsBinding); return; } // Since nativeOpName, headers, and property elements are optional, must add opName. jmsBinding.addOperationName(opName); String nativeOpName = reader.getAttributeValue(null, "selectedOperation"); // optional if (nativeOpName != null && nativeOpName.length() > 0) { jmsBinding.setNativeOperationName(opName, nativeOpName); } Map<String, BindingProperty> props = new HashMap<String, BindingProperty>(); while (true) { switch (reader.next()) { case START_ELEMENT: if (reader.getName().getLocalPart().equals("headers")) { // optional parseOperationHeaders(reader, jmsBinding, opName, monitor); } else if (reader.getName().getLocalPart().equals("property")) { // optional processProperty(reader, props, monitor); } break; case END_ELEMENT: if (reader.isEndElement()) { QName x = reader.getName(); if (x.getLocalPart().equals("headers")) { break; } if (x.getLocalPart().equals("property")) { break; } if (x.getLocalPart().equals("operationProperties")) { jmsBinding.getOperationPropertiesProperties(opName).putAll(props); return; } else { error(monitor, "UnexpectedResponseElement", reader, x.toString()); } } } } } private void parseOperationHeaders(XMLStreamReader reader, JMSBinding jmsBinding, String opName, Monitor monitor) throws XMLStreamException { String jmsType = reader.getAttributeValue(null, "type"); if (jmsType != null && jmsType.length() > 0) { jmsBinding.setOperationJMSType(opName, jmsType); } String jmsDeliveryMode = reader.getAttributeValue(null, "deliveryMode"); if (jmsDeliveryMode != null && jmsDeliveryMode.length() > 0) { if ("persistent".equalsIgnoreCase(jmsDeliveryMode)) { jmsBinding.setOperationJMSDeliveryMode(opName, true); } else if ("nonpersistent".equalsIgnoreCase(jmsDeliveryMode)) { jmsBinding.setOperationJMSDeliveryMode(opName, false); } else { error(monitor, "InvalidOPJMSDeliveryMode", jmsBinding, jmsDeliveryMode); } } String jmsTimeToLive = reader.getAttributeValue(null, "timeToLive"); if (jmsTimeToLive != null && jmsTimeToLive.length() > 0) { jmsBinding.setOperationJMSTimeToLive(opName, Long.parseLong(jmsTimeToLive)); } String jmsPriority = reader.getAttributeValue(null, "priority"); if (jmsPriority != null && jmsPriority.length() > 0) { try { int p = Integer.parseInt(jmsPriority); if (p >= 0 && p <= 9) { jmsBinding.setOperationJMSPriority(opName, p); } else { warning(monitor, "InvalidOPJMSPriority", jmsBinding, jmsPriority); } } catch (NumberFormatException ex) { error(monitor, "InvalidOPJMSPriority", jmsBinding, jmsPriority); } } while (true) { switch (reader.next()) { case START_ELEMENT: if (reader.getName().getLocalPart().equals("property")) { parseOperationPropertyProperties(reader, jmsBinding, opName); } break; case END_ELEMENT: QName x = reader.getName(); if (x.getLocalPart().equals("headers")) { return; } else { error(monitor, "UnexpectedResponseElement", reader, x.toString()); } } } } private void parseOperationPropertyProperties(XMLStreamReader reader, JMSBinding jmsBinding, String opName) throws XMLStreamException { String propName = reader.getAttributeValue(null, "name"); QName typeName = StAXHelper.getAttributeAsQName(reader, "type"); String type = typeName == null ? null : typeName.getLocalPart(); if (propName != null && propName.length() > 0) { Object value = reader.getElementText(); if ("boolean".equalsIgnoreCase(type)) { value = Boolean.parseBoolean((String)value); } else if ("byte".equalsIgnoreCase(type)) { value = Byte.parseByte(((String)value)); } else if ("short".equalsIgnoreCase(type)) { value = Short.parseShort((String)value); } else if ("int".equalsIgnoreCase(type)) { value = Integer.parseInt((String)value); } else if ("long".equalsIgnoreCase(type)) { value = Long.parseLong((String)value); } else if ("float".equalsIgnoreCase(type)) { value = Float.parseFloat((String)value); } else if ("double".equalsIgnoreCase(type)) { value = Double.parseDouble((String)value); } else if ("String".equalsIgnoreCase(type)) { // its already a string } jmsBinding.setOperationProperty(opName, propName, value); } } private void parseSubscriptionHeaders(XMLStreamReader reader, JMSBinding jmsBinding) throws XMLStreamException { String jmsSelector = reader.getAttributeValue(null, "selector"); if (jmsSelector != null && jmsSelector.length() > 0 && jmsBinding.getJMSSelector() == null) { jmsBinding.setJMSSelector(jmsSelector); } // Skip to end element while (reader.hasNext()) { if (reader.next() == END_ELEMENT && "messageSelection".equals(reader.getName().getLocalPart())) { break; } } // end while } private Map<String, BindingProperty> parseBindingProperties(XMLStreamReader reader, Monitor monitor) throws XMLStreamException { Map<String, BindingProperty> props = new HashMap<String, BindingProperty>(); String parentName = reader.getName().getLocalPart(); // Parse for all the properties within this element, until the end of // the element is reached. boolean completed = false; while (!completed) { switch (reader.next()) { case START_ELEMENT: String elementName = reader.getName().getLocalPart(); if ("property".equals(elementName)) { processProperty(reader, props, monitor); } break; case END_ELEMENT: String endName = reader.getName().getLocalPart(); if (parentName.equals(endName)) { completed = true; break; } } } return props; } private void processProperty(XMLStreamReader reader, Map<String, BindingProperty> props, Monitor monitor) throws XMLStreamException { String name = reader.getAttributeValue(null, "name"); if (name == null || name.length() < 1) { error(monitor, "InvalidPropertyElement", reader); } String type = reader.getAttributeValue(null, "type"); String value = reader.getElementText(); props.put(name, new BindingProperty(name, type, value)); } /** * 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() { validate( null, 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, Monitor monitor ) { // 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(monitor, "DestinationQueueContradiction", jmsBinding, connectionFactoryName ); } } if (JMSBindingConstants.DESTINATION_TYPE_TOPIC == jmsBinding.getDestinationType()) { if ( connectionFactoryName.contains( "queue" )) { error(monitor, "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(monitor, "ConnectionFactoryActivationSpecContradiction", jmsBinding, connectionFactoryName, activationSpecName ); } } // If URI is specified, destination should not be present if ( ( jmsBinding.getJMSURI() != null ) && ( jmsBinding.getJMSURI().length() > 0) && (jmsBinding.isDestinationSpecified())) { error(monitor, "DestinationURIContradiction", jmsBinding, jmsBinding.getJMSURI(), jmsBinding.getDestinationName()); } // If activation spec and destination are both specified, they have to match if ( ( jmsBinding.getActivationSpecName() != null ) && (jmsBinding.getActivationSpecName().length() > 0 ) && (jmsBinding.getDestinationName() != null) && (jmsBinding.getDestinationName().length() > 0 ) ) { if ( !jmsBinding.getActivationSpecName().equals(jmsBinding.getDestinationName())) { error(monitor, "ActivationSpecAndDestinationMismatch", jmsBinding, jmsBinding.getActivationSpecName(), jmsBinding.getDestinationName()); } } if ( ( jmsBinding.getResponseActivationSpecName() != null ) && (jmsBinding.getResponseActivationSpecName().length() > 0 ) && (jmsBinding.getResponseDestinationName() != null ) && (jmsBinding.getResponseDestinationName().length() > 0 ) ) { if ( !jmsBinding.getResponseActivationSpecName().equals(jmsBinding.getResponseDestinationName())) { error(monitor, "ActivationSpecAndDestinationMismatch", jmsBinding, jmsBinding.getResponseActivationSpecName(), jmsBinding.getResponseDestinationName()); } } // If activation spec exists with create=always, a jndiName must be specified if (JMSBindingConstants.CREATE_ALWAYS.equals(jmsBinding.getActivationSpecCreate()) && (jmsBinding.getActivationSpecName() == null)) { error(monitor, "ActivationSpecNameRequiredForCreateAlways", jmsBinding); } // If Connection factory specified then destination name must also be if (( connectionFactoryName != null ) && ( connectionFactoryName.length() > 0 )) { String destinationName = jmsBinding.getDestinationName(); if ((destinationName == null) || (destinationName.length() < 1 )) { error(monitor, "ConnectionFactoryDestinationContradiction", jmsBinding, connectionFactoryName); } } // 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. QName responseConnectionName = jmsBinding.getResponseConnectionName(); if (( responseConnectionName != null ) && ( responseConnectionName.getLocalPart().length() > 0 )) { String responseDestinationName = jmsBinding.getResponseDestinationName(); if (( responseDestinationName != null ) && (responseDestinationName.length() > 0)) { error(monitor, "ResponseAttrElement", jmsBinding, responseConnectionName, responseDestinationName ); } } // [BJM30029] The value of the operationProperties/@selectedOperation attribute MUST be unique across the containing binding.jms element Set<String> ops = new HashSet<String>(jmsBinding.getNativeOperationNames().values()); if (ops.size() != jmsBinding.getNativeOperationNames().values().size()) { error(monitor, "BJM30029", jmsBinding); } // Other jmsBinding model validation may be added here. } /** * Given a valid JMSBinding, write it as XML using the given XML writer. * * This high-level method handles binding.jms element and its attributes. * Sub elements have their own writer methods and are called from here. * <binding.jms * correlationScheme="string"? * initialContextFactory="xs:anyURI"? * jndiURL="xs:anyURI"? * requestConnection="QName"? * responseConnection="QName"? * operationProperties="QName"? * ...> * @param writer an XMLStreamWriter that writes XML attributes and elements * @param jmsBinding JMSBinding model */ public void write(JMSBinding jmsBinding, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException, XMLStreamException { // Write a <binding.jms> writeStart(writer, Constants.SCA11_NS, JMSBindingConstants.BINDING_JMS, new XAttr("requestConnection", jmsBinding.getRequestConnectionName()), new XAttr("responseConnection", jmsBinding.getResponseConnectionName()), new XAttr("operationProperties", jmsBinding.getOperationPropertiesName())); if (jmsBinding.getName() != null) { writer.writeAttribute("name", jmsBinding.getName()); } if (jmsBinding.getJMSURI() != null) { writer.writeAttribute("uri", jmsBinding.getJMSURI()); writeEnd(writer); return; } //String dest = jmsBinding.getDestinationName(); //if (dest != null) { // if ( dest != null ) { // writer.writeAttribute("uri", "jms:" + jmsBinding.getDestinationName()); // } //} String correlationScheme = jmsBinding.getCorrelationScheme(); if ( correlationScheme != null ) { if ( !correlationScheme.equals(JMSBindingConstants.CORRELATE_MSG_ID) ) { writer.writeAttribute("correlationScheme", jmsBinding.getCorrelationScheme()); } } if ( jmsBinding.getInitialContextFactoryName() != null ) { writer.writeAttribute("initialContextFactory", jmsBinding.getInitialContextFactoryName()); } if ( jmsBinding.getJndiURL() != null ) { writer.writeAttribute("jndiURL", jmsBinding.getJndiURL()); } if ( jmsBinding.containsHeaders() ) { writeHeaders( jmsBinding, writer); } writeOperationProperties( jmsBinding, writer ); writeSubscriptionHeaders( jmsBinding, writer ); writeDestinationProperties( jmsBinding, writer ); writeConnectionFactoryProperties( jmsBinding, writer ); writeActivationSpecProperties( jmsBinding, writer ); // Write response info, if names are not defaults. String responseDestName = jmsBinding.getResponseDestinationName(); String responseCFName = jmsBinding.getResponseConnectionFactoryName(); String responseASName = jmsBinding.getResponseActivationSpecName(); if ( responseDestName != null || responseCFName != null || responseASName != null ) { writer.writeStartElement(Constants.SCA11_NS, "response"); writeResponseDestinationProperties( jmsBinding, writer ); writeResponseConnectionFactoryProperties( jmsBinding, writer ); writeResponseActivationSpecProperties( jmsBinding, writer ); if ((jmsBinding.getResponseWireFormat() != null) && !(jmsBinding.getResponseWireFormat() instanceof WireFormatJMSDefault)){ writeWireFormat(jmsBinding.getResponseWireFormat(), writer, context); } writer.writeEndElement(); // Strange bug. Without white space, headers end tag improperly read. writer.writeCharacters( " " ); } writeResourceAdapterProperties( jmsBinding, writer ); writeConfiguredOperations( jmsBinding, writer, context ); if ((jmsBinding.getRequestWireFormat() != null) && !(jmsBinding.getRequestWireFormat() instanceof WireFormatJMSDefault)){ writeWireFormat(jmsBinding.getRequestWireFormat(), writer, context); } if ((jmsBinding.getOperationSelector() != null) && !(jmsBinding.getOperationSelector() instanceof OperationSelectorJMSDefault)){ writeOperationSelector(jmsBinding.getOperationSelector(), writer, context); } writeEnd(writer); } /** * Writes headers element and its attributes. * <headers JMSType="string"? * JMSCorrelationID="string"? * JMSDeliveryMode="PERSISTENT or NON_PERSISTENT"? * timeToLive="long"? * JMSPriority="0 .. 9"?> * <property name="NMTOKEN" type="NMTOKEN"?>* * </headers>? */ private void writeHeaders( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException { writer.writeStartElement(Constants.SCA11_NS, JMSBindingConstants.HEADERS); String jmsType = jmsBinding.getJMSHeaderType(); if (jmsType != null && jmsType.length() > 0) { writer.writeAttribute("type", jmsType); } Boolean jmsDeliveryMode = jmsBinding.isHeaderDeliveryModePersistent(); if (jmsDeliveryMode != null) { if ( jmsDeliveryMode.booleanValue() ) writer.writeAttribute("deliveryMode", "persistent"); else writer.writeAttribute("deliveryMode", "nonpersistent"); } Long jmsTimeToLive = jmsBinding.getJMSHeaderTimeToLive(); if (jmsTimeToLive != null) { writer.writeAttribute("timeToLive", jmsTimeToLive.toString()); } Integer jmsPriority = jmsBinding.getJMSHeaderPriority(); if (jmsPriority != null) { writer.writeAttribute("priority", jmsPriority.toString()); } Map<String, Object> properties = jmsBinding.getProperties(); writeProperties( properties, writer ); //writer.writeCharacters( " " ); writer.writeEndElement(); // Strange bug. Without white space, headers end tag improperly read. writer.writeCharacters( " " ); } /** * Writes a complete set of properties to the given XML stream writer. * If the value is of type string, the property will be output: * <property name="key">StringValue</property> * If the value is of type box (e.g.Integer, Long) or BindingProperty, the output will be * <property name="key" type="int">42</property> */ @SuppressWarnings("unchecked") private void writeProperties(Map<String, Object> properties, XMLStreamWriter writer) throws XMLStreamException { if (( properties == null ) || ( properties.size() == 0 )) { return; } // For both the keys and values of a map for (Iterator it=properties.entrySet().iterator(); it.hasNext(); ) { Map.Entry entry = (Map.Entry)it.next(); Object key = entry.getKey(); Object value = entry.getValue(); writer.writeStartElement(Constants.SCA11_NS, "property" ); writer.writeAttribute("name", key.toString()); if ( value instanceof String) { writer.writeCharacters( value.toString() ); } else if ( value instanceof BindingProperty ) { BindingProperty property = (BindingProperty) value; String type = property.getType(); if ( type != null ) { writer.writeAttribute("type", type); } writer.writeCharacters( property.getValue().toString() ); } else if ( value instanceof Boolean ) { writer.writeAttribute("type", "boolean"); writer.writeCharacters( value.toString() ); } else if ( value instanceof Byte ) { writer.writeAttribute("type", "byte"); writer.writeCharacters( value.toString() ); } else if ( value instanceof Short ) { writer.writeAttribute("type", "short"); writer.writeCharacters( value.toString() ); } else if ( value instanceof Integer ) { writer.writeAttribute("type", "int"); writer.writeCharacters( value.toString() ); } else if ( value instanceof Long ) { writer.writeAttribute("type", "long"); writer.writeCharacters( value.toString() ); } else if ( value instanceof Float ) { writer.writeAttribute("type", "float"); writer.writeCharacters( value.toString() ); } else if ( value instanceof Double ) { writer.writeAttribute("type", "double"); writer.writeCharacters( value.toString() ); } else { writer.writeCharacters( value.toString() ); } writer.writeEndElement(); } } /** * Writes operation properties if there are any. * * <operationProperties name="string" selectedOperation="string"?> * <property name="NMTOKEN" type="NMTOKEN">* * <headers JMSType="string"? * JMSCorrelationID="string"? * JMSDeliveryMode="string"? * timeToLive="int"? * JMSPriority="string"?> * <property name="NMTOKEN" type="NMTOKEN">* * </headers>? * </operationProperties>* * </binding.jms> */ private void writeOperationProperties( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException { if (jmsBinding.getOperationPropertiesBinding() != null) { return; } Set<String> operationNames = jmsBinding.getOperationNames(); if (operationNames == null || (operationNames.size() < 1)) { return; } for(Iterator<String> it=operationNames.iterator(); it.hasNext(); ) { String opName = it.next(); writer.writeStartElement(Constants.SCA11_NS, "operationProperties"); writer.writeAttribute("name", opName); String nativeOperation = jmsBinding.getNativeOperationName(opName); if (nativeOperation != null && nativeOperation.length() > 0) { if ( !nativeOperation.equals( opName )) { writer.writeAttribute("selectedOperation", nativeOperation); } } Map<String, BindingProperty> operationPropertiesProperties = jmsBinding.getOperationPropertiesProperties(opName); writeBindingProperties( operationPropertiesProperties, writer ); String jmsType = jmsBinding.getOperationJMSType(opName); String jmsCorrelationId = jmsBinding.getOperationJMSCorrelationId(opName); Boolean jmsDeliveryMode = jmsBinding.getOperationJMSDeliveryMode(opName); Long jmsTimeToLive = jmsBinding.getOperationJMSTimeToLive(opName); Integer jmsPriority = jmsBinding.getOperationJMSPriority(opName); Map<String, Object> operationProperties = jmsBinding.getOperationProperties(opName); if (operationProperties != null){ if ((jmsType != null && jmsType.length() > 0) || (jmsCorrelationId != null && jmsCorrelationId.length() > 0) || jmsDeliveryMode != null || jmsTimeToLive != null || jmsPriority != null) { writer.writeStartElement(Constants.SCA11_NS, JMSBindingConstants.HEADERS); if (jmsType != null && jmsType.length() > 0) { writer.writeAttribute("type", jmsType); } if (jmsDeliveryMode != null) { if (jmsDeliveryMode.booleanValue()) writer.writeAttribute("deliveryMode", "persistent"); else writer.writeAttribute("deliveryMode", "nonpersistent"); } if (jmsTimeToLive != null) { writer.writeAttribute("timeToLive", jmsTimeToLive.toString()); } if (jmsPriority != null) { writer.writeAttribute("priority", jmsPriority.toString()); } writeProperties( operationProperties, writer ); writer.writeEndElement(); // Strange bug. Without white space, headers end tag improperly read. // writer.writeCharacters( " " ); } } writer.writeEndElement(); // Strange bug. Without white space, headers end tag improperly read. writer.writeCharacters(" "); } } /** * Writes a complete set of properties to the given XML stream writer. * If the value is of type string, the property will be output: * <property name="key">StringValue</property> * If the value is of type box (e.g.Integer, Long) or BindingProperty, the output will be * <property name="key" type="int">42</property> */ @SuppressWarnings("unchecked") private void writeBindingProperties(Map<String, BindingProperty> properties, XMLStreamWriter writer) throws XMLStreamException { if (( properties == null ) || ( properties.size() == 0 )) { return; } // For both the keys and values of a map for (Iterator it=properties.entrySet().iterator(); it.hasNext(); ) { Map.Entry entry = (Map.Entry)it.next(); Object key = entry.getKey(); Object value = entry.getValue(); writer.writeStartElement(Constants.SCA11_NS, "property" ); if (key != null){ writer.writeAttribute("name", key.toString()); } if ( value instanceof String) { writer.writeCharacters( value.toString() ); } else if ( value instanceof BindingProperty ) { BindingProperty property = (BindingProperty) value; String type = property.getType(); if ( type != null ) { writer.writeAttribute("type", type); } writer.writeCharacters( property.getValue().toString() ); } else { writer.writeCharacters( value.toString() ); } writer.writeEndElement(); } } /** * Writes subscription headers if there are any. * <complexType name="messageSelection"> * <attribute name="selector" type="string"/> * </complexType> * */ private void writeSubscriptionHeaders( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException { String jmsSubscriptionHeaders = jmsBinding.getJMSSelector(); if (jmsSubscriptionHeaders != null && jmsSubscriptionHeaders.length() > 0) { writer.writeStartElement(Constants.SCA11_NS, "messageSelection"); writer.writeAttribute("selector", jmsSubscriptionHeaders); writer.writeEndElement(); // Strange bug. Without white space, headers end tag improperly read. // writer.writeCharacters( " " ); } } /** * Writes destination properties if there are any. * <destination jndiName="xs:anyURI" type="string"? create="string"?> * <property name="NMTOKEN" type="NMTOKEN">* * </destination>? */ private void writeDestinationProperties( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException { String destinationName = jmsBinding.getDestinationName(); if (destinationName == null || (destinationName.length() < 1)) { return; } if (destinationName == null) { return; } writer.writeStartElement(Constants.SCA11_NS, "destination"); if ( destinationName != null && destinationName.length() > 0) { writer.writeAttribute("jndiName", destinationName); } // Type not handled yet // String destinationType = jmsBinding.getDestinationType(); // if ( destinationType != null && destinationType.length() > 0) { // writer.writeAttribute("type", destinationType); // } String destinationCreate = jmsBinding.getDestinationCreate(); if ( destinationCreate != null && destinationCreate.length() > 0 && !destinationCreate.equals(JMSBindingConstants.CREATE_IF_NOT_EXIST)) { writer.writeAttribute("create", destinationCreate); } Map<String, BindingProperty> destinationProperties = jmsBinding.getDestinationProperties(); writeBindingProperties( destinationProperties, writer ); writer.writeEndElement(); // Strange bug. Without white space, headers end tag improperly read. writer.writeCharacters(" "); } /** * Writes connection factory properties if there are any. * <connectionFactory jndiName="xs:anyURI" create="string"?> * <property name="NMTOKEN" type="NMTOKEN">* * </connectionFactory>? */ private void writeConnectionFactoryProperties( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException { String cfName = jmsBinding.getConnectionFactoryName(); if (cfName == null || (cfName.length() < 1)) { return; } writer.writeStartElement(Constants.SCA11_NS, "connectionFactory"); if ( cfName != null && cfName.length() > 0) { writer.writeAttribute("jndiName", cfName); } String destinationCreate = jmsBinding.getConnectionFactoryCreate(); if ( destinationCreate != null && destinationCreate.length() > 0 && !destinationCreate.equals(JMSBindingConstants.CREATE_IF_NOT_EXIST)) { writer.writeAttribute("create", destinationCreate); } Map<String, BindingProperty> cfProperties = jmsBinding.getConnectionFactoryProperties(); writeBindingProperties( cfProperties, writer ); writer.writeEndElement(); // Strange bug. Without white space, headers end tag improperly read. writer.writeCharacters(" "); } /** * Writes activation Spec properties if there are any. * <activationSpec name="xs:anyURI" create="string"?> * <property name="NMTOKEN" type="NMTOKEN">* * </activationSpec>? * */ private void writeActivationSpecProperties( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException { String asName = jmsBinding.getActivationSpecName(); if (asName == null || (asName.length() < 1)) { return; } writer.writeStartElement(Constants.SCA11_NS, "activationSpec"); if ( asName != null && asName.length() > 0) { writer.writeAttribute("name", asName); } String destinationCreate = jmsBinding.getActivationSpecCreate(); if ( destinationCreate != null && destinationCreate.length() > 0) { writer.writeAttribute("create", destinationCreate); } Map<String, BindingProperty> cfProperties = jmsBinding.getActivationSpecProperties(); writeBindingProperties( cfProperties, writer ); writer.writeEndElement(); // Strange bug. Without white space, headers end tag improperly read. writer.writeCharacters(" "); } /** * Writes response destination properties if there are any. * <destination jndiName="xs:anyURI" type="string"? create="string"?> * <property name="NMTOKEN" type="NMTOKEN">* * </destination>? */ private void writeResponseDestinationProperties( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException { String destinationName = jmsBinding.getResponseDestinationName(); if (destinationName == null || (destinationName.length() < 1)) { return; } if (destinationName == null) { return; } writer.writeStartElement(Constants.SCA11_NS, "destination"); if ( destinationName != null && destinationName.length() > 0) { writer.writeAttribute("jndiName", destinationName); } // Type not handled yet // String destinationType = jmsBinding.getDestinationType(); // if ( destinationType != null && destinationType.length() > 0) { // writer.writeAttribute("type", destinationType); // } String destinationCreate = jmsBinding.getResponseDestinationCreate(); if ( destinationCreate != null && destinationCreate.length() > 0) { writer.writeAttribute("create", destinationCreate); } Map<String, BindingProperty> destinationProperties = jmsBinding.getResponseDestinationProperties(); writeBindingProperties( destinationProperties, writer ); writer.writeEndElement(); // Strange bug. Without white space, headers end tag improperly read. writer.writeCharacters(" "); } /** * Writes response connection factory properties if there are any. * <connectionFactory jndiName="xs:anyURI" create="string"?> * <property name="NMTOKEN" type="NMTOKEN">* * </connectionFactory>? * */ private void writeResponseConnectionFactoryProperties( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException { String cfName = jmsBinding.getResponseConnectionFactoryName(); if (cfName == null || (cfName.length() < 1)) { return; } writer.writeStartElement(Constants.SCA11_NS, "connectionFactory"); if ( cfName != null && cfName.length() > 0) { writer.writeAttribute("jndiName", cfName); } String destinationCreate = jmsBinding.getResponseConnectionFactoryCreate(); if ( destinationCreate != null && destinationCreate.length() > 0) { writer.writeAttribute("create", destinationCreate); } Map<String, BindingProperty> cfProperties = jmsBinding.getResponseConnectionFactoryProperties(); writeBindingProperties( cfProperties, writer ); writer.writeEndElement(); // Strange bug. Without white space, headers end tag improperly read. writer.writeCharacters(" "); } /** * Writes response activation Spec properties if there are any. * <activationSpec name="xs:anyURI" create="string"?> * <property name="NMTOKEN" type="NMTOKEN">* * </activationSpec>? * */ private void writeResponseActivationSpecProperties( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException { String asName = jmsBinding.getResponseActivationSpecName(); if (asName == null || (asName.length() < 1)) { return; } writer.writeStartElement(Constants.SCA11_NS, "activationSpec"); if ( asName != null && asName.length() > 0) { writer.writeAttribute("name", asName); } String destinationCreate = jmsBinding.getResponseActivationSpecCreate(); if ( destinationCreate != null && destinationCreate.length() > 0) { writer.writeAttribute("create", destinationCreate); } Map<String, BindingProperty> cfProperties = jmsBinding.getResponseActivationSpecProperties(); writeBindingProperties( cfProperties, writer ); writer.writeEndElement(); // Strange bug. Without white space, headers end tag improperly read. writer.writeCharacters(" "); } /** * Writes resource adapter properties if there are any. * <resourceAdapter name="NMTOKEN">? * <property name="NMTOKEN" type="NMTOKEN">* * </resourceAdapter>? */ private void writeResourceAdapterProperties( JMSBinding jmsBinding, XMLStreamWriter writer) throws XMLStreamException { String asName = jmsBinding.getResourceAdapterName(); if (asName == null || (asName.length() < 1)) { return; } writer.writeStartElement(Constants.SCA11_NS, "resourceAdapter"); if ( asName != null && asName.length() > 0) { writer.writeAttribute("name", asName); } Map<String, BindingProperty> cfProperties = jmsBinding.getResourceAdapterProperties(); writeBindingProperties( cfProperties, writer ); writer.writeEndElement(); // Strange bug. Without white space, headers end tag improperly read. writer.writeCharacters(" "); } /** * Writes configured operations if there are any. * <binding.jms uri=\"jms:testQueue\" >" * <operationProperties name=\"op1\">" * </operationProperties >" * <operation name=\"op1\" requires=\"IntentOne IntentTwo\"/>" * </binding.jms>" */ private void writeConfiguredOperations( JMSBinding jmsBinding, XMLStreamWriter writer, ProcessorContext context) throws XMLStreamException, ContributionWriteException { List<ConfiguredOperation> configOps = jmsBinding.getConfiguredOperations(); if (configOps == null || (configOps.size() < 1)) { return; } for( Iterator<ConfiguredOperation> it = configOps.iterator(); it.hasNext();) { configuredOperationProcessor.write(it.next(), writer, context); } // Strange bug. Without white space, headers end tag improperly read. writer.writeCharacters(" "); } /** * Wire out a request or response wire format element. Uses extension processors * to do this as wire format is an extension point * * @param wireFormat * @param writer */ private void writeWireFormat(WireFormat wireFormat, XMLStreamWriter writer, ProcessorContext context ) throws XMLStreamException, ContributionWriteException { extensionProcessor.write(wireFormat, writer, context); } /** * Wire out an operation selector element. Uses extension processors * to do this as operation selector is an extension point * * @param operationSeletor * @param writer */ private void writeOperationSelector(OperationSelector operationSeletor, XMLStreamWriter writer, ProcessorContext context ) throws XMLStreamException, ContributionWriteException{ extensionProcessor.write(operationSeletor, writer, context); } }