Android Open Source - android-sdk Ad View Controller






From Project

Back to project page android-sdk.

License

The source code is released under:

Copyright (c) 2013 Adcash OU. All rights reserved under Creative Commons Attribution 3.0 Unported http://creativecommons.org/licenses/by/3.0/ Redistribution and use in source and binary forms, with or...

If you think the Android project android-sdk listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (c) 2010-2013, Adcash OU./*w w w .j a  v a  2  s. c o m*/
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *  Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 *  Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 *  Neither the name of 'MoPub Inc.' nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.adcash.mobileads;

import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;

import com.adcash.mobileads.AdcashView.LocationAwareness;
import static com.adcash.mobileads.GpsHelper.GpsHelperListener;
import static com.adcash.mobileads.GpsHelper.asyncFetchAdvertisingInfoIfNotCached;
import com.adcash.mobileads.factories.AdFetcherFactory;
import com.adcash.mobileads.factories.HttpClientFactory;
import com.adcash.mobileads.util.Dips;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import java.math.BigDecimal;
import java.util.*;

import static android.Manifest.permission.ACCESS_NETWORK_STATE;
import static com.adcash.mobileads.AdcashView.DEFAULT_LOCATION_PRECISION;

public class AdViewController {
    static final int MINIMUM_REFRESH_TIME_MILLISECONDS = 10000;
    static final int DEFAULT_REFRESH_TIME_MILLISECONDS = 60000;
    private static final FrameLayout.LayoutParams WRAP_AND_CENTER_LAYOUT_PARAMS =
            new FrameLayout.LayoutParams(
                    FrameLayout.LayoutParams.WRAP_CONTENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT,
                    Gravity.CENTER);
    private static WeakHashMap<View,Boolean> sViewShouldHonorServerDimensions = new WeakHashMap<View, Boolean>();;

    private final Context mContext;
    private AdcashView mAdcashView;
    private final AdUrlGenerator mUrlGenerator;
    private AdFetcher mAdFetcher;
    private AdConfiguration mAdConfiguration;
    private final Runnable mRefreshRunnable;

    private boolean mIsDestroyed;
    private Handler mHandler;
    private boolean mIsLoading;
    private String mUrl;

    private Map<String, Object> mLocalExtras = new HashMap<String, Object>();
    private boolean mAutoRefreshEnabled = true;
    private String mKeywords;
    private Location mLocation;
    private LocationAwareness mLocationAwareness = LocationAwareness.LOCATION_AWARENESS_NORMAL;
    private int mLocationPrecision = DEFAULT_LOCATION_PRECISION;
    private boolean mIsFacebookSupported = true;
    private boolean mIsTesting;
  private GpsHelperListener mGpsHelperListener;

    protected static void setShouldHonorServerDimensions(View view) {
        sViewShouldHonorServerDimensions.put(view, true);
    }

    private static boolean getShouldHonorServerDimensions(View view) {
        return sViewShouldHonorServerDimensions.get(view) != null;
    }

    public AdViewController(Context context, AdcashView view) {
        mContext = context;
        mAdcashView = view;

        mUrlGenerator = new AdUrlGenerator(context);
        mAdConfiguration = new AdConfiguration(mContext);

        mAdFetcher = AdFetcherFactory.create(this, mAdConfiguration.getUserAgent());
          
        mGpsHelperListener = new AdViewControllerGpsHelperListener();
        
        mRefreshRunnable = new Runnable() {
            public void run() {
                loadAd();
            }
        };

        mHandler = new Handler();
    }

    public AdcashView getAdcashView() {
        return mAdcashView;
    }

    public void loadAd() {
        if (mAdConfiguration.getAdUnitId() == null) {
            Log.d("Adcash", "Can't load an ad in this ad view because the ad unit ID is null. " +
                    "Did you forget to call setAdUnitId()?");
            return;
        }

        if (!isNetworkAvailable()) {
            Log.d("Adcash", "Can't load an ad because there is no network connectivity.");
            scheduleRefreshTimerIfEnabled();
            return;
        }

        if (mLocation == null) {
            mLocation = getLastKnownLocation();
        }
        
        // If we have access to Google Play Services (GPS) but the advertising info
        // is not cached then guarantee we get it before building the ad request url
        // in the callback, this is a requirement from Google
        asyncFetchAdvertisingInfoIfNotCached(mContext, mGpsHelperListener);
        
    }

