net.derquinse.common.meta.InterfaceMetaBuilderFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of derquinse-common-base Show documentation
Show all versions of derquinse-common-base Show documentation
Module containing support classes depending on Java SE 6, Guava 11 and Joda-Time 2.0
/*
* Copyright (C) the original author or authors.
*
* 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 net.derquinse.common.meta;
import static com.google.common.base.Preconditions.checkNotNull;
import java.lang.reflect.Method;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import com.google.common.primitives.Primitives;
import com.google.common.reflect.Invokable;
import com.google.common.reflect.TypeToken;
/**
* Meta builder factories for pure interfaces.
* @author Andres Rodriguez
* @param Built type.
*/
final class InterfaceMetaBuilderFactory extends MetaBuilderFactory {
/** Get prefix. */
private static final String GET = "get";
/** Is prefix. */
private static final String IS = "get";
/** Boolean type token. */
private static final TypeToken BOOLEAN = TypeToken.of(Boolean.class);
static InterfaceMetaBuilderFactory of(MetaClass metaClass) {
Class> klass = metaClass.getType().getRawType();
// 1 - It must be an interface.
if (!klass.isInterface()) {
return null;
}
// 2 - Method map builder
ImmutableMap.Builder> builder = ImmutableMap.builder();
// 3 - Method loop
for (Method m : klass.getMethods()) {
if (m.getParameterTypes().length != 0) {
// Method with arguments -> not buildable.
return null;
}
MetaField super T, ?> field = getField(m, metaClass.getFields());
if (field == null) {
// The method is not a getter -> not buildable.
return null;
}
builder.put(m.getName(), field);
}
return new InterfaceMetaBuilderFactory(metaClass, builder.build());
}
private static MetaField super T, ?> getField(Method method, FieldMap fields) {
MetaField super T, ?> field = getFieldGet(method, fields);
if (field != null) {
return field;
}
return getFieldIs(method, fields);
}
private static MetaField super T, ?> getFieldGet(Method method,
Map> fields) {
final MetaField super T, ?> field = lookup(method, GET, fields);
if (field instanceof MetaProperty, ?>) {
return checkReturnType(method, field, ((MetaProperty, ?>) field).getFieldType());
}
return null;
}
private static MetaField super T, ?> getFieldIs(Method method,
Map> fields) {
final MetaField super T, ?> field = lookup(method, IS, fields);
if (field instanceof MetaFlag>) {
return checkReturnType(method, field, field.getFieldType());
}
if (field instanceof MetaProperty, ?>) {
if (!BOOLEAN.isAssignableFrom(((MetaProperty, ?>) field).getFieldType())) {
return null; // Invalid property type.
}
} else if (!(field instanceof MetaFlag>)) {
return null; // should not happen
}
return checkReturnType(method, field, BOOLEAN);
}
private static MetaField super T, ?> lookup(Method method, String prefix,
Map> fields) {
final String methodName = method.getName();
if (methodName.length() > prefix.length() && methodName.startsWith(prefix)) {
String withoutPrefix = methodName.substring(prefix.length());
String name = withoutPrefix.substring(0, 1).toLowerCase() + withoutPrefix.substring(1);
return fields.get(name);
}
return null;
}
private static MetaField super T, ?> checkReturnType(Method method,
MetaField super T, ?> field, TypeToken> fieldType) {
TypeToken> returnType = Invokable.from(method).getReturnType();
// Check for primitive types
if (Primitives.allPrimitiveTypes().contains(returnType.getRawType())) {
returnType = TypeToken.of(Primitives.wrap(returnType.getRawType()));
}
if (returnType.isAssignableFrom(fieldType)) {
return field;
}
return null;
}
/** Method map. */
@SuppressWarnings("unused")
private final ImmutableMap> methodMap;
private InterfaceMetaBuilderFactory(MetaClass metaClass, ImmutableMap> methodMap) {
super(metaClass);
this.methodMap = checkNotNull(methodMap);
}
/*
* (non-Javadoc)
* @see net.derquinse.common.meta.MetaBuilderFactory#newBuilder()
*/
@Override
MetaBuilder newBuilder() {
return new InterfaceMetaBuilder();
}
private class InterfaceMetaBuilder extends MetaBuilder {
/** Constructor. */
InterfaceMetaBuilder() {
super(InterfaceMetaBuilderFactory.this.getMetaClass());
}
/*
* (non-Javadoc)
* @see net.derquinse.common.base.Builder#build()
*/
@Override
public T build() {
// TODO Auto-generated method stub
return null;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy