
org.inferred.freebuilder.processor.Metadata Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of freebuilder Show documentation
Show all versions of freebuilder Show documentation
Automatic generation of the Builder pattern for Java 1.6+
/*
* Copyright 2014 Google Inc. All rights reserved.
*
* 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.inferred.freebuilder.processor;
import static com.google.common.base.Preconditions.checkState;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Ordering;
import org.inferred.freebuilder.processor.util.Excerpt;
import org.inferred.freebuilder.processor.util.ParameterizedType;
import org.inferred.freebuilder.processor.util.QualifiedName;
import org.inferred.freebuilder.processor.util.SourceBuilder;
import javax.annotation.Nullable;
import javax.lang.model.type.TypeMirror;
/**
* Metadata about a @{@link org.inferred.freebuilder.FreeBuilder FreeBuilder} type.
*/
public abstract class Metadata {
/** Standard Java methods that may be underridden. */
public enum StandardMethod {
TO_STRING, HASH_CODE, EQUALS
}
/** How compulsory the underride is. */
public enum UnderrideLevel {
/** There is no underride. */
ABSENT,
/** The underride can be overridden (viz. to respect Partials). */
OVERRIDEABLE,
/** The underride is declared final. */
FINAL;
}
public enum Visibility implements Excerpt {
PUBLIC("public "), PROTECTED("protected "), PACKAGE(""), PRIVATE("private ");
private final String excerpt;
private Visibility(String excerpt) {
this.excerpt = excerpt;
}
public static Visibility mostVisible(Visibility a, Visibility b) {
return Ordering.natural().min(a, b);
}
@Override
public void addTo(SourceBuilder code) {
code.add(excerpt);
}
}
/** Returns the type itself. */
public abstract ParameterizedType getType();
/** Returns true if the type is an interface. */
public abstract boolean isInterfaceType();
abstract Optional getOptionalBuilder();
/**
* Returns true if there is a user-visible Builder subclass defined.
*/
public boolean hasBuilder() {
return getOptionalBuilder().isPresent();
}
/**
* Returns the builder type that users will see.
*
* @throws IllegalStateException if {@link #hasBuilder} returns false.
*/
public ParameterizedType getBuilder() {
return getOptionalBuilder().get();
}
/** Returns the builder factory mechanism the user has exposed, if any. */
public abstract Optional getBuilderFactory();
/** Returns the builder class that should be generated. */
public abstract ParameterizedType getGeneratedBuilder();
/** Returns the value class that should be generated. */
public abstract ParameterizedType getValueType();
/** Returns the partial value class that should be generated. */
public abstract ParameterizedType getPartialType();
/**
* Returns a set of nested types that will be visible in the generated class, either because they
* will be generated, or because they are present in a superclass.
*/
public abstract ImmutableSet getVisibleNestedTypes();
/** Returns the Property enum that may be generated. */
public abstract ParameterizedType getPropertyEnum();
/** Returns metadata about the properties of the type. */
public abstract ImmutableList getProperties();
public UnderrideLevel standardMethodUnderride(StandardMethod standardMethod) {
UnderrideLevel underrideLevel = getStandardMethodUnderrides().get(standardMethod);
return (underrideLevel == null) ? UnderrideLevel.ABSENT : underrideLevel;
}
public abstract ImmutableMap getStandardMethodUnderrides();
/** Returns whether the builder type should be serializable. */
public abstract boolean isBuilderSerializable();
/** Returns a list of annotations that should be applied to the generated builder class. */
public abstract ImmutableList getGeneratedBuilderAnnotations();
/** Returns a list of annotations that should be applied to the generated value class. */
public abstract ImmutableList getValueTypeAnnotations();
/** Returns the visibility of the generated value class. */
public abstract Visibility getValueTypeVisibility();
/** Returns a list of nested classes that should be added to the generated builder class. */
public abstract ImmutableList> getNestedClasses();
/** Metadata about a property of a {@link Metadata}. */
public interface Property {
/** Returns the type of the property. */
TypeMirror getType();
/** Returns the boxed form of {@link #getType()}, or null if type is not primitive. */
@Nullable TypeMirror getBoxedType();
/** Returns the name of the property, e.g. myProperty. */
String getName();
/** Returns the capitalized name of the property, e.g. MyProperty. */
String getCapitalizedName();
/** Returns the name of the property in all-caps with underscores, e.g. MY_PROPERTY. */
String getAllCapsName();
/** Returns the name of the getter for the property, e.g. getMyProperty, or isSomethingTrue. */
String getGetterName();
/**
* Returns the code generator to use for this property, or null if no generator has been picked
* (i.e. when passed to {@link PropertyCodeGenerator.Factory#create}.
*/
@Nullable PropertyCodeGenerator getCodeGenerator();
/**
* Returns true if a cast to this property type is guaranteed to be fully checked at runtime.
* This is true for any type that is non-generic, raw, or parameterized with unbounded
* wildcards, such as {@code Integer}, {@code List} or {@code Map, ?>}.
*/
boolean isFullyCheckedCast();
/**
* Returns a list of annotations that should be applied to the accessor methods of this
* property; that is, the getter method, and a single setter method that will accept the result
* of the getter method as its argument. For a list, for example, that would be getX() and
* addAllX().
*/
ImmutableList getAccessorAnnotations();
/** Builder for {@link Property}. */
class Builder extends Metadata_Property_Builder {}
}
public static final Function GET_CODE_GENERATOR =
new Function() {
@Override
public PropertyCodeGenerator apply(Property input) {
return input.getCodeGenerator();
}
};
/** Builder for {@link Metadata}. */
public static class Builder extends Metadata_Builder {
public Builder() {
super.setValueTypeVisibility(Visibility.PRIVATE);
}
/**
* Sets the value to be returned by {@link Metadata#getValueTypeVisibility()} to the most visible
* of the current value and {@code visibility}. Will not decrease visibility.
*
* @return this {@code Builder} object
* @throws NullPointerException if {@code visibility} is null
*/
@Override
public Builder setValueTypeVisibility(Visibility visibility) {
return super.setValueTypeVisibility(
Visibility.mostVisible(getValueTypeVisibility(), visibility));
}
/** Sets the builder class that users will see, if any. */
public Builder setBuilder(Optional builder) {
return setOptionalBuilder(builder);
}
/** Sets the builder class that users will see. */
public Builder setBuilder(ParameterizedType builder) {
return setOptionalBuilder(builder);
}
/**
* Returns a newly-built {@link Metadata} based on the content of the {@code Builder}.
*/
@Override
public Metadata build() {
Metadata metadata = super.build();
QualifiedName generatedBuilder = metadata.getGeneratedBuilder().getQualifiedName();
checkState(metadata.getValueType().getQualifiedName().getEnclosingType()
.equals(generatedBuilder),
"%s not a nested class of %s", metadata.getValueType(), generatedBuilder);
checkState(metadata.getPartialType().getQualifiedName().getEnclosingType()
.equals(generatedBuilder),
"%s not a nested class of %s", metadata.getPartialType(), generatedBuilder);
checkState(metadata.getPropertyEnum().getQualifiedName().getEnclosingType()
.equals(generatedBuilder),
"%s not a nested class of %s", metadata.getPropertyEnum(), generatedBuilder);
return metadata;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy