| /* |
| * 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 java.io.Serializable; |
| |
| /** |
| * A base type for all artifacts relating to the link process. In order to |
| * ensure stable output between runs of the compiler, Artifact types must |
| * implement a stable comparison between instances of a relevant base type (the |
| * exact comparison order is irrelevant). |
| * |
| * @param <C> The type of Artifact interface that the Artifact can be compared |
| * to. |
| */ |
| public abstract class Artifact<C extends Artifact<C>> implements |
| Comparable<Artifact<?>>, Serializable { |
| private transient Class<? extends Linker> linker; |
| private final String linkerName; |
| |
| /** |
| * Constructor. |
| * |
| * @param linker the type of Linker that instantiated the Artifact. |
| */ |
| protected Artifact(Class<? extends Linker> linker) { |
| assert linker != null; |
| this.linkerName = linker.getName(); |
| this.linker = linker; |
| } |
| |
| @Override |
| public final int compareTo(Artifact<?> o) { |
| if (getComparableArtifactType().equals(o.getComparableArtifactType())) { |
| return compareToComparableArtifact(getComparableArtifactType().cast(o)); |
| } else { |
| return getComparableArtifactType().getName().compareTo( |
| o.getComparableArtifactType().getName()); |
| } |
| } |
| |
| /** |
| * Delegates to {@link #compareTo(Artifact)}. |
| */ |
| @Override |
| public final boolean equals(Object obj) { |
| if (obj instanceof Artifact<?>) { |
| return compareTo((Artifact<?>) obj) == 0; |
| } else { |
| return false; |
| } |
| } |
| |
| /** |
| * Returns the Linker that created the Artifact. |
| */ |
| public final Class<? extends Linker> getLinker() { |
| // linker is null when deserialized. |
| if (linker == null) { |
| try { |
| Class<?> clazz = Class.forName(linkerName, false, |
| Thread.currentThread().getContextClassLoader()); |
| linker = clazz.asSubclass(Linker.class); |
| } catch (ClassNotFoundException e) { |
| // The class may not be available. |
| linker = Linker.class; |
| } |
| } |
| return linker; |
| } |
| |
| /** |
| * The class which is returned from {@link #getComparableArtifactType()} must |
| * declare a final implementation which returns the same hash code for objects |
| * for which {@link #compareToComparableArtifact(Artifact)} returns 0. |
| */ |
| @Override |
| public abstract int hashCode(); |
| |
| /** |
| * Returns whether the {@link Transferable} annotation is present on this |
| * class. See {@link Transferable} for the implications. |
| */ |
| public final boolean isTransferableFromShards() { |
| return getClass().isAnnotationPresent(Transferable.class); |
| } |
| |
| @Override |
| public String toString() { |
| return getClass().getName() + " created by " + getLinker().getName(); |
| } |
| |
| /** |
| * Performs comparison with an artifact of a compatible base type. Objects |
| * which compare to 0 are assumed equal, and must return the same |
| * {@link #hashCode()}. |
| */ |
| protected abstract int compareToComparableArtifact(C o); |
| |
| /** |
| * Returns the base type to use for comparisons between Artifacts. All |
| * concrete implementations of this methods must be final. |
| */ |
| protected abstract Class<C> getComparableArtifactType(); |
| } |