Package org.springframework.integration.xquery.core

Source Code of org.springframework.integration.xquery.core.AbstractXQueryExecutorTests

/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed 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.springframework.integration.xquery.core;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.xquery.XQDataSource;
import javax.xml.xquery.XQResultSequence;

import org.junit.Assert;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.integration.Message;
import org.springframework.integration.MessagingException;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.xquery.support.AbstractXQueryResultMapper;
import org.springframework.integration.xquery.support.BooleanResultMapper;
import org.springframework.integration.xquery.support.NodeResultMapper;
import org.springframework.integration.xquery.support.NumberResultMapper;
import org.springframework.integration.xquery.support.StringResultMapper;
import org.springframework.integration.xquery.support.XQueryParameter;
import org.springframework.integration.xquery.support.XQueryResultMapper;
import org.w3c.dom.Node;

/**
* The base test class for the XQueryExecutor tests
*
* @author Amol Nayak
*
* @since 1.0
*
*/
public abstract class AbstractXQueryExecutorTests {


  private final static String EXT_VARIABLE_XQUERY =
    "declare variable $name as xs:string external;" +
    "declare variable $class as xs:int external;" +
    " for   $student in /mappings/students/student," +
    "    $subject in /mappings/subjects/subject " +
    "where  $student/@id = $subject/students/studentId " +
    "and  $student/name = $name " +
    "and  $student/class = $class " +
    "return $subject/name/text()";

  private final String xmlString = "<person active=\"true\">" +
                      "<name>Mike</name>" +
                      "<age>29</age>" +
                    "</person>";


