SliceEntityManagerContainerFactory.java 7.4 KB
Newer Older
R
test  
roo00 已提交
1 2 3 4 5 6
package com.x.base.core.container.factory;

import java.io.File;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.ArrayList;
R
roo00 已提交
7
import java.util.Collections;
R
test  
roo00 已提交
8 9 10 11
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
R
fix  
roo00 已提交
12
import java.util.Properties;
R
test  
roo00 已提交
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import javax.persistence.EntityManagerFactory;
import javax.persistence.Id;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.openjpa.persistence.OpenJPAPersistence;
import org.apache.openjpa.persistence.PersistenceProductDerivation;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.x.base.core.entity.JpaObject;
import com.x.base.core.entity.annotation.CheckPersist;
import com.x.base.core.entity.annotation.CheckRemove;
import com.x.base.core.entity.annotation.Flag;
import com.x.base.core.entity.annotation.RestrictFlag;

public abstract class SliceEntityManagerContainerFactory {

R
Ray 已提交
35 36
	protected static final String META_INF = "META-INF";
	protected static final String PERSISTENCE_XML_PATH = META_INF + "/persistence.xml";
R
test  
roo00 已提交
37 38

	/* class 与 entityManagerFactory 映射表 */
R
Ray 已提交
39
	protected Map<Class<? extends JpaObject>, EntityManagerFactory> entityManagerFactoryMap = new ConcurrentHashMap<>();
R
test  
roo00 已提交
40
	/* class 与 @Flag字段 映射表 */
R
Ray 已提交
41
	protected Map<Class<? extends JpaObject>, List<Field>> flagMap = new ConcurrentHashMap<>();
R
test  
roo00 已提交
42
	/* class 与 entityManagerFactory 映射表 */
R
Ray 已提交
43
	protected Map<Class<? extends JpaObject>, List<Field>> restrictFlagMap = new ConcurrentHashMap<>();
R
test  
roo00 已提交
44
	/* class 与 class 中需要检查 Persist 字段的对应表 */
R
Ray 已提交
45
	protected Map<Class<? extends JpaObject>, Map<Field, CheckPersist>> checkPersistFieldMap = new ConcurrentHashMap<>();
R
test  
roo00 已提交
46
	/* class 与 class 中需要检查 Remove 字段的对应表 */
R
Ray 已提交
47
	protected Map<Class<? extends JpaObject>, Map<Field, CheckRemove>> checkRemoveFieldMap = new ConcurrentHashMap<>();
R
test  
roo00 已提交
48

R
Ray 已提交
49
	@SuppressWarnings("unchecked")
R
roo00 已提交
50
	protected SliceEntityManagerContainerFactory(String webApplicationDirectory, List<String> entities,
R
Ray 已提交
51
			boolean sliceFeatureEnable, ClassLoader classLoader) throws Exception {
R
fix  
roo00 已提交
52
		File path = new File(webApplicationDirectory + "/WEB-INF/classes/" + PERSISTENCE_XML_PATH);
R
Ray 已提交
53
		List<String> classNames = PersistenceXmlHelper.write(path.getAbsolutePath(), entities, classLoader);
R
Ray 已提交
54 55
		ClassLoader cl = null == classLoader ? Thread.currentThread().getContextClassLoader() : classLoader;
		Class<? extends JpaObject> clz;
R
fix  
roo00 已提交
56
		for (String className : classNames) {
R
Ray 已提交
57
			clz = (Class<? extends JpaObject>) cl.loadClass(className);
R
fix  
roo00 已提交
58 59
			checkPersistFieldMap.put(clz, this.loadCheckPersistField(clz));
			checkRemoveFieldMap.put(clz, this.loadCheckRemoveField(clz));
R
roo00 已提交
60
			Properties properties = PersistenceXmlHelper.properties(clz.getName(), sliceFeatureEnable);
R
fix  
roo00 已提交
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
			entityManagerFactoryMap.put(clz,
					OpenJPAPersistence.createEntityManagerFactory(clz.getName(), PERSISTENCE_XML_PATH, properties));
			List<Field> flagFields = new ArrayList<>();
			List<Field> restrictFlagFields = new ArrayList<>();
			for (Field o : FieldUtils.getFieldsListWithAnnotation(clz, Id.class)) {
				flagFields.add(o);
				restrictFlagFields.add(o);
			}
			for (Field o : FieldUtils.getFieldsListWithAnnotation(clz, Flag.class)) {
				flagFields.add(o);
				restrictFlagFields.add(o);
			}
			for (Field o : FieldUtils.getFieldsListWithAnnotation(clz, RestrictFlag.class)) {
				restrictFlagFields.add(o);
			}
			flagMap.put(clz, Collections.unmodifiableList(flagFields));
			restrictFlagMap.put(clz, Collections.unmodifiableList(restrictFlagFields));
		}
R
Ray 已提交
79
		if (null != classLoader) {
R
Ray 已提交
80 81 82 83 84 85 86 87 88
			clz = (Class<? extends JpaObject>) cl.loadClass("com.x.base.core.entity.dynamic.DynamicBaseEntity");
			checkPersistFieldMap.put(clz, new HashMap<>());
			checkRemoveFieldMap.put(clz, new HashMap<>());
			Properties properties = PersistenceXmlHelper.properties(clz.getName(), sliceFeatureEnable);
			entityManagerFactoryMap.put(clz,
					OpenJPAPersistence.createEntityManagerFactory(clz.getName(), PERSISTENCE_XML_PATH, properties));
			flagMap.put(clz, new ArrayList<>());
			restrictFlagMap.put(clz, new ArrayList<>());
		}
R
fix  
roo00 已提交
89 90
	}

R
Ray 已提交
91
	protected SliceEntityManagerContainerFactory(String source) {
R
roo00 已提交
92
		Set<Class<? extends JpaObject>> classes = this.listUnitClass(source);
R
test  
roo00 已提交
93 94
		for (Class<? extends JpaObject> clz : classes) {
			checkPersistFieldMap.put(clz, this.loadCheckPersistField(clz));
R
roo00 已提交
95
			checkRemoveFieldMap.put(clz, this.loadCheckRemoveField(clz));
R
roo00 已提交
96
			entityManagerFactoryMap.put(clz, OpenJPAPersistence.createEntityManagerFactory(clz.getName(), source));
R
roo00 已提交
97 98
			List<Field> flagFields = new ArrayList<>();
			List<Field> restrictFlagFields = new ArrayList<>();
R
test  
roo00 已提交
99
			for (Field o : FieldUtils.getFieldsListWithAnnotation(clz, Id.class)) {
R
roo00 已提交
100 101
				flagFields.add(o);
				restrictFlagFields.add(o);
R
test  
roo00 已提交
102 103
			}
			for (Field o : FieldUtils.getFieldsListWithAnnotation(clz, Flag.class)) {
R
roo00 已提交
104 105
				flagFields.add(o);
				restrictFlagFields.add(o);
R
test  
roo00 已提交
106 107
			}
			for (Field o : FieldUtils.getFieldsListWithAnnotation(clz, RestrictFlag.class)) {
R
roo00 已提交
108
				restrictFlagFields.add(o);
R
test  
roo00 已提交
109
			}
R
roo00 已提交
110 111
			flagMap.put(clz, Collections.unmodifiableList(flagFields));
			restrictFlagMap.put(clz, Collections.unmodifiableList(restrictFlagFields));
R
test  
roo00 已提交
112 113 114 115
		}
	}

