From a6101b78ac846e034604b456153db5778aafcbcc Mon Sep 17 00:00:00 2001
From: Konstantin Krivopustov <krivopustov@haulmont.com>
Date: Mon, 18 Mar 2013 15:30:15 +0000
Subject: [PATCH] @SystemLevel for Attributes. #PL-1433

---
 .../com/haulmont/cuba/core/MetadataTest.java  | 12 +++++++++++-
 .../core/loader/ChileAnnotationsLoader.java   |  2 +-
 .../cuba/core/global/MetadataTools.java       | 19 +++++++++++++++++++
 .../addcondition/ModelPropertiesFilter.java   |  8 +++++---
 4 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/modules/core/test/com/haulmont/cuba/core/MetadataTest.java b/modules/core/test/com/haulmont/cuba/core/MetadataTest.java
index 4507463403..84aad3b019 100644
--- a/modules/core/test/com/haulmont/cuba/core/MetadataTest.java
+++ b/modules/core/test/com/haulmont/cuba/core/MetadataTest.java
@@ -12,6 +12,7 @@ package com.haulmont.cuba.core;
 
 import com.haulmont.chile.core.model.MetaClass;
 import com.haulmont.chile.core.model.MetaModel;
+import com.haulmont.chile.core.model.MetaProperty;
 import com.haulmont.chile.core.model.Session;
 import com.haulmont.chile.core.model.utils.PrintUtils;
 import com.haulmont.cuba.core.entity.Folder;
@@ -20,6 +21,7 @@ import com.haulmont.cuba.core.global.Metadata;
 import com.haulmont.cuba.core.global.MetadataTools;
 import com.haulmont.cuba.security.entity.EntityLogItem;
 import com.haulmont.cuba.security.entity.User;
+import com.haulmont.cuba.security.entity.UserRole;
 import com.haulmont.cuba.security.entity.UserSessionEntity;
 
 import java.util.Collection;
@@ -38,7 +40,6 @@ public class MetadataTest extends CubaTestCase
     }
 
     public void testPersistentAndTransientProperties() throws Exception {
-        Metadata metadata = AppBeans.get(Metadata.class);
         MetadataTools tools = metadata.getTools();
 
         // User
@@ -62,4 +63,13 @@ public class MetadataTest extends CubaTestCase
         metaClass = metadata.getSession().getClassNN(UserSessionEntity.class);
         assertTrue(tools.isTransient(metaClass.getPropertyNN("login")));
     }
+
+    public void testSystemLevel() throws Exception {
+        MetadataTools tools = metadata.getTools();
+
+        assertTrue(tools.isSystemLevel(metadata.getSession().getClassNN(UserRole.class)));
+
+        MetaClass metaClass = metadata.getSession().getClassNN(User.class);
+        assertTrue(tools.isSystemLevel(metaClass.getPropertyNN("password")));
+    }
 }