  /**
   * Test if default created result mappers are appropriately instantiated
   */
  @Test
  public void initializeDefaultMappers() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("'Hello World'");
    executor.afterPropertiesSet();
    @SuppressWarnings("rawtypes")
    Map executorMap = TestUtils.getPropertyValue(executor, "resultMappers", Map.class);
    Assert.assertNotNull(executorMap);
    Assert.assertEquals(4, executorMap.size());
    Assert.assertEquals(StringResultMapper.class, executorMap.get(String.class).getClass());
    Assert.assertEquals(BooleanResultMapper.class, executorMap.get(Boolean.class).getClass());
    Assert.assertEquals(NumberResultMapper.class, executorMap.get(Number.class).getClass());
    Assert.assertEquals(NodeResultMapper.class, executorMap.get(Node.class).getClass());
  }

  /**
   * Tests of the registered mappers take priority over the defaults
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
  @Test
  public void registerCustomMappers() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("'Hello'");
    Map map = new HashMap();
    map.put(MyCustomClass.class, new XQueryResultMapper<MyCustomClass>() {
      public List<MyCustomClass> mapResults(XQResultSequence result) {
        // TODO Auto-generated method stub
        return null;
      }
    });
    map.put(Node.class, new CustomNodeMapper());
    executor.setResultMappers(map);
    executor.afterPropertiesSet();
    Map executorMap = TestUtils.getPropertyValue(executor, "resultMappers", Map.class);
    Assert.assertNotNull(executorMap);
    Assert.assertEquals(5, executorMap.size());
    Assert.assertEquals(StringResultMapper.class, executorMap.get(String.class).getClass());
    Assert.assertEquals(BooleanResultMapper.class, executorMap.get(Boolean.class).getClass());
    Assert.assertEquals(NumberResultMapper.class, executorMap.get(Number.class).getClass());
    Assert.assertEquals(CustomNodeMapper.class, executorMap.get(Node.class).getClass());
  }


  /**
   * Tries to execute the result passing an unmapped class
   */
  @Test
  public void executeForUnknownClassType() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("'Hello World'");
    executor.afterPropertiesSet();
    try {
      executor.execute(MessageBuilder.withPayload("").build(), MyCustomClass.class);
    } catch (IllegalArgumentException e) {
      Assert.assertEquals("No Result mapper found for the type org.springframework.integration.xquery.core.AbstractXQueryExecutorTests$MyCustomClass",
          e.getMessage());
    }
  }

  /**
   * @return
   */
  protected abstract XQueryExecutor getExecutor();

  /**
   * Test with null message
   */
  @Test
  public void withNullMessage() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("'Hello World'");
    executor.afterPropertiesSet();
    try {
      executor.execute(null, String.class);
    } catch (IllegalArgumentException e) {
      Assert.assertEquals("Non null message expected", e.getMessage());
    }

  }

  @Test
  public void executeWithStringForNonLeaf() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery(".//person");
    executor.afterPropertiesSet();
    List<String> names = executor.executeForString(MessageBuilder.withPayload(xmlString).build());
    Assert.assertNotNull(names);
    Assert.assertEquals(1, names.size());
  }


  @Test
  public void executeWithBooleanForNonLeaf() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("//person");
    executor.afterPropertiesSet();
    List<Boolean> names = executor.executeForBoolean(MessageBuilder.withPayload(xmlString).build());
    Assert.assertNotNull(names);
    Assert.assertEquals(1, names.size());
    Assert.assertTrue(names.contains(Boolean.FALSE));
  }


  @Test
  public void executeWithNumberForNonLeaf() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("//person");
    executor.afterPropertiesSet();
    @SuppressWarnings("unused")
    List<Number> names;
    try {
      names = executor.executeForNumber(MessageBuilder.withPayload(xmlString).build());
    } catch (MessagingException e) {
      Assert.assertEquals(NumberFormatException.class,e.getCause().getClass());
    }
  }


  /**
   * Test case to execute the XQuery and return a {@link List} of {@link String}
   */
  @Test
  public void executeWithString() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery(".//person/name/text()");
    executor.afterPropertiesSet();
    List<String> names = executor.executeForString(MessageBuilder.withPayload(xmlString).build());
    Assert.assertNotNull(names);
    Assert.assertEquals(1, names.size());
    Assert.assertTrue(names.contains("Mike"));
  }


  /**
   * Test case to execute the XQuery and return a {@link List} of {@link Boolean}
   */
  @Test
  public void executeWithBoolean() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("//person/@active");
    executor.afterPropertiesSet();
    List<Boolean> names = executor.executeForBoolean(MessageBuilder.withPayload(xmlString).build());
    Assert.assertNotNull(names);
    Assert.assertEquals(1, names.size());
    Assert.assertTrue(names.contains(Boolean.TRUE));
  }


  /**
   * Test case to execute the XQuery and return a {@link List} of {@link Number}
   */
  @Test
  public void executeWithNumber() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("//person/age/text()");
    executor.afterPropertiesSet();
    List<Number> names = executor.executeForNumber(MessageBuilder.withPayload(xmlString).build());
    Assert.assertNotNull(names);
    Assert.assertEquals(1, names.size());
    Assert.assertTrue(names.contains(Long.valueOf(29)));
  }


  /**
   * Test case to execute the XQuery and return a {@link List} of {@link Node}
   */
  @Test
  public void executeWithNode() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("//person");
    executor.afterPropertiesSet();
    List<Node> names = executor.executeForNode(MessageBuilder.withPayload(xmlString).build());
    Assert.assertNotNull(names);
    Assert.assertEquals(1, names.size());
    Assert.assertEquals("person",names.get(0).getLocalName());
  }


  /**
   * Test with null message
   */
  @Test
  public void withNullType() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("'Hello World'");
    executor.afterPropertiesSet();
    try {
      executor.execute(MessageBuilder.withPayload("").build(),(Class<?>) null);
    } catch (IllegalArgumentException e) {
      Assert.assertEquals("Non null type expected", e.getMessage());
    }

  }


  /**
   * Executes the case where the router has no parameters but the query expects parameters
   */
  @Test
  public void noParametersProvided() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery(EXT_VARIABLE_XQUERY);
    try {
      executor.afterPropertiesSet();
    } catch (MessagingException e) {
      Assert.assertEquals("Expecting 2 parameters in the xquery, but none provided to the router", e.getMessage());
    }
  }

  /**
   * Execute the case where parameters are provided, but some or all of the parameters are missing
   */
  @Test
  public void fewParametersProvided() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery(EXT_VARIABLE_XQUERY);
    executor.addXQueryParameter(new XQueryParameter("class",Integer.valueOf(3)));
    try {
      executor.afterPropertiesSet();
    } catch (MessagingException e) {
      Assert.assertEquals("Missing parameter(s) [$name]", e.getMessage());
    }
  }

  /**
   * Sets null XQuery, should get an exception
   */
  @Test
  public void setNullXQuery() {
    XQueryExecutor executor = getExecutor();
    try {
      executor.setXQuery(null);
    } catch (IllegalArgumentException e) {
      Assert.assertEquals("Provide a non null XQuery", e.getMessage());
    }
  }


  /**
   * Sets the XQuery file resource and then the xquery
   */
  @Test
  public void setResourceAndXQuery() {
    XQueryExecutor executor = getExecutor();
    Resource res = new ClassPathResource("/org/springframework/integration/xquery/XQuery.xq");
    Assert.assertTrue(res.exists());
    executor.setXQueryFileResource(res);
    try {
      executor.setXQuery("'Hello World'");
    } catch (IllegalArgumentException e) {
      Assert.assertEquals("Only one of XQuery resource file or XQuery may be specified", e.getMessage());
    }
    Assert.assertNull(TestUtils.getPropertyValue(executor, "xQuery"));
    executor.addXQueryParameter(new XQueryParameter("name", "headers['studentName']"));
    executor.addXQueryParameter(new XQueryParameter("class", Integer.valueOf(1)));
    executor.afterPropertiesSet();
    Assert.assertNotNull(TestUtils.getPropertyValue(executor, "xQuery",String.class));
  }

  /**
   * Initialize the router without setting the xquery
   */
  @Test
  public void withoutXQuery() {
    XQueryExecutor executor = getExecutor();
    try {
      executor.afterPropertiesSet();
    } catch (IllegalArgumentException e) {
      Assert.assertEquals("One of XQuery or the XQuery resource is mandatory", e.getMessage());
    }
  }

  /**
   *Sets the XQuery and then the resource
   */
  @Test
  public void setXQueryAndResource() {
    XQueryExecutor executor = getExecutor();
    Resource res = new ClassPathResource("org/springframework/integration/xquery/XQuery.xq");
    Assert.assertTrue(res.exists());
    executor.setXQuery("'Hello World'");
    try {
      executor.setXQueryFileResource(res);
    } catch (IllegalArgumentException e) {
      Assert.assertEquals("Only one of XQuery resource file or XQuery may be specified", e.getMessage());
    }
  }

  /**
   *Sets a null {@link XQDataSource} instance
   */
  @Test
  public void setNullXQataSource() {
    XQueryExecutor executor = getExecutor();
    try {
      executor.setXQDataSource(null);
    } catch (IllegalArgumentException e) {
      Assert.assertEquals("Provide a non null instance of the XQDatasource", e.getMessage());
    }
  }


  /**
   * Tests the router with valid xml payload. The values returned will be the
   * text content of the node, if the node is a text or attribute type
   */
  @Test
  public void withValidPayload() {
    withValidPayloadInternal(true);
  }

  /**
   * Tests the router with valid xml payload. The values returned will be the
   * {@link Node}, irrespective of the type of the node
   */
  @Test
  public void withValidPayload2() {
    withValidPayloadInternal(false);
  }

  /**
   *
   */
  private void withValidPayloadInternal(boolean extractNodeText) {
    File file = new File("./src/test/resources/org/springframework/integration/xquery/SubjectMapping.xml");
    Message<File> message = MessageBuilder.withPayload(file)
                  .setHeader("studentName", "Jughead")
                  .build();
    XQueryExecutor executor = getExecutor();
    executor.setXQuery(EXT_VARIABLE_XQUERY);
    executor.addXQueryParameter(new XQueryParameter("name", "headers['studentName']"));
    executor.addXQueryParameter(new XQueryParameter("class", Integer.valueOf(1)));
    executor.afterPropertiesSet();
    List<Object> subjects;
    if(extractNodeText) {
      subjects = new ArrayList<Object>(executor.executeForString(message));
    }
    else {
      subjects = new ArrayList<Object>(executor.executeForNode(message));
    }
    Assert.assertNotNull(subjects);
    Assert.assertEquals(2, subjects.size());
    if(extractNodeText) {
      Assert.assertEquals(String.class, subjects.get(0).getClass());
      Assert.assertTrue(subjects.contains("Cooking"));
      Assert.assertTrue(subjects.contains("Math"));
    }
    else {
      Assert.assertTrue(Node.class.isAssignableFrom(subjects.get(0).getClass()));
    }
  }

  /**
   * Tests with a query that will generate a numeric value and we get the result as {@link Number}
   */
  @Test
  public void withNumericExpression() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("2 + 2");
    executor.afterPropertiesSet();
    List<Number> result = executor.executeForNumber(MessageBuilder.withPayload("<test/>").build());
    Assert.assertEquals(1, result.size());
    Assert.assertTrue(result.get(0).intValue() == 4);

  }

  /**
   *Tests a query that will generate a decimal value and we get the result as a {@link Number}
   */
  @Test
  public void withDecimalExpression() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("2.0 + 2.1");
    executor.afterPropertiesSet();
    List<Number> result = executor.executeForNumber(MessageBuilder.withPayload("<test/>").build());
    Assert.assertEquals(1, result.size());
    Assert.assertTrue(result.contains(Double.valueOf(4.1)));

  }

  /**
   * Execute the XQuery that gives a boolean value and get the value as a Boolean
   */
  @Test
  public void withBooleanResult() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("1 = 1");
    executor.afterPropertiesSet();
    List<Boolean> result = executor.executeForBoolean(MessageBuilder.withPayload("<test/>").build());
    Assert.assertEquals(1, result.size());
    Assert.assertTrue(result.contains(Boolean.TRUE));
  }

  /**
   *The XQuery gives a string value and we want the result to be a string value
   */
  @Test
  public void getTextString() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("'Hello World'");
    executor.afterPropertiesSet();
    List<String> result = executor.executeForString(MessageBuilder.withPayload("<test/>").build());
    Assert.assertEquals(1, result.size());
    Assert.assertTrue(result.contains("Hello World"));
  }

  /**
   *The XQuery gives a boolean value and we want the result to be a string value
   */
  @Test
  public void getBooleanAsTextString() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("1 = 2");
    executor.afterPropertiesSet();
    List<String> result = executor.executeForString(MessageBuilder.withPayload("<test/>").build());
    Assert.assertEquals(1, result.size());
    Assert.assertTrue(result.contains("false"));
  }

  /**
   *The XQuery gives a text value in the node and we want the result to be a string value
   */
  @Test
  public void getTextNodeAsString() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("//test/text()");
    executor.afterPropertiesSet();
    List<String> result = executor.executeForString(MessageBuilder.withPayload("<test>Some Value</test>").build());
    Assert.assertEquals(1, result.size());
    Assert.assertTrue(result.contains("Some Value"));
  }

  /**
   *The XQuery gives a text value in the node and we want the result to be a Boolean
   */
  @Test
  public void getTextNodeAsBoolean() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("//test/text()");
    executor.afterPropertiesSet();
    List<Boolean> result = executor.executeForBoolean(MessageBuilder.withPayload("<test>Some Value</test>").build());
    Assert.assertEquals(1, result.size());
    Assert.assertTrue(result.contains(Boolean.FALSE));
  }

  /**
   *The XQuery gives a text value in the node and we want the result to be a Long
   */
  @Test
  public void getTextNodeAsLong() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("//number/text()");
    executor.afterPropertiesSet();
    List<Number> result = executor.executeForNumber(MessageBuilder.withPayload("<number>1</number>").build());
    Assert.assertEquals(1, result.size());
    Assert.assertTrue(result.contains(Long.valueOf(1)));
  }

  /**
   *The XQuery gives a text value in the node and we want the result to be a Long
   */
  @Test
  public void getTextNodeAsDouble() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("//number/text()");
    executor.afterPropertiesSet();
    List<Number> result = executor.executeForNumber(MessageBuilder.withPayload("<number>1.1</number>").build());
    Assert.assertEquals(1, result.size());
    Assert.assertTrue(result.contains(Double.valueOf(1.1)));
  }



  /**
   * Tests by using a String that is a non decimal number and we get the value as a {@link Number}
   */
  @Test
  public void withNonDecimalStringExpression() {
    XQueryExecutor executor = getExecutor();
    executor.setResultMappers(Collections.singletonMap(Number.class,
        (XQueryResultMapper<Number>)new NumberResultMapper()));
    executor.setXQuery("'4'");
    executor.afterPropertiesSet();
    List<Number> result = executor.executeForNumber(MessageBuilder.withPayload("<test/>").build());
    Assert.assertEquals(1, result.size());
    Assert.assertTrue(result.contains(Long.valueOf(4)));
  }

  /**
   * Tests by using a String that is a decimal number and we get the value as a {@link Number}
   */
  @Test
  public void withDecimalStringExpression() {
    XQueryExecutor executor = getExecutor();
    executor.setResultMappers(Collections.singletonMap(Number.class,
        (XQueryResultMapper<Number>)new NumberResultMapper()));
    executor.setXQuery("'4.1'");
    executor.afterPropertiesSet();
    List<Number> result = executor.executeForNumber(MessageBuilder.withPayload("<test/>").build());
    Assert.assertEquals(1, result.size());
    Assert.assertTrue(result.contains(Double.valueOf(4.1)));
  }

  /**
   * Tests by getting the Integer value and getting the result as {@link String}
   */
  @Test
  public void getIntegerAsString() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("4");
    executor.afterPropertiesSet();
    List<String> result = executor.executeForString(MessageBuilder.withPayload("<test/>").build());
    Assert.assertEquals(1, result.size());
    Assert.assertTrue(result.contains("4"));
  }



  /**
   * Uses a decimal value and gets the result as {@link String}
   */
  @Test
  public void getDecimalAsString() {
    XQueryExecutor executor = getExecutor();
    executor.setXQuery("4.1");
    executor.afterPropertiesSet();
    List<String> result = executor.executeForString(MessageBuilder.withPayload("<test/>").build());
    Assert.assertEquals(1, result.size());
    Assert.assertTrue(result.contains("4.1"));
  }

