All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.derquinse.common.meta.InterfaceMetaBuilderFactory Maven / Gradle / Ivy

Go to download

Module containing support classes depending on Java SE 6, Guava 11 and Joda-Time 2.0

There is a newer version: 1.0.37
Show newest version
/*
 * 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 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 getField(Method method, FieldMap fields) {
		MetaField field = getFieldGet(method, fields);
		if (field != null) {
			return field;
		}
		return getFieldIs(method, fields);
	}

	private static  MetaField getFieldGet(Method method,
			Map> fields) {
		final MetaField field = lookup(method, GET, fields);
		if (field instanceof MetaProperty) {
			return checkReturnType(method, field, ((MetaProperty) field).getFieldType());
		}
		return null;
	}

	private static  MetaField getFieldIs(Method method,
			Map> fields) {
		final MetaField 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 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 checkReturnType(Method method,
			MetaField 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