diff --git a/modules/global/src/com/haulmont/chile/core/loader/ChileAnnotationsLoader.java b/modules/global/src/com/haulmont/chile/core/loader/ChileAnnotationsLoader.java
index f8e74a8a3c..295950a27f 100644
--- a/modules/global/src/com/haulmont/chile/core/loader/ChileAnnotationsLoader.java
+++ b/modules/global/src/com/haulmont/chile/core/loader/ChileAnnotationsLoader.java
@@ -279,7 +279,7 @@ public class ChileAnnotationsLoader implements ClassMetadataLoader {
     protected void onPropertyLoaded(MetaProperty metaProperty, Field field) {
         SystemLevel systemLevel = field.getAnnotation(SystemLevel.class);
         if (systemLevel != null) {
-            metaProperty.getAnnotations().put("system", true);
+            metaProperty.getAnnotations().put(SystemLevel.class.getName(), systemLevel.value());
         }
     }
 
diff --git a/modules/global/src/com/haulmont/cuba/core/global/MetadataTools.java b/modules/global/src/com/haulmont/cuba/core/global/MetadataTools.java
index 95a7078036..72582aae2b 100644
--- a/modules/global/src/com/haulmont/cuba/core/global/MetadataTools.java
+++ b/modules/global/src/com/haulmont/cuba/core/global/MetadataTools.java
@@ -13,6 +13,7 @@ import com.haulmont.cuba.core.entity.BaseEntity;
 import com.haulmont.cuba.core.entity.SoftDelete;
 import com.haulmont.cuba.core.entity.Updatable;
 import com.haulmont.cuba.core.entity.Versioned;
+import com.haulmont.cuba.core.entity.annotation.SystemLevel;
 import org.apache.commons.lang.StringUtils;
 
 import javax.annotation.ManagedBean;
@@ -193,6 +194,24 @@ public class MetadataTools {
         return metaProperty.getAnnotatedElement().isAnnotationPresent(Embedded.class);
     }
 
+    /**
+     * Determine whether the given entity is marked as {@link SystemLevel}.
+     */
+    public boolean isSystemLevel(MetaClass metaClass) {
+        Objects.requireNonNull(metaClass, "metaClass is null");
+        Boolean systemLevel = (Boolean) metaClass.getAnnotations().get(SystemLevel.class.getName());
+        return systemLevel == null ? false : systemLevel;
+    }
+
+    /**
+     * Determine whether the given property is marked as {@link SystemLevel}.
+     */
+    public boolean isSystemLevel(MetaProperty metaProperty) {
+        Objects.requireNonNull(metaProperty, "metaProperty is null");
+        Boolean systemLevel = (Boolean) metaProperty.getAnnotations().get(SystemLevel.class.getName());
+        return systemLevel == null ? false : systemLevel;
+    }
+
     /**
      * Determine whether the given annotation is present in the object's class or in any of its superclasses.
      * @param object            entity instance
diff --git a/modules/gui/src/com/haulmont/cuba/gui/components/filter/addcondition/ModelPropertiesFilter.java b/modules/gui/src/com/haulmont/cuba/gui/components/filter/addcondition/ModelPropertiesFilter.java
index 12caa7ef9d..3ea9580cdb 100644
--- a/modules/gui/src/com/haulmont/cuba/gui/components/filter/addcondition/ModelPropertiesFilter.java
+++ b/modules/gui/src/com/haulmont/cuba/gui/components/filter/addcondition/ModelPropertiesFilter.java
@@ -9,10 +9,10 @@ package com.haulmont.cuba.gui.components.filter.addcondition;
 import com.haulmont.chile.core.model.MetaProperty;
 import com.haulmont.cuba.core.global.AppBeans;
 import com.haulmont.cuba.core.global.MessageTools;
+import com.haulmont.cuba.core.global.MetadataTools;
 import com.haulmont.cuba.core.global.UserSessionSource;
 import com.haulmont.cuba.security.entity.EntityAttrAccess;
 import com.haulmont.cuba.security.global.UserSession;
-import org.apache.commons.lang.BooleanUtils;
 
 /**
  * @author artamonov
@@ -22,17 +22,19 @@ public class ModelPropertiesFilter {
 
     private UserSession userSession;
     private final MessageTools messageTools;
+    private final MetadataTools metadataTools;
 
     public ModelPropertiesFilter() {
         userSession = AppBeans.get(UserSessionSource.class).getUserSession();
         messageTools = AppBeans.get(MessageTools.class);
+        metadataTools = AppBeans.get(MetadataTools.class);
     }
 
     public boolean isPropertyFilterAllowed(MetaProperty property) {
         if (userSession.isEntityAttrPermitted(property.getDomain(), property.getName(), EntityAttrAccess.VIEW)) {
             // exclude system level attributes
-            Boolean systemLevel = (Boolean) property.getAnnotations().get("system");
-            if (!BooleanUtils.isTrue(systemLevel)) {
+            Boolean systemLevel = metadataTools.isSystemLevel(property);
+            if (!systemLevel) {
                 // exclude not localized properties (they are usually not for end user) and ToMany
                 if (messageTools.hasPropertyCaption(property) && !property.getRange().getCardinality().isMany()) {
                     return true;