    void loadNonJavascript(String url) {
        if (url == null) return;

        Log.d("Adcash", "Loading url: " + url);
        if (mIsLoading) {
            if (mAdConfiguration.getAdUnitId() != null) {
                Log.i("Adcash", "Already loading an ad for " + mAdConfiguration.getAdUnitId() + ", wait to finish.");
            }
            return;
        }

        mUrl = url;
        mAdConfiguration.setFailUrl(null);
        mIsLoading = true;

        fetchAd(mUrl);
    }

    public void reload() {
        Log.d("Adcash", "Reload ad: " + mUrl);
        loadNonJavascript(mUrl);
    }

    void loadFailUrl(AdcashErrorCode errorCode) {
        mIsLoading = false;

        Log.v("Adcash", "AdcashErrorCode: " + (errorCode == null ? "" : errorCode.toString()));

        if (mAdConfiguration.getFailUrl() != null) {
            Log.d("Adcash", "Loading failover url: " + mAdConfiguration.getFailUrl());
            loadNonJavascript(mAdConfiguration.getFailUrl());
        } else {
            // No other URLs to try, so signal a failure.
            adDidFail(AdcashErrorCode.NO_FILL);
        }
    }

    void setFailUrl(String failUrl) {
        mAdConfiguration.setFailUrl(failUrl);
    }

    void setNotLoading() {
        this.mIsLoading = false;
    }

    public String getKeywords() {
        return mKeywords;
    }

    public void setKeywords(String keywords) {
        mKeywords = keywords;
    }

    public boolean isFacebookSupported() {
        return mIsFacebookSupported;
    }

    public void setFacebookSupported(boolean enabled) {
        mIsFacebookSupported = enabled;
    }

    public Location getLocation() {
        return mLocation;
    }

    public void setLocation(Location location) {
        mLocation = location;
    }

    public String getAdUnitId() {
        return mAdConfiguration.getAdUnitId();
    }

    public void setAdUnitId(String adUnitId) {
        mAdConfiguration.setAdUnitId(adUnitId);
    }

    public void setTimeout(int milliseconds) {
        if (mAdFetcher != null) {
            mAdFetcher.setTimeout(milliseconds);
        }
    }

    public int getAdWidth() {
        return mAdConfiguration.getWidth();
    }

    public int getAdHeight() {
        return mAdConfiguration.getHeight();
    }

    public String getClickthroughUrl() {
        return mAdConfiguration.getClickthroughUrl();
    }

    @Deprecated
    public void setClickthroughUrl(String clickthroughUrl) {
        mAdConfiguration.setClickthroughUrl(clickthroughUrl);
    }

    public String getRedirectUrl() {
        return mAdConfiguration.getRedirectUrl();
    }

    public String getResponseString() {
        return mAdConfiguration.getResponseString();
    }

    public boolean getAutorefreshEnabled() {
        return mAutoRefreshEnabled;
    }

    public void setAutorefreshEnabled(boolean enabled) {
        mAutoRefreshEnabled = enabled;

        if (mAdConfiguration.getAdUnitId() != null) {
            Log.d("Adcash", "Automatic refresh for " + mAdConfiguration + " set to: " + enabled + ".");

        }

        if (mAutoRefreshEnabled) {
            scheduleRefreshTimerIfEnabled();
        } else {
            cancelRefreshTimer();
        }
    }

    public boolean getTesting() {
        return mIsTesting;
    }

    public void setTesting(boolean enabled) {
        mIsTesting = enabled;
    }

    int getLocationPrecision() {
        return mLocationPrecision;
    }

    void setLocationPrecision(int precision) {
        mLocationPrecision = Math.max(0, precision);
    }

    AdConfiguration getAdConfiguration() {
        return mAdConfiguration;
    }

    boolean isDestroyed() {
        return mIsDestroyed;
    }

    /*
     * Clean up the internal state of the AdViewController.
     */
    void cleanup() {
        if (mIsDestroyed) {
            return;
        }

        setAutorefreshEnabled(false);
        cancelRefreshTimer();

        // WebView subclasses are not garbage-collected in a timely fashion on Froyo and below,
        // thanks to some persistent references in WebViewCore. We manually release some resources
        // to compensate for this "leak".

        mAdFetcher.cleanup();
        mAdFetcher = null;

        mAdConfiguration.cleanup();

        mAdcashView = null;

        // Flag as destroyed. LoadUrlTask checks this before proceeding in its onPostExecute().
        mIsDestroyed = true;
    }

    void configureUsingHttpResponse(final HttpResponse response) {
        mAdConfiguration.addHttpResponse(response);
    }

    Integer getAdTimeoutDelay() {
        return mAdConfiguration.getAdTimeoutDelay();
    }

