mirror of
https://gitee.com/jmix/cuba.git
synced 2024-12-03 03:38:33 +08:00
ViewBuilder #PL-2048
This commit is contained in:
parent
925710cf5a
commit
a0e4261b14
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.util
|
||||
|
||||
import com.haulmont.cuba.core.CubaTestCase
|
||||
import com.haulmont.cuba.core.global.View
|
||||
import com.haulmont.cuba.core.util.ViewBuilder
|
||||
|
||||
/**
|
||||
* @author artamonov
|
||||
* @version $Id$
|
||||
*/
|
||||
class ViewBuilderTest extends CubaTestCase {
|
||||
|
||||
ViewBuilder builder
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp()
|
||||
|
||||
builder = new ViewBuilder()
|
||||
}
|
||||
|
||||
public void testSimpleViewDefinition() {
|
||||
View view1 = builder.view(class: 'com.haulmont.cuba.security.entity.Group',
|
||||
name: 'group.edit.test', extends: 'group.browse') {
|
||||
property(name: 'constraints', view: '_local')
|
||||
property(name: 'sessionAttributes', view: '_local')
|
||||
}
|
||||
|
||||
assertNotNull(view1)
|
||||
assertEquals(4, view1.properties.size())
|
||||
}
|
||||
|
||||
public void testDeepViewDefinition() {
|
||||
View view2 = builder.view(entity: 'sec$Group', name: 'group.edit.test', extends: 'group.browse') {
|
||||
property(name: 'constraints', view: 'group.browse')
|
||||
property(name: 'sessionAttributes', view: '_local')
|
||||
property(name: 'parent', view: '_local') {
|
||||
property(name: 'parent') {
|
||||
property(name: 'name')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assertNotNull(view2)
|
||||
assertEquals(4, view2.properties.size())
|
||||
assertEquals(2, view2.getProperty('parent').getView().properties.size())
|
||||
assertEquals(1, view2.getProperty('parent').getView().getProperty('parent').getView().properties.size())
|
||||
}
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.core.util
|
||||
|
||||
import com.haulmont.bali.util.ReflectionHelper
|
||||
import com.haulmont.cuba.core.global.AppBeans
|
||||
import com.haulmont.cuba.core.global.Metadata
|
||||
import com.haulmont.cuba.core.global.View
|
||||
import com.haulmont.cuba.core.global.ViewRepository
|
||||
import org.apache.commons.lang.StringUtils
|
||||
|
||||
/**
|
||||
* Simple Groovy builder for view definitions
|
||||
*
|
||||
* @author artamonov
|
||||
* @version $Id$
|
||||
*/
|
||||
class ViewBuilder {
|
||||
|
||||
private Metadata metadata = AppBeans.get(Metadata.class)
|
||||
private ViewRepository viewRepository = AppBeans.get(ViewRepository.class)
|
||||
|
||||
private View createView(ViewNode viewNode) {
|
||||
String entity = viewNode.entity
|
||||
|
||||
com.haulmont.chile.core.model.MetaClass metaClass
|
||||
if (StringUtils.isBlank(entity)) {
|
||||
String className = viewNode.className
|
||||
if (StringUtils.isBlank(className))
|
||||
throw new IllegalStateException('Invalid view definition: no \'entity\' or \'class\' attribute')
|
||||
|
||||
Class entityClass = ReflectionHelper.getClass(className)
|
||||
metaClass = metadata.getClassNN(entityClass)
|
||||
} else {
|
||||
metaClass = metadata.getClassNN(entity)
|
||||
}
|
||||
|
||||
String viewName = viewNode.name
|
||||
String extendsView = viewNode.extendsView
|
||||
|
||||
if (viewNode.systemProperties == null)
|
||||
viewNode.systemProperties = false;
|
||||
|
||||
View view
|
||||
if (StringUtils.isNotBlank(extendsView)) {
|
||||
View ancestorView = viewRepository.getView(metaClass, extendsView)
|
||||
|
||||
boolean includeSystemProperties = viewNode.systemProperties == null ?
|
||||
ancestorView.isIncludeSystemProperties() : viewNode.systemProperties
|
||||
|
||||
view = new View(ancestorView, metaClass.getJavaClass(), viewName, includeSystemProperties)
|
||||
} else {
|
||||
view = new View(metaClass.getJavaClass(), viewName, viewNode.systemProperties)
|
||||
}
|
||||
|
||||
for (ViewPropertyNode propertyNode : viewNode.viewProperties) {
|
||||
createPropertyView(view, propertyNode)
|
||||
}
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
private void createPropertyView(View view, ViewPropertyNode viewPropertyNode) {
|
||||
final com.haulmont.chile.core.model.MetaClass metaClass = metadata.getClassNN(view.getEntityClass())
|
||||
|
||||
String propertyName = viewPropertyNode.name
|
||||
com.haulmont.chile.core.model.MetaProperty metaProperty = metaClass.getProperty(propertyName)
|
||||
if (metaProperty == null) {
|
||||
throw new IllegalStateException(
|
||||
String.format("View ${metaClass.name}/${view.name} definition error: property $propertyName doesn't exists")
|
||||
)
|
||||
}
|
||||
|
||||
View refView = null
|
||||
com.haulmont.chile.core.model.MetaClass refMetaClass
|
||||
com.haulmont.chile.core.model.Range range = metaProperty.getRange()
|
||||
|
||||
if (range == null) {
|
||||
throw new IllegalStateException("Cannot find range for meta property ${metaProperty}");
|
||||
}
|
||||
|
||||
boolean inlineView = !viewPropertyNode.viewProperties.isEmpty()
|
||||
if (StringUtils.isNotBlank(viewPropertyNode.view) && !inlineView) {
|
||||
if (!range.isClass()) {
|
||||
throw new IllegalStateException(
|
||||
String.format("View ${metaClass.name}/${view.name} definition error: property $propertyName is not an entity")
|
||||
);
|
||||
}
|
||||
|
||||
refMetaClass = range.asClass()
|
||||
|
||||
refView = viewRepository.findView(refMetaClass, viewPropertyNode.name)
|
||||
}
|
||||
|
||||
if (range.isClass() && refView == null && inlineView) {
|
||||
String extendsView = viewPropertyNode.view
|
||||
if (StringUtils.isBlank(extendsView)) {
|
||||
refView = new View(range.asClass().getJavaClass())
|
||||
} else {
|
||||
refMetaClass = range.asClass()
|
||||
View ancestorView = viewRepository.getView(refMetaClass, extendsView)
|
||||
refView = new View(ancestorView, range.asClass().getJavaClass(), "", true)
|
||||
}
|
||||
|
||||
for (ViewPropertyNode childPropertyNode : viewPropertyNode.viewProperties) {
|
||||
createPropertyView(refView, childPropertyNode)
|
||||
}
|
||||
}
|
||||
|
||||
if (viewPropertyNode.lazy == null)
|
||||
viewPropertyNode.lazy = false
|
||||
|
||||
view.addProperty(propertyName, refView, viewPropertyNode.lazy)
|
||||
}
|
||||
|
||||
View view(Map attributes, Closure definition) {
|
||||
ViewNode viewNode = new ViewNodeBuilder().view(attributes, definition)
|
||||
|
||||
return createView(viewNode)
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.core.util
|
||||
|
||||
/**
|
||||
* @author artamonov
|
||||
* @version $Id$
|
||||
*/
|
||||
class ViewNode {
|
||||
|
||||
String className
|
||||
String entity
|
||||
String name
|
||||
String extendsView
|
||||
Boolean systemProperties
|
||||
|
||||
List<ViewPropertyNode> viewProperties = []
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.core.util
|
||||
|
||||
import javax.naming.OperationNotSupportedException
|
||||
|
||||
/**
|
||||
* @author artamonov
|
||||
* @version $Id$
|
||||
*/
|
||||
@PackageScope
|
||||
class ViewNodeBuilder extends BuilderSupport {
|
||||
|
||||
@Override
|
||||
protected void setParent(Object parent, Object child) {
|
||||
if (child != null)
|
||||
parent.viewProperties.add(child)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object createNode(Object name) {
|
||||
throw new OperationNotSupportedException()
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object createNode(Object name, Object value) {
|
||||
throw new OperationNotSupportedException()
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object createNode(Object name, Map attributes) {
|
||||
if ('view' == name) {
|
||||
return new ViewNode(
|
||||
name: attributes['name'],
|
||||
entity: attributes['entity'],
|
||||
className: attributes['class'],
|
||||
extendsView: attributes['extends'],
|
||||
systemProperties: attributes['systemProperties']
|
||||
)
|
||||
}
|
||||
|
||||
if ('property' == name) {
|
||||
return new ViewPropertyNode(
|
||||
name: attributes['name'],
|
||||
view: attributes['view'],
|
||||
lazy: attributes['lazy']
|
||||
)
|
||||
}
|
||||
|
||||
throw new OperationNotSupportedException()
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object createNode(Object name, Map attributes, Object value) {
|
||||
throw new OperationNotSupportedException()
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.core.util
|
||||
|
||||
/**
|
||||
* @author artamonov
|
||||
* @version $Id$
|
||||
*/
|
||||
class ViewPropertyNode {
|
||||
String name
|
||||
String view
|
||||
Boolean lazy
|
||||
|
||||
List<ViewPropertyNode> viewProperties = []
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.core.util
|
||||
|
||||
import junit.framework.TestCase
|
||||
|
||||
/**
|
||||
* @author artamonov
|
||||
* @version $Id$
|
||||
*/
|
||||
class ViewNodeBuilderTest extends TestCase {
|
||||
|
||||
public void testSimpleView() {
|
||||
def builder = new ViewNodeBuilder()
|
||||
|
||||
def viewDefinition = builder.view(entity: 'sec$UserSubstitution', extends: 'user.edit') {
|
||||
property(name: 'substitutedUser') {
|
||||
property(name: 'name')
|
||||
property(name: 'login')
|
||||
}
|
||||
property(name: 'startDate')
|
||||
property(name: 'endDate')
|
||||
}
|
||||
|
||||
assertNotNull(viewDefinition)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user