/* * Copyright 2014 Lukas Krejci * * 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 org.revapi.java.model; import java.util.SortedSet; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.lang.model.element.Element; import javax.lang.model.type.TypeMirror; import org.revapi.API; import org.revapi.Archive; import org.revapi.java.compilation.ProbingEnvironment; import org.revapi.java.spi.JavaElement; import org.revapi.java.spi.JavaModelElement; import org.revapi.java.spi.JavaTypeElement; import org.revapi.java.spi.TypeEnvironment; import org.revapi.java.spi.Util; import org.revapi.simple.SimpleElement; /** * @author Lukas Krejci * @since 0.1 */ public abstract class JavaElementBase<E extends Element, T extends TypeMirror> extends SimpleElement implements JavaModelElement { protected final ProbingEnvironment environment; protected final E element; protected final T representation; private final Archive archive; private String comparableSignature; private boolean inherited = false; private String stringRepre; JavaElementBase(ProbingEnvironment env, Archive archive, E element, T representation) { this.environment = env; this.element = element; this.archive = archive; this.representation = representation; } @Nonnull protected abstract String getHumanReadableElementType(); @Nullable @Override public JavaModelElement getParent() { return (JavaModelElement) super.getParent(); } @Override public void setParent(@Nullable org.revapi.Element parent) { if (parent != null && !(parent instanceof JavaModelElement)) { throw new IllegalArgumentException("A parent must be a java model element."); } super.setParent(parent); } @Nonnull @Override public API getApi() { return environment.getApi(); } @Nullable @Override public Archive getArchive() { return archive; } @Override public int compareTo(@Nonnull org.revapi.Element o) { if (getClass() != o.getClass()) { return JavaElementFactory.compareByType(this, o); } return getComparableSignature().compareTo(((JavaElementBase<?, ?>) o).getComparableSignature()); } @Nonnull @Override public TypeEnvironment getTypeEnvironment() { return environment; } public E getDeclaringElement() { return element; } @Override public T getModelRepresentation() { return representation; } @Nonnull @Override @SuppressWarnings("unchecked") public SortedSet<JavaElement> getChildren() { return (SortedSet<JavaElement>) super.getChildren(); } @Override public boolean isInherited() { return inherited; } public void setInherited(boolean inherited) { this.inherited = inherited; } @Nonnull @Override public final String getFullHumanReadableString() { if (environment.isScanningComplete() && stringRepre != null) { return stringRepre; } String ret = createFullHumanReadableString(); if (environment.isScanningComplete()) { stringRepre = ret; } return ret; } protected String createFullHumanReadableString() { String decl = Util.toHumanReadableString(getDeclaringElement()); if (isInherited()) { org.revapi.Element parent = getParent(); while (parent != null && !(parent instanceof JavaTypeElement)) { parent = parent.getParent(); } JavaTypeElement parentType = (JavaTypeElement) parent; if (parentType != null) { decl += " @ " + Util.toHumanReadableString(parentType.getDeclaringElement()); } } return getHumanReadableElementType() + " " + decl; } @Override public int hashCode() { return getFullHumanReadableString().hashCode(); } @Override public boolean equals(Object obj) { if (obj == this) { return true; } return obj != null && obj instanceof JavaElementBase && getFullHumanReadableString().equals(((JavaElementBase<?, ?>) obj).getFullHumanReadableString()); } @Override public String toString() { return getFullHumanReadableString(); } protected String getComparableSignature() { if (comparableSignature == null) { comparableSignature = createComparableSignature(); } return comparableSignature; } protected abstract String createComparableSignature(); }