    int getRefreshTimeMilliseconds() {
        return mAdConfiguration.getRefreshTimeMilliseconds();
    }

    @Deprecated
    void setRefreshTimeMilliseconds(int refreshTimeMilliseconds) {
        mAdConfiguration.setRefreshTimeMilliseconds(refreshTimeMilliseconds);
    }

    void trackImpression() {
        new Thread(new Runnable() {
            public void run () {
                if (mAdConfiguration.getImpressionUrl() == null) return;

                DefaultHttpClient httpClient = HttpClientFactory.create();
                try {
                    HttpGet httpget = new HttpGet(mAdConfiguration.getImpressionUrl());
                    httpget.addHeader("User-Agent", mAdConfiguration.getUserAgent());
                    httpClient.execute(httpget);
                } catch (Exception e) {
                    Log.d("Adcash", "Impression tracking failed : " + mAdConfiguration.getImpressionUrl(), e);
                } finally {
                    httpClient.getConnectionManager().shutdown();
                }
            }
        }).start();
    }

    void registerClick() {
        new Thread(new Runnable() {
            public void run () {
                if (mAdConfiguration.getClickthroughUrl() == null) return;

                DefaultHttpClient httpClient = HttpClientFactory.create();
                try {
                    Log.d("Adcash", "Tracking click for: " + mAdConfiguration.getClickthroughUrl());
                    HttpGet httpget = new HttpGet(mAdConfiguration.getClickthroughUrl());
                    httpget.addHeader("User-Agent", mAdConfiguration.getUserAgent());
                    httpClient.execute(httpget);
                } catch (Exception e) {
                    Log.d("Adcash", "Click tracking failed: " + mAdConfiguration.getClickthroughUrl(), e);
                } finally {
                    httpClient.getConnectionManager().shutdown();
                }
            }
        }).start();
    }

    void fetchAd(String mUrl) {
        if (mAdFetcher != null) {
            mAdFetcher.fetchAdForUrl(mUrl);
        }
    }

    void forceRefresh() {
        setNotLoading();
        loadAd();
    }

    String generateAdUrl() {
        return mUrlGenerator
                .withAdUnitId(mAdConfiguration.getAdUnitId())
                .withKeywords(mKeywords)
                .withFacebookSupported(mIsFacebookSupported)
                .withLocation(mLocation)
                .generateUrlString(getServerHostname());
    }

    void adDidFail(AdcashErrorCode errorCode) {
        Log.i("Adcash", "Ad failed to load.");
        setNotLoading();
        scheduleRefreshTimerIfEnabled();
        getAdcashView().adFailed(errorCode);
    }

    void scheduleRefreshTimerIfEnabled() {
        cancelRefreshTimer();
        if (mAutoRefreshEnabled && mAdConfiguration.getRefreshTimeMilliseconds() > 0) {
            mHandler.postDelayed(mRefreshRunnable, mAdConfiguration.getRefreshTimeMilliseconds());
        }

    }

    void setLocalExtras(Map<String, Object> localExtras) {
        mLocalExtras = (localExtras != null)
                ? new HashMap<String,Object>(localExtras)
                : new HashMap<String,Object>();
    }

    Map<String, Object> getLocalExtras() {
        return (mLocalExtras != null)
                ? new HashMap<String,Object>(mLocalExtras)
                : new HashMap<String,Object>();
    }

    private void cancelRefreshTimer() {
        mHandler.removeCallbacks(mRefreshRunnable);
    }

    private String getServerHostname() {
        return mIsTesting ? AdcashView.HOST_FOR_TESTING : AdcashView.HOST;
    }

    private boolean isNetworkAvailable() {
        // If we don't have network state access, just assume the network is up.
        int result = mContext.checkCallingPermission(ACCESS_NETWORK_STATE);
        if (result == PackageManager.PERMISSION_DENIED) return true;

        // Otherwise, perform the connectivity check.
        ConnectivityManager cm
                = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
        return networkInfo != null && networkInfo.isConnected();
    }