	@SuppressWarnings("unchecked")
R
Ray 已提交
116
	public <T> Class<T> assignableFrom(Class<T> cls) {
R
test  
roo00 已提交
117 118 119 120 121
		for (Class<?> clazz : this.entityManagerFactoryMap.keySet()) {
			if (clazz.isAssignableFrom(cls)) {
				return (Class<T>) clazz;
			}
		}
R
Ray 已提交
122
		throw new IllegalStateException("can not find jpa assignable class for " + cls + ".");
R
test  
roo00 已提交
123 124
	}

R
Ray 已提交
125 126
	private <T extends JpaObject> Map<Field, CheckPersist> loadCheckPersistField(Class<T> cls) {
		Map<Field, CheckPersist> map = new HashMap<>();
R
test  
roo00 已提交
127 128 129 130 131 132 133 134 135
		for (Field fld : cls.getDeclaredFields()) {
			CheckPersist checkPersist = fld.getAnnotation(CheckPersist.class);
			if (null != checkPersist) {
				map.put(fld, checkPersist);
			}
		}
		return map;
	}

R
Ray 已提交
136 137
	private <T extends JpaObject> Map<Field, CheckRemove> loadCheckRemoveField(Class<T> cls) {
		Map<Field, CheckRemove> map = new HashMap<>();
R
test  
roo00 已提交
138 139 140 141 142 143 144 145 146
		for (Field fld : cls.getDeclaredFields()) {
			CheckRemove checkRemove = fld.getAnnotation(CheckRemove.class);
			if (null != checkRemove) {
				map.put(fld, checkRemove);
			}
		}
		return map;
	}

R
Ray 已提交
147 148
	@SuppressWarnings("unchecked")
	private Set<Class<? extends JpaObject>> listUnitClass(String source) {
R
test  
roo00 已提交
149 150 151 152 153 154 155 156 157
		try {
			Set<Class<? extends JpaObject>> classes = new HashSet<>();
			URL url;
			if (StringUtils.isEmpty(source)) {
				url = this.getClass().getClassLoader().getResource(PersistenceProductDerivation.RSRC_DEFAULT);
			} else {
				url = this.getClass().getClassLoader().getResource(source);
			}
			if (null == url) {
R
Ray 已提交
158
				throw new IllegalStateException("can not load resource: " + source + ".");
R
test  
roo00 已提交
159 160 161
			}
			File file = new File(url.toURI());
			SAXReader reader = new SAXReader();
R
Ray 已提交
162 163 164
			reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
			reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
			reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
R
test  
roo00 已提交
165
			Document document = reader.read(file);
R
Ray 已提交
166
			for (Element unit : document.getRootElement().elements("persistence-unit")) {
R
fix  
Ray 已提交
167 168
				classes.add((Class<JpaObject>) Thread.currentThread().getContextClassLoader()
						.loadClass(unit.attribute("name").getValue()));
R
test  
roo00 已提交
169 170 171
			}
			return classes;
		} catch (Exception e) {
R
Ray 已提交
172
			throw new IllegalStateException("list unit error:" + source, e);
R
test  
roo00 已提交
173 174 175 176
		}
	}

}