/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, version 2 as published by the Free Software * Foundation. * * You should have received a copy of the GNU General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * * Copyright 2006 - 2017 Pentaho Corporation. All rights reserved. */ package org.pentaho.reporting.platform.plugin; import com.google.common.collect.Lists; import org.apache.commons.collections.map.HashedMap; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.pentaho.reporting.engine.classic.core.ClassicEngineBoot; import org.pentaho.reporting.engine.classic.core.CompoundDataFactory; import org.pentaho.reporting.engine.classic.core.DataFactory; import org.pentaho.reporting.engine.classic.core.DataRow; import org.pentaho.reporting.engine.classic.core.DefaultReportEnvironment; import org.pentaho.reporting.engine.classic.core.DefaultResourceBundleFactory; import org.pentaho.reporting.engine.classic.core.MasterReport; import org.pentaho.reporting.engine.classic.core.ReportDataFactoryException; import org.pentaho.reporting.engine.classic.core.ReportEnvironment; import org.pentaho.reporting.engine.classic.core.ResourceBundleFactory; import org.pentaho.reporting.engine.classic.core.StaticDataRow; import org.pentaho.reporting.engine.classic.core.TableDataFactory; import org.pentaho.reporting.engine.classic.core.metadata.DataFactoryMetaData; import org.pentaho.reporting.engine.classic.core.modules.misc.tablemodel.GeneratorTableModel; import org.pentaho.reporting.engine.classic.core.parameters.DefaultListParameter; import org.pentaho.reporting.engine.classic.core.parameters.DefaultParameterContext; import org.pentaho.reporting.engine.classic.core.parameters.ParameterAttributeNames; import org.pentaho.reporting.engine.classic.core.parameters.ParameterContext; import org.pentaho.reporting.engine.classic.core.parameters.ParameterDefinitionEntry; import org.pentaho.reporting.engine.classic.core.parameters.PlainParameter; import org.pentaho.reporting.engine.classic.core.parameters.ReportParameterDefinition; import org.pentaho.reporting.engine.classic.core.parameters.ValidationMessage; import org.pentaho.reporting.engine.classic.core.parameters.ValidationResult; import org.pentaho.reporting.engine.classic.core.util.ReportParameterValues; import org.pentaho.reporting.engine.classic.core.util.beans.BeanException; import org.pentaho.reporting.libraries.base.config.Configuration; import org.pentaho.reporting.libraries.base.util.HashNMap; import org.pentaho.reporting.libraries.resourceloader.ResourceKey; import org.pentaho.reporting.libraries.resourceloader.ResourceManager; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import java.io.StringWriter; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import static org.junit.Assert.*; import static org.mockito.Matchers.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; /** * see backlog-7980 * <p> * Created by dima.prokopenko@gmail.com on 6/27/2016. */ public class ParameterXmlContentHandlerTest { private static XPathFactory xpathFactory = XPathFactory.newInstance(); private ParameterXmlContentHandler handler; private MasterReport report; private ReportParameterDefinition definition; private CompoundDataFactory factory; @BeforeClass public static void beforeClass() { ClassicEngineBoot.getInstance().start(); } // helper method private String toString( final Document doc ) { try { final StringWriter stringWriter = new StringWriter(); final TransformerFactory factory = TransformerFactory.newInstance(); final Transformer transformer = factory.newTransformer(); transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); transformer.setOutputProperty( OutputKeys.METHOD, "xml" ); transformer.setOutputProperty( OutputKeys.INDENT, "yes" ); transformer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" ); transformer.transform( new DOMSource( doc ), new StreamResult( stringWriter ) ); return stringWriter.toString(); } catch ( final Exception ex ) { // no op return "fail"; } } @Before public void before() { final ParameterContentGenerator generator = mock( ParameterContentGenerator.class ); handler = new ParameterXmlContentHandler( generator, true ); report = mock( MasterReport.class ); final Configuration conf = mock( Configuration.class ); final ResourceManager rmanager = new ResourceManager(); final ResourceKey rkey = new ResourceKey( "", "", Collections.emptyMap() ); final ResourceBundleFactory resBFactory = mock( ResourceBundleFactory.class ); final ReportEnvironment environment = mock( ReportEnvironment.class ); when( report.getConfiguration() ).thenReturn( conf ); when( report.getResourceManager() ).thenReturn( rmanager ); when( report.getContentBase() ).thenReturn( rkey ); when( report.getResourceBundleFactory() ).thenReturn( resBFactory ); when( report.getReportEnvironment() ).thenReturn( environment ); definition = mock( ReportParameterDefinition.class ); when( report.getParameterDefinition() ).thenReturn( definition ); factory = mock( CompoundDataFactory.class ); // preparation of data factory to fetch parameter names // the actual factory for query will be returned when 'getDataFactoryForQuery' called. when( factory.isNormalized() ).thenReturn( true ); when( factory.derive() ).thenReturn( factory ); when( report.getDataFactory() ).thenReturn( factory ); } @Test public void testGetSelections() throws ReportDataFactoryException, BeanException { final Map<String, Object> inputs = new HashMap<String, Object>( ) { { put( "changed_unverified", "value" ); put( "unchanged_unverified", "value1" ); put( "verified", "value2" ); put( "plain", "value3" ); } }; final Set<Object> changedParameters = Collections.singleton( "changed_unverified" ); final ParameterDefinitionEntry changed = new DefaultListParameter( "query", "keyColumn", "textColumn", "changed_unverified", false, false, String.class ); final ParameterDefinitionEntry unchanged = new DefaultListParameter( "query", "keyColumn", "textColumn", "unchanged_unverified", false, false, String.class ); final ParameterDefinitionEntry verified = new DefaultListParameter( "query", "keyColumn", "textColumn", "verified", false, true, String.class ); final ParameterDefinitionEntry plain = new PlainParameter( "plain", String.class ); //Initial call final Object changedResult = handler.getSelections( changed, null, inputs ); final Object unchangedResult = handler.getSelections( unchanged, null, inputs ); final Object verifiedResult = handler.getSelections( verified, null, inputs ); final Object plainResult = handler.getSelections( plain, null, inputs ); assertEquals( "value", changedResult ); assertEquals( "value1", unchangedResult ); assertEquals( "value2", verifiedResult ); assertEquals( "value3", plainResult ); //Changed call final Object changedResult1 = handler.getSelections( changed, changedParameters, inputs ); final Object unchangedResult1 = handler.getSelections( unchanged, changedParameters, inputs ); final Object verifiedResult1 = handler.getSelections( verified, changedParameters, inputs ); final Object plainResult1 = handler.getSelections( plain, changedParameters, inputs ); assertEquals( "value", changedResult1 ); assertEquals( null, unchangedResult1 ); assertEquals( "value2", verifiedResult1 ); assertEquals( "value3", plainResult1 ); } @Test public void testParameterDependencies() throws ReportDataFactoryException { final ReportParameterValues computedParameterValues = mock( ReportParameterValues.class ); final ParameterContext parameterContext = mock( ParameterContext.class ); final ParameterDefinitionEntry[] entries = getDefinitions(); when( definition.getParameterDefinitions() ).thenReturn( entries ); // this factory will be used to get parameter names final CompoundDataFactory localFactory1 = mock( CompoundDataFactory.class ); when( factory.getDataFactoryForQuery( eq( "query1" ) ) ).thenReturn( localFactory1 ); final DataFactoryMetaData meth1 = mock( DataFactoryMetaData.class ); when( localFactory1.getMetaData() ).thenReturn( meth1 ); when( meth1.getReferencedFields( any( DataFactory.class ), anyString(), any( DataRow.class ) ) ) .thenReturn( new String[] { "f1", "f2" } ); final CompoundDataFactory localFactory2 = mock( CompoundDataFactory.class ); when( factory.getDataFactoryForQuery( eq( "query2" ) ) ).thenReturn( localFactory2 ); final DataFactoryMetaData meth2 = mock( DataFactoryMetaData.class ); when( localFactory2.getMetaData() ).thenReturn( meth2 ); when( meth2.getReferencedFields( any( DataFactory.class ), anyString(), any( DataRow.class ) ) ) .thenReturn( new String[] { "g1", "g2" } ); final HashNMap<String, String> parameters = handler.getDependentParameters( computedParameterValues, parameterContext, report ); assertNotNull( parameters ); assertFalse( parameters.isEmpty() ); assertEquals( 4, parameters.keySet().size() ); final List<String> list1 = Lists.newArrayList( parameters.getAll( "f1" ) ); assertFalse( list1.isEmpty() ); assertEquals( 1, list1.size() ); assertTrue( list1.contains( "name1" ) ); final List<String> list11 = Lists.newArrayList( parameters.getAll( "f2" ) ); assertFalse( list11.isEmpty() ); assertEquals( 1, list11.size() ); assertTrue( list11.contains( "name1" ) ); final List<String> list2 = Lists.newArrayList( parameters.getAll( "g1" ) ); assertFalse( list2.isEmpty() ); assertEquals( 1, list2.size() ); assertTrue( list2.contains( "name2" ) ); final List<String> list22 = Lists.newArrayList( parameters.getAll( "g1" ) ); assertFalse( list22.isEmpty() ); assertEquals( 1, list22.size() ); assertTrue( list22.contains( "name2" ) ); } private ParameterDefinitionEntry[] getDefinitions() { final ParameterDefinitionEntry entry1 = mock( ParameterDefinitionEntry.class ); when( entry1.getName() ).thenReturn( "someName" ); final ParameterDefinitionEntry entry2 = new DefaultListParameter( "query1", "keyColumn1", "textColumn1", "name1", false, true, String.class ); final ParameterDefinitionEntry entry3 = new DefaultListParameter( "query2", "keyColumn2", "textColumn2", "name2", false, true, String.class ); return new ParameterDefinitionEntry[] { entry1, entry2, entry3 }; } @Test public void testComputeNormalizeLinage() { final ParameterContext pc = mock( ParameterContext.class ); final ParameterDefinitionEntry pe = mock( ParameterDefinitionEntry.class ); final HashNMap<String, String> map = new HashNMap<>(); when( pe.getName() ).thenReturn( "aname" ); when( pe.getParameterAttribute( eq( ParameterAttributeNames.Core.NAMESPACE ), eq( ParameterAttributeNames.Core.DEFAULT_VALUE_FORMULA ), eq( pc ) ) ).thenReturn( "=LEN([sPostal1])" ); when( pe.getParameterAttribute( eq( ParameterAttributeNames.Core.NAMESPACE ), eq( ParameterAttributeNames.Core.POST_PROCESSOR_FORMULA ), eq( pc ) ) ).thenReturn( "=LEN([sPostal2])" ); when( pe.getParameterAttribute( eq( ParameterAttributeNames.Core.NAMESPACE ), eq( ParameterAttributeNames.Core.DISPLAY_VALUE_FORMULA ), eq( pc ) ) ).thenReturn( "=LEN([sPostal3])" ); handler.computeNormalLineage( pc, pe, map ); assertNotNull( map ); assertFalse( map.isEmpty() ); assertEquals( 3, map.keySet().size() ); final List<List<String>> list = new ArrayList<>(); list.add( Lists.newArrayList( map.getAll( "sPostal1" ) ) ); list.add( Lists.newArrayList( map.getAll( "sPostal2" ) ) ); list.add( Lists.newArrayList( map.getAll( "sPostal3" ) ) ); list.stream().forEach( i -> assertNotNull( i ) ); list.stream().forEach( i -> assertFalse( i.isEmpty() ) ); list.stream().forEach( i -> assertEquals( 1, i.size() ) ); final List empty = list.stream().filter( i -> i.contains( "aname" ) && ( i.size() == 1 ) ).collect( Collectors.toList() ); assertEquals( 3, list.size() ); } /** * Test that 'skip' validation messages does not mess up with errors. * <p> * generated xml should look like: * <errors> * <error message="" parameter="parameter3"/> * <error message="not good at all" parameter="parameter2"/> * <error message="not good" parameter="parameter1"/> * <global-error message="kernel panic"/> * </errors> * * @throws ParserConfigurationException */ @Test public void createErrorElementsTest() throws ParserConfigurationException, XPathExpressionException { final ValidationResult vr = new ValidationResult(); vr.addError( "parameter1", new ValidationMessage( "not good" ) ); vr.addError( "parameter2", new ValidationMessage( "not good at all" ) ); vr.addError( new ValidationMessage( "kernel panic" ) ); // save parameter name - attribute value mapping final Map<String, String> attrMap = new HashMap(); attrMap.put( "parameter3", "" ); attrMap.put( "parameter2", "not good at all" ); attrMap.put( "parameter1", "not good" ); handler.document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); final Element el = handler.createErrorElements( vr ); handler.document.appendChild( el ); assertNotNull( el ); assertEquals( 3, el.getChildNodes().getLength() ); // use xpath for future validation just to get rid of numerous for() loops in DOM api final XPath xpath = xpathFactory.newXPath(); final NodeList found = NodeList.class.cast( xpath.evaluate( "/errors/error", handler.document, XPathConstants.NODESET ) ); assertNotNull( found ); for ( int i = 0; i < found.getLength(); i++ ) { final Node node = found.item( i ); assertEquals( "error", node.getNodeName() ); final Element oneError = (Element) node; final String paramName = oneError.getAttribute( "parameter" ); assertTrue( attrMap.containsKey( paramName ) ); assertEquals( attrMap.get( paramName ), oneError.getAttribute( "message" ) ); } final Node globalError = (Node) xpath.evaluate( "/errors/global-error", handler.document, XPathConstants.NODE ); assertNotNull( globalError ); assertEquals( "global-error", globalError.getNodeName() ); final Element globalErrEl = Element.class.cast( globalError ); assertEquals( "kernel panic", globalErrEl.getAttribute( "message" ) ); } /** * Creates simple parameter xml. Output should look like: * <pre> * {@code * * <parameter is-list="true" is-mandatory="false" is-multi-select="true" is-strict="true" name="name" * type="java.lang.String"> * <attribute name="role" namespace="http://reporting.pentaho.org/namespaces/engine/parameter-attributes/core" * value="user"/> * <values> * <value label="c20" null="false" selected="false" type="java.lang.String" value="c10"/> * <value label="c21" null="false" selected="false" type="java.lang.String" value="c11"/> * </values> * </parameter> } * </pre> * * @throws BeanException * @throws ReportDataFactoryException * @throws ParserConfigurationException */ @Test public void createParameterElementTest() throws BeanException, ReportDataFactoryException, ParserConfigurationException, XPathExpressionException { final DefaultListParameter parameter = new DefaultListParameter( "query", "c1", "c2", "name", true, true, String.class ); final ParameterContext context = getTestParameterContext(); handler.document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); final HashNMap<String, String> dependencies = new HashNMap<>(); dependencies.add( "name", "dep1" ); dependencies.add( "name", "dep2" ); final Element element = handler.createParameterElement( parameter, context, null, dependencies, false ); assertNotNull( element ); handler.document.appendChild( element ); handler.createParameterDependencies( element, parameter, new HashNMap() ); final String xml = toString( handler.document ); examineStandardXml( handler.document ); assertTrue( isThereAttributes( handler.document ) ); } /** * Creates simple parameter xml. Output should look like: * <p> * <pre> * {@code * * <parameter is-list="true" is-mandatory="false" is-multi-select="true" is-strict="true" name="name" * type="java.lang.String"> * <attribute name="role" namespace="http://reporting.pentaho.org/namespaces/engine/parameter-attributes/core" * value="user"/> * <attribute name="must-validate-on-server" namespace="http://reporting.pentaho * .org/namespaces/engine/parameter-attributes/server" value="true"/> * <attribute name="has-downstream-dependent-parameter" namespace="http://reporting.pentaho * .org/namespaces/engine/parameter-attributes/server" value="true"/> * <values> * <value label="c20" null="false" selected="false" type="java.lang.String" value="c10"/> * <value label="c21" null="false" selected="false" type="java.lang.String" value="c11"/> * </values> * <dependencies> * <name>dep1</name> * <name>dep2</name> * </dependencies> * </parameter> * } * </pre> * * @throws BeanException * @throws ReportDataFactoryException * @throws ParserConfigurationException * @throws XPathExpressionException */ @Test public void createParameterWithDependenciesTest() throws BeanException, ReportDataFactoryException, ParserConfigurationException, XPathExpressionException { final DefaultListParameter parameter = new DefaultListParameter( "query", "c1", "c2", "name", true, true, String.class ); final ParameterContext context = getTestParameterContext(); handler.document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); final HashNMap<String, String> dependencies = new HashNMap<>(); dependencies.add( "name", "dep0" ); dependencies.add( "name", "dep1" ); final Element element = handler.createParameterElement( parameter, context, null, dependencies, false ); assertNotNull( element ); handler.document.appendChild( element ); handler.createParameterDependencies( element, parameter, dependencies ); examineStandardXml( handler.document ); assertTrue( isThereAttributes( handler.document ) ); final String xml = toString( handler.document ); // test dependencies specific elements: final XPath xpath = xpathFactory.newXPath(); final NodeList list = (NodeList) xpath.evaluate( "/parameter/dependencies/name", handler.document, XPathConstants.NODESET ); assertNotNull( list ); assertEquals( 2, list.getLength() ); for ( int i = 0; i < list.getLength(); i++ ) { final Node node = list.item( i ); assertNotNull( node ); assertEquals( "dep" + i, node.getTextContent() ); } // specific attributes: must-validate-on-server Node attr1 = (Node) xpath .evaluate( "/parameter/attribute[@name='must-validate-on-server']", handler.document, XPathConstants.NODE ); assertNotNull( attr1 ); Element elAttr1 = (Element) attr1; assertEquals( "true", elAttr1.getAttribute( "value" ) ); // specific attributes: has-downstream-dependent-parameter attr1 = (Node) xpath .evaluate( "/parameter/attribute[@name='has-downstream-dependent-parameter']", handler.document, XPathConstants.NODE ); assertNotNull( attr1 ); elAttr1 = (Element) attr1; assertEquals( "true", elAttr1.getAttribute( "value" ) ); } private void examineStandardXml( final Document doc ) throws XPathExpressionException { final XPath xpath = xpathFactory.newXPath(); final NodeList nodeList = (NodeList) xpath.evaluate( "/parameter/values/value", doc, XPathConstants.NODESET ); assertNotNull( nodeList ); assertEquals( 2, nodeList.getLength() ); for ( int i = 0; i < nodeList.getLength(); i++ ) { final Element item = (Element) nodeList.item( i ); assertEquals( "c1" + i, item.getAttribute( "value" ) ); } } /** * Creates very simple parameter context. * * @return * @throws ReportDataFactoryException */ private DefaultParameterContext getTestParameterContext() throws ReportDataFactoryException { final GeneratorTableModel model = new GeneratorTableModel( new String[] { "c1", "c2" }, new Class[] { String.class, String.class }, 2 ); final DataFactory df = new TableDataFactory( "query", model ); final DataRow dr = new StaticDataRow( new String[] { "1" }, new Object[] { 1 } ); final Configuration conf = ClassicEngineBoot.getInstance().getExtendedConfig(); final ResourceBundleFactory factory = new DefaultResourceBundleFactory(); final ResourceManager manager = new ResourceManager(); final ResourceKey key = new ResourceKey( "", "", Collections.emptyMap() ); final ReportEnvironment env = new DefaultReportEnvironment( conf ); return new DefaultParameterContext( df, dr, conf, factory, manager, key, env ); } @Test public void createParameterElementNoAttributesTest() throws BeanException, ReportDataFactoryException, ParserConfigurationException, XPathExpressionException { final DefaultListParameter parameter = new DefaultListParameter( "query", "c1", "c2", "name", true, true, String.class ); final ParameterContext context = getTestParameterContext(); handler.document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); final HashNMap<String, String> dependencies = new HashNMap<>(); dependencies.add( "name", "dep1" ); dependencies.add( "name", "dep2" ); final Element element = handler.createParameterElement( parameter, context, null, dependencies, Boolean.TRUE ); assertNotNull( element ); handler.document.appendChild( element ); handler.createParameterDependencies( element, parameter, new HashNMap() ); examineStandardXml( handler.document ); assertFalse( isThereAttributes( handler.document ) ); } @Test public void appendInitialParametersList() throws BeanException, ReportDataFactoryException, ParserConfigurationException, XPathExpressionException, CloneNotSupportedException { final LinkedHashMap<String, ParameterDefinitionEntry> parameterDefinitions = getParametersMap(); final DefaultParameterContext context = getTestParameterContext(); final ValidationResult vr = new ValidationResult(); vr.setParameterValues( new ReportParameterValues( ) ); handler.document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); final HashNMap<String, String> dependencies = new HashNMap<>(); dependencies.add( "first", "second" ); dependencies.add( "second", "third" ); final Element parameters = handler.document.createElement( "parameters" ); handler.document.appendChild( parameters ); handler.appendParametersList( context, vr, parameters, dependencies, parameterDefinitions, new HashMap( ), null ); examineInitialParameters( handler.document ); } @Test public void appendChangedParametersList() throws BeanException, ReportDataFactoryException, ParserConfigurationException, XPathExpressionException, CloneNotSupportedException { final LinkedHashMap<String, ParameterDefinitionEntry> parameterDefinitions = getParametersMap(); final DefaultParameterContext context = getTestParameterContext(); final ValidationResult vr = new ValidationResult(); vr.setParameterValues( new ReportParameterValues( ) ); handler.document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); final HashNMap<String, String> dependencies = new HashNMap<>(); dependencies.add( "first", "second" ); dependencies.add( "first", "fourth" ); dependencies.add( "second", "third" ); dependencies.add( "third", "seventh" ); dependencies.add( "second", "fourth" ); //How about some cycles? dependencies.add( "fourth", "third" ); dependencies.add( "third", "fourth" ); //Independent parameters dependencies.add( "fifth", "sixth" ); final Element parameters = handler.document.createElement( "parameters" ); handler.document.appendChild( parameters ); handler.appendParametersList( context, vr, parameters, dependencies, parameterDefinitions, new HashMap( ), new String[]{"first"} ); examineChangedDependentParameters( handler.document ); } @Test public void appendChangedIndependentParametersList() throws BeanException, ReportDataFactoryException, ParserConfigurationException, XPathExpressionException, CloneNotSupportedException { final LinkedHashMap<String, ParameterDefinitionEntry> parameterDefinitions = getParametersMap(); final DefaultParameterContext context = getTestParameterContext(); final ValidationResult vr = new ValidationResult(); vr.setParameterValues( new ReportParameterValues( ) ); handler.document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); final HashNMap<String, String> dependencies = new HashNMap<>(); dependencies.add( "first", "second" ); dependencies.add( "second", "third" ); final Element parameters = handler.document.createElement( "parameters" ); handler.document.appendChild( parameters ); handler.appendParametersList( context, vr, parameters, dependencies, parameterDefinitions, new HashedMap( ), new String[]{"fourth"} ); examineChangedIndependentParameters( handler.document ); } @Test public void resetInputParentChanged() throws BeanException, ReportDataFactoryException, ParserConfigurationException, XPathExpressionException, CloneNotSupportedException { final LinkedHashMap<String, ParameterDefinitionEntry> parameterDefinitions = getParametersMap( false ); final DefaultParameterContext context = getTestParameterContext(); final ValidationResult vr = new ValidationResult(); vr.setParameterValues( new ReportParameterValues( ) ); handler.document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); final HashNMap<String, String> dependencies = new HashNMap<>(); dependencies.add( "first", "second" ); dependencies.add( "second", "third" ); final Element parameters = handler.document.createElement( "parameters" ); handler.document.appendChild( parameters ); final Map<String, Object> inputs = new HashMap<>( ); inputs.put( "first", new String[]{ "c11", "c10" } ); inputs.put( "second", new String[]{ "c11", "c10" } ); inputs.put( "third", new String[]{ "c11", "c10" } ); handler.appendParametersList( context, vr, parameters, dependencies, parameterDefinitions, inputs, new String[]{"first"} ); examineChangedResetParameters( handler.document ); } @Test public void resetInputParentChangedChildSentFromUI() throws BeanException, ReportDataFactoryException, ParserConfigurationException, XPathExpressionException, CloneNotSupportedException { final LinkedHashMap<String, ParameterDefinitionEntry> parameterDefinitions = getParametersMap( false ); final DefaultParameterContext context = getTestParameterContext(); final ValidationResult vr = new ValidationResult(); vr.setParameterValues( new ReportParameterValues( ) ); handler.document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); final HashNMap<String, String> dependencies = new HashNMap<>(); dependencies.add( "first", "second" ); dependencies.add( "second", "third" ); final Element parameters = handler.document.createElement( "parameters" ); handler.document.appendChild( parameters ); final Map<String, Object> inputs = new HashMap<>( ); inputs.put( "first", new String[]{ "c11", "c10" } ); inputs.put( "second", new String[]{ "c11", "c10" } ); inputs.put( "third", new String[]{ "c11", "c10" } ); handler.appendParametersList( context, vr, parameters, dependencies, parameterDefinitions, inputs, new String[]{"first", "second"} ); examineChangedResetParameters( handler.document ); } @Test public void resetInputParentInTheMiddleChangedChildSentFromUI() throws BeanException, ReportDataFactoryException, ParserConfigurationException, XPathExpressionException, CloneNotSupportedException { final LinkedHashMap<String, ParameterDefinitionEntry> parameterDefinitions = getParametersMap( false ); final DefaultParameterContext context = getTestParameterContext(); final ValidationResult vr = new ValidationResult(); vr.setParameterValues( new ReportParameterValues( ) ); handler.document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); final HashNMap<String, String> dependencies = new HashNMap<>(); dependencies.add( "first", "second" ); dependencies.add( "second", "third" ); final Element parameters = handler.document.createElement( "parameters" ); handler.document.appendChild( parameters ); final Map<String, Object> inputs = new HashMap<>( ); inputs.put( "first", new String[]{ "c11", "c10" } ); inputs.put( "second", new String[]{ "c11", "c10" } ); inputs.put( "third", new String[]{ "c11", "c10" } ); handler.appendParametersList( context, vr, parameters, dependencies, parameterDefinitions, inputs, new String[]{"third", "second"} ); examineChangedMiddleResetParameters( handler.document ); } private LinkedHashMap<String, ParameterDefinitionEntry> getParametersMap() { return getParametersMap( true ); } private LinkedHashMap<String, ParameterDefinitionEntry> getParametersMap( boolean isStrict ) { final LinkedHashMap<String, ParameterDefinitionEntry> parameterDefinitions = new LinkedHashMap<>( ); final DefaultListParameter parameter = new DefaultListParameter( "query", "c1", "c2", "first", true, isStrict, String.class ); final DefaultListParameter parameter1 = new DefaultListParameter( "query", "c1", "c2", "second", true, isStrict, String.class ); final DefaultListParameter parameter2 = new DefaultListParameter( "query", "c1", "c2", "third", true, isStrict, String.class ); final DefaultListParameter parameter3 = new DefaultListParameter( "query", "c1", "c2", "fourth", true, isStrict, String.class ); final DefaultListParameter parameter4 = new DefaultListParameter( "query", "c1", "c2", "fifth", true, isStrict, String.class ); final DefaultListParameter parameter5 = new DefaultListParameter( "query", "c1", "c2", "sixth", true, isStrict, String.class ); final DefaultListParameter parameter6 = new DefaultListParameter( "query", "c1", "c2", "seventh", true, isStrict, String.class ); parameterDefinitions.put( "first", parameter ); parameterDefinitions.put( "second", parameter1 ); parameterDefinitions.put( "third", parameter2 ); parameterDefinitions.put( "fourth", parameter3 ); parameterDefinitions.put( "fifth", parameter4 ); parameterDefinitions.put( "sixth", parameter5 ); parameterDefinitions.put( "seventh", parameter6 ); return parameterDefinitions; } private void examineInitialParameters( final Document doc ) throws XPathExpressionException { final XPath xpath = xpathFactory.newXPath(); final NodeList root = (NodeList) xpath.evaluate( "/parameters", doc, XPathConstants.NODESET ); assertEquals( 1, root.getLength() ); final Node minimized = root.item( 0 ).getAttributes().getNamedItem( "minimized" ); assertNull( minimized ); final NodeList nodeList = (NodeList) xpath.evaluate( "/parameters/parameter", doc, XPathConstants.NODESET ); assertEquals( 7, nodeList.getLength() ); final NodeList first = (NodeList) xpath.evaluate( "/parameters/parameter[@name='first']", doc, XPathConstants.NODESET ); assertEquals( 1, first.getLength() ); final NodeList second = (NodeList) xpath.evaluate( "/parameters/parameter[@name='second']", doc, XPathConstants.NODESET ); assertEquals( 1, second.getLength() ); final NodeList third = (NodeList) xpath.evaluate( "/parameters/parameter[@name='third']", doc, XPathConstants.NODESET ); assertEquals( 1, third.getLength() ); final NodeList fourth = (NodeList) xpath.evaluate( "/parameters/parameter[@name='fourth']", doc, XPathConstants.NODESET ); assertEquals( 1, fourth.getLength() ); final NodeList attributes = (NodeList) xpath.evaluate( "/parameters/parameter/attribute", doc, XPathConstants.NODESET ); assertTrue( attributes.getLength() != 0 ); final NodeList dependencies = (NodeList) xpath.evaluate( "/parameters/parameter/dependencies", doc, XPathConstants.NODESET ); assertTrue( dependencies.getLength() != 0 ); } private void examineChangedDependentParameters( final Document doc ) throws XPathExpressionException { final XPath xpath = xpathFactory.newXPath(); final NodeList root = (NodeList) xpath.evaluate( "/parameters", doc, XPathConstants.NODESET ); assertEquals( 1, root.getLength() ); final Node minimized = root.item( 0 ).getAttributes().getNamedItem( "minimized" ); assertNotNull( minimized ); final NodeList nodeList = (NodeList) xpath.evaluate( "/parameters/parameter", doc, XPathConstants.NODESET ); assertEquals( 5, nodeList.getLength() ); final NodeList first = (NodeList) xpath.evaluate( "/parameters/parameter[@name='first']", doc, XPathConstants.NODESET ); assertEquals( 1, first.getLength() ); final NodeList second = (NodeList) xpath.evaluate( "/parameters/parameter[@name='second']", doc, XPathConstants.NODESET ); assertEquals( 1, second.getLength() ); final NodeList third = (NodeList) xpath.evaluate( "/parameters/parameter[@name='third']", doc, XPathConstants.NODESET ); assertEquals( 1, third.getLength() ); final NodeList fourth = (NodeList) xpath.evaluate( "/parameters/parameter[@name='fourth']", doc, XPathConstants.NODESET ); assertEquals( 1, fourth.getLength() ); final NodeList fifth = (NodeList) xpath.evaluate( "/parameters/parameter[@name='fifth']", doc, XPathConstants.NODESET ); assertEquals( 0, fifth.getLength() ); final NodeList sixth = (NodeList) xpath.evaluate( "/parameters/parameter[@name='sixth']", doc, XPathConstants.NODESET ); assertEquals( 0, sixth.getLength() ); final NodeList seventh = (NodeList) xpath.evaluate( "/parameters/parameter[@name='seventh']", doc, XPathConstants.NODESET ); assertEquals( 1, seventh.getLength() ); final NodeList attributes = (NodeList) xpath.evaluate( "/parameters/parameter/attribute", doc, XPathConstants.NODESET ); assertFalse( attributes.getLength() != 0 ); final NodeList dependencies = (NodeList) xpath.evaluate( "/parameters/parameter/dependencies", doc, XPathConstants.NODESET ); assertFalse( dependencies.getLength() != 0 ); } private void examineChangedIndependentParameters( final Document doc ) throws XPathExpressionException { final XPath xpath = xpathFactory.newXPath(); final NodeList root = (NodeList) xpath.evaluate( "/parameters", doc, XPathConstants.NODESET ); assertEquals( 1, root.getLength() ); final Node minimized = root.item( 0 ).getAttributes().getNamedItem( "minimized" ); assertNotNull( minimized ); final NodeList nodeList = (NodeList) xpath.evaluate( "/parameters/parameter", doc, XPathConstants.NODESET ); assertEquals( 1, nodeList.getLength() ); final NodeList first = (NodeList) xpath.evaluate( "/parameters/parameter[@name='first']", doc, XPathConstants.NODESET ); assertEquals( 0, first.getLength() ); final NodeList second = (NodeList) xpath.evaluate( "/parameters/parameter[@name='second']", doc, XPathConstants.NODESET ); assertEquals( 0, second.getLength() ); final NodeList third = (NodeList) xpath.evaluate( "/parameters/parameter[@name='third']", doc, XPathConstants.NODESET ); assertEquals( 0, third.getLength() ); final NodeList fourth = (NodeList) xpath.evaluate( "/parameters/parameter[@name='fourth']", doc, XPathConstants.NODESET ); assertEquals( 1, fourth.getLength() ); final NodeList attributes = (NodeList) xpath.evaluate( "/parameters/parameter/attribute", doc, XPathConstants.NODESET ); assertFalse( attributes.getLength() != 0 ); final NodeList dependencies = (NodeList) xpath.evaluate( "/parameters/parameter/dependencies", doc, XPathConstants.NODESET ); assertFalse( dependencies.getLength() != 0 ); } private void examineChangedResetParameters( final Document doc ) throws XPathExpressionException { final XPath xpath = xpathFactory.newXPath(); final NodeList root = (NodeList) xpath.evaluate( "/parameters", doc, XPathConstants.NODESET ); assertEquals( 1, root.getLength() ); final Node minimized = root.item( 0 ).getAttributes().getNamedItem( "minimized" ); assertNotNull( minimized ); final NodeList nodeList = (NodeList) xpath.evaluate( "/parameters/parameter", doc, XPathConstants.NODESET ); assertEquals( 3, nodeList.getLength() ); final NodeList first = (NodeList) xpath.evaluate( "/parameters/parameter[@name='first']", doc, XPathConstants.NODESET ); assertEquals( 1, first.getLength() ); final NodeList firstValues = (NodeList) xpath.evaluate( "/parameters/parameter[@name='first']/values/value", doc, XPathConstants.NODESET ); assertEquals( 2, firstValues.getLength() ); final NodeList firstSelectedValues = (NodeList) xpath.evaluate( "/parameters/parameter[@name='first']/values/value[@selected='true']", doc, XPathConstants.NODESET ); assertEquals( 2, firstSelectedValues.getLength() ); final NodeList second = (NodeList) xpath.evaluate( "/parameters/parameter[@name='second']", doc, XPathConstants.NODESET ); assertEquals( 1, second.getLength() ); final NodeList secondValues = (NodeList) xpath.evaluate( "/parameters/parameter[@name='second']/values/value", doc, XPathConstants.NODESET ); assertEquals( 2, secondValues.getLength() ); //Values are reset final NodeList secondSelectedValues = (NodeList) xpath.evaluate( "/parameters/parameter[@name='second']/values/value[@selected='true']", doc, XPathConstants.NODESET ); assertEquals( 0, secondSelectedValues.getLength() ); final NodeList third = (NodeList) xpath.evaluate( "/parameters/parameter[@name='third']", doc, XPathConstants.NODESET ); assertEquals( 1, third.getLength() ); final NodeList thirdValues = (NodeList) xpath.evaluate( "/parameters/parameter[@name='third']/values/value", doc, XPathConstants.NODESET ); assertEquals( 2, thirdValues.getLength() ); //Deeper levels are also reset final NodeList thirdSelectedValues = (NodeList) xpath.evaluate( "/parameters/parameter[@name='third']/values/value[@selected='true']", doc, XPathConstants.NODESET ); assertEquals( 0, thirdSelectedValues.getLength() ); final NodeList fourth = (NodeList) xpath.evaluate( "/parameters/parameter[@name='fourth']", doc, XPathConstants.NODESET ); assertEquals( 0, fourth.getLength() ); final NodeList attributes = (NodeList) xpath.evaluate( "/parameters/parameter/attribute", doc, XPathConstants.NODESET ); assertFalse( attributes.getLength() != 0 ); final NodeList dependencies = (NodeList) xpath.evaluate( "/parameters/parameter/dependencies", doc, XPathConstants.NODESET ); assertFalse( dependencies.getLength() != 0 ); } private void examineChangedMiddleResetParameters( final Document doc ) throws XPathExpressionException { final XPath xpath = xpathFactory.newXPath(); final NodeList root = (NodeList) xpath.evaluate( "/parameters", doc, XPathConstants.NODESET ); assertEquals( 1, root.getLength() ); final Node minimized = root.item( 0 ).getAttributes().getNamedItem( "minimized" ); assertNotNull( minimized ); final NodeList nodeList = (NodeList) xpath.evaluate( "/parameters/parameter", doc, XPathConstants.NODESET ); assertEquals( 2, nodeList.getLength() ); final NodeList first = (NodeList) xpath.evaluate( "/parameters/parameter[@name='first']", doc, XPathConstants.NODESET ); assertEquals( 0, first.getLength() ); final NodeList second = (NodeList) xpath.evaluate( "/parameters/parameter[@name='second']", doc, XPathConstants.NODESET ); assertEquals( 1, second.getLength() ); final NodeList secondValues = (NodeList) xpath.evaluate( "/parameters/parameter[@name='second']/values/value", doc, XPathConstants.NODESET ); assertEquals( 2, secondValues.getLength() ); //Values are not reset final NodeList secondSelectedValues = (NodeList) xpath.evaluate( "/parameters/parameter[@name='second']/values/value[@selected='true']", doc, XPathConstants.NODESET ); assertEquals( 2, secondSelectedValues.getLength() ); final NodeList third = (NodeList) xpath.evaluate( "/parameters/parameter[@name='third']", doc, XPathConstants.NODESET ); assertEquals( 1, third.getLength() ); final NodeList thirdValues = (NodeList) xpath.evaluate( "/parameters/parameter[@name='third']/values/value", doc, XPathConstants.NODESET ); assertEquals( 2, thirdValues.getLength() ); //Deeper levels are reset final NodeList thirdSelectedValues = (NodeList) xpath.evaluate( "/parameters/parameter[@name='third']/values/value[@selected='true']", doc, XPathConstants.NODESET ); assertEquals( 0, thirdSelectedValues.getLength() ); final NodeList fourth = (NodeList) xpath.evaluate( "/parameters/parameter[@name='fourth']", doc, XPathConstants.NODESET ); assertEquals( 0, fourth.getLength() ); final NodeList attributes = (NodeList) xpath.evaluate( "/parameters/parameter/attribute", doc, XPathConstants.NODESET ); assertFalse( attributes.getLength() != 0 ); final NodeList dependencies = (NodeList) xpath.evaluate( "/parameters/parameter/dependencies", doc, XPathConstants.NODESET ); assertFalse( dependencies.getLength() != 0 ); } private boolean isThereAttributes( final Document doc ) throws XPathExpressionException { final XPath xpath = xpathFactory.newXPath(); final NodeList nodeList = (NodeList) xpath.evaluate( "/parameter/attribute", doc, XPathConstants.NODESET ); return nodeList.getLength() != 0; } }