    void setAdContentView(final View view) {
        // XXX: This method is called from the WebViewClient's callbacks, which has caused an error on a small portion of devices
        // We suspect that the code below may somehow be running on the wrong UI Thread in the rare case.
        // see: http://stackoverflow.com/questions/10426120/android-got-calledfromwrongthreadexception-in-onpostexecute-how-could-it-be
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                AdcashView adCashView = getAdcashView();
                if (adCashView == null) {
                    return;
                }
                adCashView.removeAllViews();
                adCashView.addView(view, getAdLayoutParams(view));
            }
        });
    }

    private FrameLayout.LayoutParams getAdLayoutParams(View view) {
        int width = mAdConfiguration.getWidth();
        int height = mAdConfiguration.getHeight();

        if (getShouldHonorServerDimensions(view) && width > 0 && height > 0) {
            int scaledWidth = Dips.asIntPixels(width, mContext);
            int scaledHeight = Dips.asIntPixels(height, mContext);

            return new FrameLayout.LayoutParams(scaledWidth, scaledHeight, Gravity.CENTER);
        } else {
            return WRAP_AND_CENTER_LAYOUT_PARAMS;
        }
    }
    
    class AdViewControllerGpsHelperListener implements GpsHelperListener {
        @Override
        public void onFetchAdInfoCompleted() {
            String adUrl = generateAdUrl();
            loadNonJavascript(adUrl);
        }
    }
    
    /*
     * Returns the last known location of the device using its GPS and network location providers.
     * May be null if:
     * - Location permissions are not requested in the Android manifest file
     * - The location providers don't exist
     * - Location awareness is disabled in the parent AdcashView
     */
    private Location getLastKnownLocation() {
        Location result;

        if (mLocationAwareness == LocationAwareness.LOCATION_AWARENESS_DISABLED) {
            return null;
        }

        LocationManager lm = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
        Location gpsLocation = null;
        try {
            gpsLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        } catch (SecurityException e) {
            Log.d("Adcash", "Failed to retrieve GPS location: access appears to be disabled.");
        } catch (IllegalArgumentException e) {
            Log.d("Adcash", "Failed to retrieve GPS location: device has no GPS provider.");
        }

        Location networkLocation = null;
        try {
            networkLocation = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        } catch (SecurityException e) {
            Log.d("Adcash", "Failed to retrieve network location: access appears to be disabled.");
        } catch (IllegalArgumentException e) {
            Log.d("Adcash", "Failed to retrieve network location: device has no network provider.");
        }

        if (gpsLocation == null && networkLocation == null) {
            return null;
        }
        else if (gpsLocation != null && networkLocation != null) {
            if (gpsLocation.getTime() > networkLocation.getTime()) result = gpsLocation;
            else result = networkLocation;
        }
        else if (gpsLocation != null) result = gpsLocation;
        else result = networkLocation;

        // Truncate latitude/longitude to the number of digits specified by locationPrecision.
        if (mLocationAwareness == LocationAwareness.LOCATION_AWARENESS_TRUNCATED) {
            double lat = result.getLatitude();
            double truncatedLat = BigDecimal.valueOf(lat)
                    .setScale(mLocationPrecision, BigDecimal.ROUND_HALF_DOWN)
                    .doubleValue();
            result.setLatitude(truncatedLat);

            double lon = result.getLongitude();
            double truncatedLon = BigDecimal.valueOf(lon)
                    .setScale(mLocationPrecision, BigDecimal.ROUND_HALF_DOWN)
                    .doubleValue();
            result.setLongitude(truncatedLon);
        }

        return result;
    }

    @Deprecated
    public void customEventDidLoadAd() {
        setNotLoading();
        trackImpression();
        scheduleRefreshTimerIfEnabled();
    }

    @Deprecated
    public void customEventDidFailToLoadAd() {
        loadFailUrl(AdcashErrorCode.UNSPECIFIED);
    }

    @Deprecated
    public void customEventActionWillBegin() {
        registerClick();
    }
}




Java Source Code List

