com.google.gwt.core.ext.linker.EmittedArtifact.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.core.ext.linker.EmittedArtifact.java

Source

/*
 * Copyright 2008 Google Inc.
 * 
 * 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.google.gwt.core.ext.linker;

import com.google.gwt.core.ext.Linker;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.util.Util;
import com.google.gwt.util.tools.Utility;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * An artifact that will be emitted into the output. All EmittedArtifacts
 * contained in the {@link ArtifactSet} at the end of the Linking process will
 * be emitted by the compiler into the module's output directory. This type may
 * be extended by Linker providers to provide alternative implementations of
 * {@link #getContents(TreeLogger)}.
 * 
 * TODO(bobv): provide a timestamp so we can make the time on output files match
 * that of input files?
 */
public abstract class EmittedArtifact extends Artifact<EmittedArtifact> {

    /**
     * Describes the visibility of an artifact.
     */
    public enum Visibility {

        /**
         * A public artifact is something that may be served to clients.
         */
        Public,

        /**
         * A private artifact is something that is only used during the build
         * process.
         */
        Private {
            @Override
            public boolean matches(Visibility visibility) {
                switch (visibility) {
                case LegacyDeploy:
                case Private:
                    return true;
                default:
                    return false;
                }
            }
        },

        /**
         * A deploy artifact is deployed to the server but is never served to the
         * client.
         */
        Deploy {
            @Override
            public boolean matches(Visibility visibility) {
                switch (visibility) {
                case Deploy:
                case LegacyDeploy:
                    return true;
                default:
                    return false;
                }
            }
        },

        /**
         * For legacy use only - used for artifacts that were previously marked as
         * private because they should not be delivered to the client, but actually
         * should be visible to the server.  These artifacts will now be treated as
         * both Private and Deploy, so that existing build tools that expect to find
         * them in the output directory for Private artifacts will find them.
         * 
         * New code should use Deploy instead.
         */
        LegacyDeploy {
            @Override
            public boolean matches(Visibility visibility) {
                switch (visibility) {
                case Deploy:
                case LegacyDeploy:
                case Private:
                    return true;
                default:
                    return false;
                }
            }
        };

        /**
         * Returns true if this visibility matches the requested visibility level,
         * dealing with the fact that {@link #LegacyDeploy} matches both
         * {@link #Private} and {@link #Deploy}.
         * 
         * @param visibility
         * @return true if this visibility matches the requested level
         */
        public boolean matches(Visibility visibility) {
            return this == visibility;
        }
    }

    private final String partialPath;

    /**
     * This is mutable because it has no effect on identity.
     */
    private Visibility visibility;

    protected EmittedArtifact(Class<? extends Linker> linker, String partialPath) {
        super(linker);
        assert partialPath != null;
        this.partialPath = partialPath;
        visibility = Visibility.Public;
    }

    /**
     * Provides access to the contents of the EmittedResource.
     */
    public abstract InputStream getContents(TreeLogger logger) throws UnableToCompleteException;

    /**
     * Returns the time, measured in milliseconds from the epoch, at which the
     * Artifact was last modified. This will be used to set the last-modified
     * timestamp on the files written to disk.
     * <p>
     * The default implementation always returns the current time. Subclasses
     * should override this method to provide a type-appropriate value.
     * 
     * @return the time at which the Artifact was last modified
     */
    public long getLastModified() {
        return System.currentTimeMillis();
    }

    /**
     * Returns the partial path within the output directory of the
     * EmittedArtifact.
     */
    public final String getPartialPath() {
        return partialPath;
    }

    /**
     * @return the visibility
     */
    public Visibility getVisibility() {
        return visibility;
    }

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

    /**
     * Returns whether or not the data contained in the EmittedArtifact should be
     * written into the module output directory or into an auxiliary directory.
     * <p>
     * EmittedArtifacts that return <code>true</code> for this method will not
     * be emitted into the normal module output location, but will instead be
     * written into a directory that is a sibling to the module output directory.
     * The partial path of the EmittedArtifact will be prepended with the
     * short-name of the Linker type that created the EmittedArtifact.
     * <p>
     * Private EmittedArtifacts are intended for resources that generally should
     * not be deployed to the server in the same location as the module
     * compilation artifacts.
     * 
     * @deprecated use {@link #getVisibility()} instead
     */
    @Deprecated
    public boolean isPrivate() {
        return visibility == Visibility.Private;
    }

    /**
     * Sets the private attribute of the EmittedResource.
     * 
     * @param isPrivate true if this artifact is private
     *
     * @deprecated use {@link #setVisibility(Visibility)} instead
     */
    @Deprecated
    public void setPrivate(boolean isPrivate) {
        this.visibility = isPrivate ? Visibility.Private : Visibility.Public;
    }

    /**
     * @param visibility the visibility to set
     */
    public void setVisibility(Visibility visibility) {
        this.visibility = visibility;
    }

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

    /**
     * Provides access to the contents of the EmittedResource.
     */
    public void writeTo(TreeLogger logger, OutputStream out) throws UnableToCompleteException {
        try {
            InputStream in = getContents(logger);
            Util.copyNoClose(in, out);
            Utility.close(in);
        } catch (IOException e) {
            logger.log(TreeLogger.ERROR, "Unable to read or write stream", e);
            throw new UnableToCompleteException();
        }
    }

    @Override
    protected final int compareToComparableArtifact(EmittedArtifact o) {
        return getPartialPath().compareTo(o.getPartialPath());
    }

    @Override
    protected final Class<EmittedArtifact> getComparableArtifactType() {
        return EmittedArtifact.class;
    }
}