com.shazam.fork.model.InstrumentationInfo.java Source code

Java tutorial

Introduction

Here is the source code for com.shazam.fork.model.InstrumentationInfo.java

Source

/*
 * Copyright 2014 Shazam Entertainment Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License.
 *
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package com.shazam.fork.model;

import com.squareup.spoon.axmlparser.AXMLParser;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import javax.annotation.Nonnull;

import static com.google.common.base.Preconditions.checkNotNull;

public final class InstrumentationInfo {
    private final String applicationPackage;
    private final String instrumentationPackage;
    private final String testRunnerClass;

    private InstrumentationInfo(String applicationPackage, String instrumentationPackage, String testRunnerClass) {
        this.applicationPackage = applicationPackage;
        this.instrumentationPackage = instrumentationPackage;
        this.testRunnerClass = testRunnerClass;
    }

    public String getApplicationPackage() {
        return applicationPackage;
    }

    public String getInstrumentationPackage() {
        return instrumentationPackage;
    }

    public String getTestRunnerClass() {
        return testRunnerClass;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    /**
     * Parse key information from an instrumentation APK's manifest.
     * @param apkTestFile the instrumentation APK
     * @return the instrumentation info instance
     */
    @Nonnull
    public static InstrumentationInfo parseFromFile(File apkTestFile) {
        InputStream is = null;
        try {
            ZipFile zip = new ZipFile(apkTestFile);
            ZipEntry entry = zip.getEntry("AndroidManifest.xml");
            is = zip.getInputStream(entry);

            AXMLParser parser = new AXMLParser(is);
            int eventType = parser.getType();

            String appPackage = null;
            String testPackage = null;
            String testRunnerClass = null;
            while (eventType != AXMLParser.END_DOCUMENT) {
                if (eventType == AXMLParser.START_TAG) {
                    String parserName = parser.getName();
                    boolean isManifest = "manifest".equals(parserName);
                    boolean isInstrumentation = "instrumentation".equals(parserName);
                    if (isManifest || isInstrumentation) {
                        for (int i = 0; i < parser.getAttributeCount(); i++) {
                            String parserAttributeName = parser.getAttributeName(i);
                            if (isManifest && "package".equals(parserAttributeName)) {
                                testPackage = parser.getAttributeValueString(i);
                            } else if (isInstrumentation && "targetPackage".equals(parserAttributeName)) {
                                appPackage = parser.getAttributeValueString(i);
                            } else if (isInstrumentation && "name".equals(parserAttributeName)) {
                                testRunnerClass = parser.getAttributeValueString(i);
                            }
                        }
                    }
                }
                eventType = parser.next();
            }
            checkNotNull(testPackage, "Could not find test application package.");
            checkNotNull(appPackage, "Could not find application package.");
            checkNotNull(testRunnerClass, "Could not find test runner class.");

            // Support relative declaration of instrumentation test runner.
            if (testRunnerClass.startsWith(".")) {
                testRunnerClass = testPackage + testRunnerClass;
            } else if (!testRunnerClass.contains(".")) {
                testRunnerClass = testPackage + "." + testRunnerClass;
            }

            return new InstrumentationInfo(appPackage, testPackage, testRunnerClass);
        } catch (IOException e) {
            throw new RuntimeException("Unable to parse test app AndroidManifest.xml.", e);
        } finally {
            IOUtils.closeQuietly(is);
        }
    }
}