PageRenderTime 31ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/api/src/main/java/org/switchyard/transform/TransformSequence.java

https://github.com/lincolnthree/switchyard-core
Java | 229 lines | 102 code | 30 blank | 97 comment | 29 complexity | 78bc4bda25b484d270adf9c9c37d3496 MD5 | raw file
  1. /*
  2. * JBoss, Home of Professional Open Source
  3. * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors
  4. * as indicated by the @author tags. All rights reserved.
  5. * See the copyright.txt in the distribution for a
  6. * full listing of individual contributors.
  7. *
  8. * This copyrighted material is made available to anyone wishing to use,
  9. * modify, copy, or redistribute it subject to the terms and conditions
  10. * of the GNU Lesser General Public License, v. 2.1.
  11. * This program is distributed in the hope that it will be useful, but WITHOUT A
  12. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  13. * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
  14. * You should have received a copy of the GNU Lesser General Public License,
  15. * v.2.1 along with this distribution; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  17. * MA 02110-1301, USA.
  18. */
  19. package org.switchyard.transform;
  20. import java.io.Serializable;
  21. import java.util.ArrayList;
  22. import java.util.List;
  23. import javax.xml.namespace.QName;
  24. import org.apache.log4j.Logger;
  25. import org.switchyard.Exchange;
  26. import org.switchyard.Message;
  27. import org.switchyard.Property;
  28. import org.switchyard.Scope;
  29. /**
  30. * Transformation sequence/pipeline.
  31. * <p/>
  32. * Allows the stringing together of a sequence of transformers and then associating that
  33. * with a Message context e.g.
  34. * <pre>
  35. * TransformSequence.from("a").to("b").to("c').associateWith(messageContext);
  36. * </pre>
  37. *
  38. * @author <a href="mailto:tom.fennelly@gmail.com">tom.fennelly@gmail.com</a>
  39. */
  40. public final class TransformSequence implements Serializable {
  41. /**
  42. * Serial UID
  43. */
  44. static final long serialVersionUID = -1;
  45. /**
  46. * Logger.
  47. */
  48. private static final Logger LOGGER = Logger.getLogger(TransformSequence.class);
  49. /**
  50. * Transform Sequence.
  51. */
  52. private List<QName> _sequence = new ArrayList<QName>();
  53. /**
  54. * Create an {@link #associateWith(Exchange, Scope) unassociated} sequence.
  55. */
  56. private TransformSequence() {
  57. }
  58. /**
  59. * Associate this instance with the supplied message context.
  60. * @param exchange associate the transform to this exchange
  61. * @param scope associate the transform with this scope
  62. */
  63. public void associateWith(Exchange exchange, Scope scope) {
  64. exchange.getContext().setProperty(
  65. TransformSequence.class.getName(), this, scope);
  66. }
  67. /**
  68. * Start the transformation sequence.
  69. *
  70. * @param typeName The from type.
  71. * @return The sequence.
  72. */
  73. public static TransformSequence from(final QName typeName) {
  74. TransformSequence newSequence = new TransformSequence();
  75. newSequence.add(typeName);
  76. return newSequence;
  77. }
  78. /**
  79. * Add to the transformation sequence.
  80. *
  81. * @param typeName The from type.
  82. * @return The sequence.
  83. */
  84. public TransformSequence to(final QName typeName) {
  85. add(typeName);
  86. return this;
  87. }
  88. /**
  89. * Apply this {@link TransformSequence} to the supplied {@link Message} instance.
  90. * @param message Message instance.
  91. * @param registry Transformation Registry.
  92. */
  93. public void apply(Message message, TransformerRegistry registry) {
  94. while (_sequence.size() > 1) {
  95. QName from = _sequence.get(0);
  96. QName to = _sequence.get(1);
  97. Transformer transformer = registry.getTransformer(from, to);
  98. if (transformer == null) {
  99. break;
  100. }
  101. Object result;
  102. if (Message.class.isAssignableFrom(transformer.getFromType())) {
  103. // A returned object just indicates that the transformation took place.
  104. result = transformer.transform(message);
  105. } else {
  106. // A returned object indicates that the transformation took place and is
  107. // used as the new Message payload.
  108. result = transformer.transform(message.getContent(transformer.getFromType()));
  109. if (result != null) {
  110. message.setContent(result);
  111. }
  112. }
  113. if (result != null) {
  114. // We can now remove the 1st element in the sequence. 2nd element will become the
  115. // "from" for the next transformation in the sequence, if one is required...
  116. _sequence.remove(0);
  117. if (LOGGER.isDebugEnabled()) {
  118. LOGGER.debug("Transformed Message (" + System.identityHashCode(message) + ") from '" + transformer.getFrom() + "' to '" + transformer.getTo() + "' using transformer type '" + transformer.getClass().getName() + "'.");
  119. }
  120. } else {
  121. LOGGER.warn("Transformer '" + transformer.getClass().getName() + "' returned a null transformation result. Check input payload matches requirements of the Transformer implementation.");
  122. break;
  123. }
  124. }
  125. }
  126. /**
  127. * Get the current message type for the specified exchange.
  128. *
  129. * @param exchange The exchange.
  130. * @return The current exchange message type, or null if
  131. * no TransformSequence is set on the exchange.
  132. */
  133. public static QName getCurrentMessageType(final Exchange exchange) {
  134. TransformSequence transformSequence = get(exchange);
  135. if (transformSequence != null && !transformSequence._sequence.isEmpty()) {
  136. return transformSequence._sequence.get(0);
  137. }
  138. return null;
  139. }
  140. /**
  141. * Get the target message type for the specified exchange phase.
  142. *
  143. * @param exchange The exchange.
  144. * @return The target exchange message type, or null if
  145. * no TransformSequence is set on the exchange.
  146. */
  147. public static QName getTargetMessageType(final Exchange exchange) {
  148. TransformSequence transformSequence = get(exchange);
  149. if (transformSequence != null && !transformSequence._sequence.isEmpty()) {
  150. // Return the last entry in the sequence...
  151. return transformSequence._sequence.get(transformSequence._sequence.size() - 1);
  152. }
  153. return null;
  154. }
  155. /**
  156. * Utility assertion method for checking if the source to destination transformations
  157. * have been applied to the Exchange.
  158. *
  159. * @param exchange The exchange instance.
  160. * @return True if the transformations have been applied (or are not specified), otherwise false.
  161. */
  162. public static boolean assertTransformsApplied(final Exchange exchange) {
  163. QName fromName = getCurrentMessageType(exchange);
  164. QName toName = getTargetMessageType(exchange);
  165. if (fromName != null && toName != null && !fromName.equals(toName)) {
  166. return false;
  167. }
  168. return true;
  169. }
  170. /**
  171. * Apply the active exchange transformation sequence to the supplied
  172. * Exchange Message.
  173. *
  174. * @param exchange The Exchange instance.
  175. * @param registry The transformation registry.
  176. */
  177. public static void applySequence(final Exchange exchange, final TransformerRegistry registry) {
  178. Message message = exchange.getMessage();
  179. TransformSequence transformSequence = get(exchange);
  180. if (transformSequence == null) {
  181. return;
  182. }
  183. transformSequence.apply(message, registry);
  184. }
  185. private void add(final QName typeName) {
  186. if (typeName == null) {
  187. throw new IllegalArgumentException("null 'typeName' arg passed.");
  188. }
  189. _sequence.add(typeName);
  190. }
  191. private static TransformSequence get(final Exchange exchange) {
  192. Property sequenceProperty = exchange.getContext().getProperty(TransformSequence.class.getName(), Scope.activeScope(exchange));
  193. if (sequenceProperty != null) {
  194. return (TransformSequence)sequenceProperty.getValue();
  195. } else {
  196. return null;
  197. }
  198. }
  199. }