
br.com.objectos.way.code.MethodInfo Maven / Gradle / Ivy
/*
* Copyright 2014 Objectos, Fábrica de Software LTDA.
*
* 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 br.com.objectos.way.code;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import br.com.objectos.way.pojo.Pojo;
import br.com.objectos.way.testable.Equality;
import br.com.objectos.way.testable.Testable;
import br.com.objectos.way.testable.Tester;
/**
* @author [email protected] (Marcio Endo)
*/
@Pojo
public abstract class MethodInfo
implements
CanGenerateCompilationError,
HasAnnotationInfoList,
Testable {
public abstract AccessInfo accessInfo();
abstract Set modifierInfoSet();
public abstract String name();
@Override
public abstract List annotationInfoList();
public abstract SimpleTypeInfo returnTypeInfo();
abstract List parameterInfoList();
MethodInfo() {
}
public static Predicate distinctSignature() {
Set signatureSet = new HashSet<>();
return (MethodInfo m) -> signatureSet.add(m.signature());
}
public static MethodInfoBuilder newPojo() {
return new MethodInfoBuilderPojo();
}
public String className() {
return Code.upperCaseFirstChar(name());
}
public boolean hasAccessInfo(AccessInfo accessInfo) {
return accessInfo().equals(accessInfo);
}
public boolean hasModifierInfo(ModifierInfo modifierInfo) {
return modifierInfoSet().contains(modifierInfo);
}
public boolean hasName(String name) {
return name().equals(name);
}
public boolean hasNamePrefix(String prefix) {
return name().startsWith(prefix);
}
public boolean hasParameterInfoListSize(int size) {
return parameterInfoList().size() == size;
}
public boolean hasParameterInfoTypes(Class>... types) {
Objects.requireNonNull(types);
if (!hasParameterInfoListSize(types.length)) {
return false;
}
int index = 0;
Iterator iterator = parameterInfoList().iterator();
while (iterator.hasNext()) {
ParameterInfo parameterInfo = iterator.next();
Class> type = types[index++];
if (!parameterInfo.isInfoOf(type)) {
return false;
}
}
return true;
}
public boolean hasReturnTypeInfo(SimpleTypeInfo typeInfo) {
return returnTypeInfo().equals(typeInfo);
}
public boolean hasReturnTypeInfoInstanceOf(Class> type) {
return returnTypeInfo().isSubType(type);
}
@Override
public Equality isEqualTo(Object that) {
return Tester.of(MethodInfo.class)
.add("name", o -> o.name())
.add("accessInfo", o -> o.accessInfo())
.add("modifierInfoSet", o -> o.modifierInfoSet())
.add("returnTypeInfo", o -> o.returnTypeInfo())
.add("annotationInfoList", o -> o.annotationInfoList())
.add("parameterInfoList", o -> o.parameterInfoList())
.test(this, that);
}
@Override
public Stream annotationInfoStream() {
Set nameSet = annotationInfoList().stream()
.map(AnnotationInfo::qualifiedName)
.collect(Collectors.toSet());
Stream enclosingStream = enclosingTypeInfoAnnotationStream()
.filter(m -> nameSet.add(m.qualifiedName()));
return Stream.concat(enclosingStream, annotationInfoList().stream());
}
public MethodInfoCodeWriter codeWriter() {
return MethodInfoCodeWriter.codeWriter(this);
}
@Override
public void compilationError(String message) {
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof MethodInfo)) {
return false;
}
MethodInfo that = (MethodInfo) obj;
return toString().equals(that.toString());
}
public String fieldName() {
String prefix = getterPrefix();
String field = name().replace(prefix, "");
return Code.lowerCaseFirstChar(field);
}
public MethodInfoFieldWriter fieldWriter() {
return new MethodInfoFieldWriter(this);
}
@Override
public int hashCode() {
return toString().hashCode();
}
public Object invoke(Object instance) {
try {
Method method = instance.getClass().getDeclaredMethod(name());
if (!method.isAccessible()) {
method.setAccessible(true);
}
return method.invoke(instance);
} catch (SecurityException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new AssertionError(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new AssertionError(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
public MethodInfoOverloadWriter overloadWriter() {
return new MethodInfoOverloadWriter(this);
}
public MethodInfoOverrideWriter overrideWriter() {
return new MethodInfoOverrideWriter(this);
}
public Stream parameterInfoStream() {
return parameterInfoList().stream();
}
public MethodInfoCodeWriter statementWriter() {
return MethodInfoCodeWriter.statementWriter(this);
}
public FieldInfo toFieldInfo() {
return FieldInfo.newPojo()
.annotationInfoList(Collections. emptyList())
.simpleTypeInfo(returnTypeInfo())
.name(fieldName())
.build();
}
@Override
public String toString() {
StringBuilder toString = new StringBuilder();
toString.append(accessInfo().declaration());
Iterator modifierInfo = modifierInfoSet().iterator();
while (modifierInfo.hasNext()) {
toString.append(modifierInfo.next());
toString.append(" ");
}
toString.append(returnTypeInfo().qualifiedName());
toString.append(" ");
toString.append(name());
toString.append("(");
Iterator parameters = parameterInfoList().iterator();
if (parameters.hasNext()) {
parameters.next().toString(toString);
while (parameters.hasNext()) {
toString.append(", ");
parameters.next().toString(toString);
}
}
toString.append(")");
return toString.toString();
}
Optional enclosingTypeInfo() {
return Optional.empty();
}
String signature() {
StringBuilder sig = new StringBuilder();
sig.append(name());
sig.append("(");
Iterator parameters = parameterInfoList().iterator();
if (parameters.hasNext()) {
parameters.next().signature(sig);
while (parameters.hasNext()) {
sig.append(",");
parameters.next().signature(sig);
}
}
sig.append(")");
return sig.toString();
}
private Stream enclosingTypeInfoAnnotationStream() {
String signature = signature();
return enclosingTypeInfo()
.map(TypeInfo::superMethodInfoStream)
.map(stream -> stream
.filter(m -> m.signature().equals(signature))
.flatMap(MethodInfo::annotationInfoStream))
.orElse(Stream.empty());
}
private String getterPrefix() {
return returnTypeInfo().getGetterPrefix();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy