mirror of
https://gitee.com/jmix/cuba.git
synced 2024-12-04 12:17:41 +08:00
PL-8127 Queries with scalars and aggregates from the client side
This commit is contained in:
parent
03f2185a3b
commit
2851052d6e
@ -20,6 +20,7 @@ package com.haulmont.cuba.client.sys;
|
|||||||
import com.haulmont.chile.core.model.MetaClass;
|
import com.haulmont.chile.core.model.MetaClass;
|
||||||
import com.haulmont.cuba.core.app.DataService;
|
import com.haulmont.cuba.core.app.DataService;
|
||||||
import com.haulmont.cuba.core.entity.Entity;
|
import com.haulmont.cuba.core.entity.Entity;
|
||||||
|
import com.haulmont.cuba.core.entity.KeyValueEntity;
|
||||||
import com.haulmont.cuba.core.global.*;
|
import com.haulmont.cuba.core.global.*;
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -131,6 +132,11 @@ public class DataManagerClientImpl implements DataManager {
|
|||||||
commit(context);
|
commit(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<KeyValueEntity> loadValues(ValueLoadContext context) {
|
||||||
|
return dataService.loadValues(context);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataManager secure() {
|
public DataManager secure() {
|
||||||
return this;
|
return this;
|
||||||
|
@ -18,10 +18,7 @@
|
|||||||
package com.haulmont.cuba.core.app;
|
package com.haulmont.cuba.core.app;
|
||||||
|
|
||||||
import com.haulmont.chile.core.model.MetaClass;
|
import com.haulmont.chile.core.model.MetaClass;
|
||||||
import com.haulmont.cuba.core.entity.AbstractNotPersistentEntity;
|
import com.haulmont.cuba.core.entity.*;
|
||||||
import com.haulmont.cuba.core.entity.BaseEntityInternalAccess;
|
|
||||||
import com.haulmont.cuba.core.entity.BaseGenericIdEntity;
|
|
||||||
import com.haulmont.cuba.core.entity.Entity;
|
|
||||||
import com.haulmont.cuba.core.global.*;
|
import com.haulmont.cuba.core.global.*;
|
||||||
import com.haulmont.cuba.core.sys.AppContext;
|
import com.haulmont.cuba.core.sys.AppContext;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -207,6 +204,12 @@ public class DataManagerBean implements DataManager {
|
|||||||
commit(context);
|
commit(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<KeyValueEntity> loadValues(ValueLoadContext context) {
|
||||||
|
DataStore store = storeFactory.get(context.getStoreName());
|
||||||
|
return store.loadValues(context);
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean entityHasDynamicAttributes(Entity entity) {
|
protected boolean entityHasDynamicAttributes(Entity entity) {
|
||||||
return entity instanceof BaseGenericIdEntity
|
return entity instanceof BaseGenericIdEntity
|
||||||
&& ((BaseGenericIdEntity) entity).getDynamicAttributes() != null;
|
&& ((BaseGenericIdEntity) entity).getDynamicAttributes() != null;
|
||||||
|
@ -17,9 +17,11 @@
|
|||||||
package com.haulmont.cuba.core.app;
|
package com.haulmont.cuba.core.app;
|
||||||
|
|
||||||
import com.haulmont.cuba.core.entity.Entity;
|
import com.haulmont.cuba.core.entity.Entity;
|
||||||
|
import com.haulmont.cuba.core.entity.KeyValueEntity;
|
||||||
import com.haulmont.cuba.core.global.CommitContext;
|
import com.haulmont.cuba.core.global.CommitContext;
|
||||||
import com.haulmont.cuba.core.global.DataManager;
|
import com.haulmont.cuba.core.global.DataManager;
|
||||||
import com.haulmont.cuba.core.global.LoadContext;
|
import com.haulmont.cuba.core.global.LoadContext;
|
||||||
|
import com.haulmont.cuba.core.global.ValueLoadContext;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -53,4 +55,9 @@ public class DataServiceBean implements DataService {
|
|||||||
public long getCount(LoadContext<? extends Entity> context) {
|
public long getCount(LoadContext<? extends Entity> context) {
|
||||||
return dataManager.secure().getCount(context);
|
return dataManager.secure().getCount(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<KeyValueEntity> loadValues(ValueLoadContext context) {
|
||||||
|
return dataManager.secure().loadValues(context);
|
||||||
|
}
|
||||||
}
|
}
|
@ -140,8 +140,8 @@ public class DataServiceQueryBuilder {
|
|||||||
value = list;
|
value = list;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value instanceof LoadContext.Query.TemporalValue) {
|
if (value instanceof TemporalValue) {
|
||||||
LoadContext.Query.TemporalValue temporalValue = (LoadContext.Query.TemporalValue) value;
|
TemporalValue temporalValue = (TemporalValue) value;
|
||||||
query.setParameter(name, temporalValue.date, temporalValue.type);
|
query.setParameter(name, temporalValue.date, temporalValue.type);
|
||||||
} else {
|
} else {
|
||||||
query.setParameter(name, value);
|
query.setParameter(name, value);
|
||||||
|
@ -17,8 +17,10 @@
|
|||||||
package com.haulmont.cuba.core.app;
|
package com.haulmont.cuba.core.app;
|
||||||
|
|
||||||
import com.haulmont.cuba.core.entity.Entity;
|
import com.haulmont.cuba.core.entity.Entity;
|
||||||
|
import com.haulmont.cuba.core.entity.KeyValueEntity;
|
||||||
import com.haulmont.cuba.core.global.CommitContext;
|
import com.haulmont.cuba.core.global.CommitContext;
|
||||||
import com.haulmont.cuba.core.global.LoadContext;
|
import com.haulmont.cuba.core.global.LoadContext;
|
||||||
|
import com.haulmont.cuba.core.global.ValueLoadContext;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -54,4 +56,6 @@ public interface DataStore {
|
|||||||
* @return set of committed instances
|
* @return set of committed instances
|
||||||
*/
|
*/
|
||||||
Set<Entity> commit(CommitContext context);
|
Set<Entity> commit(CommitContext context);
|
||||||
|
|
||||||
|
List<KeyValueEntity> loadValues(ValueLoadContext context);
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.haulmont.cuba.core.app;
|
package com.haulmont.cuba.core.app;
|
||||||
|
|
||||||
|
import com.haulmont.bali.util.Preconditions;
|
||||||
import com.haulmont.chile.core.model.MetaClass;
|
import com.haulmont.chile.core.model.MetaClass;
|
||||||
import com.haulmont.chile.core.model.MetaProperty;
|
import com.haulmont.chile.core.model.MetaProperty;
|
||||||
import com.haulmont.chile.core.model.Session;
|
import com.haulmont.chile.core.model.Session;
|
||||||
@ -390,6 +391,60 @@ public class RdbmsStore implements DataStore {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<KeyValueEntity> loadValues(ValueLoadContext context) {
|
||||||
|
Preconditions.checkNotNullArgument(context, "context is null");
|
||||||
|
Preconditions.checkNotNullArgument(context.getQuery(), "query is null");
|
||||||
|
|
||||||
|
ValueLoadContext.Query contextQuery = context.getQuery();
|
||||||
|
|
||||||
|
if (log.isDebugEnabled())
|
||||||
|
log.debug("query: " + (DataServiceQueryBuilder.printQuery(contextQuery.getQueryString()))
|
||||||
|
+ (contextQuery.getFirstResult() == 0 ? "" : ", first=" + contextQuery.getFirstResult())
|
||||||
|
+ (contextQuery.getMaxResults() == 0 ? "" : ", max=" + contextQuery.getMaxResults()));
|
||||||
|
|
||||||
|
List<KeyValueEntity> entities = new ArrayList<>();
|
||||||
|
|
||||||
|
try (Transaction tx = persistence.createTransaction(storeName)) {
|
||||||
|
EntityManager em = persistence.getEntityManager(storeName);
|
||||||
|
em.setSoftDeletion(context.isSoftDeletion());
|
||||||
|
|
||||||
|
List<String> keys = context.getProperties();
|
||||||
|
|
||||||
|
DataServiceQueryBuilder queryBuilder = AppBeans.get(DataServiceQueryBuilder.NAME);
|
||||||
|
queryBuilder.init(contextQuery.getQueryString(), contextQuery.getParameters(), null, metadata.getClassNN(KeyValueEntity.class).getName());
|
||||||
|
Query query = queryBuilder.getQuery(em);
|
||||||
|
|
||||||
|
if (contextQuery.getFirstResult() != 0)
|
||||||
|
query.setFirstResult(contextQuery.getFirstResult());
|
||||||
|
if (contextQuery.getMaxResults() != 0)
|
||||||
|
query.setMaxResults(contextQuery.getMaxResults());
|
||||||
|
|
||||||
|
List resultList = query.getResultList();
|
||||||
|
for (Object item : resultList) {
|
||||||
|
KeyValueEntity entity = new KeyValueEntity();
|
||||||
|
entity.setIdName(context.getIdName());
|
||||||
|
entities.add(entity);
|
||||||
|
|
||||||
|
if (item instanceof Object[]) {
|
||||||
|
Object[] row = (Object[]) item;
|
||||||
|
for (int i = 0; i < keys.size(); i++) {
|
||||||
|
String key = keys.get(i);
|
||||||
|
if (row.length > i) {
|
||||||
|
entity.setValue(key, row[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!keys.isEmpty()) {
|
||||||
|
entity.setValue(keys.get(0), item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tx.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
return entities;
|
||||||
|
}
|
||||||
|
|
||||||
protected View getViewFromContext(CommitContext context, Entity entity) {
|
protected View getViewFromContext(CommitContext context, Entity entity) {
|
||||||
View view = context.getViews().get(entity);
|
View view = context.getViews().get(entity);
|
||||||
if (view == null) {
|
if (view == null) {
|
||||||
|
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2016 Haulmont.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.haulmont.cuba.core;
|
||||||
|
|
||||||
|
import com.haulmont.cuba.core.entity.KeyValueEntity;
|
||||||
|
import com.haulmont.cuba.core.global.AppBeans;
|
||||||
|
import com.haulmont.cuba.core.global.DataManager;
|
||||||
|
import com.haulmont.cuba.core.global.ValueLoadContext;
|
||||||
|
import com.haulmont.cuba.testsupport.TestContainer;
|
||||||
|
import com.haulmont.cuba.testsupport.TestSupport;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class NonEntityQueryTest {
|
||||||
|
|
||||||
|
@ClassRule
|
||||||
|
public static TestContainer cont = TestContainer.Common.INSTANCE;
|
||||||
|
|
||||||
|
private DataManager dataManager;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
dataManager = AppBeans.get(DataManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testScalars() throws Exception {
|
||||||
|
ValueLoadContext context = ValueLoadContext.create()
|
||||||
|
.setQuery(ValueLoadContext.createQuery("select u.id, u.login from sec$User u where u.id = :id1 or u.id = :id2 order by u.login")
|
||||||
|
.setParameter("id1", TestSupport.ADMIN_USER_ID)
|
||||||
|
.setParameter("id2", TestSupport.ANONYMOUS_USER_ID))
|
||||||
|
.addProperty("userId").addProperty("login");
|
||||||
|
|
||||||
|
List<KeyValueEntity> list = dataManager.loadValues(context);
|
||||||
|
|
||||||
|
assertEquals(2, list.size());
|
||||||
|
KeyValueEntity e = list.get(0);
|
||||||
|
assertEquals(TestSupport.ADMIN_USER_ID, e.getValue("userId"));
|
||||||
|
assertEquals("admin", e.getValue("login"));
|
||||||
|
e = list.get(1);
|
||||||
|
assertEquals(TestSupport.ANONYMOUS_USER_ID, e.getValue("userId"));
|
||||||
|
assertEquals("anonymous", e.getValue("login"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAggregates() throws Exception {
|
||||||
|
ValueLoadContext context = ValueLoadContext.create();
|
||||||
|
ValueLoadContext.Query query = context.setQueryString("select count(u) from sec$User u where u.id = :id1 or u.id = :id2");
|
||||||
|
query.setParameter("id1", TestSupport.ADMIN_USER_ID);
|
||||||
|
query.setParameter("id2", TestSupport.ANONYMOUS_USER_ID);
|
||||||
|
context.addProperty("count");
|
||||||
|
|
||||||
|
List<KeyValueEntity> list = dataManager.loadValues(context);
|
||||||
|
|
||||||
|
assertEquals(1, list.size());
|
||||||
|
KeyValueEntity e = list.get(0);
|
||||||
|
assertEquals(Long.valueOf(2), e.getValue("count"));
|
||||||
|
}
|
||||||
|
}
|
@ -49,7 +49,7 @@ public class QueryFilter2Test {
|
|||||||
@Test
|
@Test
|
||||||
public void testParse() throws Exception {
|
public void testParse() throws Exception {
|
||||||
Element element = Dom4j.readDocument(xml).getRootElement();
|
Element element = Dom4j.readDocument(xml).getRootElement();
|
||||||
QueryFilter queryFilter = new QueryFilter(element, "sec$User");
|
QueryFilter queryFilter = new QueryFilter(element);
|
||||||
|
|
||||||
Condition root = queryFilter.getRoot();
|
Condition root = queryFilter.getRoot();
|
||||||
System.out.println(new GroovyGenerator().generateGroovy(root));
|
System.out.println(new GroovyGenerator().generateGroovy(root));
|
||||||
|
@ -55,7 +55,7 @@ public class QueryFilterTest {
|
|||||||
private QueryFilter createFilter(String name) {
|
private QueryFilter createFilter(String name) {
|
||||||
InputStream stream = QueryFilterTest.class.getResourceAsStream("/com/haulmont/cuba/core/global/filter/" + name);
|
InputStream stream = QueryFilterTest.class.getResourceAsStream("/com/haulmont/cuba/core/global/filter/" + name);
|
||||||
Document doc = Dom4j.readDocument(stream);
|
Document doc = Dom4j.readDocument(stream);
|
||||||
return new QueryFilter(doc.getRootElement(), "saneco$GenDoc");
|
return new QueryFilter(doc.getRootElement());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -29,6 +29,8 @@ public class TestSupport {
|
|||||||
|
|
||||||
public static final UUID ADMIN_USER_ID = UUID.fromString("60885987-1b61-4247-94c7-dff348347f93");
|
public static final UUID ADMIN_USER_ID = UUID.fromString("60885987-1b61-4247-94c7-dff348347f93");
|
||||||
|
|
||||||
|
public static final UUID ANONYMOUS_USER_ID = UUID.fromString("a405db59-e674-4f63-8afe-269dda788fe8");
|
||||||
|
|
||||||
public static final UUID COMPANY_GROUP_ID = UUID.fromString("0fa2b1a5-1d68-4d69-9fbd-dff348347f93");
|
public static final UUID COMPANY_GROUP_ID = UUID.fromString("0fa2b1a5-1d68-4d69-9fbd-dff348347f93");
|
||||||
|
|
||||||
public static final UUID ADMIN_ROLE_ID = UUID.fromString("0c018061-b26f-4de2-a5be-dff348347f93");
|
public static final UUID ADMIN_ROLE_ID = UUID.fromString("0c018061-b26f-4de2-a5be-dff348347f93");
|
||||||
|
@ -17,8 +17,10 @@
|
|||||||
package com.haulmont.cuba.core.app;
|
package com.haulmont.cuba.core.app;
|
||||||
|
|
||||||
import com.haulmont.cuba.core.entity.Entity;
|
import com.haulmont.cuba.core.entity.Entity;
|
||||||
|
import com.haulmont.cuba.core.entity.KeyValueEntity;
|
||||||
import com.haulmont.cuba.core.global.CommitContext;
|
import com.haulmont.cuba.core.global.CommitContext;
|
||||||
import com.haulmont.cuba.core.global.LoadContext;
|
import com.haulmont.cuba.core.global.LoadContext;
|
||||||
|
import com.haulmont.cuba.core.global.ValueLoadContext;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -65,4 +67,6 @@ public interface DataService {
|
|||||||
* @return number of instances in the database
|
* @return number of instances in the database
|
||||||
*/
|
*/
|
||||||
long getCount(LoadContext<? extends Entity> context);
|
long getCount(LoadContext<? extends Entity> context);
|
||||||
|
|
||||||
|
List<KeyValueEntity> loadValues(ValueLoadContext context);
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,10 @@ public class KeyValueMetaClass extends MetadataObjectImpl implements MetaClass {
|
|||||||
properties.remove(propertyName);
|
properties.remove(propertyName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KeyValueMetaClass() {
|
||||||
|
name = "sys$KeyValueEntity";
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public MetaClass getAncestor() {
|
public MetaClass getAncestor() {
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package com.haulmont.cuba.core.app.keyvalue;
|
package com.haulmont.cuba.core.app.keyvalue;
|
||||||
|
|
||||||
|
import com.haulmont.chile.core.datatypes.Datatype;
|
||||||
import com.haulmont.chile.core.datatypes.Datatypes;
|
import com.haulmont.chile.core.datatypes.Datatypes;
|
||||||
import com.haulmont.chile.core.model.*;
|
import com.haulmont.chile.core.model.*;
|
||||||
import com.haulmont.chile.core.model.impl.ClassRange;
|
import com.haulmont.chile.core.model.impl.ClassRange;
|
||||||
@ -62,6 +63,16 @@ public class KeyValueMetaProperty extends MetadataObjectImpl implements MetaProp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KeyValueMetaProperty(MetaClass metaClass, String name, Datatype datatype) {
|
||||||
|
this.name = name;
|
||||||
|
this.javaClass = datatype.getJavaClass();
|
||||||
|
this.metaClass = metaClass;
|
||||||
|
this.mandatory = false;
|
||||||
|
|
||||||
|
this.range = new DatatypeRange(datatype);
|
||||||
|
this.type = Type.DATATYPE;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MetaModel getModel() {
|
public MetaModel getModel() {
|
||||||
return metaClass.getModel();
|
return metaClass.getModel();
|
||||||
|
@ -18,12 +18,16 @@
|
|||||||
package com.haulmont.cuba.core.entity;
|
package com.haulmont.cuba.core.entity;
|
||||||
|
|
||||||
import com.haulmont.chile.core.model.MetaClass;
|
import com.haulmont.chile.core.model.MetaClass;
|
||||||
|
import com.haulmont.chile.core.model.impl.AbstractInstance;
|
||||||
import com.haulmont.cuba.core.entity.annotation.SystemLevel;
|
import com.haulmont.cuba.core.entity.annotation.SystemLevel;
|
||||||
|
import com.haulmont.cuba.core.global.UuidProvider;
|
||||||
import com.haulmont.cuba.core.sys.CubaEnhancingDisabled;
|
import com.haulmont.cuba.core.sys.CubaEnhancingDisabled;
|
||||||
import org.apache.commons.lang.ObjectUtils;
|
import org.apache.commons.lang.ObjectUtils;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entity that contains a variable set of attributes. For example:
|
* Entity that contains a variable set of attributes. For example:
|
||||||
@ -41,11 +45,21 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
@com.haulmont.chile.core.annotations.MetaClass(name = "sys$KeyValueEntity")
|
@com.haulmont.chile.core.annotations.MetaClass(name = "sys$KeyValueEntity")
|
||||||
@SystemLevel
|
@SystemLevel
|
||||||
public class KeyValueEntity extends AbstractNotPersistentEntity implements CubaEnhancingDisabled {
|
public class KeyValueEntity
|
||||||
|
extends AbstractInstance
|
||||||
|
implements Entity<Object>, CubaEnhancingDisabled {
|
||||||
|
|
||||||
private Map<String, Object> properties = new LinkedHashMap<>();
|
protected UUID uuid;
|
||||||
|
|
||||||
private MetaClass metaClass;
|
protected Map<String, Object> properties = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
protected String idName;
|
||||||
|
|
||||||
|
protected MetaClass metaClass;
|
||||||
|
|
||||||
|
public KeyValueEntity() {
|
||||||
|
uuid = UuidProvider.createUuid();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MetaClass getMetaClass() {
|
public MetaClass getMetaClass() {
|
||||||
@ -58,6 +72,14 @@ public class KeyValueEntity extends AbstractNotPersistentEntity implements CubaE
|
|||||||
this.metaClass = metaClass;
|
this.metaClass = metaClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getIdName() {
|
||||||
|
return idName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdName(String idName) {
|
||||||
|
this.idName = idName;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T getValue(String name) {
|
public <T> T getValue(String name) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
@ -72,4 +94,51 @@ public class KeyValueEntity extends AbstractNotPersistentEntity implements CubaE
|
|||||||
propertyChanged(name, oldValue, value);
|
propertyChanged(name, oldValue, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getId() {
|
||||||
|
if (idName == null)
|
||||||
|
return uuid;
|
||||||
|
else
|
||||||
|
return properties.get(idName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Object id) {
|
||||||
|
if (idName == null)
|
||||||
|
throw new IllegalStateException("Id name is not set");
|
||||||
|
properties.put(idName, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
KeyValueEntity that = (KeyValueEntity) o;
|
||||||
|
Object id = getId();
|
||||||
|
Object thatId = that.getId();
|
||||||
|
|
||||||
|
if (id != null && thatId != null)
|
||||||
|
return id.equals(thatId);
|
||||||
|
|
||||||
|
return Objects.equals(uuid, that.uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
Object id = getId();
|
||||||
|
if (id != null)
|
||||||
|
return id.hashCode();
|
||||||
|
return uuid.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
Object id = null;
|
||||||
|
if (idName != null)
|
||||||
|
id = properties.get(idName);
|
||||||
|
if (id == null)
|
||||||
|
id = "?(" + uuid + ")";
|
||||||
|
return "sys$KeyValueEntity-" + id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2016 Haulmont.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.haulmont.cuba.core.global;
|
||||||
|
|
||||||
|
public interface DataLoadContext {
|
||||||
|
|
||||||
|
DataLoadContextQuery setQueryString(String queryString);
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2016 Haulmont.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.haulmont.cuba.core.global;
|
||||||
|
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface DataLoadContextQuery {
|
||||||
|
|
||||||
|
DataLoadContextQuery setParameter(String name, Object value);
|
||||||
|
|
||||||
|
DataLoadContextQuery setParameter(String name, Date value, TemporalType temporalType);
|
||||||
|
|
||||||
|
Map<String, Object> getParameters();
|
||||||
|
DataLoadContextQuery setParameters(Map<String, Object> parameters);
|
||||||
|
|
||||||
|
int getFirstResult();
|
||||||
|
DataLoadContextQuery setFirstResult(int firstResult);
|
||||||
|
|
||||||
|
int getMaxResults();
|
||||||
|
DataLoadContextQuery setMaxResults(int maxResults);
|
||||||
|
}
|
@ -19,6 +19,7 @@ package com.haulmont.cuba.core.global;
|
|||||||
|
|
||||||
import com.haulmont.chile.core.model.MetaClass;
|
import com.haulmont.chile.core.model.MetaClass;
|
||||||
import com.haulmont.cuba.core.entity.Entity;
|
import com.haulmont.cuba.core.entity.Entity;
|
||||||
|
import com.haulmont.cuba.core.entity.KeyValueEntity;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -142,6 +143,8 @@ public interface DataManager {
|
|||||||
*/
|
*/
|
||||||
void remove(Entity entity);
|
void remove(Entity entity);
|
||||||
|
|
||||||
|
List<KeyValueEntity> loadValues(ValueLoadContext context);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the DataManager implementation that is guaranteed to apply security restrictions.
|
* Returns the DataManager implementation that is guaranteed to apply security restrictions.
|
||||||
* <p>By default, DataManager does not apply security when used on the middleware. Use this method if you want
|
* <p>By default, DataManager does not apply security when used on the middleware. Use this method if you want
|
||||||
|
@ -37,7 +37,7 @@ import java.util.stream.Collectors;
|
|||||||
List<User> users = dataManager.loadList(context);
|
List<User> users = dataManager.loadList(context);
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
public class LoadContext<E extends Entity> implements Serializable {
|
public class LoadContext<E extends Entity> implements DataLoadContext, Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -8808320502197308698L;
|
private static final long serialVersionUID = -8808320502197308698L;
|
||||||
|
|
||||||
@ -118,6 +118,7 @@ public class LoadContext<E extends Entity> implements Serializable {
|
|||||||
* @param queryString JPQL query string. Only named parameters are supported.
|
* @param queryString JPQL query string. Only named parameters are supported.
|
||||||
* @return query definition object
|
* @return query definition object
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Query setQueryString(String queryString) {
|
public Query setQueryString(String queryString) {
|
||||||
final Query query = new Query(queryString);
|
final Query query = new Query(queryString);
|
||||||
setQuery(query);
|
setQuery(query);
|
||||||
@ -283,7 +284,7 @@ public class LoadContext<E extends Entity> implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* Class that defines a query to be executed for data loading.
|
* Class that defines a query to be executed for data loading.
|
||||||
*/
|
*/
|
||||||
public static class Query implements Serializable {
|
public static class Query implements DataLoadContextQuery, Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 3819951144050635838L;
|
private static final long serialVersionUID = 3819951144050635838L;
|
||||||
|
|
||||||
@ -293,18 +294,6 @@ public class LoadContext<E extends Entity> implements Serializable {
|
|||||||
private int maxResults;
|
private int maxResults;
|
||||||
private boolean cacheable;
|
private boolean cacheable;
|
||||||
|
|
||||||
public static class TemporalValue implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 4972088045550018312L;
|
|
||||||
|
|
||||||
public final Date date;
|
|
||||||
public final TemporalType type;
|
|
||||||
|
|
||||||
public TemporalValue(Date date, TemporalType type) {
|
|
||||||
this.date = date;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @param queryString JPQL query string. Only named parameters are supported.
|
* @param queryString JPQL query string. Only named parameters are supported.
|
||||||
*/
|
*/
|
||||||
@ -359,8 +348,9 @@ public class LoadContext<E extends Entity> implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* @param parameters map of the query parameters
|
* @param parameters map of the query parameters
|
||||||
*/
|
*/
|
||||||
public void setParameters(Map<String, Object> parameters) {
|
public Query setParameters(Map<String, Object> parameters) {
|
||||||
this.parameters.putAll(parameters);
|
this.parameters.putAll(parameters);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2016 Haulmont.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.haulmont.cuba.core.global;
|
||||||
|
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class TemporalValue implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 4972088045550018312L;
|
||||||
|
|
||||||
|
public final Date date;
|
||||||
|
public final TemporalType type;
|
||||||
|
|
||||||
|
public TemporalValue(Date date, TemporalType type) {
|
||||||
|
this.date = date;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,208 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2016 Haulmont.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.haulmont.cuba.core.global;
|
||||||
|
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class ValueLoadContext implements DataLoadContext, Serializable {
|
||||||
|
|
||||||
|
protected String storeName = Stores.MAIN;
|
||||||
|
protected Query query;
|
||||||
|
protected boolean softDeletion = true;
|
||||||
|
protected String idName;
|
||||||
|
protected List<String> properties = new ArrayList<>();
|
||||||
|
|
||||||
|
public static ValueLoadContext create() {
|
||||||
|
return new ValueLoadContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Query createQuery(String queryString) {
|
||||||
|
return new Query(queryString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query setQueryString(String queryString) {
|
||||||
|
query = new Query(queryString);
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStoreName() {
|
||||||
|
return storeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueLoadContext setStoreName(String storeName) {
|
||||||
|
this.storeName = storeName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueLoadContext setQuery(Query query) {
|
||||||
|
this.query = query;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Query getQuery() {
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueLoadContext setSoftDeletion(boolean softDeletion) {
|
||||||
|
this.softDeletion = softDeletion;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSoftDeletion() {
|
||||||
|
return softDeletion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIdName() {
|
||||||
|
return idName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdName(String idName) {
|
||||||
|
this.idName = idName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueLoadContext addProperty(String name) {
|
||||||
|
properties.add(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueLoadContext setProperties(List<String> properties) {
|
||||||
|
this.properties.clear();
|
||||||
|
this.properties.addAll(properties);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getProperties() {
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("ValuesContext{query=%s, softDeletion=%s, keys=%s}", query, softDeletion, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Query implements DataLoadContextQuery, Serializable {
|
||||||
|
|
||||||
|
private String queryString;
|
||||||
|
private int firstResult;
|
||||||
|
private int maxResults;
|
||||||
|
private Map<String, Object> parameters = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param queryString JPQL query string. Only named parameters are supported.
|
||||||
|
*/
|
||||||
|
public Query(String queryString) {
|
||||||
|
this.queryString = queryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return JPQL query string
|
||||||
|
*/
|
||||||
|
public String getQueryString() {
|
||||||
|
return queryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param queryString JPQL query string. Only named parameters are supported.
|
||||||
|
*/
|
||||||
|
public void setQueryString(String queryString) {
|
||||||
|
this.queryString = queryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set value for a query parameter.
|
||||||
|
* @param name parameter name
|
||||||
|
* @param value parameter value
|
||||||
|
* @return this query instance for chaining
|
||||||
|
*/
|
||||||
|
public Query setParameter(String name, Object value) {
|
||||||
|
parameters.put(name, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set value for a parameter of java.util.Date type.
|
||||||
|
* @param name parameter name
|
||||||
|
* @param value date value
|
||||||
|
* @param temporalType temporal type
|
||||||
|
* @return this query instance for chaining
|
||||||
|
*/
|
||||||
|
public Query setParameter(String name, Date value, TemporalType temporalType) {
|
||||||
|
parameters.put(name, new TemporalValue(value, temporalType));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return editable map of the query parameters
|
||||||
|
*/
|
||||||
|
public Map<String, Object> getParameters() {
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param parameters map of the query parameters
|
||||||
|
*/
|
||||||
|
public Query setParameters(Map<String, Object> parameters) {
|
||||||
|
this.parameters.putAll(parameters);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param firstResult results offset
|
||||||
|
* @return this query instance for chaining
|
||||||
|
*/
|
||||||
|
public Query setFirstResult(int firstResult) {
|
||||||
|
this.firstResult = firstResult;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param maxResults results limit
|
||||||
|
* @return this query instance for chaining
|
||||||
|
*/
|
||||||
|
public Query setMaxResults(int maxResults) {
|
||||||
|
this.maxResults = maxResults;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return results offset
|
||||||
|
*/
|
||||||
|
public int getFirstResult() {
|
||||||
|
return firstResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return results limit
|
||||||
|
*/
|
||||||
|
public int getMaxResults() {
|
||||||
|
return maxResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Query{" +
|
||||||
|
"queryString='" + queryString + '\'' +
|
||||||
|
", firstResult=" + firstResult +
|
||||||
|
", maxResults=" + maxResults +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -26,31 +26,24 @@ import org.dom4j.Element;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class QueryFilter extends FilterParser {
|
public class QueryFilter extends FilterParser {
|
||||||
private final String targetEntity;
|
|
||||||
|
|
||||||
public QueryFilter(Condition condition, String targetEntity) {
|
public QueryFilter(Condition condition) {
|
||||||
super(condition);
|
super(condition);
|
||||||
this.targetEntity = targetEntity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryFilter(Element element, String targetEntity) {
|
public QueryFilter(Element element) {
|
||||||
super(element);
|
super(element);
|
||||||
this.targetEntity = targetEntity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static QueryFilter merge(QueryFilter src1, QueryFilter src2) {
|
public static QueryFilter merge(QueryFilter src1, QueryFilter src2) {
|
||||||
if (src1 == null || src2 == null)
|
if (src1 == null || src2 == null)
|
||||||
throw new IllegalArgumentException("Source query filter is null");
|
throw new IllegalArgumentException("Source query filter is null");
|
||||||
|
|
||||||
if (!src1.targetEntity.equals(src2.targetEntity))
|
|
||||||
throw new IllegalArgumentException("Target entities do not match");
|
|
||||||
|
|
||||||
|
|
||||||
Condition root = new LogicalCondition("root", LogicalOp.AND);
|
Condition root = new LogicalCondition("root", LogicalOp.AND);
|
||||||
root.getConditions().add(src1.getRoot());
|
root.getConditions().add(src1.getRoot());
|
||||||
root.getConditions().add(src2.getRoot());
|
root.getConditions().add(src2.getRoot());
|
||||||
|
|
||||||
QueryFilter queryFilter = new QueryFilter(root, src1.targetEntity);
|
QueryFilter queryFilter = new QueryFilter(root);
|
||||||
return queryFilter;
|
return queryFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1246,7 +1246,7 @@ public class FilterDelegateImpl implements FilterDelegate {
|
|||||||
|
|
||||||
if (getResultingManualApplyRequired()) {
|
if (getResultingManualApplyRequired()) {
|
||||||
// set initial denying condition to get empty datasource before explicit filter applying
|
// set initial denying condition to get empty datasource before explicit filter applying
|
||||||
QueryFilter queryFilter = new QueryFilter(new DenyingClause(), datasource.getMetaClass().getName());
|
QueryFilter queryFilter = new QueryFilter(new DenyingClause());
|
||||||
if (dsQueryFilter != null) {
|
if (dsQueryFilter != null) {
|
||||||
queryFilter = QueryFilter.merge(dsQueryFilter, queryFilter);
|
queryFilter = QueryFilter.merge(dsQueryFilter, queryFilter);
|
||||||
}
|
}
|
||||||
@ -1471,7 +1471,7 @@ public class FilterDelegateImpl implements FilterDelegate {
|
|||||||
|
|
||||||
if (!Strings.isNullOrEmpty(currentFilterXml)) {
|
if (!Strings.isNullOrEmpty(currentFilterXml)) {
|
||||||
Element element = Dom4j.readDocument(currentFilterXml).getRootElement();
|
Element element = Dom4j.readDocument(currentFilterXml).getRootElement();
|
||||||
QueryFilter queryFilter = new QueryFilter(element, datasource.getMetaClass().getName());
|
QueryFilter queryFilter = new QueryFilter(element);
|
||||||
|
|
||||||
if (dsQueryFilter != null) {
|
if (dsQueryFilter != null) {
|
||||||
queryFilter = QueryFilter.merge(dsQueryFilter, queryFilter);
|
queryFilter = QueryFilter.merge(dsQueryFilter, queryFilter);
|
||||||
|
@ -433,7 +433,7 @@ public class DsBuilder {
|
|||||||
return datasource;
|
return datasource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RuntimePropsDatasource buildRuntimePropsDataSource(String mainDsId, @Nullable MetaClass categorizedEntityClass) {
|
public RuntimePropsDatasource buildRuntimePropsDatasource(String mainDsId, @Nullable MetaClass categorizedEntityClass) {
|
||||||
init();
|
init();
|
||||||
RuntimePropsDatasourceImpl datasource;
|
RuntimePropsDatasourceImpl datasource;
|
||||||
datasource = new RuntimePropsDatasourceImpl(dsContext, dataSupplier, id, mainDsId, categorizedEntityClass);
|
datasource = new RuntimePropsDatasourceImpl(dsContext, dataSupplier, id, mainDsId, categorizedEntityClass);
|
||||||
@ -441,6 +441,36 @@ public class DsBuilder {
|
|||||||
return datasource;
|
return datasource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ValueCollectionDatasourceImpl buildValuesCollectionDatasource() {
|
||||||
|
ValueCollectionDatasourceImpl datasource = new ValueCollectionDatasourceImpl();
|
||||||
|
datasource.setup(dsContext, dataSupplier, id, metaClass, null);
|
||||||
|
if (maxResults > 0)
|
||||||
|
datasource.setMaxResults(maxResults);
|
||||||
|
datasource.setSoftDeletion(softDeletion);
|
||||||
|
registerDatasource(datasource);
|
||||||
|
return datasource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueGroupDatasourceImpl buildValuesGroupDatasource() {
|
||||||
|
ValueGroupDatasourceImpl datasource = new ValueGroupDatasourceImpl();
|
||||||
|
datasource.setup(dsContext, dataSupplier, id, metaClass, null);
|
||||||
|
if (maxResults > 0)
|
||||||
|
datasource.setMaxResults(maxResults);
|
||||||
|
datasource.setSoftDeletion(softDeletion);
|
||||||
|
registerDatasource(datasource);
|
||||||
|
return datasource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueHierarchicalDatasourceImpl buildValuesHierarchicalDatasourceImpl() {
|
||||||
|
ValueHierarchicalDatasourceImpl datasource = new ValueHierarchicalDatasourceImpl();
|
||||||
|
datasource.setup(dsContext, dataSupplier, id, metaClass, null);
|
||||||
|
if (maxResults > 0)
|
||||||
|
datasource.setMaxResults(maxResults);
|
||||||
|
datasource.setSoftDeletion(softDeletion);
|
||||||
|
registerDatasource(datasource);
|
||||||
|
return datasource;
|
||||||
|
}
|
||||||
|
|
||||||
private void registerDatasource(Datasource datasource) {
|
private void registerDatasource(Datasource datasource) {
|
||||||
if (dsContext != null && id != null) {
|
if (dsContext != null && id != null) {
|
||||||
((DsContextImplementation) dsContext).register(datasource);
|
((DsContextImplementation) dsContext).register(datasource);
|
||||||
|
@ -494,8 +494,8 @@ public abstract class AbstractCollectionDatasource<T extends Entity<K>, K>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected LoadContext.Query createLoadContextQuery(LoadContext context, Map<String, Object> params) {
|
protected DataLoadContextQuery createDataQuery(DataLoadContext context, Map<String, Object> params) {
|
||||||
LoadContext.Query q;
|
DataLoadContextQuery q = null;
|
||||||
if (query != null && queryParameters != null) {
|
if (query != null && queryParameters != null) {
|
||||||
Map<String, Object> parameters = getQueryParameters(params);
|
Map<String, Object> parameters = getQueryParameters(params);
|
||||||
for (ParameterInfo info : queryParameters) {
|
for (ParameterInfo info : queryParameters) {
|
||||||
@ -532,7 +532,7 @@ public abstract class AbstractCollectionDatasource<T extends Entity<K>, K>
|
|||||||
if (paramNames.contains(entry.getKey()))
|
if (paramNames.contains(entry.getKey()))
|
||||||
q.setParameter(entry.getKey(), entry.getValue());
|
q.setParameter(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!(context instanceof ValueLoadContext)) {
|
||||||
Collection<MetaProperty> properties = metadata.getTools().getNamePatternProperties(metaClass);
|
Collection<MetaProperty> properties = metadata.getTools().getNamePatternProperties(metaClass);
|
||||||
if (!properties.isEmpty()) {
|
if (!properties.isEmpty()) {
|
||||||
StringBuilder orderBy = new StringBuilder();
|
StringBuilder orderBy = new StringBuilder();
|
||||||
@ -550,8 +550,8 @@ public abstract class AbstractCollectionDatasource<T extends Entity<K>, K>
|
|||||||
} else
|
} else
|
||||||
q = context.setQueryString("select e from " + metaClass.getName() + " e");
|
q = context.setQueryString("select e from " + metaClass.getName() + " e");
|
||||||
}
|
}
|
||||||
if (q != null) {
|
if (q instanceof LoadContext.Query) {
|
||||||
q.setCacheable(isCacheable());
|
((LoadContext.Query) q).setCacheable(isCacheable());
|
||||||
}
|
}
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
@ -563,7 +563,7 @@ public abstract class AbstractCollectionDatasource<T extends Entity<K>, K>
|
|||||||
*/
|
*/
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
LoadContext<Entity> context = new LoadContext<>(metaClass);
|
LoadContext<Entity> context = new LoadContext<>(metaClass);
|
||||||
LoadContext.Query q = createLoadContextQuery(context, savedParameters == null ? Collections.<String, Object>emptyMap() : savedParameters);
|
LoadContext.Query q = (LoadContext.Query) createDataQuery(context, savedParameters == null ? Collections.<String, Object>emptyMap() : savedParameters);
|
||||||
context.setSoftDeletion(isSoftDeletion());
|
context.setSoftDeletion(isSoftDeletion());
|
||||||
if (q == null)
|
if (q == null)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -499,7 +499,7 @@ public class CollectionDatasourceImpl<T extends Entity<K>, K>
|
|||||||
params = Collections.emptyMap();
|
params = Collections.emptyMap();
|
||||||
} else
|
} else
|
||||||
params = savedParameters;
|
params = savedParameters;
|
||||||
LoadContext.Query q = createLoadContextQuery(context, params);
|
LoadContext.Query q = (LoadContext.Query) createDataQuery(context, params);
|
||||||
if (sortInfos != null && sortOnDb) {
|
if (sortInfos != null && sortOnDb) {
|
||||||
setSortDirection(q);
|
setSortDirection(q);
|
||||||
}
|
}
|
||||||
@ -552,7 +552,7 @@ public class CollectionDatasourceImpl<T extends Entity<K>, K>
|
|||||||
protected LoadContext beforeLoadData(Map<String, Object> params) {
|
protected LoadContext beforeLoadData(Map<String, Object> params) {
|
||||||
final LoadContext context = new LoadContext(metaClass);
|
final LoadContext context = new LoadContext(metaClass);
|
||||||
|
|
||||||
LoadContext.Query q = createLoadContextQuery(context, params);
|
LoadContext.Query q = (LoadContext.Query) createDataQuery(context, params);
|
||||||
if (q == null) {
|
if (q == null) {
|
||||||
detachListener(data.values());
|
detachListener(data.values());
|
||||||
data.clear();
|
data.clear();
|
||||||
|
@ -18,6 +18,7 @@ package com.haulmont.cuba.gui.data.impl;
|
|||||||
|
|
||||||
import com.haulmont.chile.core.model.MetaClass;
|
import com.haulmont.chile.core.model.MetaClass;
|
||||||
import com.haulmont.cuba.core.entity.Entity;
|
import com.haulmont.cuba.core.entity.Entity;
|
||||||
|
import com.haulmont.cuba.core.entity.KeyValueEntity;
|
||||||
import com.haulmont.cuba.core.global.*;
|
import com.haulmont.cuba.core.global.*;
|
||||||
import com.haulmont.cuba.gui.data.DataSupplier;
|
import com.haulmont.cuba.gui.data.DataSupplier;
|
||||||
|
|
||||||
@ -78,6 +79,11 @@ public class GenericDataSupplier implements DataSupplier {
|
|||||||
dataManager.remove(entity);
|
dataManager.remove(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<KeyValueEntity> loadValues(ValueLoadContext context) {
|
||||||
|
return dataManager.loadValues(context);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataManager secure() {
|
public DataManager secure() {
|
||||||
return dataManager;
|
return dataManager;
|
||||||
|
@ -42,18 +42,18 @@ public class HierarchicalDatasourceImpl<T extends Entity<K>, K>
|
|||||||
@Override
|
@Override
|
||||||
public Collection<K> getChildren(K itemId) {
|
public Collection<K> getChildren(K itemId) {
|
||||||
if (hierarchyPropertyName != null) {
|
if (hierarchyPropertyName != null) {
|
||||||
final Entity item = getItem(itemId);
|
final Entity currentItem = getItem(itemId);
|
||||||
if (item == null)
|
if (currentItem == null)
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
|
||||||
List<K> res = new ArrayList<>();
|
List<K> res = new ArrayList<>();
|
||||||
|
|
||||||
Collection<K> ids = getItemIds();
|
Collection<K> ids = getItemIds();
|
||||||
for (K id : ids) {
|
for (K id : ids) {
|
||||||
Entity<K> currentItem = getItem(id);
|
Entity<K> item = getItemNN(id);
|
||||||
Object parentItem = currentItem.getValue(hierarchyPropertyName);
|
Entity<K> parentItem = item.getValue(hierarchyPropertyName);
|
||||||
if (parentItem != null && parentItem.equals(item))
|
if (parentItem != null && parentItem.getId().equals(itemId))
|
||||||
res.add(currentItem.getId());
|
res.add(item.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@ -68,8 +68,8 @@ public class HierarchicalDatasourceImpl<T extends Entity<K>, K>
|
|||||||
if (item == null)
|
if (item == null)
|
||||||
return null;
|
return null;
|
||||||
else {
|
else {
|
||||||
Entity<K> value = item.getValue(hierarchyPropertyName);
|
Entity<K> parentItem = item.getValue(hierarchyPropertyName);
|
||||||
return value == null ? null : value.getId();
|
return parentItem == null ? null : parentItem.getId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -83,8 +83,8 @@ public class HierarchicalDatasourceImpl<T extends Entity<K>, K>
|
|||||||
Set<K> result = new LinkedHashSet<>();
|
Set<K> result = new LinkedHashSet<>();
|
||||||
for (K id : ids) {
|
for (K id : ids) {
|
||||||
Entity<K> item = getItemNN(id);
|
Entity<K> item = getItemNN(id);
|
||||||
Object value = item.getValue(hierarchyPropertyName);
|
Entity<K> parentItem = item.getValue(hierarchyPropertyName);
|
||||||
if (value == null || !containsItem(((T) value).getId()))
|
if (parentItem == null || !containsItem(parentItem.getId()))
|
||||||
result.add(item.getId());
|
result.add(item.getId());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -99,8 +99,8 @@ public class HierarchicalDatasourceImpl<T extends Entity<K>, K>
|
|||||||
if (item == null) return false;
|
if (item == null) return false;
|
||||||
|
|
||||||
if (hierarchyPropertyName != null) {
|
if (hierarchyPropertyName != null) {
|
||||||
Object value = item.getValue(hierarchyPropertyName);
|
Entity<K> parentItem = item.getValue(hierarchyPropertyName);
|
||||||
return (value == null || !containsItem(((T) value).getId()));
|
return (parentItem == null || !containsItem(parentItem.getId()));
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -108,15 +108,16 @@ public class HierarchicalDatasourceImpl<T extends Entity<K>, K>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasChildren(K itemId) {
|
public boolean hasChildren(K itemId) {
|
||||||
final Entity item = getItem(itemId);
|
final Entity currentItem = getItem(itemId);
|
||||||
if (item == null) return false;
|
if (currentItem == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (hierarchyPropertyName != null) {
|
if (hierarchyPropertyName != null) {
|
||||||
Collection<K> ids = getItemIds();
|
Collection<K> ids = getItemIds();
|
||||||
for (K id : ids) {
|
for (K id : ids) {
|
||||||
Entity currentItem = getItem(id);
|
Entity item = getItemNN(id);
|
||||||
Object parentItem = currentItem.getValue(hierarchyPropertyName);
|
Entity parentItem = item.getValue(hierarchyPropertyName);
|
||||||
if (parentItem != null && parentItem.equals(item))
|
if (parentItem != null && parentItem.getId().equals(itemId))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,23 +17,34 @@
|
|||||||
|
|
||||||
package com.haulmont.cuba.gui.data.impl;
|
package com.haulmont.cuba.gui.data.impl;
|
||||||
|
|
||||||
|
import com.haulmont.chile.core.datatypes.Datatype;
|
||||||
import com.haulmont.chile.core.model.MetaClass;
|
import com.haulmont.chile.core.model.MetaClass;
|
||||||
import com.haulmont.cuba.core.app.keyvalue.KeyValueMetaClass;
|
import com.haulmont.cuba.core.app.keyvalue.KeyValueMetaClass;
|
||||||
import com.haulmont.cuba.core.app.keyvalue.KeyValueMetaProperty;
|
|
||||||
import com.haulmont.cuba.core.entity.KeyValueEntity;
|
import com.haulmont.cuba.core.entity.KeyValueEntity;
|
||||||
import com.haulmont.cuba.core.global.View;
|
import com.haulmont.cuba.core.global.View;
|
||||||
import com.haulmont.cuba.gui.data.CollectionDatasource;
|
import com.haulmont.cuba.gui.data.CollectionDatasource;
|
||||||
import com.haulmont.cuba.gui.data.DataSupplier;
|
import com.haulmont.cuba.gui.data.DataSupplier;
|
||||||
import com.haulmont.cuba.gui.data.DsContext;
|
import com.haulmont.cuba.gui.data.DsContext;
|
||||||
|
import com.haulmont.cuba.gui.logging.UIPerformanceLogger;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.perf4j.StopWatch;
|
||||||
|
import org.perf4j.log4j.Log4JStopWatch;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link CollectionDatasource} that supports {@link KeyValueEntity}.
|
* {@link CollectionDatasource} that supports {@link KeyValueEntity}.
|
||||||
*/
|
*/
|
||||||
public class KeyValueCollectionDatasourceImpl extends CollectionDatasourceImpl<KeyValueEntity, UUID>{
|
public class ValueCollectionDatasourceImpl
|
||||||
|
extends CollectionDatasourceImpl<KeyValueEntity, Object>
|
||||||
|
implements ValueDatasource {
|
||||||
|
|
||||||
|
protected final ValueDatasourceDelegate delegate;
|
||||||
|
|
||||||
|
public ValueCollectionDatasourceImpl() {
|
||||||
|
delegate = new ValueDatasourceDelegate(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setup(DsContext dsContext, DataSupplier dataSupplier, String id, MetaClass metaClass, @Nullable View view) {
|
public void setup(DsContext dsContext, DataSupplier dataSupplier, String id, MetaClass metaClass, @Nullable View view) {
|
||||||
@ -43,13 +54,35 @@ public class KeyValueCollectionDatasourceImpl extends CollectionDatasourceImpl<K
|
|||||||
this.metaClass = new KeyValueMetaClass();
|
this.metaClass = new KeyValueMetaClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyValueCollectionDatasourceImpl addProperty(String name) {
|
@Override
|
||||||
((KeyValueMetaClass) metaClass).addProperty(new KeyValueMetaProperty(metaClass, name, String.class));
|
public ValueCollectionDatasourceImpl setIdName(String name) {
|
||||||
|
delegate.setIdName(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueCollectionDatasourceImpl addProperty(String name) {
|
||||||
|
delegate.addProperty(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueCollectionDatasourceImpl addProperty(String name, Class aClass) {
|
||||||
|
delegate.addProperty(name, aClass);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueCollectionDatasourceImpl addProperty(String name, Datatype type) {
|
||||||
|
delegate.addProperty(name, type);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void loadData(Map<String, Object> params) {
|
protected void loadData(Map<String, Object> params) {
|
||||||
|
String tag = getLoggingTag("VDS");
|
||||||
|
StopWatch sw = new Log4JStopWatch(tag, Logger.getLogger(UIPerformanceLogger.class));
|
||||||
|
|
||||||
|
delegate.loadData(params);
|
||||||
|
|
||||||
|
sw.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -63,4 +96,8 @@ public class KeyValueCollectionDatasourceImpl extends CollectionDatasourceImpl<K
|
|||||||
super.addItem(item);
|
super.addItem(item);
|
||||||
item.setMetaClass(metaClass);
|
item.setMetaClass(metaClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStoreName(String storeName) {
|
||||||
|
this.delegate.setStoreName(storeName);
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2016 Haulmont.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.haulmont.cuba.gui.data.impl;
|
||||||
|
|
||||||
|
import com.haulmont.chile.core.datatypes.Datatype;
|
||||||
|
import com.haulmont.chile.core.model.MetaClass;
|
||||||
|
|
||||||
|
public interface ValueDatasource {
|
||||||
|
|
||||||
|
MetaClass getMetaClass();
|
||||||
|
|
||||||
|
ValueDatasource setIdName(String name);
|
||||||
|
|
||||||
|
ValueDatasource addProperty(String name);
|
||||||
|
|
||||||
|
ValueDatasource addProperty(String name, Class aClass);
|
||||||
|
|
||||||
|
ValueDatasource addProperty(String name, Datatype type);
|
||||||
|
}
|
@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2016 Haulmont.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.haulmont.cuba.gui.data.impl;
|
||||||
|
|
||||||
|
import com.haulmont.bali.util.Preconditions;
|
||||||
|
import com.haulmont.chile.core.datatypes.Datatype;
|
||||||
|
import com.haulmont.chile.core.model.MetaProperty;
|
||||||
|
import com.haulmont.cuba.core.app.keyvalue.KeyValueMetaClass;
|
||||||
|
import com.haulmont.cuba.core.app.keyvalue.KeyValueMetaProperty;
|
||||||
|
import com.haulmont.cuba.core.entity.KeyValueEntity;
|
||||||
|
import com.haulmont.cuba.core.global.ValueLoadContext;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ValueDatasourceDelegate {
|
||||||
|
|
||||||
|
private String storeName;
|
||||||
|
|
||||||
|
private String idName;
|
||||||
|
|
||||||
|
protected CollectionDatasourceImpl ds;
|
||||||
|
|
||||||
|
public ValueDatasourceDelegate(CollectionDatasourceImpl datasource) {
|
||||||
|
this.ds = datasource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStoreName() {
|
||||||
|
return storeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStoreName(String storeName) {
|
||||||
|
this.storeName = storeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdName(String name) {
|
||||||
|
this.idName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addProperty(String name) {
|
||||||
|
Preconditions.checkNotNullArgument(name, "name is null");
|
||||||
|
((KeyValueMetaClass) ds.metaClass).addProperty(new KeyValueMetaProperty(ds.metaClass, name, String.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addProperty(String name, Class type) {
|
||||||
|
Preconditions.checkNotNullArgument(name, "name is null");
|
||||||
|
Preconditions.checkNotNullArgument(name, "type is null");
|
||||||
|
((KeyValueMetaClass) ds.metaClass).addProperty(new KeyValueMetaProperty(ds.metaClass, name, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addProperty(String name, Datatype type) {
|
||||||
|
Preconditions.checkNotNullArgument(name, "name is null");
|
||||||
|
Preconditions.checkNotNullArgument(name, "type is null");
|
||||||
|
((KeyValueMetaClass) ds.metaClass).addProperty(new KeyValueMetaProperty(ds.metaClass, name, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void loadData(Map<String, Object> params) {
|
||||||
|
if (ds.needLoading()) {
|
||||||
|
ValueLoadContext context = beforeLoadValues(params);
|
||||||
|
if (context == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
List<KeyValueEntity> entities = ds.dataSupplier.loadValues(context);
|
||||||
|
|
||||||
|
afterLoadValues(params, context, entities);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
ds.dataLoadError = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ValueLoadContext beforeLoadValues(Map<String, Object> params) {
|
||||||
|
ValueLoadContext context = new ValueLoadContext();
|
||||||
|
|
||||||
|
ValueLoadContext.Query q = (ValueLoadContext.Query) ds.createDataQuery(context, params);
|
||||||
|
if (q == null) {
|
||||||
|
ds.detachListener(ds.data.values());
|
||||||
|
ds.data.clear();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ds.firstResult > 0)
|
||||||
|
q.setFirstResult(ds.firstResult);
|
||||||
|
|
||||||
|
if (ds.maxResults > 0) {
|
||||||
|
q.setMaxResults(ds.maxResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (storeName != null)
|
||||||
|
context.setStoreName(storeName);
|
||||||
|
|
||||||
|
context.setSoftDeletion(ds.isSoftDeletion());
|
||||||
|
|
||||||
|
context.setIdName(idName);
|
||||||
|
for (MetaProperty property : ds.metaClass.getProperties()) {
|
||||||
|
context.addProperty(property.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
ds.dataLoadError = null;
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void afterLoadValues(Map<String, Object> params, ValueLoadContext context, List<KeyValueEntity> entities) {
|
||||||
|
ds.detachListener(ds.data.values());
|
||||||
|
ds.data.clear();
|
||||||
|
|
||||||
|
for (KeyValueEntity entity : entities) {
|
||||||
|
ds.data.put(entity.getId(), entity);
|
||||||
|
ds.attachListener(entity);
|
||||||
|
entity.setMetaClass(ds.metaClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,23 +17,34 @@
|
|||||||
|
|
||||||
package com.haulmont.cuba.gui.data.impl;
|
package com.haulmont.cuba.gui.data.impl;
|
||||||
|
|
||||||
|
import com.haulmont.chile.core.datatypes.Datatype;
|
||||||
import com.haulmont.chile.core.model.MetaClass;
|
import com.haulmont.chile.core.model.MetaClass;
|
||||||
import com.haulmont.cuba.core.app.keyvalue.KeyValueMetaClass;
|
import com.haulmont.cuba.core.app.keyvalue.KeyValueMetaClass;
|
||||||
import com.haulmont.cuba.core.app.keyvalue.KeyValueMetaProperty;
|
|
||||||
import com.haulmont.cuba.core.entity.KeyValueEntity;
|
import com.haulmont.cuba.core.entity.KeyValueEntity;
|
||||||
import com.haulmont.cuba.core.global.View;
|
import com.haulmont.cuba.core.global.View;
|
||||||
import com.haulmont.cuba.gui.data.DataSupplier;
|
import com.haulmont.cuba.gui.data.DataSupplier;
|
||||||
import com.haulmont.cuba.gui.data.DsContext;
|
import com.haulmont.cuba.gui.data.DsContext;
|
||||||
import com.haulmont.cuba.gui.data.GroupDatasource;
|
import com.haulmont.cuba.gui.data.GroupDatasource;
|
||||||
|
import com.haulmont.cuba.gui.logging.UIPerformanceLogger;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.perf4j.StopWatch;
|
||||||
|
import org.perf4j.log4j.Log4JStopWatch;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link GroupDatasource} that supports {@link KeyValueEntity}.
|
* {@link GroupDatasource} that supports {@link KeyValueEntity}.
|
||||||
*/
|
*/
|
||||||
public class KeyValueGroupDatasourceImpl extends GroupDatasourceImpl<KeyValueEntity, UUID> {
|
public class ValueGroupDatasourceImpl
|
||||||
|
extends GroupDatasourceImpl<KeyValueEntity, Object>
|
||||||
|
implements ValueDatasource {
|
||||||
|
|
||||||
|
protected final ValueDatasourceDelegate delegate;
|
||||||
|
|
||||||
|
public ValueGroupDatasourceImpl() {
|
||||||
|
delegate = new ValueDatasourceDelegate(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setup(DsContext dsContext, DataSupplier dataSupplier, String id, MetaClass metaClass, @Nullable View view) {
|
public void setup(DsContext dsContext, DataSupplier dataSupplier, String id, MetaClass metaClass, @Nullable View view) {
|
||||||
@ -43,13 +54,35 @@ public class KeyValueGroupDatasourceImpl extends GroupDatasourceImpl<KeyValueEnt
|
|||||||
this.metaClass = new KeyValueMetaClass();
|
this.metaClass = new KeyValueMetaClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyValueGroupDatasourceImpl addProperty(String name) {
|
@Override
|
||||||
((KeyValueMetaClass) metaClass).addProperty(new KeyValueMetaProperty(metaClass, name, String.class));
|
public ValueGroupDatasourceImpl setIdName(String name) {
|
||||||
|
delegate.setIdName(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueGroupDatasourceImpl addProperty(String name) {
|
||||||
|
delegate.addProperty(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueGroupDatasourceImpl addProperty(String name, Class aClass) {
|
||||||
|
delegate.addProperty(name, aClass);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueGroupDatasourceImpl addProperty(String name, Datatype type) {
|
||||||
|
delegate.addProperty(name, type);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void loadData(Map<String, Object> params) {
|
protected void loadData(Map<String, Object> params) {
|
||||||
|
String tag = getLoggingTag("VGDS");
|
||||||
|
StopWatch sw = new Log4JStopWatch(tag, Logger.getLogger(UIPerformanceLogger.class));
|
||||||
|
|
||||||
|
delegate.loadData(params);
|
||||||
|
|
||||||
|
sw.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -63,4 +96,8 @@ public class KeyValueGroupDatasourceImpl extends GroupDatasourceImpl<KeyValueEnt
|
|||||||
super.addItem(item);
|
super.addItem(item);
|
||||||
item.setMetaClass(metaClass);
|
item.setMetaClass(metaClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStoreName(String storeName) {
|
||||||
|
this.delegate.setStoreName(storeName);
|
||||||
|
}
|
||||||
}
|
}
|
@ -17,23 +17,34 @@
|
|||||||
|
|
||||||
package com.haulmont.cuba.gui.data.impl;
|
package com.haulmont.cuba.gui.data.impl;
|
||||||
|
|
||||||
|
import com.haulmont.chile.core.datatypes.Datatype;
|
||||||
import com.haulmont.chile.core.model.MetaClass;
|
import com.haulmont.chile.core.model.MetaClass;
|
||||||
import com.haulmont.cuba.core.app.keyvalue.KeyValueMetaClass;
|
import com.haulmont.cuba.core.app.keyvalue.KeyValueMetaClass;
|
||||||
import com.haulmont.cuba.core.app.keyvalue.KeyValueMetaProperty;
|
|
||||||
import com.haulmont.cuba.core.entity.KeyValueEntity;
|
import com.haulmont.cuba.core.entity.KeyValueEntity;
|
||||||
import com.haulmont.cuba.core.global.View;
|
import com.haulmont.cuba.core.global.View;
|
||||||
import com.haulmont.cuba.gui.data.DataSupplier;
|
import com.haulmont.cuba.gui.data.DataSupplier;
|
||||||
import com.haulmont.cuba.gui.data.DsContext;
|
import com.haulmont.cuba.gui.data.DsContext;
|
||||||
import com.haulmont.cuba.gui.data.HierarchicalDatasource;
|
import com.haulmont.cuba.gui.data.HierarchicalDatasource;
|
||||||
|
import com.haulmont.cuba.gui.logging.UIPerformanceLogger;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.perf4j.StopWatch;
|
||||||
|
import org.perf4j.log4j.Log4JStopWatch;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link HierarchicalDatasource} that supports {@link KeyValueEntity}.
|
* {@link HierarchicalDatasource} that supports {@link KeyValueEntity}.
|
||||||
*/
|
*/
|
||||||
public class KeyValueHierarchicalDatasourceImpl extends HierarchicalDatasourceImpl<KeyValueEntity, UUID>{
|
public class ValueHierarchicalDatasourceImpl
|
||||||
|
extends HierarchicalDatasourceImpl<KeyValueEntity, Object>
|
||||||
|
implements ValueDatasource {
|
||||||
|
|
||||||
|
protected final ValueDatasourceDelegate delegate;
|
||||||
|
|
||||||
|
public ValueHierarchicalDatasourceImpl() {
|
||||||
|
delegate = new ValueDatasourceDelegate(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setup(DsContext dsContext, DataSupplier dataSupplier, String id, MetaClass metaClass, @Nullable View view) {
|
public void setup(DsContext dsContext, DataSupplier dataSupplier, String id, MetaClass metaClass, @Nullable View view) {
|
||||||
@ -43,8 +54,24 @@ public class KeyValueHierarchicalDatasourceImpl extends HierarchicalDatasourceIm
|
|||||||
this.metaClass = new KeyValueMetaClass();
|
this.metaClass = new KeyValueMetaClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyValueHierarchicalDatasourceImpl addProperty(String name) {
|
@Override
|
||||||
((KeyValueMetaClass) metaClass).addProperty(new KeyValueMetaProperty(metaClass, name, String.class));
|
public ValueHierarchicalDatasourceImpl setIdName(String name) {
|
||||||
|
delegate.setIdName(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueHierarchicalDatasourceImpl addProperty(String name) {
|
||||||
|
delegate.addProperty(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueHierarchicalDatasourceImpl addProperty(String name, Class aClass) {
|
||||||
|
delegate.addProperty(name, aClass);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueHierarchicalDatasourceImpl addProperty(String name, Datatype type) {
|
||||||
|
delegate.addProperty(name, type);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,14 +79,19 @@ public class KeyValueHierarchicalDatasourceImpl extends HierarchicalDatasourceIm
|
|||||||
public void setHierarchyPropertyName(String hierarchyPropertyName) {
|
public void setHierarchyPropertyName(String hierarchyPropertyName) {
|
||||||
super.setHierarchyPropertyName(hierarchyPropertyName);
|
super.setHierarchyPropertyName(hierarchyPropertyName);
|
||||||
KeyValueMetaClass metaClass = (KeyValueMetaClass) this.metaClass;
|
KeyValueMetaClass metaClass = (KeyValueMetaClass) this.metaClass;
|
||||||
if (metaClass.getProperty(hierarchyPropertyName) != null) {
|
if (metaClass.getProperty(hierarchyPropertyName) == null) {
|
||||||
metaClass.removeProperty(hierarchyPropertyName);
|
throw new IllegalStateException("Hierarchy property must be added to the datasource as property first");
|
||||||
}
|
}
|
||||||
metaClass.addProperty(new KeyValueMetaProperty(metaClass, hierarchyPropertyName, KeyValueEntity.class));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void loadData(Map<String, Object> params) {
|
protected void loadData(Map<String, Object> params) {
|
||||||
|
String tag = getLoggingTag("VHDS");
|
||||||
|
StopWatch sw = new Log4JStopWatch(tag, Logger.getLogger(UIPerformanceLogger.class));
|
||||||
|
|
||||||
|
delegate.loadData(params);
|
||||||
|
|
||||||
|
sw.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -73,4 +105,8 @@ public class KeyValueHierarchicalDatasourceImpl extends HierarchicalDatasourceIm
|
|||||||
super.addItem(item);
|
super.addItem(item);
|
||||||
item.setMetaClass(metaClass);
|
item.setMetaClass(metaClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStoreName(String storeName) {
|
||||||
|
this.delegate.setStoreName(storeName);
|
||||||
|
}
|
||||||
}
|
}
|
@ -1926,6 +1926,76 @@
|
|||||||
<xs:attribute name="categorizedEntityClass" type="xs:string" use="optional"/>
|
<xs:attribute name="categorizedEntityClass" type="xs:string" use="optional"/>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
|
|
||||||
|
<!-- ValueCollectionDatasource -->
|
||||||
|
<xs:complexType name="valueCollectionDatasourceType">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="query" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:complexType mixed="true">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="filter" type="filterType" minOccurs="0" maxOccurs="1"/>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="properties" type="valueDatasourcePropertiesType"/>
|
||||||
|
</xs:sequence>
|
||||||
|
|
||||||
|
<xs:attribute name="id" type="xs:string" use="required"/>
|
||||||
|
<xs:attribute name="maxResults" type="xs:int"/>
|
||||||
|
<xs:attribute name="store" type="xs:string"/>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<!-- ValueGroupDatasource -->
|
||||||
|
<xs:complexType name="valueGroupDatasourceType">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="query" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:complexType mixed="true">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="filter" type="filterType" minOccurs="0" maxOccurs="1"/>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="properties" type="valueDatasourcePropertiesType"/>
|
||||||
|
</xs:sequence>
|
||||||
|
|
||||||
|
<xs:attribute name="id" type="xs:string" use="required"/>
|
||||||
|
<xs:attribute name="maxResults" type="xs:int"/>
|
||||||
|
<xs:attribute name="store" type="xs:string"/>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<!-- ValueHierarchicalDatasource -->
|
||||||
|
<xs:complexType name="valueHierarchicalDatasourceType">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="query" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:complexType mixed="true">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="filter" type="filterType" minOccurs="0" maxOccurs="1"/>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="properties" type="valueDatasourcePropertiesType"/>
|
||||||
|
</xs:sequence>
|
||||||
|
|
||||||
|
<xs:attribute name="id" type="xs:string" use="required"/>
|
||||||
|
<xs:attribute name="maxResults" type="xs:int"/>
|
||||||
|
<xs:attribute name="store" type="xs:string"/>
|
||||||
|
<xs:attribute name="hierarchyProperty" type="xs:string"/>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:complexType name="valueDatasourcePropertiesType">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="property" minOccurs="1" maxOccurs="unbounded">
|
||||||
|
<xs:complexType mixed="true">
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required"/>
|
||||||
|
<xs:attribute name="type" type="datatypeEnum" />
|
||||||
|
<xs:attribute name="class" type="xs:string" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="properties" type="valueDatasourcePropertiesType"/>
|
||||||
|
</xs:sequence>
|
||||||
|
|
||||||
|
<xs:attribute name="id" type="xs:string"/>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
<!-- PropertyDatasource -->
|
<!-- PropertyDatasource -->
|
||||||
<xs:group name="nestedDatasources">
|
<xs:group name="nestedDatasources">
|
||||||
<xs:sequence>
|
<xs:sequence>
|
||||||
@ -2104,6 +2174,9 @@
|
|||||||
<xs:element name="collectionDatasource" type="collectionDatasourceType"/>
|
<xs:element name="collectionDatasource" type="collectionDatasourceType"/>
|
||||||
<xs:element name="hierarchicalDatasource" type="hierarchicalDatasourceType"/>
|
<xs:element name="hierarchicalDatasource" type="hierarchicalDatasourceType"/>
|
||||||
<xs:element name="runtimePropsDatasource" type="runtimePropsDatasourceType"/>
|
<xs:element name="runtimePropsDatasource" type="runtimePropsDatasourceType"/>
|
||||||
|
<xs:element name="valueCollectionDatasource" type="valueCollectionDatasourceType"/>
|
||||||
|
<xs:element name="valueGroupDatasource" type="valueGroupDatasourceType"/>
|
||||||
|
<xs:element name="valueHierarchicalDatasource" type="valueHierarchicalDatasourceType"/>
|
||||||
</xs:choice>
|
</xs:choice>
|
||||||
</xs:sequence>
|
</xs:sequence>
|
||||||
<xs:attribute name="class" type="xs:string"/>
|
<xs:attribute name="class" type="xs:string"/>
|
||||||
|
@ -17,15 +17,19 @@
|
|||||||
|
|
||||||
package com.haulmont.cuba.gui.xml.data;
|
package com.haulmont.cuba.gui.xml.data;
|
||||||
|
|
||||||
|
import com.haulmont.bali.util.Dom4j;
|
||||||
import com.haulmont.bali.util.ReflectionHelper;
|
import com.haulmont.bali.util.ReflectionHelper;
|
||||||
|
import com.haulmont.chile.core.datatypes.Datatype;
|
||||||
|
import com.haulmont.chile.core.datatypes.Datatypes;
|
||||||
|
import com.haulmont.chile.core.datatypes.impl.StringDatatype;
|
||||||
import com.haulmont.chile.core.model.MetaClass;
|
import com.haulmont.chile.core.model.MetaClass;
|
||||||
|
import com.haulmont.cuba.core.entity.KeyValueEntity;
|
||||||
import com.haulmont.cuba.core.global.AppBeans;
|
import com.haulmont.cuba.core.global.AppBeans;
|
||||||
import com.haulmont.cuba.core.global.DevelopmentException;
|
import com.haulmont.cuba.core.global.DevelopmentException;
|
||||||
import com.haulmont.cuba.core.global.Metadata;
|
import com.haulmont.cuba.core.global.Metadata;
|
||||||
import com.haulmont.cuba.core.global.Scripting;
|
import com.haulmont.cuba.core.global.Scripting;
|
||||||
import com.haulmont.cuba.gui.data.*;
|
import com.haulmont.cuba.gui.data.*;
|
||||||
import com.haulmont.cuba.gui.data.impl.DsContextImpl;
|
import com.haulmont.cuba.gui.data.impl.*;
|
||||||
import com.haulmont.cuba.gui.data.impl.DsContextImplementation;
|
|
||||||
import com.haulmont.cuba.core.global.filter.QueryFilter;
|
import com.haulmont.cuba.core.global.filter.QueryFilter;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.dom4j.Element;
|
import org.dom4j.Element;
|
||||||
@ -110,7 +114,25 @@ public class DsContextLoader {
|
|||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
elements = element.elements("runtimePropsDatasource");
|
elements = element.elements("runtimePropsDatasource");
|
||||||
for (Element ds : elements) {
|
for (Element ds : elements) {
|
||||||
loadRuntimePropsDataSource(ds);
|
loadRuntimePropsDatasource(ds);
|
||||||
|
}
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
elements = element.elements("valueCollectionDatasource");
|
||||||
|
for (Element ds : elements) {
|
||||||
|
loadValueCollectionDatasource(ds);
|
||||||
|
}
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
elements = element.elements("valueGroupDatasource");
|
||||||
|
for (Element ds : elements) {
|
||||||
|
loadValueGroupDatasource(ds);
|
||||||
|
}
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
elements = element.elements("valueHierarchicalDatasource");
|
||||||
|
for (Element ds : elements) {
|
||||||
|
loadValueHierarchicalDatasource(ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.executeLazyTasks();
|
context.executeLazyTasks();
|
||||||
@ -154,7 +176,7 @@ public class DsContextLoader {
|
|||||||
if (datasource instanceof CollectionDatasource.Suspendable)
|
if (datasource instanceof CollectionDatasource.Suspendable)
|
||||||
((CollectionDatasource.Suspendable) datasource).setSuspended(true);
|
((CollectionDatasource.Suspendable) datasource).setSuspended(true);
|
||||||
|
|
||||||
loadQuery(element, metaClass, datasource);
|
loadQuery(element, datasource);
|
||||||
|
|
||||||
loadDatasources(element, datasource);
|
loadDatasources(element, datasource);
|
||||||
|
|
||||||
@ -190,7 +212,7 @@ public class DsContextLoader {
|
|||||||
if (datasource instanceof CollectionDatasource.Suspendable)
|
if (datasource instanceof CollectionDatasource.Suspendable)
|
||||||
((CollectionDatasource.Suspendable) datasource).setSuspended(true);
|
((CollectionDatasource.Suspendable) datasource).setSuspended(true);
|
||||||
|
|
||||||
loadQuery(element, metaClass, datasource);
|
loadQuery(element, datasource);
|
||||||
|
|
||||||
loadDatasources(element, datasource);
|
loadDatasources(element, datasource);
|
||||||
|
|
||||||
@ -260,7 +282,7 @@ public class DsContextLoader {
|
|||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
elements = element.elements("runtimePropsDatasource");
|
elements = element.elements("runtimePropsDatasource");
|
||||||
for (Element ds : elements) {
|
for (Element ds : elements) {
|
||||||
loadRuntimePropsDataSource(ds);
|
loadRuntimePropsDatasource(ds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,14 +379,14 @@ public class DsContextLoader {
|
|||||||
if (datasource instanceof CollectionDatasource.Suspendable)
|
if (datasource instanceof CollectionDatasource.Suspendable)
|
||||||
((CollectionDatasource.Suspendable) datasource).setSuspended(true);
|
((CollectionDatasource.Suspendable) datasource).setSuspended(true);
|
||||||
|
|
||||||
loadQuery(element, metaClass, datasource);
|
loadQuery(element, datasource);
|
||||||
|
|
||||||
loadDatasources(element, datasource);
|
loadDatasources(element, datasource);
|
||||||
|
|
||||||
return datasource;
|
return datasource;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadQuery(Element element, MetaClass metaClass, CollectionDatasource datasource) {
|
private void loadQuery(Element element, CollectionDatasource datasource) {
|
||||||
Element queryElem = element.element("query");
|
Element queryElem = element.element("query");
|
||||||
if (queryElem != null) {
|
if (queryElem != null) {
|
||||||
Element filterElem = queryElem.element("filter");
|
Element filterElem = queryElem.element("filter");
|
||||||
@ -372,7 +394,7 @@ public class DsContextLoader {
|
|||||||
String query = queryElem.getText();
|
String query = queryElem.getText();
|
||||||
if (!StringUtils.isBlank(query)) {
|
if (!StringUtils.isBlank(query)) {
|
||||||
if (filterElem != null)
|
if (filterElem != null)
|
||||||
datasource.setQuery(query, new QueryFilter(filterElem, metaClass.getName()));
|
datasource.setQuery(query, new QueryFilter(filterElem));
|
||||||
else
|
else
|
||||||
datasource.setQuery(query);
|
datasource.setQuery(query);
|
||||||
}
|
}
|
||||||
@ -414,7 +436,7 @@ public class DsContextLoader {
|
|||||||
return StringUtils.isEmpty(allowCommitStr) || Boolean.parseBoolean(allowCommitStr);
|
return StringUtils.isEmpty(allowCommitStr) || Boolean.parseBoolean(allowCommitStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RuntimePropsDatasource loadRuntimePropsDataSource(Element element){
|
protected RuntimePropsDatasource loadRuntimePropsDatasource(Element element){
|
||||||
String id = getDatasourceId(element);
|
String id = getDatasourceId(element);
|
||||||
MetaClass metaClass = loadMetaClass(element);
|
MetaClass metaClass = loadMetaClass(element);
|
||||||
|
|
||||||
@ -432,12 +454,103 @@ public class DsContextLoader {
|
|||||||
|
|
||||||
builder.reset().setMetaClass(metaClass).setId(id);
|
builder.reset().setMetaClass(metaClass).setId(id);
|
||||||
|
|
||||||
RuntimePropsDatasource datasource = builder.buildRuntimePropsDataSource(mainDsId, categorizedEntityMetaClass);
|
RuntimePropsDatasource datasource = builder.buildRuntimePropsDatasource(mainDsId, categorizedEntityMetaClass);
|
||||||
|
|
||||||
loadDatasources(element, datasource);
|
loadDatasources(element, datasource);
|
||||||
return datasource;
|
return datasource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ValueCollectionDatasourceImpl loadValueCollectionDatasource(Element element) {
|
||||||
|
String id = getDatasourceId(element);
|
||||||
|
builder.reset().setMetaClass(metadata.getClassNN(KeyValueEntity.class)).setId(id);
|
||||||
|
|
||||||
|
ValueCollectionDatasourceImpl datasource = builder.buildValuesCollectionDatasource();
|
||||||
|
|
||||||
|
String maxResults = element.attributeValue("maxResults");
|
||||||
|
if (!StringUtils.isEmpty(maxResults))
|
||||||
|
datasource.setMaxResults(Integer.parseInt(maxResults));
|
||||||
|
|
||||||
|
datasource.setSuspended(true);
|
||||||
|
|
||||||
|
loadQuery(element, datasource);
|
||||||
|
|
||||||
|
loadProperties(element, datasource);
|
||||||
|
|
||||||
|
datasource.setStoreName(element.attributeValue("store"));
|
||||||
|
|
||||||
|
return datasource;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ValueGroupDatasourceImpl loadValueGroupDatasource(Element element) {
|
||||||
|
String id = getDatasourceId(element);
|
||||||
|
builder.reset().setMetaClass(metadata.getClassNN(KeyValueEntity.class)).setId(id);
|
||||||
|
|
||||||
|
ValueGroupDatasourceImpl datasource = builder.buildValuesGroupDatasource();
|
||||||
|
|
||||||
|
String maxResults = element.attributeValue("maxResults");
|
||||||
|
if (!StringUtils.isEmpty(maxResults))
|
||||||
|
datasource.setMaxResults(Integer.parseInt(maxResults));
|
||||||
|
|
||||||
|
datasource.setSuspended(true);
|
||||||
|
|
||||||
|
loadQuery(element, datasource);
|
||||||
|
|
||||||
|
loadProperties(element, datasource);
|
||||||
|
|
||||||
|
datasource.setStoreName(element.attributeValue("store"));
|
||||||
|
|
||||||
|
return datasource;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ValueHierarchicalDatasourceImpl loadValueHierarchicalDatasource(Element element) {
|
||||||
|
String id = getDatasourceId(element);
|
||||||
|
builder.reset().setMetaClass(metadata.getClassNN(KeyValueEntity.class)).setId(id);
|
||||||
|
|
||||||
|
ValueHierarchicalDatasourceImpl datasource = builder.buildValuesHierarchicalDatasourceImpl();
|
||||||
|
|
||||||
|
String maxResults = element.attributeValue("maxResults");
|
||||||
|
if (!StringUtils.isEmpty(maxResults))
|
||||||
|
datasource.setMaxResults(Integer.parseInt(maxResults));
|
||||||
|
|
||||||
|
datasource.setSuspended(true);
|
||||||
|
|
||||||
|
loadQuery(element, datasource);
|
||||||
|
|
||||||
|
loadProperties(element, datasource);
|
||||||
|
|
||||||
|
String hierarchyProperty = element.attributeValue("hierarchyProperty");
|
||||||
|
if (!StringUtils.isEmpty(hierarchyProperty)) {
|
||||||
|
datasource.setHierarchyPropertyName(hierarchyProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
datasource.setStoreName(element.attributeValue("store"));
|
||||||
|
|
||||||
|
return datasource;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadProperties(Element element, ValueDatasource datasource) {
|
||||||
|
Element propsEl = element.element("properties");
|
||||||
|
if (propsEl != null) {
|
||||||
|
for (Element propEl : Dom4j.elements(propsEl)) {
|
||||||
|
String name = propEl.attributeValue("name");
|
||||||
|
String className = propEl.attributeValue("class");
|
||||||
|
if (className != null) {
|
||||||
|
datasource.addProperty(name, ReflectionHelper.getClass(className));
|
||||||
|
} else {
|
||||||
|
String typeName = propEl.attributeValue("type");
|
||||||
|
Datatype datatype = typeName == null ? Datatypes.get(StringDatatype.NAME) : Datatypes.get(typeName);
|
||||||
|
datasource.addProperty(name, datatype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String idName = propsEl.attributeValue("id");
|
||||||
|
if (idName != null) {
|
||||||
|
if (datasource.getMetaClass().getProperty(idName) == null)
|
||||||
|
throw new DevelopmentException(String.format("Property '%s' is not defined", idName));
|
||||||
|
datasource.setIdName(idName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected String getDatasourceId(Element element) {
|
protected String getDatasourceId(Element element) {
|
||||||
String id = element.attributeValue("id");
|
String id = element.attributeValue("id");
|
||||||
for (Datasource datasource : context.getAll()) {
|
for (Datasource datasource : context.getAll()) {
|
||||||
|
@ -19,10 +19,8 @@ package com.haulmont.cuba.gui.data.impl;
|
|||||||
|
|
||||||
import com.haulmont.chile.core.model.MetaClass;
|
import com.haulmont.chile.core.model.MetaClass;
|
||||||
import com.haulmont.cuba.core.entity.Entity;
|
import com.haulmont.cuba.core.entity.Entity;
|
||||||
import com.haulmont.cuba.core.global.CommitContext;
|
import com.haulmont.cuba.core.entity.KeyValueEntity;
|
||||||
import com.haulmont.cuba.core.global.DataManager;
|
import com.haulmont.cuba.core.global.*;
|
||||||
import com.haulmont.cuba.core.global.LoadContext;
|
|
||||||
import com.haulmont.cuba.core.global.View;
|
|
||||||
import com.haulmont.cuba.gui.data.DataSupplier;
|
import com.haulmont.cuba.gui.data.DataSupplier;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -116,6 +114,11 @@ public class TestDataSupplier implements DataSupplier {
|
|||||||
public void remove(Entity entity) {
|
public void remove(Entity entity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<KeyValueEntity> loadValues(ValueLoadContext context) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataManager secure() {
|
public DataManager secure() {
|
||||||
return this;
|
return this;
|
||||||
|
@ -838,10 +838,8 @@ public abstract class WebAbstractTable<T extends com.vaadin.ui.Table & CubaEnhan
|
|||||||
Collection<MetaPropertyPath> paths = datasource.getView() != null ?
|
Collection<MetaPropertyPath> paths = datasource.getView() != null ?
|
||||||
// if a view is specified - use view properties
|
// if a view is specified - use view properties
|
||||||
metadataTools.getViewPropertyPaths(datasource.getView(), datasource.getMetaClass()) :
|
metadataTools.getViewPropertyPaths(datasource.getView(), datasource.getMetaClass()) :
|
||||||
// otherwise use only string properties from meta-class - the temporary solution for KeyValue datasources
|
// otherwise use all properties from meta-class
|
||||||
metadataTools.getPropertyPaths(datasource.getMetaClass()).stream()
|
metadataTools.getPropertyPaths(datasource.getMetaClass());
|
||||||
.filter(mpp -> mpp.getRangeJavaClass().equals(String.class))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
for (MetaPropertyPath metaPropertyPath : paths) {
|
for (MetaPropertyPath metaPropertyPath : paths) {
|
||||||
MetaProperty property = metaPropertyPath.getMetaProperty();
|
MetaProperty property = metaPropertyPath.getMetaProperty();
|
||||||
if (!property.getRange().getCardinality().isMany() && !metadataTools.isSystem(property)) {
|
if (!property.getRange().getCardinality().isMany() && !metadataTools.isSystem(property)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user