Views added

This commit is contained in:
Konstantin Krivopustov 2008-12-19 14:05:01 +00:00
parent 7fcfc8f908
commit 8eb932a3c9
17 changed files with 510 additions and 13 deletions

View File

@ -62,6 +62,15 @@
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="js">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="false" />
<option name="SMART_TABS" value="false" />
<option name="LABEL_INDENT_SIZE" value="0" />
<option name="LABEL_INDENT_ABSOLUTE" value="false" />
</ADDITIONAL_INDENT_OPTIONS>
<ADDITIONAL_INDENT_OPTIONS fileType="jsp">
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="8" />
@ -116,7 +125,7 @@
<option name="ENCODED_DATABASE_PASSWORD" value="" />
<option name="DEFAULT_SCHEMA_NAME" />
<option name="TABLE_PATTERN" value="" />
<option name="UUID" value="52dca3c0-fbab-4812-9bc7-f7103804c65b" />
<option name="UUID" value="e0ea3ee8-6b3c-400c-92f4-18a6fabef2e2" />
<option name="NAME" value="CubaDB" />
<TABLE_DATA>
<option name="NAME" value="SEC_PROFILE" />

View File

@ -7,4 +7,9 @@
name="haulmont.cuba:service=ResourceRepository">
<depends>jboss:service=Naming</depends>
</mbean>
<mbean code="com.haulmont.cuba.core.app.ViewRepository"
name="haulmont.cuba:service=ViewRepository">
<depends>jboss:service=Naming</depends>
</mbean>
</server>

View File

@ -10,6 +10,7 @@
package com.haulmont.cuba.core;
import com.haulmont.cuba.core.entity.BaseEntity;
import com.haulmont.cuba.core.global.View;
public interface EntityManager
{
@ -23,6 +24,8 @@ public interface EntityManager
Query createQuery(String qlStr);
void setView(View view);
void flush();
void close();

View File

@ -10,6 +10,8 @@
*/
package com.haulmont.cuba.core;
import com.haulmont.cuba.core.global.View;
import javax.persistence.TemporalType;
import java.util.List;
import java.util.Date;
@ -33,4 +35,6 @@ public interface Query
Query setParameter(int position, Object value);
Query setParameter(int position, Date value, TemporalType temporalType);
Query setView(View view);
}

View File

@ -42,6 +42,9 @@ public class BasicWorkerBean implements BasicWorker
public <T extends BaseEntity> T get(BasicInvocationContext ctx) {
EntityManager em = PersistenceProvider.getEntityManager();
if (ctx.getView() != null) {
em.setView(ctx.getView());
}
BaseEntity result = em.find(ctx.getEntityClass(), ctx.getId());
return (T) result;
}
@ -53,6 +56,9 @@ public class BasicWorkerBean implements BasicWorker
PersistenceProvider.getEntityName(ctx.getEntityClass()) + " e where e.id = ?1";
Query query = em.createQuery(queryString);
query.setParameter(1, ctx.getId());
if (ctx.getView() != null) {
query.setView(ctx.getView());
}
Object result = query.getSingleResult();
return (T) result;
}
@ -60,6 +66,9 @@ public class BasicWorkerBean implements BasicWorker
public <T extends BaseEntity> List<T> loadList(BasicInvocationContext ctx) {
EntityManager em = PersistenceProvider.getEntityManager();
Query query = em.createQuery(ctx.getQueryString());
if (ctx.getView() != null) {
query.setView(ctx.getView());
}
List resultList = query.getResultList();
return resultList;
}

View File

