Package com.eviware.soapui.support.xml

Source Code of com.eviware.soapui.support.xml.XPathData

/*
*  soapUI, copyright (C) 2004-2011 eviware.com
*
*  soapUI is free software; you can redistribute it and/or modify it under the
*  terms of version 2.1 of the GNU Lesser General Public License as published by
*  the Free Software Foundation.
*
*  soapUI 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 at gnu.org.
*/

package com.eviware.soapui.support.xml;

import java.io.IOException;
import java.io.LineNumberReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import com.eviware.soapui.support.types.StringToStringMap;

/**
*
* @author lars
*/
public class XPathData
{
  private StringToStringMap nsMap = new StringToStringMap();
  private List<String> pathComponents = new ArrayList<String>();
  private String function;
  private boolean absolute = false;

  public XPathData( StringToStringMap nsMap, List<String> pathComponents, boolean absolute )
  {
    this.nsMap = nsMap;
    this.pathComponents = pathComponents;
    this.absolute = absolute;
  }

  public XPathData( String xpath, boolean skipFirst )
  {
    try
    {
      LineNumberReader reader = new LineNumberReader( new StringReader( xpath.trim() ) );
      String s;
      while( ( s = reader.readLine() ) != null )
      {
        if( s.startsWith( "declare namespace " ) )
        {
          String[] words = s.substring( "declare namespace ".length() ).split( "=" );
          String prefix = words[0];
          int ix1 = words[1].indexOf( '\'' );
          int ix2 = words[1].lastIndexOf( '\'' );
          String ns = words[1].substring( ix1 + 1, ix2 - ix1 );
          nsMap.put( ns, prefix );
        }
        else
        {
          if( s.startsWith( "count(" ) && s.endsWith( ")" ) )
          {
            function = "count";
            s = s.substring( "count(".length(), s.length() - ")".length() );
          }
          else if( s.startsWith( "exists(" ) && s.endsWith( ")" ) )
          {
            function = "exists";
            s = s.substring( "exists(".length(), s.length() - ")".length() );
          }

          String[] words = s.split( "/" );
          int firstWord = 1 + ( skipFirst ? 1 : 0 );
          for( int i = firstWord; i < words.length; i++ )
          {
            pathComponents.add( 0, words[i] );
          }
        }
      }
    }
    catch( IOException e )
    {
      throw new RuntimeException( e );
    }
  }

  public void strip()
  {
    if( pathComponents.size() > 0 && "text()".equals( pathComponents.get( 0 ) ) )
      pathComponents.remove( 0 );

    for( int i1 = 0; i1 < pathComponents.size(); i1++ )
    {
      String s = pathComponents.get( i1 );
      if( s.indexOf( '[' ) >= 0 )
      {
        StringBuffer buf = new StringBuffer();
        boolean skip = false;
        for( int i2 = 0; i2 < s.length(); i2++ )
        {
          char ch = s.charAt( i2 );
          if( ch == '[' )
            skip = true;
          if( !skip )
            buf.append( ch );

          if( ch == ']' )
            skip = false;
        }

        s = buf.toString();
        pathComponents.set( i1, s );
      }
    }

    function = null;
  }

  public XPathData createParent()
  {
    if( pathComponents.isEmpty() )
      return null;

    StringToStringMap nsMap2 = new StringToStringMap( nsMap );
    ArrayList<String> pathComponents2 = new ArrayList<String>( pathComponents );
    pathComponents2.remove( 0 );
    return new XPathData( nsMap2, pathComponents2, absolute );
  }

  @Override
  public String toString()
  {
    return getShortPath();
  }

  @Override
  public boolean equals( Object obj )
  {
    if( obj == null || obj.getClass() != XPathData.class )
      return false;

    XPathData other = ( XPathData )obj;
    return this.getHashKey().equals( other.getHashKey() );
  }

  @Override
  public int hashCode()
  {
    return getHashKey().hashCode();
  }

  public String getHashKey()
  {
    return getCanonicalPath();
  }

  public StringToStringMap getNamespaceMap()
  {
    return nsMap;
  }

  public List<String> getPathComponents()
  {
    return pathComponents;
  }

  public boolean isAttribute()
  {
    if( pathComponents.isEmpty() )
      return false;

    String c = pathComponents.get( 0 );
    return c.startsWith( "@" );
  }

  public String getAttributeName()
  {
    String c = pathComponents.get( 0 );
    return c.substring( 1 );
  }

  public String getFunction()
  {
    return function;
  }

  public String getXPath()
  {
    return buildXPath( null );
  }

  public String getFullPath()
  {
    return buildXPath( null );
  }

  public String buildXPath( XPathModifier modifier )
  {
    StringBuffer xpath = new StringBuffer();

    for( Iterator<String> i = nsMap.keySet().iterator(); i.hasNext(); )
    {
      String ns = i.next();
      xpath.append( "declare namespace " + nsMap.get( ns ) + "='" + ns + "';\n" );
    }

    if( function != null )
      xpath.append( function ).append( "(" );

    if( modifier != null )
      modifier.beforeSelector( xpath );

    String firstComponent = "";
    if( pathComponents.size() > 0 )
      firstComponent = pathComponents.get( pathComponents.size() - 1 );
    if( !absolute && !"".equals( firstComponent ) )
      xpath.append( "/" );

    for( int c = pathComponents.size() - 1; c >= 0; c-- )
    {
      xpath.append( "/" ).append( pathComponents.get( c ) );
    }

    if( modifier != null )
      modifier.afterSelector( xpath );

    if( function != null )
      xpath.append( ")" );

    return xpath.toString();
  }

  public String getPath()
  {
    StringBuffer buf = new StringBuffer();
    buf.append( "/" );

    for( int c = pathComponents.size() - 1; c >= 0; c-- )
    {
      buf.append( "/" ).append( pathComponents.get( c ) );
    }

    return buf.toString();
  }

  /** Get a path with all namespaces replaced. */
  public String getCanonicalPath()
  {
    HashMap<String, String> inverseNsMap = new HashMap<String, String>();
    for( String key : nsMap.keySet() )
    {
      String value = nsMap.get( key );
      inverseNsMap.put( value, key );
    }

    StringBuffer buf = new StringBuffer();
    buf.append( "/" );

    for( int c = pathComponents.size() - 1; c >= 0; c-- )
    {
      buf.append( "/" );
      String s = pathComponents.get( c );
      String[] words = s.split( ":" );
      if( words.length == 2 )
      {
        String ns = inverseNsMap.get( words[0] );
        if( ns != null )
        {
          buf.append( ns ).append( ":" ).append( words[1] );
        }
        else
        {
          buf.append( s );
        }
      }
      else
      {
        buf.append( s );
      }
    }

    return buf.toString();
  }

  /** Get a path with no namespaces or namespace prefixes. */
  public String getShortPath()
  {
    StringBuffer buf = new StringBuffer();
    buf.append( "/" );

    for( int c = pathComponents.size() - 1; c >= 0; c-- )
    {
      buf.append( "/" );
      String s = pathComponents.get( c );
      String[] words = s.split( ":" );
      if( words.length == 2 )
      {
        buf.append( words[1] );
      }
      else
      {
        buf.append( s );
      }
    }

    return buf.toString();
  }

  public Collection<String> getNamespaces()
  {
    return nsMap.keySet();
  }

  public boolean hasNamespaces()
  {
    return nsMap != null && !nsMap.isEmpty();
  }
}
TOP

Related Classes of com.eviware.soapui.support.xml.XPathData

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.