Metadata initialization is too slow. #PL-3662

This commit is contained in:
Konstantin Krivopustov 2014-03-20 08:10:31 +00:00
parent 1a80be1acd
commit cd50a4e4d0
21 changed files with 275 additions and 217 deletions

View File

@ -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']

View File

@ -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();

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}
}
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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>

View File

@ -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) {

View File

@ -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);

View File

@ -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);
}

View File

@ -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>

View 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>

View File

@ -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

View 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>

View File

@ -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

View 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>