//  @Test
//  public void getCurrentDate() {
//    XQueryExecutor executor = new XQueryExecutor();
//    executor.setXQuery("current-date()");
//    executor.afterPropertiesSet();
//    executor.executeForString(MessageBuilder.withPayload("<test/>").build());
//  }


  @Test
  public void withStringExpression2() {
    XQueryExecutor executor = getExecutor();
    executor.setResultMappers(Collections.singletonMap(Number.class,
        (XQueryResultMapper<Number>)new NumberResultMapper()));
    executor.setXQuery("/person/age/text()");
    executor.afterPropertiesSet();
    List<Number> result = executor.executeForNumber(MessageBuilder.withPayload(xmlString).build());
    Assert.assertEquals(1, result.size());
    Assert.assertTrue(result.contains(Long.valueOf(29)));
  }

  @Test
  public void withFormatingFlag() {
    XQueryExecutor executor = getExecutor();
    executor.setFormatOutput(true);
    executor.setXQuery("'Hello World'");
    executor.afterPropertiesSet();
    //should not fail
    executor.executeForString(MessageBuilder.withPayload("<dummy/>").build());
    @SuppressWarnings("unchecked")
    Map<Class<Object>, XQueryResultMapper<Object>>  mappers = TestUtils.getPropertyValue(executor, "resultMappers", Map.class);
    for(Object val:mappers.values()) {
      if(val instanceof AbstractXQueryResultMapper) {
        Assert.assertEquals(true,
            TestUtils.getPropertyValue(val, "formatOutput", Boolean.class).booleanValue());
      }
    }

  }



  private class MyCustomClass {}
  private class CustomNodeMapper implements XQueryResultMapper<Node> {
    public List<Node> mapResults(XQResultSequence result) {
      return null;
    }

  }
}
TOP

Related Classes of org.springframework.integration.xquery.core.AbstractXQueryExecutorTests

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.