mirror of
https://gitee.com/jmix/cuba.git
synced 2024-11-30 10:17:43 +08:00
Metadata initialization is too slow. #PL-3662
This commit is contained in:
parent
1a80be1acd
commit
cd50a4e4d0
21
build.gradle
21
build.gradle
@ -201,6 +201,10 @@ configure(globalModule) {
|
||||
task enhance(type: CubaEnhancing) {
|
||||
persistenceXml = "$globalModule.projectDir/src/cuba-persistence.xml"
|
||||
}
|
||||
|
||||
task enhanceTransient(type: CubaEnhanceTransient) {
|
||||
metadataXml = "$globalModule.projectDir/src/cuba-metadata.xml"
|
||||
}
|
||||
}
|
||||
|
||||
configure(coreModule) {
|
||||
@ -343,14 +347,7 @@ configure(guiModule) {
|
||||
}
|
||||
|
||||
task enhanceTransient(type: CubaEnhanceTransient) {
|
||||
classes = [
|
||||
'com.haulmont.cuba.gui.security.entity.AbstractPermissionTarget',
|
||||
'com.haulmont.cuba.gui.security.entity.AttributeTarget',
|
||||
'com.haulmont.cuba.gui.security.entity.BasicPermissionTarget',
|
||||
'com.haulmont.cuba.gui.security.entity.MultiplePermissionTarget',
|
||||
'com.haulmont.cuba.gui.security.entity.OperationPermissionTarget',
|
||||
'com.haulmont.cuba.gui.security.entity.UiPermissionTarget'
|
||||
]
|
||||
metadataXml = "$guiModule.projectDir/src/cuba-gui-metadata.xml"
|
||||
}
|
||||
|
||||
test {
|
||||
@ -388,6 +385,10 @@ configure(webModule) {
|
||||
|
||||
classes.dependsOn resourceTimeStampInject
|
||||
|
||||
task enhanceTransient(type: CubaEnhanceTransient) {
|
||||
metadataXml = "$webModule.projectDir/src/cuba-web-metadata.xml"
|
||||
}
|
||||
|
||||
task buildScssThemes(type: CubaWebScssThemeCreation) {
|
||||
buildTimeStamp = resourceBuildTimeStamp
|
||||
themes = ['havana']
|
||||
@ -596,6 +597,10 @@ configure(webLegacyModule) {
|
||||
|
||||
classes.dependsOn resourceTimeStampInject
|
||||
|
||||
task enhanceTransient(type: CubaEnhanceTransient) {
|
||||
metadataXml = "$webLegacyModule.projectDir/src/cuba-web-metadata.xml"
|
||||
}
|
||||
|
||||
task buildScssThemes(type: CubaWebScssThemeCreation) {
|
||||
buildTimeStamp = resourceBuildTimeStamp
|
||||
themes = ['havana']
|
||||
|
@ -35,7 +35,7 @@ public class TestMetadataClient extends MetadataImpl {
|
||||
protected void initMetadata() {
|
||||
MetadataLoader persistentEntitiesMetadataLoader = new PersistentEntitiesMetadataLoader();
|
||||
for (String p : packages) {
|
||||
persistentEntitiesMetadataLoader.loadPackage(p, p);
|
||||
persistentEntitiesMetadataLoader.loadModel(p, null);
|
||||
}
|
||||
persistentEntitiesMetadataLoader.postProcess();
|
||||
|
||||
|
@ -27,7 +27,7 @@ cuba.windowConfig=cuba-desktop-screens.xml
|
||||
cuba.menuConfig=cuba-desktop-menu.xml
|
||||
cuba.permissionConfig=cuba-desktop-permissions.xml
|
||||
cuba.mainMessagePack=com.haulmont.cuba.desktop
|
||||
cuba.metadataConfig=cuba-metadata.xml
|
||||
cuba.metadataConfig=cuba-metadata.xml cuba-gui-metadata.xml
|
||||
|
||||
cuba.groovyClassPath=
|
||||
cuba.groovyEvaluatorImport=com.haulmont.cuba.core.global.PersistenceHelper
|
||||
|
@ -6,13 +6,11 @@
|
||||
package com.haulmont.chile.core.loader;
|
||||
|
||||
import com.haulmont.bali.util.ReflectionHelper;
|
||||
import com.haulmont.chile.core.annotations.*;
|
||||
import com.haulmont.chile.core.annotations.Composition;
|
||||
import com.haulmont.chile.core.datatypes.Datatype;
|
||||
import com.haulmont.chile.core.datatypes.Datatypes;
|
||||
import com.haulmont.chile.core.datatypes.impl.EnumerationImpl;
|
||||
import com.haulmont.chile.core.model.*;
|
||||
import com.haulmont.chile.core.model.MetaClass;
|
||||
import com.haulmont.chile.core.model.MetaProperty;
|
||||
import com.haulmont.chile.core.model.impl.*;
|
||||
import com.haulmont.cuba.core.entity.annotation.SystemLevel;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
@ -33,15 +31,14 @@ import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author krivopustov
|
||||
* @author abramov
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
public class ChileAnnotationsLoader implements MetaClassLoader {
|
||||
|
||||
private Log log = LogFactory.getLog(ChileAnnotationsLoader.class);
|
||||
|
||||
protected Session session;
|
||||
protected String packageName;
|
||||
|
||||
protected ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
|
||||
protected MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver);
|
||||
@ -51,34 +48,40 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session loadPackage(String modelName, final String packageName) {
|
||||
this.packageName = packageName;
|
||||
public void loadPackage(String packageName, List<String> classNames) {
|
||||
List<Class<?>> classes;
|
||||
List<MetadataObjectInitTask> tasks = new ArrayList<>();
|
||||
|
||||
List<MetadataObjectInitTask> tasks =
|
||||
new ArrayList<>();
|
||||
|
||||
final String packagePrefix = packageName.replace(".", "/") + "/**/*.class";
|
||||
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + packagePrefix;
|
||||
Resource[] resources;
|
||||
try {
|
||||
resources = resourcePatternResolver.getResources(packageSearchPath);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
if (classNames != null) {
|
||||
classes = new ArrayList<>();
|
||||
for (String className : classNames) {
|
||||
try {
|
||||
classes.add(ReflectionHelper.loadClass(className));
|
||||
} catch (ClassNotFoundException e) {
|
||||
log.warn("Class " + className + " not found for model " + packageName);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String packagePrefix = packageName.replace(".", "/") + "/**/*.class";
|
||||
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + packagePrefix;
|
||||
Resource[] resources;
|
||||
try {
|
||||
resources = resourcePatternResolver.getResources(packageSearchPath);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
classes = getClasses(resources);
|
||||
}
|
||||
|
||||
List<Class<?>> annotated = getClasses(resources);
|
||||
|
||||
for (Class<?> aClass : annotated) {
|
||||
for (Class<?> aClass : classes) {
|
||||
if (aClass.getName().startsWith(packageName)) {
|
||||
tasks.addAll(__loadClass(modelName, aClass).getTasks());
|
||||
tasks.addAll(loadClass(packageName, aClass).getTasks());
|
||||
}
|
||||
}
|
||||
|
||||
for (MetadataObjectInitTask task : tasks) {
|
||||
task.execute();
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
protected List<Class<?>> getClasses(Resource[] resources) {
|
||||
@ -123,23 +126,23 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
return method.isAnnotationPresent(com.haulmont.chile.core.annotations.MetaProperty.class);
|
||||
}
|
||||
|
||||
protected MetaClassImpl createMetaClass(String modelName, String className) {
|
||||
MetaModel model = session.getModel(modelName);
|
||||
protected MetaClassImpl createMetaClass(String packageName, String className) {
|
||||
MetaModel model = session.getModel(packageName);
|
||||
if (model == null) {
|
||||
model = new MetaModelImpl(session, modelName);
|
||||
model = new MetaModelImpl(session, packageName);
|
||||
}
|
||||
|
||||
return new MetaClassImpl(model, className);
|
||||
}
|
||||
|
||||
protected MetaClassImpl __createClass(Class<?> clazz, String modelName) {
|
||||
if (Object.class.equals(clazz)) return null;
|
||||
protected MetaClassImpl createClass(Class<?> clazz, String packageName) {
|
||||
if (Object.class.equals(clazz))
|
||||
return null;
|
||||
|
||||
final com.haulmont.chile.core.annotations.MetaClass metaClassAnnotaion =
|
||||
clazz.getAnnotation(com.haulmont.chile.core.annotations.MetaClass.class);
|
||||
|
||||
if (metaClassAnnotaion == null) {
|
||||
log.trace(String.format("Class '%s' isn't annotated as metadata entity, ignore it", clazz.getName()));
|
||||
log.trace(String.format("Class %s isn't annotated as metadata entity, ignore it", clazz.getName()));
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -148,7 +151,7 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
className = clazz.getSimpleName();
|
||||
}
|
||||
|
||||
return __createClass(clazz, modelName, className);
|
||||
return createClass(clazz, packageName, className);
|
||||
}
|
||||
|
||||
protected boolean isCollection(Field field) {
|
||||
@ -171,8 +174,8 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
return Collection.class.isAssignableFrom(type);
|
||||
}
|
||||
|
||||
public MetadataObjectInfo<MetaClass> __loadClass(String modelName, Class<?> clazz) {
|
||||
final MetaClassImpl metaClass = __createClass(clazz, modelName);
|
||||
protected MetadataObjectInfo<MetaClass> loadClass(String packageName, Class<?> clazz) {
|
||||
final MetaClassImpl metaClass = createClass(clazz, packageName);
|
||||
if (metaClass == null)
|
||||
return null;
|
||||
|
||||
@ -207,9 +210,9 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
if (isCollection(field) || isMap(field)) {
|
||||
collectionProps.add(field);
|
||||
} else {
|
||||
info = __loadProperty(metaClass, field);
|
||||
info = loadProperty(metaClass, field);
|
||||
tasks.addAll(info.getTasks());
|
||||
final MetaProperty metaProperty = info.getObject();
|
||||
MetaProperty metaProperty = info.getObject();
|
||||
onPropertyLoaded(metaProperty, field);
|
||||
}
|
||||
} else {
|
||||
@ -220,9 +223,9 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
}
|
||||
|
||||
for (Field f : collectionProps) {
|
||||
MetadataObjectInfo<MetaProperty> info = __loadCollectionProperty(metaClass, f);
|
||||
MetadataObjectInfo<MetaProperty> info = loadCollectionProperty(metaClass, f);
|
||||
tasks.addAll(info.getTasks());
|
||||
final MetaProperty metaProperty = info.getObject();
|
||||
MetaProperty metaProperty = info.getObject();
|
||||
onPropertyLoaded(metaProperty, f);
|
||||
}
|
||||
|
||||
@ -243,10 +246,10 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
if (isCollection(method) || isMap(method)) {
|
||||
throw new UnsupportedOperationException("Method-based properties don't support collections and maps");
|
||||
} else {
|
||||
info = __loadProperty(metaClass, method, name);
|
||||
info = loadProperty(metaClass, method, name);
|
||||
tasks.addAll(info.getTasks());
|
||||
}
|
||||
final MetaProperty metaProperty = info.getObject();
|
||||
MetaProperty metaProperty = info.getObject();
|
||||
onPropertyLoaded(metaProperty, method);
|
||||
} else {
|
||||
log.warn("Method " + clazz.getSimpleName() + "." + method.getName()
|
||||
@ -256,37 +259,6 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session loadClass(String modelName, Class<?> clazz) {
|
||||
final MetadataObjectInfo<MetaClass> info = __loadClass(modelName, clazz);
|
||||
checkWarnings(info);
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
protected void checkWarnings(MetadataObjectInfo<? extends MetadataObject> info) {
|
||||
if (info != null) {
|
||||
for (MetadataObjectInitTask task : info.getTasks()) {
|
||||
log.warn(task.getWarning());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session loadClass(String modelName, String className) {
|
||||
final Class<?> clazz = ReflectionHelper.getClass(className);
|
||||
|
||||
final MetadataObjectInfo<MetaClass> info = __loadClass(modelName, clazz);
|
||||
checkWarnings(info);
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected void onPropertyLoaded(MetaProperty metaProperty, Field field) {
|
||||
@ -296,13 +268,13 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
}
|
||||
}
|
||||
|
||||
private void onPropertyLoaded(MetaProperty metaProperty, Method method) {
|
||||
protected void onPropertyLoaded(MetaProperty metaProperty, Method method) {
|
||||
}
|
||||
|
||||
protected void onClassLoaded(MetaClass metaClass, Class<?> clazz) {
|
||||
}
|
||||
|
||||
protected MetadataObjectInfo<MetaProperty> __loadProperty(MetaClassImpl metaClass, Field field) {
|
||||
protected MetadataObjectInfo<MetaProperty> loadProperty(MetaClassImpl metaClass, Field field) {
|
||||
Collection<MetadataObjectInitTask> tasks = new ArrayList<>();
|
||||
|
||||
MetaPropertyImpl property = new MetaPropertyImpl(metaClass, field.getName());
|
||||
@ -322,8 +294,8 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
else
|
||||
type = field.getType();
|
||||
|
||||
MetadataObjectInfo<Range> info = __loadRange(property, type, map);
|
||||
final Range range = info.getObject();
|
||||
MetadataObjectInfo<Range> info = loadRange(property, type, map);
|
||||
Range range = info.getObject();
|
||||
if (range != null) {
|
||||
((AbstractRange) range).setCardinality(cardinality);
|
||||
property.setRange(range);
|
||||
@ -352,7 +324,7 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
return annotation != null && !annotation.datatype().equals("") ? Datatypes.get(annotation.datatype()) : null;
|
||||
}
|
||||
|
||||
private boolean setterExists(Field field) {
|
||||
protected boolean setterExists(Field field) {
|
||||
String name = "set" + StringUtils.capitalize(field.getName());
|
||||
Method[] methods = field.getDeclaringClass().getDeclaredMethods();
|
||||
for (Method method : methods) {
|
||||
@ -362,8 +334,8 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected MetadataObjectInfo<MetaProperty> __loadProperty(MetaClassImpl metaClass,
|
||||
Method method, String name) {
|
||||
protected MetadataObjectInfo<MetaProperty> loadProperty(MetaClassImpl metaClass,
|
||||
Method method, String name) {
|
||||
Collection<MetadataObjectInitTask> tasks = new ArrayList<>();
|
||||
|
||||
MetaPropertyImpl property = new MetaPropertyImpl(metaClass, name);
|
||||
@ -381,8 +353,8 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
else
|
||||
type = method.getReturnType();
|
||||
|
||||
MetadataObjectInfo<Range> info = __loadRange(property, type, map);
|
||||
final Range range = info.getObject();
|
||||
MetadataObjectInfo<Range> info = loadRange(property, type, map);
|
||||
Range range = info.getObject();
|
||||
if (range != null) {
|
||||
((AbstractRange) range).setCardinality(Range.Cardinality.NONE);
|
||||
property.setRange(range);
|
||||
@ -399,7 +371,7 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
return new MetadataObjectInfo<MetaProperty>(property, tasks);
|
||||
}
|
||||
|
||||
private boolean setterExists(Method getter) {
|
||||
protected boolean setterExists(Method getter) {
|
||||
if (getter.getName().startsWith("get")) {
|
||||
String setterName = "set" + getter.getName().substring(3);
|
||||
Method[] methods = getter.getDeclaringClass().getDeclaredMethods();
|
||||
@ -430,7 +402,7 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
protected MetadataObjectInfo<Range> __loadRange(MetaProperty metaProperty, Class type, Map<String, Object> map) {
|
||||
protected MetadataObjectInfo<Range> loadRange(MetaProperty metaProperty, Class type, Map<String, Object> map) {
|
||||
Datatype datatype = (Datatype) map.get("datatype");
|
||||
if (datatype != null) {
|
||||
return new MetadataObjectInfo<Range>(new DatatypeRange(datatype));
|
||||
@ -438,14 +410,14 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
|
||||
datatype = Datatypes.get(type);
|
||||
if (datatype != null) {
|
||||
final MetaClass metaClass = metaProperty.getDomain();
|
||||
final Class javaClass = metaClass.getJavaClass();
|
||||
MetaClass metaClass = metaProperty.getDomain();
|
||||
Class javaClass = metaClass.getJavaClass();
|
||||
|
||||
try {
|
||||
final String name = "get" + StringUtils.capitalize(metaProperty.getName());
|
||||
final Method method = javaClass.getMethod(name);
|
||||
String name = "get" + StringUtils.capitalize(metaProperty.getName());
|
||||
Method method = javaClass.getMethod(name);
|
||||
|
||||
final Class<Enum> returnType = (Class<Enum>) method.getReturnType();
|
||||
Class<Enum> returnType = (Class<Enum>) method.getReturnType();
|
||||
if (returnType.isEnum()) {
|
||||
return new MetadataObjectInfo<Range>(new EnumerationRange(new EnumerationImpl<>(returnType)));
|
||||
}
|
||||
@ -507,7 +479,7 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected MetadataObjectInfo<MetaProperty> __loadCollectionProperty(MetaClassImpl metaClass, Field field) {
|
||||
protected MetadataObjectInfo<MetaProperty> loadCollectionProperty(MetaClassImpl metaClass, Field field) {
|
||||
Collection<MetadataObjectInitTask> tasks = new ArrayList<>();
|
||||
|
||||
MetaPropertyImpl property = new MetaPropertyImpl(metaClass, field.getName());
|
||||
@ -526,7 +498,7 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
if (inverseField != null)
|
||||
map.put("inverseField", inverseField);
|
||||
|
||||
MetadataObjectInfo<Range> info = __loadRange(property, type, map);
|
||||
MetadataObjectInfo<Range> info = loadRange(property, type, map);
|
||||
Range range = info.getObject();
|
||||
if (range != null) {
|
||||
((AbstractRange) range).setCardinality(cardinality);
|
||||
@ -545,7 +517,7 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
return new MetadataObjectInfo<MetaProperty>(property, tasks);
|
||||
}
|
||||
|
||||
private void assignInverse(MetaPropertyImpl property, Range range, String inverseField) {
|
||||
protected void assignInverse(MetaPropertyImpl property, Range range, String inverseField) {
|
||||
if (inverseField == null)
|
||||
return;
|
||||
|
||||
@ -561,21 +533,21 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
}
|
||||
|
||||
protected boolean isOrdered(Field field) {
|
||||
final Class<?> type = field.getType();
|
||||
Class<?> type = field.getType();
|
||||
return List.class.isAssignableFrom(type) || Set.class.isAssignableFrom(type);
|
||||
}
|
||||
|
||||
protected MetaClassImpl __createClass(Class<?> clazz, String modelName, String className) {
|
||||
protected MetaClassImpl createClass(Class<?> clazz, String packageName, String className) {
|
||||
MetaClassImpl metaClass = (MetaClassImpl) session.getClass(clazz);
|
||||
if (metaClass != null) {
|
||||
return metaClass;
|
||||
} else if (packageName == null || clazz.getName().startsWith(packageName)) {
|
||||
metaClass = createMetaClass(modelName, className);
|
||||
metaClass = createMetaClass(packageName, className);
|
||||
metaClass.setJavaClass(clazz);
|
||||
|
||||
final Class<?> ancestor = clazz.getSuperclass();
|
||||
Class<?> ancestor = clazz.getSuperclass();
|
||||
if (ancestor != null) {
|
||||
MetaClass ancestorClass = __createClass(ancestor, modelName);
|
||||
MetaClass ancestorClass = createClass(ancestor, packageName);
|
||||
if (ancestorClass != null) {
|
||||
metaClass.addAncestor(ancestorClass);
|
||||
}
|
||||
@ -589,6 +561,7 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
}
|
||||
|
||||
protected class RangeInitTask implements MetadataObjectInitTask {
|
||||
|
||||
private MetaProperty metaProperty;
|
||||
private Class rangeClass;
|
||||
private Map<String, Object> map;
|
||||
@ -608,13 +581,13 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
final MetaClass rangeClass = session.getClass(this.rangeClass);
|
||||
MetaClass rangeClass = session.getClass(this.rangeClass);
|
||||
if (rangeClass == null) {
|
||||
throw new IllegalStateException(
|
||||
String.format("Can't find range class '%s' for property '%s.%s'",
|
||||
this.rangeClass.getName(), metaProperty.getDomain(), metaProperty.getName()));
|
||||
} else {
|
||||
final ClassRange range = new ClassRange(rangeClass);
|
||||
ClassRange range = new ClassRange(rangeClass);
|
||||
|
||||
Range.Cardinality cardinality = (Range.Cardinality) map.get("cardinality");
|
||||
range.setCardinality(cardinality);
|
||||
@ -623,7 +596,7 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
range.setOrdered((Boolean) map.get("ordered"));
|
||||
}
|
||||
|
||||
final Boolean mandatory = (Boolean) map.get("mandatory");
|
||||
Boolean mandatory = (Boolean) map.get("mandatory");
|
||||
if (mandatory != null) {
|
||||
((MetaPropertyImpl) metaProperty).setMandatory(mandatory);
|
||||
}
|
||||
|
@ -9,69 +9,37 @@ import com.haulmont.chile.core.model.MetaClass;
|
||||
import com.haulmont.chile.core.model.MetaProperty;
|
||||
import com.haulmont.chile.core.model.Session;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.dom4j.Element;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author krivopustov
|
||||
* @author abramov
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ChileMetadataLoader implements MetadataLoader {
|
||||
|
||||
protected Session session;
|
||||
protected ClassMetadataLoader annotationsLoader;
|
||||
protected MetaClassLoader metaClassLoader;
|
||||
|
||||
public ChileMetadataLoader(@Nullable Session session) {
|
||||
if (session != null) {
|
||||
this.session = session;
|
||||
annotationsLoader = createAnnotationsLoader(session);
|
||||
}
|
||||
}
|
||||
public ChileMetadataLoader(Session session) {
|
||||
this.session = session;
|
||||
metaClassLoader = createMetaClassLoader(session);
|
||||
}
|
||||
|
||||
protected ClassMetadataLoader createAnnotationsLoader(Session session) {
|
||||
protected MetaClassLoader createMetaClassLoader(Session session) {
|
||||
return new ChileAnnotationsLoader(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session loadXml(String xml) {
|
||||
throw new UnsupportedOperationException();
|
||||
public void loadModel(String modelName, List<String> classNames) {
|
||||
metaClassLoader.loadPackage(modelName, classNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session loadXml(Element xml) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session loadXml(InputStream xml) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session loadPackage(String modelName, String packageName) {
|
||||
return annotationsLoader.loadPackage(modelName, packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session loadClass(String modelName, Class<?> clazz) {
|
||||
return annotationsLoader.loadClass(modelName, clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session loadClass(String modelName, String className) {
|
||||
return annotationsLoader.loadClass(modelName, className);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session postProcess() {
|
||||
for (MetaClass metaClass : session.getClasses()) {
|
||||
initMetaClass(metaClass);
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
@ -80,7 +48,7 @@ public class ChileMetadataLoader implements MetadataLoader {
|
||||
initMetaProperty(metaClass, property);
|
||||
}
|
||||
|
||||
Collection<MetaClass> missingDescendants = new HashSet<MetaClass>(1);
|
||||
Collection<MetaClass> missingDescendants = new HashSet<>(1);
|
||||
|
||||
findMissingDescendants(metaClass, missingDescendants);
|
||||
|
||||
@ -116,4 +84,4 @@ public class ChileMetadataLoader implements MetadataLoader {
|
||||
public Session getSession() {
|
||||
return session;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2013 Haulmont. All rights reserved.
|
||||
* Use is subject to license terms, see http://www.cuba-platform.com/license for details.
|
||||
*/
|
||||
|
||||
package com.haulmont.chile.core.loader;
|
||||
|
||||
import com.haulmont.chile.core.model.Session;
|
||||
|
||||
public interface ClassMetadataLoader {
|
||||
Session loadPackage(String modelName, String packageName);
|
||||
Session loadClass(String modelName, Class<?> clazz);
|
||||
Session loadClass(String modelName, String className);
|
||||
|
||||
Session getSession();
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2014 Haulmont. All rights reserved.
|
||||
* Use is subject to license terms, see http://www.cuba-platform.com/license for details.
|
||||
*/
|
||||
|
||||
package com.haulmont.chile.core.loader;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author krivopustov
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface MetaClassLoader {
|
||||
|
||||
void loadPackage(String packageName, List<String> classNames);
|
||||
}
|
@ -7,7 +7,17 @@ package com.haulmont.chile.core.loader;
|
||||
|
||||
import com.haulmont.chile.core.model.Session;
|
||||
|
||||
public interface MetadataLoader extends ClassMetadataLoader, XmlMetadataLoader {
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abramov
|
||||
* @version $Id: MetadataBuildSupport.java 12898 2013-09-16 10:23:29Z krivopustov $
|
||||
*/
|
||||
public interface MetadataLoader {
|
||||
|
||||
void loadModel(String modelName, List<String> classNames);
|
||||
|
||||
Session postProcess();
|
||||
}
|
||||
|
||||
Session getSession();
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2013 Haulmont. All rights reserved.
|
||||
* Use is subject to license terms, see http://www.cuba-platform.com/license for details.
|
||||
*/
|
||||
|
||||
package com.haulmont.chile.core.loader;
|
||||
|
||||
import com.haulmont.chile.core.model.Session;
|
||||
import org.dom4j.Element;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public interface XmlMetadataLoader {
|
||||
Session loadXml(String xml);
|
||||
Session loadXml(Element xml);
|
||||
Session loadXml(InputStream xml);
|
||||
|
||||
Session getSession();
|
||||
}
|
@ -7,7 +7,6 @@ package com.haulmont.chile.jpa.loader;
|
||||
import com.haulmont.bali.util.ReflectionHelper;
|
||||
import com.haulmont.chile.core.annotations.MetaClass;
|
||||
import com.haulmont.chile.core.loader.ChileAnnotationsLoader;
|
||||
import com.haulmont.chile.core.loader.ClassMetadataLoader;
|
||||
import com.haulmont.chile.core.model.MetaProperty;
|
||||
import com.haulmont.chile.core.model.Range;
|
||||
import com.haulmont.chile.core.model.Session;
|
||||
@ -32,7 +31,7 @@ import static org.apache.commons.lang.StringUtils.isBlank;
|
||||
* @author krivopustov
|
||||
* @version $Id$
|
||||
*/
|
||||
public class JPAAnnotationsLoader extends ChileAnnotationsLoader implements ClassMetadataLoader {
|
||||
public class JPAAnnotationsLoader extends ChileAnnotationsLoader {
|
||||
|
||||
private Log log = LogFactory.getLog(JPAMetadataLoader.class);
|
||||
|
||||
@ -172,7 +171,7 @@ public class JPAAnnotationsLoader extends ChileAnnotationsLoader implements Clas
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MetaClassImpl __createClass(Class<?> clazz, String modelName) {
|
||||
protected MetaClassImpl createClass(Class<?> clazz, String packageName) {
|
||||
if (Object.class.equals(clazz)) return null;
|
||||
|
||||
Entity entityAnnotation = clazz.getAnnotation(Entity.class);
|
||||
@ -198,7 +197,7 @@ public class JPAAnnotationsLoader extends ChileAnnotationsLoader implements Clas
|
||||
className = clazz.getSimpleName();
|
||||
}
|
||||
|
||||
return __createClass(clazz, modelName, className);
|
||||
return createClass(clazz, packageName, className);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -6,7 +6,7 @@
|
||||
package com.haulmont.chile.jpa.loader;
|
||||
|
||||
import com.haulmont.chile.core.loader.ChileMetadataLoader;
|
||||
import com.haulmont.chile.core.loader.ClassMetadataLoader;
|
||||
import com.haulmont.chile.core.loader.MetaClassLoader;
|
||||
import com.haulmont.chile.core.model.Session;
|
||||
|
||||
public class JPAMetadataLoader extends ChileMetadataLoader {
|
||||
@ -16,7 +16,7 @@ public class JPAMetadataLoader extends ChileMetadataLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassMetadataLoader createAnnotationsLoader(Session session) {
|
||||
protected MetaClassLoader createMetaClassLoader(Session session) {
|
||||
return new JPAAnnotationsLoader(session);
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,9 @@
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="metadataModelType">
|
||||
<xs:sequence>
|
||||
<xs:element type="xs:string" name="class" maxOccurs="unbounded" minOccurs="0"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:string" name="root-package" use="required"/>
|
||||
</xs:complexType>
|
||||
|
||||
|
@ -25,13 +25,24 @@ import java.util.*;
|
||||
@ManagedBean("cuba_MetadataBuildSupport")
|
||||
public class MetadataBuildSupport {
|
||||
|
||||
public static final String PERSISTENCE_CONFIG = "cuba.persistenceConfig";
|
||||
public static final String METADATA_CONFIG = "cuba.metadataConfig";
|
||||
|
||||
@Inject
|
||||
private Resources resources;
|
||||
|
||||
/**
|
||||
* Get the location of non-persistent metadata descriptor
|
||||
* @return location of persistent entities descriptor
|
||||
*/
|
||||
public String getPersistenceConfig() {
|
||||
String config = AppContext.getProperty(PERSISTENCE_CONFIG);
|
||||
if (StringUtils.isBlank(config))
|
||||
throw new IllegalStateException(PERSISTENCE_CONFIG + " application property is not defined");
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return location of metadata descriptor
|
||||
*/
|
||||
public String getMetadataConfig() {
|
||||
String config = AppContext.getProperty(METADATA_CONFIG);
|
||||
@ -40,11 +51,18 @@ public class MetadataBuildSupport {
|
||||
return config;
|
||||
}
|
||||
|
||||
public List<String> getEntityPackages() {
|
||||
String config = getMetadataConfig();
|
||||
List<String> packages = new ArrayList<>();
|
||||
StrTokenizer tokenizer = new StrTokenizer(config);
|
||||
for (String fileName : tokenizer.getTokenArray()) {
|
||||
public Map<String, List<String>> getEntityPackages() {
|
||||
Map<String, List<String>> packages = new LinkedHashMap<>();
|
||||
|
||||
loadFromMetadataConfig(packages);
|
||||
loadFromPersistenceConfig(packages);
|
||||
|
||||
return packages;
|
||||
}
|
||||
|
||||
protected void loadFromMetadataConfig(Map<String, List<String>> packages) {
|
||||
StrTokenizer metadataFilesTokenizer = new StrTokenizer(getMetadataConfig());
|
||||
for (String fileName : metadataFilesTokenizer.getTokenArray()) {
|
||||
Element root = readXml(fileName);
|
||||
//noinspection unchecked
|
||||
for (Element element : (List<Element>) root.elements("metadata-model")) {
|
||||
@ -52,11 +70,53 @@ public class MetadataBuildSupport {
|
||||
if (StringUtils.isBlank(rootPackage))
|
||||
throw new IllegalStateException("metadata-model/@root-package is empty in " + fileName);
|
||||
|
||||
if (!packages.contains(rootPackage))
|
||||
packages.add(rootPackage);
|
||||
List<String> classNames = packages.get(rootPackage);
|
||||
if (classNames == null) {
|
||||
classNames = new ArrayList<>();
|
||||
packages.put(rootPackage, classNames);
|
||||
}
|
||||
for (Element classEl : Dom4j.elements(element, "class")) {
|
||||
classNames.add(classEl.getText().trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadFromPersistenceConfig(Map<String, List<String>> packages) {
|
||||
StrTokenizer persistenceFilestokenizer = new StrTokenizer(getPersistenceConfig());
|
||||
for (String fileName : persistenceFilestokenizer.getTokenArray()) {
|
||||
Element root = readXml(fileName);
|
||||
Element puEl = root.element("persistence-unit");
|
||||
if (puEl == null)
|
||||
throw new IllegalStateException("File " + fileName + " has no persistence-unit element");
|
||||
|
||||
for (Element classEl : Dom4j.elements(puEl, "class")) {
|
||||
String className = classEl.getText().trim();
|
||||
boolean included = false;
|
||||
for (String rootPackage : packages.keySet()) {
|
||||
if (className.startsWith(rootPackage + ".")) {
|
||||
// check if the class is already included into a model
|
||||
for (Map.Entry<String, List<String>> entry : packages.entrySet()) {
|
||||
if (entry.getValue().contains(className)) {
|
||||
throw new IllegalStateException("Class " + className
|
||||
+ " is already included into model " + entry.getKey());
|
||||
}
|
||||
}
|
||||
List<String> classNames = packages.get(rootPackage);
|
||||
if (classNames == null) {
|
||||
classNames = new ArrayList<>();
|
||||
packages.put(rootPackage, classNames);
|
||||
}
|
||||
classNames.add(className);
|
||||
included = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!included)
|
||||
throw new IllegalStateException("Can not find a model for class " + className
|
||||
+ ". The class's package must be inside of some model's root package.");
|
||||
}
|
||||
}
|
||||
return packages;
|
||||
}
|
||||
|
||||
public Element readXml(String path) {
|
||||
|
@ -85,9 +85,9 @@ public class MetadataImpl implements Metadata {
|
||||
return tools;
|
||||
}
|
||||
|
||||
protected void loadMetadata(MetadataLoader loader, List<String> packages) {
|
||||
for (String p : packages) {
|
||||
loader.loadPackage(p, p);
|
||||
protected void loadMetadata(MetadataLoader loader, Map<String, List<String>> packages) {
|
||||
for (Map.Entry<String, List<String>> entry : packages.entrySet()) {
|
||||
loader.loadModel(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,9 +125,10 @@ public class MetadataImpl implements Metadata {
|
||||
|
||||
initExtensionMetaAnnotations(session);
|
||||
|
||||
Map<String, Map<String, String>> xmlAnnotations = metadataBuildSupport.getEntityAnnotations();
|
||||
for (MetaClass metaClass : session.getClasses()) {
|
||||
initMetaAnnotations(session, metaClass);
|
||||
addMetaAnnotationsFromXml(metadataBuildSupport.getEntityAnnotations(), metaClass);
|
||||
addMetaAnnotationsFromXml(xmlAnnotations, metaClass);
|
||||
}
|
||||
|
||||
this.session = new CachingMetadataSession(session);
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
package com.haulmont.cuba.core.sys;
|
||||
|
||||
import com.haulmont.chile.core.loader.ClassMetadataLoader;
|
||||
import com.haulmont.chile.core.loader.MetaClassLoader;
|
||||
import com.haulmont.chile.core.model.MetaClass;
|
||||
import com.haulmont.chile.core.model.MetaProperty;
|
||||
import com.haulmont.chile.core.model.Session;
|
||||
@ -20,10 +20,9 @@ import java.lang.reflect.AnnotatedElement;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>$Id$</p>
|
||||
*
|
||||
* @author krivopustov
|
||||
*/
|
||||
* @author krivopustov
|
||||
* @version $Id$
|
||||
*/
|
||||
@ManagedBean("cuba_PersistentEntitiesMetadataLoader")
|
||||
public class PersistentEntitiesMetadataLoader extends JPAMetadataLoader {
|
||||
|
||||
@ -32,7 +31,7 @@ public class PersistentEntitiesMetadataLoader extends JPAMetadataLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassMetadataLoader createAnnotationsLoader(Session session) {
|
||||
protected MetaClassLoader createMetaClassLoader(Session session) {
|
||||
return new CubaAnnotationsLoader(session);
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,17 @@
|
||||
|
||||
<metadata xmlns="http://schemas.haulmont.com/cuba/5.2/metadata.xsd">
|
||||
|
||||
<metadata-model root-package="com.haulmont.cuba"/>
|
||||
<metadata-model root-package="com.haulmont.cuba">
|
||||
<class>com.haulmont.cuba.core.entity.diff.EntityBasicPropertyDiff</class>
|
||||
<class>com.haulmont.cuba.core.entity.diff.EntityClassPropertyDiff</class>
|
||||
<class>com.haulmont.cuba.core.entity.diff.EntityCollectionPropertyDiff</class>
|
||||
<class>com.haulmont.cuba.core.entity.diff.EntityDiff</class>
|
||||
<class>com.haulmont.cuba.core.entity.diff.EntityPropertyDiff</class>
|
||||
<class>com.haulmont.cuba.core.global.LockInfo</class>
|
||||
<class>com.haulmont.cuba.core.sys.SetValueEntity</class>
|
||||
<class>com.haulmont.cuba.security.entity.EntityLogAttr</class>
|
||||
<class>com.haulmont.cuba.security.entity.UserSessionEntity</class>
|
||||
</metadata-model>
|
||||
|
||||
<!-- Use this element to define or override entity annotations available through MetaClass.getAnnotations()
|
||||
<annotations>
|
||||
|
13
modules/gui/src/cuba-gui-metadata.xml
Normal file
13
modules/gui/src/cuba-gui-metadata.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2008-2014 Haulmont. All rights reserved.
|
||||
~ Use is subject to license terms, see http://www.cuba-platform.com/license for details.
|
||||
-->
|
||||
|
||||
<metadata xmlns="http://schemas.haulmont.com/cuba/5.2/metadata.xsd">
|
||||
|
||||
<metadata-model root-package="com.haulmont.cuba">
|
||||
<class>com.haulmont.cuba.gui.app.core.showinfo.KeyValueEntity</class>
|
||||
</metadata-model>
|
||||
|
||||
</metadata>
|
@ -39,7 +39,8 @@ cuba.classpath.directories=${catalina.home}/lib;\
|
||||
|
||||
cuba.springContextConfig=cuba-web-spring.xml
|
||||
cuba.dispatcherSpringContextConfig=cuba-dispatcher-spring.xml
|
||||
cuba.metadataConfig=cuba-metadata.xml
|
||||
cuba.persistenceConfig=cuba-persistence.xml
|
||||
cuba.metadataConfig=cuba-metadata.xml cuba-gui-metadata.xml cuba-web-metadata.xml
|
||||
cuba.viewsConfig=
|
||||
|
||||
cuba.windowConfig=cuba-web-screens.xml
|
||||
|
17
modules/web/src/cuba-web-metadata.xml
Normal file
17
modules/web/src/cuba-web-metadata.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2008-2014 Haulmont. All rights reserved.
|
||||
~ Use is subject to license terms, see http://www.cuba-platform.com/license for details.
|
||||
-->
|
||||
|
||||
<metadata xmlns="http://schemas.haulmont.com/cuba/5.2/metadata.xsd">
|
||||
|
||||
<metadata-model root-package="com.haulmont.cuba">
|
||||
<class>com.haulmont.cuba.web.jmx.entity.ManagedBeanAttribute</class>
|
||||
<class>com.haulmont.cuba.web.jmx.entity.ManagedBeanDomain</class>
|
||||
<class>com.haulmont.cuba.web.jmx.entity.ManagedBeanInfo</class>
|
||||
<class>com.haulmont.cuba.web.jmx.entity.ManagedBeanOperation</class>
|
||||
<class>com.haulmont.cuba.web.jmx.entity.ManagedBeanOperationParameter</class>
|
||||
</metadata-model>
|
||||
|
||||
</metadata>
|
@ -39,7 +39,7 @@ cuba.classpath.directories=${catalina.home}/lib;\
|
||||
|
||||
cuba.springContextConfig=cuba-web-spring.xml
|
||||
cuba.dispatcherSpringContextConfig=cuba-dispatcher-spring.xml
|
||||
cuba.metadataConfig=cuba-metadata.xml
|
||||
cuba.metadataConfig=cuba-metadata.xml cuba-gui-metadata.xml cuba-web-metadata.xml
|
||||
cuba.viewsConfig=
|
||||
|
||||
cuba.windowConfig=cuba-web-screens.xml
|
||||
|
17
modules/web6/src/cuba-web-metadata.xml
Normal file
17
modules/web6/src/cuba-web-metadata.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2008-2014 Haulmont. All rights reserved.
|
||||
~ Use is subject to license terms, see http://www.cuba-platform.com/license for details.
|
||||
-->
|
||||
|
||||
<metadata xmlns="http://schemas.haulmont.com/cuba/5.2/metadata.xsd">
|
||||
|
||||
<metadata-model root-package="com.haulmont.cuba">
|
||||
<class>com.haulmont.cuba.web.jmx.entity.ManagedBeanAttribute</class>
|
||||
<class>com.haulmont.cuba.web.jmx.entity.ManagedBeanDomain</class>
|
||||
<class>com.haulmont.cuba.web.jmx.entity.ManagedBeanInfo</class>
|
||||
<class>com.haulmont.cuba.web.jmx.entity.ManagedBeanOperation</class>
|
||||
<class>com.haulmont.cuba.web.jmx.entity.ManagedBeanOperationParameter</class>
|
||||
</metadata-model>
|
||||
|
||||
</metadata>
|
Loading…
Reference in New Issue
Block a user