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

com.jdon.domain.model.injection.ModelProxyInjection Maven / Gradle / Ivy

/*
 * Copyright 2003-2009 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 com.jdon.domain.model.injection;

import java.lang.reflect.Field;
import java.util.List;

import com.jdon.annotation.Component;
import com.jdon.annotation.Service;
import com.jdon.annotation.model.Inject;
import com.jdon.container.finder.ContainerCallback;
import com.jdon.domain.advsior.ModelAdvisor;
import com.jdon.util.ClassUtil;
import com.jdon.util.Debug;
import com.jdon.util.ObjectCreator;

/**
 * This class is responsible for inject the fileds marked with @Inject into the
 * models,if the injected fields are also marked with @Introduce,the interceptor
 * will be involved again.
 * 
 * for example:
 * 
 * 
 * public class MyModle{
 * 
 * @Inject MyDomainEvent myDomainEvent;
 * 
 * @Inject MyDomainService MyDomainService; }
 * 
 * @Introduce("message") class MyDomainEvent{
 * 
 *                       }
 * 
 * @author xmuzyu
 * 
 */
public class ModelProxyInjection {
	private final static String module = ModelProxyInjection.class.getName();
	private ModelAdvisor modelAdvisor;
	private ContainerCallback containerCallback;

	public ModelProxyInjection(ModelAdvisor modelAdvisor, ContainerCallback containerCallback) {
		super();
		this.modelAdvisor = modelAdvisor;
		this.containerCallback = containerCallback;
	}

	public void injectProperties(Object targetModel) {
		Class fClass = null;
		try {
			Field[] fields = ClassUtil.getAllDecaredFields(targetModel.getClass());
			if (fields == null)
				return;
			for (Field field : fields) {
				if (field.isAnnotationPresent(Inject.class)) {
					fClass = field.getType();
					Object fieldObject = getInjectObject(targetModel, fClass);
					if (field.getType().isAssignableFrom(fieldObject.getClass())) {
						try {
							field.setAccessible(true);
							field.set(targetModel, fieldObject);
						} catch (IllegalArgumentException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (IllegalAccessException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			}

		} catch (Exception e) {
			Debug.logError("inject Properties error:" + e + " in " + targetModel.getClass() + "'s field: " + fClass, module);
		}
	}

	protected Object getInjectObject(Object targetModel, Class fClass) {
		Object o = createTargetComponent(targetModel, fClass);
		if (o == null)
			o = createTargetObject(targetModel, fClass);
		return o;

	}

	protected Object createTargetObject(Object targetModel, Class fClass) {
		Object o = null;
		try {
			o = ObjectCreator.createObject(fClass);
			o = modelAdvisor.createProxy(o);
		} catch (Exception e) {
			Debug.logError("createTargetObject error:" + e + " in " + targetModel.getClass(), module);
		}
		return o;

	}

	protected Object createTargetComponent(Object targetModel, Class fClass) {
		Object o = null;
		try {
			List objects = containerCallback.getContainerWrapper().getComponentInstancesOfType(fClass);
			// List should be have only one.
			for (Object instance : objects) {
				o = instance;
				break;
			}
			if (o != null)
				o = modelAdvisor.createProxy(o);
		} catch (Exception e) {
			Debug.logError("createTargetComponent error:" + e + " in" + targetModel.getClass(), module);
		}
		return o;

	}

	protected boolean isComponent(Object instance) {
		if (instance.getClass().isAnnotationPresent(Component.class))
			return true;
		if (instance.getClass().isAnnotationPresent(Service.class))
			return true;
		return false;
	}

}