Package com.android.builder.internal.incremental

Source Code of com.android.builder.internal.incremental.FileEntity$Sha1Exception

/*
* Copyright (C) 2012 The Android Open Source Project
*
* 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.android.builder.internal.incremental;

import com.google.common.hash.HashCode;
import com.google.common.hash.Hashing;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;

import java.io.File;

/**
* A {@link File} and its associated data needed to figure out if a file changed or not.
*/
class FileEntity {

    private static final byte[] sBuffer = new byte[4096];

    private final File mFile;
    private final long mLastModified;
    private long mLength;
    private String mSha1;

    /**
     * Exception to indicate a failure to check a jar file's content.
     */
    private static final class Sha1Exception extends Exception {
        private static final long serialVersionUID = 1L;
        private final File file;

        public Sha1Exception(File jarFile, Throwable cause) {
            super(cause);
            file = jarFile;
        }

        public File getJarFile() {
            return file;
        }
    }

    /**
     * Creates an entity from cached data.
     *
     * @param file the file
     * @param lastModified when it was last modified
     * @param length its length
     * @param sha1 its sha1
     */
    FileEntity(File file, long lastModified, long length, String sha1) {
        mFile = file;
        mLastModified = lastModified;
        mLength = length;
        mSha1 = sha1;
    }

    /**
     * Creates an entity from a {@link File}.
     *
     * The sha1 is not computed yet, it'll be done on demand when {@link #getSha1()} is called.
     *
     * @param file the file.
     */
    FileEntity(File file) {
        mFile = file;
        mLastModified = file.lastModified();
        mLength = file.length();
    }

    /**
     * Returns the file's last modified info.
     * @return the file's last modified info.
     */
    long getLastModified() {
        return mLastModified;
    }

    /**
     * Return the file length.
     * @return the file length.
     */
    long getLength() {
        return mLength;
    }

    /**
     * Returns the file this entity represents.
     * @return the file.
     */
    File getFile() {
        return mFile;
    }

    /**
     * Returns the file's sha1, computing it if necessary.
     *
     * @return the fha1 or null if it couldn't be computed.
     */
    String getSha1() {
        try {
            return computeAndReturnSha1();
        } catch (Sha1Exception e) {
            return null;
        }
    }

    /**
     * Checks whether the {@link File#lastModified()} matches the cached value. If not, length
     * is updated and the sha1 is reset (but not recomputed, this is done on demand).
     *
     * @return return whether the file was changed.
     */
    private boolean checkValidity() {
        if (mLastModified != mFile.lastModified()) {
            mLength = mFile.length();
            mSha1 = null;
            return true;
        }

        return false;
    }

    /**
     * Returns whether the two entity are different files.
     *
     * This will compute the files' sha1 if they are not yet computed.
     *
     * @param fileEntity the file to compare to.
     * @return true if the files are the same, false otherwise.
     */
    public boolean isDifferentThan(FileEntity fileEntity) {
        assert fileEntity.mFile.equals(mFile);

        // same date, same files.
        if (mLastModified == fileEntity.mLastModified) {
            return false;
        }

        try {
            // different date doesn't necessarily mean different file.
            // start with size, less computing intensive than sha1.
            return mLength != fileEntity.mLength ||
                    !computeAndReturnSha1().equals(fileEntity.computeAndReturnSha1());
        } catch (Sha1Exception e) {
            // if we can't compute the sha1, we consider the files different.
            return true;
        }
    }

    /**
     * Returns the file's sha1, computing it if necessary.
     *
     * @return the sha1
     * @throws Sha1Exception
     */
    private String computeAndReturnSha1() throws Sha1Exception {
        if (mSha1 == null) {
            mSha1 = getSha1(mFile);
        }
        return mSha1;
    }

    /**
     * Computes the sha1 of a file and returns it.
     *
     * @param f the file to compute the sha1 for.
     * @return the sha1 value
     * @throws Sha1Exception if the sha1 value cannot be computed.
     */
    static String getSha1(File f) throws Sha1Exception {
        synchronized (sBuffer) {

            try {
                HashCode value = ByteStreams.hash(Files.newInputStreamSupplier(f), Hashing.sha1());
                return value.toString();
            } catch (Exception e) {
                throw new Sha1Exception(f, e);
            }
        }
    }

    @Override
    public String toString() {
        return "FileEntity{" +
                "mFile=" + mFile +
                ", mLastModified=" + mLastModified +
                ", mLength=" + mLength +
                ", mSha1='" + mSha1 + '\'' +
                '}';
    }
}
TOP

Related Classes of com.android.builder.internal.incremental.FileEntity$Sha1Exception

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.