com.adcash.mobileads.AdAlertGestureListener.java
com.adcash.mobileads.AdAlertReporter.java
com.adcash.mobileads.AdConfiguration.java
com.adcash.mobileads.AdFetchTask.java
com.adcash.mobileads.AdFetcher.java
com.adcash.mobileads.AdLoadTask.java
com.adcash.mobileads.AdTypeTranslator.java
com.adcash.mobileads.AdUrlGenerator.java
com.adcash.mobileads.AdViewController.java
com.adcash.mobileads.AdcashActivity.java
com.adcash.mobileads.AdcashConversionTracker.java
com.adcash.mobileads.AdcashErrorCode.java
com.adcash.mobileads.AdcashInterstitial.java
com.adcash.mobileads.AdcashReferrerReceiver.java
com.adcash.mobileads.AdcashView.java
com.adcash.mobileads.Adcash.java
com.adcash.mobileads.BaseHtmlWebView.java
com.adcash.mobileads.BaseInterstitialActivity.java
com.adcash.mobileads.BaseUrlGenerator.java
com.adcash.mobileads.BaseVideoView.java
com.adcash.mobileads.BaseWebView.java
com.adcash.mobileads.CustomEventBannerAdapter.java
com.adcash.mobileads.CustomEventBanner.java
com.adcash.mobileads.CustomEventInterstitialAdapter.java
com.adcash.mobileads.CustomEventInterstitial.java
com.adcash.mobileads.DefaultBannerAdListener.java
com.adcash.mobileads.DefaultInterstitialAdListener.java
com.adcash.mobileads.DiskLruCache.java
com.adcash.mobileads.EventForwardingBroadcastReceiver.java
com.adcash.mobileads.FacebookKeywordProvider.java
com.adcash.mobileads.GpsHelper.java
com.adcash.mobileads.HtmlBannerWebView.java
com.adcash.mobileads.HtmlBanner.java
com.adcash.mobileads.HtmlInterstitialWebView.java
com.adcash.mobileads.HtmlInterstitial.java
com.adcash.mobileads.HtmlWebViewClient.java
com.adcash.mobileads.HtmlWebViewListener.java
com.adcash.mobileads.Log.java
com.adcash.mobileads.MraidAbstractController.java
com.adcash.mobileads.MraidActivity.java
com.adcash.mobileads.MraidBanner.java
com.adcash.mobileads.MraidBrowserController.java
com.adcash.mobileads.MraidBrowser.java
com.adcash.mobileads.MraidCommandFactory.java
com.adcash.mobileads.MraidCommandRegistry.java
com.adcash.mobileads.MraidCommand.java
com.adcash.mobileads.MraidDisplayController.java
com.adcash.mobileads.MraidInterstitial.java
com.adcash.mobileads.MraidProperty.java
com.adcash.mobileads.MraidVideoPlayerActivity.java
com.adcash.mobileads.MraidVideoView.java
com.adcash.mobileads.MraidView.java
com.adcash.mobileads.ResponseBodyInterstitial.java
com.adcash.mobileads.SharedPreferencesHelper.java
com.adcash.mobileads.TaskTracker.java
com.adcash.mobileads.Utils.java
com.adcash.mobileads.VastVideoDownloadTask.java
com.adcash.mobileads.VastVideoInterstitial.java
com.adcash.mobileads.VastVideoView.java
com.adcash.mobileads.ViewGestureDetector.java
com.adcash.mobileads.factories.AdFetchTaskFactory.java
com.adcash.mobileads.factories.AdFetcherFactory.java
com.adcash.mobileads.factories.AdViewControllerFactory.java
com.adcash.mobileads.factories.AdcashViewFactory.java
com.adcash.mobileads.factories.CustomEventBannerAdapterFactory.java
com.adcash.mobileads.factories.CustomEventBannerFactory.java
com.adcash.mobileads.factories.CustomEventInterstitialAdapterFactory.java
com.adcash.mobileads.factories.CustomEventInterstitialFactory.java
com.adcash.mobileads.factories.HtmlBannerWebViewFactory.java
com.adcash.mobileads.factories.HtmlInterstitialWebViewFactory.java
com.adcash.mobileads.factories.HttpClientFactory.java
com.adcash.mobileads.factories.MraidViewFactory.java
com.adcash.mobileads.factories.VastManagerFactory.java
com.adcash.mobileads.factories.VastVideoDownloadTaskFactory.java
com.adcash.mobileads.factories.ViewGestureDetectorFactory.java
com.adcash.mobileads.resource.Drawables.java
com.adcash.mobileads.resource.MraidJavascript.java
com.adcash.mobileads.util.AsyncTasks.java
com.adcash.mobileads.util.Base64.java
com.adcash.mobileads.util.DateAndTime.java
com.adcash.mobileads.util.Dips.java
com.adcash.mobileads.util.Files.java
com.adcash.mobileads.util.HttpClients.java
com.adcash.mobileads.util.HttpResponses.java
com.adcash.mobileads.util.HttpUtils.java
com.adcash.mobileads.util.Json.java
com.adcash.mobileads.util.Lists.java
com.adcash.mobileads.util.Mraids.java
com.adcash.mobileads.util.Reflection.java
com.adcash.mobileads.util.ResponseHeader.java
com.adcash.mobileads.util.Streams.java
com.adcash.mobileads.util.Strings.java
com.adcash.mobileads.util.VersionCode.java
com.adcash.mobileads.util.Views.java
com.adcash.mobileads.util.WebViews.java
com.adcash.mobileads.util.vast.VastManager.java
com.adcash.mobileads.util.vast.VastXmlManager.java