/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.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 Lesser General Public License for more details. * * Copyright 2005 - 2009 Pentaho Corporation. All rights reserved. * */ package org.pentaho.platform.web.servlet; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.Node; public class AdhocWebServiceInteractXml { public static Document convertXml( final Document reportXml ) { // get the list of headers List<String> headerList = new ArrayList<String>(); List<?> nodes = reportXml.selectNodes( "/report/groupheader/@name" ); //$NON-NLS-1$ // find all the unique group header names Iterator<?> it = nodes.iterator(); Attribute attr; String name; while( it.hasNext() ) { // we only need to go until we get the first duplicate attr = (Attribute) it.next(); name = attr.getText(); if( !"dummy".equals( name ) ) { //$NON-NLS-1$ if( !headerList.contains( name ) ) { headerList.add( name ); System.out.println(name); } else { break; } } } String headerNames[] = new String[ headerList.size() ]; String headerValues[] = new String[ headerList.size() ]; Element headerNodes[] = new Element[ headerList.size() ]; String columnHeaders[] = new String[0]; Element columnHeaderNodes[] = new Element[0]; headerList.toArray( headerNames ); for( int idx=0; idx<headerValues.length; idx++ ) { headerValues[ idx ] = ""; //$NON-NLS-1$ } Document reportDoc = DocumentHelper.createDocument(); Element reportNode = DocumentHelper.createElement("report"); //$NON-NLS-1$ reportDoc.setRootElement( reportNode ); // process the top-level nodes nodes = reportXml.selectNodes( "/report/*" ); //$NON-NLS-1$ Node node; // go thru all the nodes it = nodes.iterator(); while( it.hasNext() ) { node = (Node) it.next(); name = node.getName(); if( "groupheader".equals( name ) ) { //$NON-NLS-1$ // process the group headers // get the group header name String headerName = node.selectSingleNode( "@name" ).getText(); //$NON-NLS-1$ if( !"dummy".equals( headerName ) ) { //$NON-NLS-1$ // find the header index String headerValue = node.selectSingleNode( "element[1]" ).getText();//$NON-NLS-1$ int headerIdx=-1; for( int idx=0; idx<headerNames.length; idx++ ) { if( headerNames[idx].equals( headerName ) ) { headerIdx = idx; break; } } if( !headerValues[headerIdx].equals( headerValue ) ) { // this is a new header value headerValues[headerIdx] = headerValue; // find the parent node Element parentNode; if( headerIdx == 0 ) { parentNode = reportNode; } else { parentNode = headerNodes[headerIdx-1]; } // create a group header node for this Element headerNode = DocumentHelper.createElement( "groupheader" );//$NON-NLS-1$ parentNode.add( headerNode ); headerNodes[headerIdx] = headerNode; // create the name attribute attr = DocumentHelper.createAttribute( headerNode, "name", headerName);//$NON-NLS-1$ headerNode.add( attr ); // create the value node Element elementNode = DocumentHelper.createElement( "element" );//$NON-NLS-1$ headerNode.add( elementNode ); attr = DocumentHelper.createAttribute( elementNode, "name", headerName);//$NON-NLS-1$ elementNode.add( attr ); elementNode.setText( headerValue ); } } // see if there are any column headers List<?> elements = node.selectNodes( "element" );//$NON-NLS-1$ if( elements.size() == 0 ) { elements = node.selectNodes( "band/element" );//$NON-NLS-1$ } if( elements.size() > 1 ) { // there are column headers here, get them and store them for the next set of rows columnHeaders = new String[elements.size()-1]; columnHeaderNodes = new Element[elements.size()-1]; for( int idx=1; idx<elements.size(); idx++ ) { columnHeaders[idx-1] = ((Element)elements.get(idx)).getText(); } } } else if( "items".equals( name ) ) {//$NON-NLS-1$ // process items (rows) // get the parent node, this should always be the last one on the list Element parentNode; if( headerNodes.length == 0 ) { parentNode = reportNode; } else { parentNode = headerNodes[headerNodes.length-1]; } // create the items node Element itemsNode = DocumentHelper.createElement( "items" );//$NON-NLS-1$ parentNode.add( itemsNode ); // create the headers node Element headersNode = DocumentHelper.createElement( "headers" );//$NON-NLS-1$ itemsNode.add( headersNode ); // create the rows node Element itemBandsNode = DocumentHelper.createElement( "itembands" );//$NON-NLS-1$ itemsNode.add( itemBandsNode ); for( int idx=0; idx<columnHeaders.length; idx++ ) { Element headerNode = DocumentHelper.createElement( "header" );//$NON-NLS-1$ headerNode.setText( columnHeaders[idx] ); headersNode.add( headerNode ); columnHeaderNodes[ idx ] = headerNode; } // now copy the item bands over List<?> itembands = node.selectNodes( "itemband" );//$NON-NLS-1$ Iterator<?> bands = itembands.iterator(); boolean first = true; while( bands.hasNext() ) { Element itemband = (Element) bands.next(); Element itemBandNode = DocumentHelper.createElement( "itemband" );//$NON-NLS-1$ itemBandsNode.add( itemBandNode ); List<?> elementList = itemband.selectNodes( "element" );//$NON-NLS-1$ Iterator<?> elements = elementList.iterator(); int idx = 0; while( elements.hasNext() ) { Element element = (Element) elements.next(); Element elementNode = DocumentHelper.createElement( "element" );//$NON-NLS-1$ itemBandNode.add( elementNode ); elementNode.setText( element.getText() ); name = element.selectSingleNode("@name").getText();//$NON-NLS-1$ if( name.endsWith( "Element" ) ) {//$NON-NLS-1$ name = name.substring(0, name.length()-"Element".length() );//$NON-NLS-1$ } attr = DocumentHelper.createAttribute( elementNode, "name", name );//$NON-NLS-1$ elementNode.add( attr ); if( first ) { // copy the item name over to the column header attr = DocumentHelper.createAttribute( columnHeaderNodes[idx], "name", name );//$NON-NLS-1$ columnHeaderNodes[idx].add( attr ); } idx++; } first = false; } } } return reportDoc; } }