Package com.eviware.soapui.impl.support.definition.support

Source Code of com.eviware.soapui.impl.support.definition.support.AbstractDefinitionContext

/*
*  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.impl.support.definition.support;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.SchemaTypeSystem;

import com.eviware.soapui.SoapUI;
import com.eviware.soapui.impl.support.AbstractInterface;
import com.eviware.soapui.impl.support.DefinitionContext;
import com.eviware.soapui.impl.support.definition.DefinitionCache;
import com.eviware.soapui.impl.support.definition.DefinitionLoader;
import com.eviware.soapui.impl.support.definition.InterfaceDefinition;
import com.eviware.soapui.impl.support.definition.InterfaceDefinitionPart;
import com.eviware.soapui.impl.wsdl.support.PathUtils;
import com.eviware.soapui.impl.wsdl.support.xsd.SchemaException;
import com.eviware.soapui.support.UISupport;
import com.eviware.x.dialogs.Worker;
import com.eviware.x.dialogs.XProgressDialog;
import com.eviware.x.dialogs.XProgressMonitor;

/**
* Holder for InterfaceDefinitions and related SchemaTypeLoader types
*
* @author Ole.Matzura
*/

public abstract class AbstractDefinitionContext<T extends AbstractInterface<?>, T2 extends DefinitionLoader, T3 extends AbstractInterfaceDefinition<T>>
    implements DefinitionContext<T>
{
  private String url;
  private T3 definition;
  private boolean loaded;
  private SchemaException schemaException;

  private final static Logger log = Logger.getLogger( AbstractDefinitionContext.class );

  private T2 currentLoader;
  private T iface;

  private static Map<String, InterfaceDefinition<?>> definitionCache = new HashMap<String, InterfaceDefinition<?>>();
  private static Map<String, Integer> urlReferences = new HashMap<String, Integer>();

  public AbstractDefinitionContext( String url, T iface )
  {
    this.url = PathUtils.ensureFilePathIsUrl( url );
    this.iface = iface;
  }

  public AbstractDefinitionContext( String url )
  {
    this( url, null );
  }

  public T getInterface()
  {
    return iface;
  }

  @SuppressWarnings( "unchecked" )
  public T3 getInterfaceDefinition() throws Exception
  {
    loadIfNecessary();
    return ( T3 )( definition == null ? definitionCache.get( url ) : definition );
  }

  public synchronized boolean isLoaded()
  {
    return loaded;
  }

  public synchronized boolean loadIfNecessary() throws Exception
  {
    if( !loaded )
      load();
    return loaded;
  }

  public synchronized void setDefinition( String url, boolean updateCache ) throws Exception
  {
    if( !url.equals( this.url ) )
    {
      this.url = url;

      if( updateCache )
      {
        definitionCache.remove( url );
        loaded = false;
        load();
      }

      // FIXME Refactoring: loaded = (definition != null) ?
      loaded = iface != null && definitionCache.containsKey( url );
    }
  }

  public synchronized boolean load() throws Exception
  {
    return load( null );
  }

  public synchronized boolean load( T2 wsdlLoader ) throws Exception
  {
    // only use cache if iface has been specified
    if( !loaded && iface != null )
    {
      // FIXME Refactoring: loaded = (definition != null) ?
      loaded = definitionCache.containsKey( url );
    }

    if( loaded )
      return true;

    // always use progressDialog since files can import http urls
    XProgressDialog progressDialog = UISupport.getDialogs().createProgressDialog( "Loading Definition", 3,
        "Loading definition..", true );

    Loader loader = new Loader( wsdlLoader );
    progressDialog.run( loader );

    // Get the value. It is the responsibility of the progressDialog to
    // wait for the other thread to finish.
    if( loader.hasError() )
    {
      if( loader.getError() instanceof InvalidDefinitionException )
        throw ( InvalidDefinitionException )loader.getError();

      if( loader.getError() instanceof SchemaException )
      {
        schemaException = ( SchemaException )loader.getError();
        ArrayList<?> errorList = schemaException.getErrorList();

        log.error( "Error loading schema types from " + url + ", see log for details" );

        if( errorList != null )
        {
          for( int c = 0; c < errorList.size(); c++ )
          {
            log.error( errorList.get( c ).toString() );
          }
        }

        throw new InvalidDefinitionException( schemaException );
      }
      else
        throw new Exception( loader.getError() );
    }
    else
    {
      loaded = true;
    }

    return loaded;
  }

  public SchemaTypeLoader getSchemaTypeLoader() throws Exception
  {
    loadIfNecessary();
    return iface != null && definitionCache.containsKey( url ) ? definitionCache.get( url ).getSchemaTypeLoader()
        : definition != null ? definition.getSchemaTypeLoader() : null;
  }

  public SchemaException getSchemaException()
  {
    return schemaException;
  }

  private class Loader extends Worker.WorkerAdapter
  {
    private Throwable error;
    private T2 wsdlLoader;

    public Loader( T2 wsdlLoader )
    {
      super();
      this.wsdlLoader = wsdlLoader;
    }

    private T2 getDefinitionLoader()
    {
      if( wsdlLoader != null )
      {
        return wsdlLoader;
      }
      else
      {
        return createDefinitionLoader( url );
      }
    }

    public boolean hasError()
    {
      return error != null;
    }

    public Object construct( XProgressMonitor monitor )
    {
      try
      {
        DefinitionCache cache = iface == null ? new StandaloneDefinitionCache<T>()
            : new InterfaceConfigDefinitionCache<T>( iface );

        if( !cache.validate() )
        {
          monitor.setProgress( 1, "Caching Definition from url [" + url + "]" );

          currentLoader = getDefinitionLoader();
          currentLoader.setProgressMonitor( monitor, 2 );

          cache.update( currentLoader );

          if( currentLoader.isAborted() )
            throw new Exception( "Loading of Definition from [" + url + "] was aborted" );
        }

        monitor.setProgress( 1, "Loading Definition from " + ( iface == null ? "url" : "cache" ) );

        log.debug( "Loading Definition..." );
        cacheDefinition( cache );
        return null;
      }
      catch( Throwable e )
      {
        SoapUI.logError( e );
        this.error = e;
        return e;
      }
      finally
      {
        currentLoader = null;
      }
    }

    public Throwable getError()
    {
      return error;
    }

    public boolean onCancel()
    {
      if( currentLoader == null )
        return false;

      return currentLoader.abort();
    }
  }

  private void cacheDefinition( DefinitionCache cache ) throws Exception
  {
    currentLoader = createDefinitionLoader( cache );
    currentLoader.setProgressInfo( "Loading Definition" );
    definition = loadDefinition( currentLoader );
    if( definition != null )
      definition.setDefinitionCache( cache );

    log.debug( "Loaded Definition: " + ( definition != null ? "ok" : "null" ) );

    if( !currentLoader.isAborted() && iface != null && iface.isDefinitionShareble() )
    {
      definitionCache.put( url, definition );
      if( urlReferences.containsKey( url ) )
      {
        urlReferences.put( url, urlReferences.get( url ) + 1 );
      }
      else
      {
        urlReferences.put( url, 1 );
      }
    }

    if( currentLoader.isAborted() )
      throw new Exception( "Loading of Definition from [" + url + "] was aborted" );

    loaded = true;
  }

  protected abstract T2 createDefinitionLoader( DefinitionCache definitionCache );

  protected abstract T2 createDefinitionLoader( String url );

  protected abstract T3 loadDefinition( T2 loader ) throws Exception;

  public void release()
  {
    if( iface != null && urlReferences.containsKey( url ) )
    {
      Integer i = urlReferences.get( url );
      if( i.intValue() <= 1 )
      {
        urlReferences.remove( url );
        definitionCache.remove( url );
      }
      else
      {
        urlReferences.put( url, i - 1 );
      }
    }
  }

  public SchemaTypeSystem getSchemaTypeSystem() throws Exception
  {
    if( !isLoaded() )
      load();

    if( !definitionCache.containsKey( url ) )
      return null;

    return definitionCache.get( url ).getSchemaTypeSystem();
  }

  public boolean hasSchemaTypes()
  {
    try
    {
      loadIfNecessary();
    }
    catch( Exception e )
    {
      SoapUI.logError( e );
      return false;
    }

    InterfaceDefinition<?> def = ( definition != null ? definition : definitionCache.get( url ) );
    return def != null && def.hasSchemaTypes();
  }

  public String getUrl()
  {
    return url;
  }

  public void setInterface( T iface )
  {
    if( this.iface == null && iface != null )
    {
      if( definition != null )
      {
        if( definition.getDefinitionCache().validate() )
        {
          InterfaceConfigDefinitionCache<T> cache = new InterfaceConfigDefinitionCache<T>( iface );
          try
          {
            cache.importCache( definition.getDefinitionCache() );
          }
          catch( Exception e )
          {
            SoapUI.logError( e );
          }

          definition.setDefinitionCache( cache );
        }

        definition.setIface( iface );
        definitionCache.put( url, definition );
      }
      else
      {
        loaded = false;
      }
    }

    this.iface = iface;
  }

  public static void uncache( String url )
  {
    definitionCache.remove( url );
    urlReferences.remove( url );
  }

  public void reload() throws Exception
  {
    getDefinitionCache().clear();
    definitionCache.remove( url );
    loaded = false;
    load();
  }

  public boolean isCached()
  {
    return isLoaded() && definition != null && definition.getDefinitionCache() != null;
  }

  public List<InterfaceDefinitionPart> getDefinitionParts() throws Exception
  {
    loadIfNecessary();

    return getInterfaceDefinition().getDefinitionParts();
  }

  public DefinitionCache getDefinitionCache() throws Exception
  {
    loadIfNecessary();

    return getInterfaceDefinition().getDefinitionCache();
  }
}
TOP

Related Classes of com.eviware.soapui.impl.support.definition.support.AbstractDefinitionContext

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.