@ -0,0 +1,121 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 19.12.2008 16:03:28
*
* $Id$
*/
package com.haulmont.cuba.core.app;
import com.haulmont.cuba.core.global.View;
import com.haulmont.cuba.core.global.MetadataProvider;
import com.haulmont.cuba.core.global.ViewProperty;
import com.haulmont.cuba.core.entity.BaseEntity;
import com.haulmont.cuba.core.Locator;
import com.haulmont.chile.core.model.Session;
import com.haulmont.chile.core.model.MetaClass;
import com.haulmont.chile.core.model.MetaProperty;
import com.haulmont.chile.core.model.Range;
import java.io.InputStream;
import java.util.List;
import org.dom4j.io.SAXReader;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.apache.commons.lang.StringUtils;
public class ViewRepository implements ViewRepositoryMBean
{
public static ViewRepository getInstance() {
ViewRepositoryMBean mbean = Locator.lookupMBean(ViewRepositoryMBean.class, ViewRepositoryMBean.OBJECT_NAME);
return mbean.getImplementation();
}
public void create() {
}
public ViewRepository getImplementation() {
return this;
}
public View getView(Class<? extends BaseEntity> entityClass, String name) {
return null;
}
public View getView(MetaClass metaClass, String name) {
return null;
}
private View findView(MetaClass metaClass, String name) {
return null;
}
public void deployViews(InputStream xmlStream) {
SAXReader reader = new SAXReader();
Document doc;
try {
doc = reader.read(xmlStream);
} catch (DocumentException e) {
throw new RuntimeException(e);
}
Element rootElem = doc.getRootElement();
for (Element viewElem : (List<Element>) rootElem.elements("view")) {
deployView(rootElem, viewElem);
}
}
private View deployView(Element rootElem, Element viewElem) {
String viewName = viewElem.attributeValue("name");
String entity = viewElem.attributeValue("entity");
if (StringUtils.isBlank(viewName) || StringUtils.isBlank(entity))
throw new IllegalStateException("Invalid view definition");
Session session = MetadataProvider.getSession();
MetaClass metaClass = session.getClass(entity);
View v = findView(metaClass, viewName);
if (v != null)
return v;
View view = new View(metaClass.getJavaClass(), viewName);
for (Element propElem : (List<Element>) viewElem.elements("property")) {
String propName = propElem.attributeValue("name");
MetaProperty metaProperty = metaClass.getProperty(propName);
if (metaProperty == null)
throw new IllegalStateException(
String.format("View %s/%s definition error: property %s doesn't exists", entity, viewName, propName));
View refView = null;
String refViewName = propElem.attributeValue("view");
if (refViewName != null) {
Range range = metaProperty.getRange();
if (!range.isClass())
throw new IllegalStateException(
String.format("View %s/%s definition error: property %s is not an entity", entity, viewName, propName));
refView = findView(range.asClass(), refViewName);
if (refView == null) {
for (Element e : (List<Element>) rootElem.elements("view")) {
if (range.asClass().getName().equals(e.attributeValue("entity"))
&& refViewName.equals(e.attributeValue("name")))
{
refView = deployView(rootElem, e);
break;
}
}
if (refView == null)
throw new IllegalStateException(
String.format("View %s/%s definition error: property %s is not an entity", entity, viewName, propName)
);
}
}
view.getProperties().add(new ViewProperty(propName, refView));
}
return view;
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 19.12.2008 15:56:19
*
* $Id$
*/
package com.haulmont.cuba.core.app;
import com.haulmont.cuba.core.global.View;
import com.haulmont.cuba.core.entity.BaseEntity;
import com.haulmont.chile.core.model.MetaClass;
import java.io.InputStream;
public interface ViewRepositoryMBean
{
String OBJECT_NAME = "haulmont.cuba:service=ViewRepository";
void create();
ViewRepository getImplementation();
View getView(Class<? extends BaseEntity> entityClass, String name);
View getView(MetaClass metaClass, String name);
void deployViews(InputStream is);
}

View File

@ -22,6 +22,8 @@ public class BasicInvocationContext implements Serializable
private String queryString;
private View view;
public Class<? extends BaseEntity> getEntityClass() {
return entityClass;
}
@ -48,4 +50,13 @@ public class BasicInvocationContext implements Serializable
this.queryString = queryString;
return this;
}
public View getView() {
return view;
}
public BasicInvocationContext setView(View view) {
this.view = view;
return this;
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 19.12.2008 10:40:35
*
* $Id$
*/
package com.haulmont.cuba.core.global;
import com.haulmont.cuba.core.entity.BaseEntity;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class View implements Serializable
{
private static final long serialVersionUID = 4313784222934349594L;
private Class<? extends BaseEntity> entityClass;
private String name;
private List<ViewProperty> properties = new ArrayList<ViewProperty>();
private boolean includeSystemProperties;
public View(Class<? extends BaseEntity> entityClass, String name) {
this(entityClass, name, true);
}
public View(Class<? extends BaseEntity> entityClass, String name, boolean includeSystemProperties) {
this.entityClass = entityClass;
this.name = name;
this.includeSystemProperties = includeSystemProperties;
}
public Class<? extends BaseEntity> getEntityClass() {
return entityClass;
}
public String getName() {
return name;
}
public List<ViewProperty> getProperties() {
return properties;
}
public boolean isIncludeSystemProperties() {
return includeSystemProperties;
}
public View addProperty(String name, View view) {
properties.add(new ViewProperty(name, view));
return this;
}
public View addProperty(String name) {
properties.add(new ViewProperty(name, null));
return this;
}
public String toString() {
return "View{" +
"entityClass=" + entityClass.getName() +
", name='" + name + '\'' +
'}';
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 19.12.2008 11:12:23
*
* $Id$
*/
package com.haulmont.cuba.core.global;
import java.io.Serializable;
public class ViewProperty implements Serializable
{
private static final long serialVersionUID = 4098678639930287203L;
private String name;
private View view;
public ViewProperty(String name, View view) {
this.name = name;
this.view = view;
}
public String getName() {
return name;
}
public View getView() {
return view;
}
public String toString() {
return "ViewProperty{" +
"name='" + name + '\'' +
'}';
}
}

View File

@ -16,6 +16,7 @@ import com.haulmont.cuba.core.EntityManager;
import com.haulmont.cuba.core.SecurityProvider;
import com.haulmont.cuba.core.Query;
import com.haulmont.cuba.core.global.TimeProvider;
import com.haulmont.cuba.core.global.View;
import com.haulmont.cuba.core.entity.BaseEntity;
import com.haulmont.cuba.core.entity.DeleteDeferred;
@ -56,6 +57,10 @@ public class EntityManagerImpl implements EntityManager
return new QueryImpl(jpaEm.createQuery(qlStr));
}
public void setView(View view) {
ViewHelper.setView(jpaEm.getFetchPlan(), view);
}
public void flush() {
jpaEm.flush();
}

View File

@ -16,10 +16,7 @@ import com.haulmont.chile.core.model.Session;
import com.haulmont.chile.jpa.loader.JPAMetadataLoader;
import java.io.InputStream;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.Collection;
import java.util.*;
import org.dom4j.io.SAXReader;
import org.dom4j.Document;
@ -68,7 +65,7 @@ public class MetadataProviderImpl extends MetadataProvider
throw new RuntimeException(e);
}
Element root = document.getRootElement();
Set<String> packages = new HashSet<String>();
List<String> packages = new ArrayList<String>();
for (Element unitElem : (List<Element>) root.elements("persistence-unit")) {
String name = unitElem.attributeValue("name");
if (PersistenceProvider.getPersistenceUnitName().equals(name)) {
@ -78,6 +75,7 @@ public class MetadataProviderImpl extends MetadataProvider
if (i <= 0)
throw new IllegalStateException("Invalid persistent class definition: " + className);
String packageName = className.substring(0, i);
if (!packages.contains(packageName))
packages.add(packageName);
}
}

View File

@ -11,6 +11,8 @@
package com.haulmont.cuba.core.sys;
import com.haulmont.cuba.core.Query;
import com.haulmont.cuba.core.global.View;
import com.haulmont.cuba.core.global.ViewProperty;
import javax.persistence.TemporalType;
import javax.persistence.FlushModeType;
@ -18,6 +20,7 @@ import java.util.List;
import java.util.Date;
import org.apache.openjpa.persistence.OpenJPAQuery;
import org.apache.openjpa.persistence.FetchPlan;
public class QueryImpl implements Query
{
@ -69,4 +72,9 @@ public class QueryImpl implements Query
query.setParameter(position, value, temporalType);
return this;
}
public Query setView(View view) {
ViewHelper.setView(query.getFetchPlan(), view);
return this;
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 19.12.2008 13:01:56
*
* $Id$
*/
package com.haulmont.cuba.core.sys;
import com.haulmont.chile.core.model.MetaClass;
import com.haulmont.cuba.core.entity.BaseEntity;
import com.haulmont.cuba.core.entity.DeleteDeferred;
import com.haulmont.cuba.core.entity.Updatable;
import com.haulmont.cuba.core.global.MetadataProvider;
import com.haulmont.cuba.core.global.View;
import com.haulmont.cuba.core.global.ViewProperty;
import org.apache.openjpa.persistence.FetchPlan;
public class ViewHelper
{
public static void setView(FetchPlan fetchPlan, View view) {
if (fetchPlan == null)
throw new IllegalArgumentException("FetchPlan is null");
if (view == null)
throw new IllegalArgumentException("View is null");
fetchPlan.clearFetchGroups();
fetchPlan.removeFetchGroup(FetchPlan.GROUP_DEFAULT);
processView(view, fetchPlan);
}
private static void processView(View view, FetchPlan fetchPlan) {
if (view.isIncludeSystemProperties()) {
includeSystemProperties(view, fetchPlan);
}
for (ViewProperty property : view.getProperties()) {
fetchPlan.addField(view.getEntityClass(), property.getName());
if (property.getView() != null) {
processView(property.getView(), fetchPlan);
}
}
}
private static void includeSystemProperties(View view, FetchPlan fetchPlan) {
Class<? extends BaseEntity> entityClass = view.getEntityClass();
MetaClass metaClass = MetadataProvider.getSession().getClass(entityClass);
Class<?> declaringClass = metaClass.getProperty("createTs").getJavaField().getDeclaringClass();
fetchPlan.addField(declaringClass, "createTs");
fetchPlan.addField(declaringClass, "createdBy");
if (Updatable.class.isAssignableFrom(entityClass)) {
declaringClass = metaClass.getProperty("updateTs").getJavaField().getDeclaringClass();
fetchPlan.addField(declaringClass, "updateTs");
fetchPlan.addField(declaringClass, "updatedBy");
}
if (DeleteDeferred.class.isAssignableFrom(entityClass)) {
declaringClass = metaClass.getProperty("deleteTs").getJavaField().getDeclaringClass();
fetchPlan.addField(declaringClass, "deleteTs");
fetchPlan.addField(declaringClass, "deletedBy");
}
}
}

View File

@ -10,7 +10,7 @@
package com.haulmont.cuba.core.sys.persistence;
import com.haulmont.chile.core.common.ValueListener;
import com.haulmont.chile.core.model.Clazz;
import com.haulmont.chile.core.model.MetaClass;
import com.haulmont.chile.core.model.Instance;
import com.haulmont.chile.core.model.Session;
import com.haulmont.chile.core.model.utils.InstanceUtils;
@ -204,7 +204,7 @@ public class CubaEnhancer implements PCEnhancer.AuxiliaryEnhancer {
private void createGetMetaclassMethod() {
// public Clazz getMetaClass()
BCMethod method = _pc.declareMethod("getMetaClass", Clazz.class, new Class[]{});
BCMethod method = _pc.declareMethod("getMetaClass", MetaClass.class, new Class[]{});
method.makePublic();
Code code = method.getCode(true);
@ -213,7 +213,7 @@ public class CubaEnhancer implements PCEnhancer.AuxiliaryEnhancer {
code.aload().setThis();
code.invokevirtual().setMethod("getClass", Class.class, new Class[]{});
code.invokeinterface().setMethod(Session.class, "getClass", Clazz.class, new Class[]{Class.class});
code.invokeinterface().setMethod(Session.class, "getClass", MetaClass.class, new Class[]{Class.class});
code.areturn();
code.calculateMaxStack();

View File

@ -11,7 +11,7 @@
package com.haulmont.cuba.core;
import com.haulmont.chile.core.model.Session;
import com.haulmont.chile.core.model.Model;
import com.haulmont.chile.core.model.MetaModel;
import com.haulmont.chile.core.model.utils.PrintUtils;
import com.haulmont.cuba.core.global.MetadataProvider;
@ -23,8 +23,8 @@ public class MetadataProviderTest extends CubaTestCase
Session session = MetadataProvider.getSession();
assertNotNull(session);
Collection<Model> models = session.getModels();
for (Model model : models) {
Collection<MetaModel> models = session.getModels();
for (MetaModel model : models) {
System.out.println("Model: " + model.getName());
System.out.println(PrintUtils.printClassHierarchy(model));
}

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
* Haulmont Technology proprietary and confidential.
* Use is subject to license terms.
* Author: Konstantin Krivopustov
* Created: 19.12.2008 12:03:22
*
* $Id$
*/
package com.haulmont.cuba.core;
import com.haulmont.cuba.core.global.View;
import com.haulmont.cuba.security.entity.User;
import com.haulmont.cuba.security.entity.Profile;
import com.haulmont.cuba.security.entity.Group;
import java.util.UUID;
public class ViewTest extends CubaTestCase
{
private UUID userId;
private void createEntities() {
Transaction tx = Locator.createTransaction();
try {
EntityManager em = PersistenceProvider.getEntityManager();
User user = new User();
userId = user.getId();
user.setName("testUser");
user.setLogin("login" + userId);
user.setPassword("000");
em.persist(user);
Group group = em.find(Group.class, UUID.fromString("0fa2b1a5-1d68-4d69-9fbd-dff348347f93"));
Profile profile = new Profile();
profile.setName("testProfile1");
profile.setUser(user);
profile.setGroup(group);
em.persist(profile);
profile = new Profile();
profile.setName("testProfile2");
profile.setUser(user);
profile.setGroup(group);
em.persist(profile);
tx.commit();
} finally {
tx.end();
}
}
public void testQuery() {
createEntities();
Transaction tx = Locator.createTransaction();
try {
EntityManager em = PersistenceProvider.getEntityManager();
Query q = em.createQuery("select u from sec$User u where u.id = ?1");
q.setParameter(1, userId);
View view = new View(User.class, "testUserView")
.addProperty("name")
.addProperty("login")
.addProperty("profiles",
new View(Profile.class, "testProfileView")
.addProperty("name")
);
q.setView(view);
User user = (User) q.getSingleResult();
tx.commit();
assertNull(user.getPassword());
assertEquals(2, user.getProfiles().size());
} finally {
tx.end();
}
}
public void testEntityManager() {
createEntities();
Transaction tx = Locator.createTransaction();
try {
EntityManager em = PersistenceProvider.getEntityManager();
View view = new View(User.class, "testUserView")
.addProperty("name")
.addProperty("login")
.addProperty("profiles",
new View(Profile.class, "testProfileView")
.addProperty("name")
);
em.setView(view);
User user = em.find(User.class, userId);
tx.commit();
assertNull(user.getPassword());
assertEquals(2, user.getProfiles().size());
} finally {
tx.end();
}
}
}