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

com.liferay.portal.kernel.test.rule.callback.DeleteAfterTestRunTestCallback Maven / Gradle / Ivy

/**
 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 */

package com.liferay.portal.kernel.test.rule.callback;

import com.liferay.portal.kernel.model.Company;
import com.liferay.portal.kernel.model.Group;
import com.liferay.portal.kernel.model.LayoutPrototype;
import com.liferay.portal.kernel.model.LayoutSetPrototype;
import com.liferay.portal.kernel.model.Organization;
import com.liferay.portal.kernel.model.PersistedModel;
import com.liferay.portal.kernel.model.Role;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.model.UserGroup;
import com.liferay.portal.kernel.service.PersistedModelLocalService;
import com.liferay.portal.kernel.service.PersistedModelLocalServiceRegistryUtil;
import com.liferay.portal.kernel.test.rule.DeleteAfterTestRun;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.StringBundler;

import java.lang.reflect.Field;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;

import org.junit.runner.Description;

/**
 * @author Shuyang Zhou
 */
public class DeleteAfterTestRunTestCallback
	extends BaseTestCallback {

	public static final DeleteAfterTestRunTestCallback INSTANCE =
		new DeleteAfterTestRunTestCallback();

	@Override
	public void afterMethod(
			Description description, Object object, Object target)
		throws Exception {

		Class testClass = description.getTestClass();

		Map, FieldBag> deleteAfterTestRunFieldBags = new HashMap<>();

		while (testClass != null) {
			for (Field field : testClass.getDeclaredFields()) {
				DeleteAfterTestRun deleteAfterTestRun = field.getAnnotation(
					DeleteAfterTestRun.class);

				if (deleteAfterTestRun == null) {
					continue;
				}

				Class fieldClass = field.getType();

				if (PersistedModel.class.isAssignableFrom(fieldClass)) {
					addField(deleteAfterTestRunFieldBags, fieldClass, field);

					continue;
				}

				if (fieldClass.isArray()) {
					if (!PersistedModel.class.isAssignableFrom(
							fieldClass.getComponentType())) {

						throw new IllegalArgumentException(
							StringBundler.concat(
								"Unable to annotate field ",
								String.valueOf(field),
								" because it is not an array of type ",
								PersistedModel.class.getName()));
					}

					addField(
						deleteAfterTestRunFieldBags,
						fieldClass.getComponentType(), field);

					continue;
				}

				if (Collection.class.isAssignableFrom(fieldClass)) {
					field.setAccessible(true);

					Collection collection = (Collection)field.get(target);

					if ((collection == null) || collection.isEmpty()) {
						continue;
					}

					Class collectionType = getCollectionType(collection);

					if (collectionType == null) {
						throw new IllegalArgumentException(
							StringBundler.concat(
								"Unable to annotate field ",
								String.valueOf(field),
								" because it is not a collection of type ",
								PersistedModel.class.getName()));
					}

					addField(
						deleteAfterTestRunFieldBags, collectionType, field);

					continue;
				}

				StringBundler sb = new StringBundler(6);

				sb.append("Unable to annotate field ");
				sb.append(field);
				sb.append(" because it is not type of ");
				sb.append(PersistedModel.class.getName());
				sb.append(" nor an array or collection of ");
				sb.append(PersistedModel.class.getName());

				throw new IllegalArgumentException(sb.toString());
			}

			testClass = testClass.getSuperclass();
		}

		Set, FieldBag>> set =
			deleteAfterTestRunFieldBags.entrySet();

		Iterator, FieldBag>> iterator = set.iterator();

		while (iterator.hasNext()) {
			Map.Entry, FieldBag> entry = iterator.next();

			Class clazz = entry.getKey();

			if (_orderedClasses.contains(clazz)) {
				continue;
			}

			iterator.remove();

			removeField(entry.getValue(), target);
		}

		for (Class clazz : _orderedClasses) {
			FieldBag fieldBag = deleteAfterTestRunFieldBags.remove(clazz);

			if (fieldBag == null) {
				continue;
			}

			removeField(fieldBag, target);
		}
	}

	protected void addField(
		Map, FieldBag> deleteAfterTestRunFieldBags, Class clazz,
		Field field) {

		FieldBag fieldBag = deleteAfterTestRunFieldBags.get(clazz);

		if (fieldBag == null) {
			fieldBag = new FieldBag(clazz);

			deleteAfterTestRunFieldBags.put(clazz, fieldBag);
		}

		field.setAccessible(true);

		fieldBag.addField(field);
	}

	protected Class getCollectionType(
		Collection collection) {

		Class collectionType = null;

		for (Object object : collection) {
			Queue> classes = new LinkedList<>();

			classes.add(object.getClass());

			Class clazz = null;

			while ((clazz = classes.poll()) != null) {
				if (ArrayUtil.contains(
						clazz.getInterfaces(), PersistedModel.class)) {

					if (collectionType == null) {
						collectionType = (Class)clazz;
					}
					else if (collectionType != clazz) {
						return null;
					}

					break;
				}

				classes.add(clazz.getSuperclass());

				Collections.addAll(classes, clazz.getInterfaces());
			}
		}

		return collectionType;
	}

	protected void removeField(FieldBag fieldBag, Object instance)
		throws Exception {

		Class fieldClass = fieldBag.getFieldClass();

		PersistedModelLocalService persistedModelLocalService =
			PersistedModelLocalServiceRegistryUtil.
				getPersistedModelLocalService(fieldClass.getName());

		for (Field field : fieldBag.getFields()) {
			Object object = field.get(instance);

			if (object == null) {
				continue;
			}

			Class objectClass = object.getClass();

			if (objectClass.isArray()) {
				for (PersistedModel persistedModel : (PersistedModel[])object) {
					if (persistedModel == null) {
						continue;
					}

					persistedModelLocalService.deletePersistedModel(
						persistedModel);
				}
			}
			else if (Collection.class.isAssignableFrom(objectClass)) {
				Collection collection =
					(Collection)object;

				for (PersistedModel persistedModel : collection) {
					persistedModelLocalService.deletePersistedModel(
						persistedModel);
				}
			}
			else {
				persistedModelLocalService.deletePersistedModel(
					(PersistedModel)object);
			}

			field.set(instance, null);
		}
	}

	protected static class FieldBag {

		public FieldBag(Class fieldClass) {
			_fieldClass = fieldClass;
		}

		public void addField(Field field) {
			_fields.add(field);
		}

		public Class getFieldClass() {
			return _fieldClass;
		}

		public List getFields() {
			return _fields;
		}

		private final Class _fieldClass;
		private final List _fields = new ArrayList<>();

	}

	private DeleteAfterTestRunTestCallback() {
	}

	private static final Set> _orderedClasses = new LinkedHashSet<>(
		Arrays.>asList(
			User.class, Organization.class, Role.class, UserGroup.class,
			Group.class, LayoutPrototype.class, LayoutSetPrototype.class,
			Company.class));

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy