You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2013/10/10 16:38:00 UTC

svn commit: r1531003 [4/9] - in /syncope/trunk: ./ common/src/main/java/org/apache/syncope/common/ common/src/main/java/org/apache/syncope/common/mod/ common/src/main/java/org/apache/syncope/common/to/ common/src/main/java/org/apache/syncope/common/uti...

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/connid/ConnObjectUtil.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/connid/ConnObjectUtil.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/connid/ConnObjectUtil.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/connid/ConnObjectUtil.java Thu Oct 10 14:37:56 2013
@@ -295,7 +295,7 @@ public class ConnObjectUtil {
                             attributeTO.getValues().add(attribute.getValue().get(0).toString());
                         }
 
-                        ((RoleTO) attributableTO).getAttributes().add(attributeTO);
+                        ((RoleTO) attributableTO).getAttrs().add(attributeTO);
                     }
                     break;
 
@@ -312,14 +312,14 @@ public class ConnObjectUtil {
                         }
                     }
 
-                    attributableTO.getAttributes().add(attributeTO);
+                    attributableTO.getAttrs().add(attributeTO);
                     break;
 
                 case UserDerivedSchema:
                 case RoleDerivedSchema:
                     attributeTO = new AttributeTO();
                     attributeTO.setSchema(item.getIntAttrName());
-                    attributableTO.getDerivedAttributes().add(attributeTO);
+                    attributableTO.getDerAttrs().add(attributeTO);
                     break;
 
                 case UserVirtualSchema:
@@ -336,7 +336,7 @@ public class ConnObjectUtil {
                         }
                     }
 
-                    attributableTO.getVirtualAttributes().add(attributeTO);
+                    attributableTO.getVirAttrs().add(attributeTO);
                     break;
 
                 default:
@@ -391,13 +391,21 @@ public class ConnObjectUtil {
 
                 ((RoleTO) attributableTO).getEntitlements().addAll(((RoleTO) template).getEntitlements());
 
+                ((RoleTO) attributableTO).getRAttrTemplates().addAll(((RoleTO) template).getRAttrTemplates());
+                ((RoleTO) attributableTO).getRDerAttrTemplates().addAll(((RoleTO) template).getRDerAttrTemplates());
+                ((RoleTO) attributableTO).getRVirAttrTemplates().addAll(((RoleTO) template).getRVirAttrTemplates());
+                ((RoleTO) attributableTO).getMAttrTemplates().addAll(((RoleTO) template).getMAttrTemplates());
+                ((RoleTO) attributableTO).getMDerAttrTemplates().addAll(((RoleTO) template).getMDerAttrTemplates());
+                ((RoleTO) attributableTO).getMVirAttrTemplates().addAll(((RoleTO) template).getMVirAttrTemplates());
+
                 ((RoleTO) attributableTO).setAccountPolicy(((RoleTO) template).getAccountPolicy());
                 ((RoleTO) attributableTO).setPasswordPolicy(((RoleTO) template).getPasswordPolicy());
 
                 ((RoleTO) attributableTO).setInheritOwner(((RoleTO) template).isInheritOwner());
-                ((RoleTO) attributableTO).setInheritAttributes(((RoleTO) template).isInheritAttributes());
-                ((RoleTO) attributableTO).setInheritDerivedAttributes(((RoleTO) template).isInheritDerivedAttributes());
-                ((RoleTO) attributableTO).setInheritVirtualAttributes(((RoleTO) template).isInheritVirtualAttributes());
+                ((RoleTO) attributableTO).setInheritTemplates(((RoleTO) template).isInheritTemplates());
+                ((RoleTO) attributableTO).setInheritAttrs(((RoleTO) template).isInheritAttrs());
+                ((RoleTO) attributableTO).setInheritDerAttrs(((RoleTO) template).isInheritDerAttrs());
+                ((RoleTO) attributableTO).setInheritVirAttrs(((RoleTO) template).isInheritVirAttrs());
                 ((RoleTO) attributableTO).setInheritPasswordPolicy(((RoleTO) template).isInheritPasswordPolicy());
                 ((RoleTO) attributableTO).setInheritAccountPolicy(((RoleTO) template).isInheritAccountPolicy());
             }
@@ -471,7 +479,7 @@ public class ConnObjectUtil {
                 }
             }
 
-            connObjectTO.getAttributes().add(attrTO);
+            connObjectTO.getAttrs().add(attrTO);
         }
 
         return connObjectTO;
@@ -496,7 +504,7 @@ public class ConnObjectUtil {
         // -----------------------
         // Retrieve virtual attribute values if and only if they have not been retrieved yet
         // -----------------------
-        for (AbstractVirAttr virAttr : owner.getVirtualAttributes()) {
+        for (AbstractVirAttr virAttr : owner.getVirAttrs()) {
             // reset value set
             if (virAttr.getValues().isEmpty()) {
                 retrieveVirAttrValue(owner, virAttr, attrUtil, type, externalResources, connFactory);
@@ -513,7 +521,7 @@ public class ConnObjectUtil {
             final Map<String, ConnectorObject> externalResources,
             final ConnectorFactory connFactory) {
 
-        final String schemaName = virAttr.getVirtualSchema().getName();
+        final String schemaName = virAttr.getSchema().getName();
         final List<String> values = virAttrCache.get(attrUtil.getType(), owner.getId(), schemaName);
 
         LOG.debug("Retrieve values for virtual attribute {} ({})", schemaName, type);
@@ -591,7 +599,7 @@ public class ConnObjectUtil {
         for (ExternalResource res : attr.getOwner().getResources()) {
             if (!MappingUtil.getMatchingMappingItems(
                     attrUtil.getMappingItems(res, MappingPurpose.BOTH),
-                    attr.getVirtualSchema().getName(), type).isEmpty()) {
+                    attr.getSchema().getName(), type).isEmpty()) {
 
                 resources.add(res);
             }
@@ -601,30 +609,30 @@ public class ConnObjectUtil {
     }
 
     private void fillFromTemplate(final AbstractAttributableTO attributableTO, final AbstractAttributableTO template) {
-        Map<String, AttributeTO> currentAttrMap = attributableTO.getAttributeMap();
-        for (AttributeTO templateAttr : template.getAttributes()) {
+        Map<String, AttributeTO> currentAttrMap = attributableTO.getAttrMap();
+        for (AttributeTO templateAttr : template.getAttrs()) {
             if (templateAttr.getValues() != null && !templateAttr.getValues().isEmpty()
                     && (!currentAttrMap.containsKey(templateAttr.getSchema())
                     || currentAttrMap.get(templateAttr.getSchema()).getValues().isEmpty())) {
 
-                attributableTO.getAttributes().add(evaluateAttrTemplate(attributableTO, templateAttr));
+                attributableTO.getAttrs().add(evaluateAttrTemplate(attributableTO, templateAttr));
             }
         }
 
-        currentAttrMap = attributableTO.getDerivedAttributeMap();
-        for (AttributeTO templateDerAttr : template.getDerivedAttributes()) {
+        currentAttrMap = attributableTO.getDerAttrMap();
+        for (AttributeTO templateDerAttr : template.getDerAttrs()) {
             if (!currentAttrMap.containsKey(templateDerAttr.getSchema())) {
-                attributableTO.getDerivedAttributes().add(templateDerAttr);
+                attributableTO.getDerAttrs().add(templateDerAttr);
             }
         }
 
-        currentAttrMap = attributableTO.getVirtualAttributeMap();
-        for (AttributeTO templateVirAttr : template.getDerivedAttributes()) {
+        currentAttrMap = attributableTO.getVirAttrMap();
+        for (AttributeTO templateVirAttr : template.getDerAttrs()) {
             if (templateVirAttr.getValues() != null && !templateVirAttr.getValues().isEmpty()
                     && (!currentAttrMap.containsKey(templateVirAttr.getSchema())
                     || currentAttrMap.get(templateVirAttr.getSchema()).getValues().isEmpty())) {
 
-                attributableTO.getVirtualAttributes().add(evaluateAttrTemplate(attributableTO, templateVirAttr));
+                attributableTO.getVirAttrs().add(evaluateAttrTemplate(attributableTO, templateVirAttr));
             }
         }
     }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/init/JobInstanceLoader.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/init/JobInstanceLoader.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/init/JobInstanceLoader.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/init/JobInstanceLoader.java Thu Oct 10 14:37:56 2013
@@ -18,9 +18,6 @@
  */
 package org.apache.syncope.core.init;
 
-import static org.apache.syncope.core.init.JobInstanceLoader.getJobName;
-import static org.apache.syncope.core.init.JobInstanceLoader.getTriggerName;
-
 import java.text.ParseException;
 import java.util.HashSet;
 import java.util.Set;

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/notification/NotificationManager.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/notification/NotificationManager.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/notification/NotificationManager.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/notification/NotificationManager.java Thu Oct 10 14:37:56 2013
@@ -227,23 +227,23 @@ public class NotificationManager {
                 break;
 
             case UserSchema:
-                UAttr attr = user.getAttribute(recipientAttrName);
+                UAttr attr = user.getAttr(recipientAttrName);
                 if (attr != null && !attr.getValuesAsStrings().isEmpty()) {
                     email = attr.getValuesAsStrings().get(0);
                 }
                 break;
 
             case UserVirtualSchema:
-                UVirAttr virAttr = user.getVirtualAttribute(recipientAttrName);
+                UVirAttr virAttr = user.getVirAttr(recipientAttrName);
                 if (virAttr != null && !virAttr.getValues().isEmpty()) {
                     email = virAttr.getValues().get(0);
                 }
                 break;
 
             case UserDerivedSchema:
-                UDerAttr derAttr = user.getDerivedAttribute(recipientAttrName);
+                UDerAttr derAttr = user.getDerAttr(recipientAttrName);
                 if (derAttr != null) {
-                    email = derAttr.getValue(user.getAttributes());
+                    email = derAttr.getValue(user.getAttrs());
                 }
                 break;
 

Added: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/SQLSchemaGenerator.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/SQLSchemaGenerator.java?rev=1531003&view=auto
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/SQLSchemaGenerator.java (added)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/SQLSchemaGenerator.java Thu Oct 10 14:37:56 2013
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.syncope.core.persistence;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.persistence.Entity;
+import org.apache.commons.io.FileUtils;
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
+import org.apache.openjpa.jdbc.meta.MappingTool;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.lib.meta.ClassArgParser;
+import org.apache.openjpa.lib.util.Options;
+import org.apache.openjpa.meta.MetaDataRepository;
+
+public final class SQLSchemaGenerator {
+
+    private static final String OPTION_PROPERTIES_FILE = "propertiesFile";
+
+    private static final String OPTION_CONNECTION_PROPERTIES = "ConnectionProperties";
+
+    private static final String OPTION_CONNECTION_DRIVER_NAME = "ConnectionDriverName";
+
+    private static final String OPTION_SQL_ACTION = "schemaAction";
+
+    private static final String OPTION_SQL_FILE = "sqlFile";
+
+    /**
+     * Locates and returns a list of class files found under specified class directory.
+     *
+     * @param base base class directory
+     * @return list of class files
+     */
+    private static List<File> findEntityClassFiles(final String base) {
+        File baseDir = new File(base);
+        if (!baseDir.exists() || !baseDir.isDirectory()) {
+            throw new IllegalArgumentException(baseDir + " not found or not a directory");
+        }
+
+        @SuppressWarnings("unchecked")
+        Iterator<File> itor = FileUtils.iterateFiles(baseDir, new String[] {"class"}, true);
+        List<File> entityClasses = new ArrayList<File>();
+        while (itor.hasNext()) {
+            entityClasses.add(itor.next());
+        }
+
+        return entityClasses;
+    }
+
+    /**
+     * @param cls the Class to check
+     * @return <code>true</code> if the given Class cls implements the interface {@link PersistenceCapable}
+     */
+    private static boolean implementsPersistenceCapable(final Class<?> cls) {
+        boolean isPersistenceCapable = false;
+        Class<?>[] interfaces = cls.getInterfaces();
+        for (int i = 0; i < interfaces.length; i++) {
+            if (interfaces[i].getName().equals(PersistenceCapable.class.getName())) {
+                isPersistenceCapable = true;
+                break;
+            }
+        }
+
+        return isPersistenceCapable;
+    }
+
+    /**
+     * Filter out all classes which are not PersistenceCapable.
+     * This is needed since the MappingTool fails if it gets non-persistent capable classes.
+     *
+     * @param files List with classPath Files; non persistence classes will be removed
+     * @param opts filled configuration Options
+     */
+    private static void filterPersistenceCapable(final List<File> files, final Options opts) {
+        JDBCConfiguration conf = new JDBCConfigurationImpl();
+        Configurations.populateConfiguration(conf, opts);
+        MetaDataRepository repo = conf.newMetaDataRepositoryInstance();
+        ClassArgParser cap = repo.getMetaDataFactory().newClassArgParser();
+
+        Iterator<File> fileIt = files.iterator();
+        while (fileIt.hasNext()) {
+            File classPath = fileIt.next();
+
+            Class[] classes = cap.parseTypes(classPath.getAbsolutePath());
+            if (classes == null) {
+                System.out.println("Found no classes for " + classPath.getAbsolutePath());
+            } else {
+                for (int i = 0; i < classes.length; i++) {
+                    Class<?> cls = classes[i];
+
+                    if (cls.getAnnotation(Entity.class) == null && !implementsPersistenceCapable(cls)) {
+                        fileIt.remove();
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * @param files List of files
+     * @return the paths of the given files as String[]
+     */
+    private static String[] getFilePaths(final List<File> files) {
+        String[] args = new String[files.size()];
+        for (int i = 0; i < files.size(); i++) {
+            File file = files.get(i);
+
+            args[ i] = file.getAbsolutePath();
+        }
+        return args;
+    }
+
+    /**
+     * Processes a list of class file resources and perform the proper mapping action.
+     */
+    private static void mappingTool(final List<File> files,
+            final String persistenceXmlFile, final String sqlFile, final String connectionDriverName,
+            final String connectionProperties) {
+
+        //extendRealmClasspath();
+
+        Options opts = new Options();
+        opts.put(OPTION_PROPERTIES_FILE, persistenceXmlFile);
+        opts.put(OPTION_CONNECTION_DRIVER_NAME, connectionDriverName);
+        opts.put(OPTION_CONNECTION_PROPERTIES, connectionProperties);
+        opts.put(OPTION_SQL_FILE, sqlFile);
+        opts.put(OPTION_SQL_ACTION, "build");
+
+        filterPersistenceCapable(files, opts);
+
+        // list of input files
+        final String[] args = getFilePaths(files);
+
+        boolean ok = Configurations.runAgainstAllAnchors(opts,
+                new Configurations.Runnable() {
+
+            @Override
+            public boolean run(final Options opts) throws IOException, SQLException {
+                JDBCConfiguration conf = new JDBCConfigurationImpl();
+                try {
+                    return MappingTool.run(conf, args, opts);
+                } finally {
+                    conf.close();
+                }
+            }
+        });
+
+        if (!ok) {
+            throw new IllegalStateException("The OpenJPA MappingTool detected an error!");
+        }
+
+    }
+
+    public static void main(final String[] args) {
+        List<File> entities = findEntityClassFiles(System.getProperty("base"));
+
+        mappingTool(entities, System.getProperty("persistenceXmlFile"), System.getProperty("sqlFile"),
+                System.getProperty("connectionDriverName"),
+                System.getProperty("connectionProperties").replaceAll(";", "="));
+    }
+
+    private SQLSchemaGenerator() {
+        // Empty constructor for main() class
+    }
+}

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/SQLSchemaGenerator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/SQLSchemaGenerator.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/SQLSchemaGenerator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Copied: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/SysInfoListener.java (from r1528111, syncope/trunk/core/src/main/java/org/apache/syncope/core/util/SysInfoListener.java)
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/SysInfoListener.java?p2=syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/SysInfoListener.java&p1=syncope/trunk/core/src/main/java/org/apache/syncope/core/util/SysInfoListener.java&r1=1528111&r2=1531003&rev=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/util/SysInfoListener.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/SysInfoListener.java Thu Oct 10 14:37:56 2013
@@ -16,12 +16,13 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.syncope.core.util;
+package org.apache.syncope.core.persistence;
 
 import java.util.Date;
 import javax.persistence.PrePersist;
 import javax.persistence.PreUpdate;
 import org.apache.syncope.core.persistence.beans.AbstractSysInfo;
+import org.apache.syncope.core.util.EntitlementUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -30,30 +31,24 @@ public class SysInfoListener {
     /**
      * Logger.
      */
-    protected static final Logger LOG = LoggerFactory.getLogger(SysInfoListener.class);
+    private static final Logger LOG = LoggerFactory.getLogger(SysInfoListener.class);
 
     @PrePersist
     @PreUpdate
     public void setSysInfo(final AbstractSysInfo entity) {
-        try {
-            final String username = EntitlementUtil.getAuthenticatedUsername();
-            LOG.debug("Set system properties for '{}'", entity);
-
-            final Date now = new Date();
-
-            if (entity.getCreationDate() == null) {
-                LOG.debug("Set creation date '{}' and creator '{}' for '{}'", new Object[] {now, username, entity});
-                entity.setCreationDate(now);
-                entity.setCreator(username);
-            }
-
-            LOG.debug("Set last change date '{}' and modifier '{}' for '{}'", new Object[] {now, username, entity});
-            entity.setLastModifier(username);
-            entity.setLastChangeDate(now);
-        } catch (Exception e) {
-            // In case of exception, do not trace create/update event info: maybe it's an internal management action.
-            // See SyncopeAuthenticationProvider for instance.
-            LOG.info("Unauthenticated user action: no system property to be update");
+        final String username = EntitlementUtil.getAuthenticatedUsername();
+        LOG.debug("Set system properties for '{}'", entity);
+
+        final Date now = new Date();
+
+        if (entity.getCreationDate() == null) {
+            LOG.debug("Set creation date '{}' and creator '{}' for '{}'", now, username, entity);
+            entity.setCreationDate(now);
+            entity.setCreator(username);
         }
+
+        LOG.debug("Set last change date '{}' and modifier '{}' for '{}'", now, username, entity);
+        entity.setLastModifier(username);
+        entity.setLastChangeDate(now);
     }
 }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttr.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttr.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttr.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttr.java Thu Oct 10 14:37:56 2013
@@ -67,9 +67,7 @@ public abstract class AbstractAttr exten
 
     public abstract <T extends AbstractAttributable> void setOwner(T owner);
 
-    public abstract <T extends AbstractSchema> T getSchema();
-
-    public abstract <T extends AbstractSchema> void setSchema(T schema);
+    public abstract <T extends AbstractNormalSchema> T getSchema();
 
     public abstract <T extends AbstractAttrValue> boolean addValue(T attrValue);
 

Added: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrTemplate.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrTemplate.java?rev=1531003&view=auto
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrTemplate.java (added)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrTemplate.java Thu Oct 10 14:37:56 2013
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.syncope.core.persistence.beans;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
+
+@MappedSuperclass
+public abstract class AbstractAttrTemplate<T extends AbstractSchema> extends AbstractBaseBean {
+
+    private static final long serialVersionUID = 4829112252713766666L;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    protected Long id;
+
+    public Long getId() {
+        return id;
+    }
+
+    public abstract SyncopeRole getOwner();
+
+    public abstract void setOwner(SyncopeRole role);
+
+    public abstract T getSchema();
+
+    public abstract void setSchema(T schema);
+}

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrTemplate.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrTemplate.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrTemplate.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrUniqueValue.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrUniqueValue.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrUniqueValue.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrUniqueValue.java Thu Oct 10 14:37:56 2013
@@ -22,7 +22,7 @@ public abstract class AbstractAttrUnique
 
     private static final long serialVersionUID = -1114553598914979353L;
 
-    public abstract <T extends AbstractSchema> T getSchema();
+    public abstract <T extends AbstractNormalSchema> T getSchema();
 
-    public abstract <T extends AbstractSchema> void setSchema(T schema);
+    public abstract <T extends AbstractNormalSchema> void setSchema(T schema);
 }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrValue.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrValue.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrValue.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrValue.java Thu Oct 10 14:37:56 2013
@@ -102,7 +102,7 @@ public abstract class AbstractAttrValue 
         this.stringValue = stringValue;
     }
 
-    public <T extends AbstractAttrValue> void parseValue(final AbstractSchema schema, final String value)
+    public <T extends AbstractAttrValue> void parseValue(final AbstractNormalSchema schema, final String value)
             throws ParsingValidationException {
 
         Exception exception = null;

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttributable.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttributable.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttributable.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttributable.java Thu Oct 10 14:37:56 2013
@@ -30,9 +30,9 @@ public abstract class AbstractAttributab
     private static final long serialVersionUID = -4801685541488201119L;
 
     @SuppressWarnings("unchecked")
-    public <T extends AbstractAttr> T getAttribute(final String schemaName) {
+    public <T extends AbstractAttr> T getAttr(final String schemaName) {
         T result = null;
-        for (Iterator<? extends AbstractAttr> itor = getAttributes().iterator(); result == null && itor.hasNext();) {
+        for (Iterator<? extends AbstractAttr> itor = getAttrs().iterator(); result == null && itor.hasNext();) {
             final T attribute = (T) itor.next();
             if (attribute.getSchema() != null && schemaName.equals(attribute.getSchema().getName())) {
                 result = attribute;
@@ -42,16 +42,16 @@ public abstract class AbstractAttributab
     }
 
     @SuppressWarnings("unchecked")
-    public <T extends AbstractDerAttr> T getDerivedAttribute(final String derivedSchemaName) {
+    public <T extends AbstractDerAttr> T getDerAttr(final String derSchemaName) {
         T result = null;
-        for (Iterator<? extends AbstractDerAttr> itor = getDerivedAttributes().iterator();
+        for (Iterator<? extends AbstractDerAttr> itor = getDerAttrs().iterator();
                 result == null && itor.hasNext();) {
 
-            T derivedAttribute = (T) itor.next();
-            if (derivedAttribute.getDerivedSchema() != null
-                    && derivedSchemaName.equals(derivedAttribute.getDerivedSchema().getName())) {
+            T derAttr = (T) itor.next();
+            if (derAttr.getSchema() != null
+                    && derSchemaName.equals(derAttr.getSchema().getName())) {
 
-                result = derivedAttribute;
+                result = derAttr;
             }
         }
 
@@ -59,26 +59,26 @@ public abstract class AbstractAttributab
     }
 
     @SuppressWarnings("unchecked")
-    public <T extends AbstractVirAttr> T getVirtualAttribute(final String virtualSchemaName) {
+    public <T extends AbstractVirAttr> T getVirAttr(final String virSchemaName) {
         T result = null;
-        for (Iterator<? extends AbstractVirAttr> itor = getVirtualAttributes().iterator();
+        for (Iterator<? extends AbstractVirAttr> itor = getVirAttrs().iterator();
                 result == null && itor.hasNext();) {
 
-            T virtualAttribute = (T) itor.next();
-            if (virtualAttribute.getVirtualSchema() != null
-                    && virtualSchemaName.equals(virtualAttribute.getVirtualSchema().getName())) {
+            T virAttr = (T) itor.next();
+            if (virAttr.getSchema() != null
+                    && virSchemaName.equals(virAttr.getSchema().getName())) {
 
-                result = virtualAttribute;
+                result = virAttr;
             }
         }
 
         return result;
     }
 
-    protected Map<AbstractSchema, AbstractAttr> getAttrMap() {
-        final Map<AbstractSchema, AbstractAttr> map = new HashMap<AbstractSchema, AbstractAttr>();
+    protected Map<AbstractNormalSchema, AbstractAttr> getAttrMap() {
+        final Map<AbstractNormalSchema, AbstractAttr> map = new HashMap<AbstractNormalSchema, AbstractAttr>();
 
-        for (AbstractAttr attr : getAttributes()) {
+        for (AbstractAttr attr : getAttrs()) {
             map.put(attr.getSchema(), attr);
         }
 
@@ -88,8 +88,8 @@ public abstract class AbstractAttributab
     protected Map<AbstractDerSchema, AbstractDerAttr> getDerAttrMap() {
         final Map<AbstractDerSchema, AbstractDerAttr> map = new HashMap<AbstractDerSchema, AbstractDerAttr>();
 
-        for (AbstractDerAttr attr : getDerivedAttributes()) {
-            map.put(attr.getDerivedSchema(), attr);
+        for (AbstractDerAttr attr : getDerAttrs()) {
+            map.put(attr.getSchema(), attr);
         }
 
         return map;
@@ -98,8 +98,8 @@ public abstract class AbstractAttributab
     protected Map<AbstractVirSchema, AbstractVirAttr> getVirAttrMap() {
         final Map<AbstractVirSchema, AbstractVirAttr> map = new HashMap<AbstractVirSchema, AbstractVirAttr>();
 
-        for (AbstractVirAttr attr : getVirtualAttributes()) {
-            map.put(attr.getVirtualSchema(), attr);
+        for (AbstractVirAttr attr : getVirAttrs()) {
+            map.put(attr.getSchema(), attr);
         }
 
         return map;
@@ -107,29 +107,29 @@ public abstract class AbstractAttributab
 
     public abstract Long getId();
 
-    public abstract <T extends AbstractAttr> boolean addAttribute(T attribute);
+    public abstract <T extends AbstractAttr> boolean addAttr(T attribute);
 
-    public abstract <T extends AbstractAttr> boolean removeAttribute(T attribute);
+    public abstract <T extends AbstractAttr> boolean removeAttr(T attribute);
 
-    public abstract List<? extends AbstractAttr> getAttributes();
+    public abstract List<? extends AbstractAttr> getAttrs();
 
-    public abstract void setAttributes(List<? extends AbstractAttr> attributes);
+    public abstract void setAttrs(List<? extends AbstractAttr> attributes);
 
-    public abstract <T extends AbstractDerAttr> boolean addDerivedAttribute(T derivedAttribute);
+    public abstract <T extends AbstractDerAttr> boolean addDerAttr(T derivedAttribute);
 
-    public abstract <T extends AbstractDerAttr> boolean removeDerivedAttribute(T derivedAttribute);
+    public abstract <T extends AbstractDerAttr> boolean removeDerAttr(T derivedAttribute);
 
-    public abstract List<? extends AbstractDerAttr> getDerivedAttributes();
+    public abstract List<? extends AbstractDerAttr> getDerAttrs();
 
-    public abstract void setDerivedAttributes(List<? extends AbstractDerAttr> derivedAttributes);
+    public abstract void setDerAttrs(List<? extends AbstractDerAttr> derivedAttributes);
 
-    public abstract <T extends AbstractVirAttr> boolean addVirtualAttribute(T virtualAttributes);
+    public abstract <T extends AbstractVirAttr> boolean addVirAttr(T virtualAttributes);
 
-    public abstract <T extends AbstractVirAttr> boolean removeVirtualAttribute(T virtualAttribute);
+    public abstract <T extends AbstractVirAttr> boolean removeVirAttr(T virtualAttribute);
 
-    public abstract List<? extends AbstractVirAttr> getVirtualAttributes();
+    public abstract List<? extends AbstractVirAttr> getVirAttrs();
 
-    public abstract void setVirtualAttributes(List<? extends AbstractVirAttr> virtualAttributes);
+    public abstract void setVirAttrs(List<? extends AbstractVirAttr> virtualAttributes);
 
     protected abstract Set<ExternalResource> internalGetResources();
 

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractDerAttr.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractDerAttr.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractDerAttr.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractDerAttr.java Thu Oct 10 14:37:56 2013
@@ -57,14 +57,12 @@ public abstract class AbstractDerAttr ex
         jexlUtil.addFieldsToContext(getOwner(), jexlContext);
 
         // Evaluate expression using the context prepared before
-        return jexlUtil.evaluate(getDerivedSchema().getExpression(), jexlContext);
+        return jexlUtil.evaluate(getSchema().getExpression(), jexlContext);
     }
 
     public abstract <T extends AbstractAttributable> T getOwner();
 
     public abstract <T extends AbstractAttributable> void setOwner(T owner);
 
-    public abstract <T extends AbstractDerSchema> T getDerivedSchema();
-
-    public abstract <T extends AbstractDerSchema> void setDerivedSchema(T derivedSchema);
+    public abstract <T extends AbstractDerSchema> T getSchema();
 }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractDerSchema.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractDerSchema.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractDerSchema.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractDerSchema.java Thu Oct 10 14:37:56 2013
@@ -26,7 +26,7 @@ import org.apache.syncope.core.persisten
 
 @MappedSuperclass
 @SchemaNameCheck
-public abstract class AbstractDerSchema extends AbstractBaseBean {
+public abstract class AbstractDerSchema extends AbstractSchema {
 
     private static final long serialVersionUID = -6173643493348674060L;
 
@@ -36,10 +36,12 @@ public abstract class AbstractDerSchema 
     @Column(nullable = false)
     private String expression;
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public void setName(final String name) {
         this.name = name;
     }

Copied: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractNormalSchema.java (from r1529782, syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSchema.java)
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractNormalSchema.java?p2=syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractNormalSchema.java&p1=syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSchema.java&r1=1529782&r2=1531003&rev=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSchema.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractNormalSchema.java Thu Oct 10 14:37:56 2013
@@ -18,11 +18,10 @@
  */
 package org.apache.syncope.core.persistence.beans;
 
-import static javax.persistence.EnumType.STRING;
-
 import java.lang.reflect.Constructor;
 import javax.persistence.Basic;
 import javax.persistence.Column;
+import javax.persistence.EnumType;
 import javax.persistence.Enumerated;
 import javax.persistence.Id;
 import javax.persistence.Lob;
@@ -39,9 +38,7 @@ import org.apache.syncope.core.persisten
 @MappedSuperclass
 @SchemaCheck
 @SchemaNameCheck
-public abstract class AbstractSchema extends AbstractBaseBean {
-
-    public static String enumValuesSeparator = ";";
+public abstract class AbstractNormalSchema extends AbstractSchema {
 
     private static final long serialVersionUID = -8621028596062054739L;
 
@@ -49,7 +46,7 @@ public abstract class AbstractSchema ext
     private String name;
 
     @Column(nullable = false)
-    @Enumerated(STRING)
+    @Enumerated(EnumType.STRING)
     private AttributeSchemaType type;
 
     @Column(nullable = false)
@@ -87,7 +84,7 @@ public abstract class AbstractSchema ext
     @Transient
     private AbstractValidator validator;
 
-    public AbstractSchema() {
+    public AbstractNormalSchema() {
         super();
 
         type = AttributeSchemaType.String;
@@ -97,10 +94,12 @@ public abstract class AbstractSchema ext
         readonly = getBooleanAsInteger(false);
     }
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public void setName(final String name) {
         this.name = name;
     }
@@ -152,12 +151,12 @@ public abstract class AbstractSchema ext
 
         if (getValidatorClass() != null && getValidatorClass().length() > 0) {
             try {
-                Constructor validatorConstructor = Class.forName(getValidatorClass()).getConstructor(
-                        new Class[] {getClass().getSuperclass()});
+                Constructor<?> validatorConstructor = Class.forName(getValidatorClass()).
+                        getConstructor(new Class<?>[] {getClass().getSuperclass()});
                 validator = (AbstractValidator) validatorConstructor.newInstance(this);
             } catch (Exception e) {
-                LOG.error("Could not instantiate validator of type " + getValidatorClass()
-                        + ", reverting to " + BasicValidator.class.getSimpleName(), e);
+                LOG.error("Could not instantiate validator of type {}, reverting to {}",
+                        getValidatorClass(), BasicValidator.class.getSimpleName(), e);
             }
         }
 
@@ -202,7 +201,7 @@ public abstract class AbstractSchema ext
 
     public void setConversionPattern(final String conversionPattern) {
         if (!getType().isConversionPatternNeeded()) {
-            LOG.warn("Conversion pattern will be ignored: " + "this attribute type is " + getType());
+            LOG.warn("Conversion pattern will be ignored: this attribute type is {}", getType());
         }
 
         this.conversionPattern = conversionPattern;

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSchema.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSchema.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSchema.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSchema.java Thu Oct 10 14:37:56 2013
@@ -18,193 +18,11 @@
  */
 package org.apache.syncope.core.persistence.beans;
 
-import static javax.persistence.EnumType.STRING;
-
-import java.lang.reflect.Constructor;
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Enumerated;
-import javax.persistence.Id;
-import javax.persistence.Lob;
-import javax.persistence.MappedSuperclass;
-import javax.persistence.Transient;
-import javax.validation.constraints.Max;
-import javax.validation.constraints.Min;
-import org.apache.syncope.common.types.AttributeSchemaType;
-import org.apache.syncope.core.persistence.validation.attrvalue.AbstractValidator;
-import org.apache.syncope.core.persistence.validation.attrvalue.BasicValidator;
-import org.apache.syncope.core.persistence.validation.entity.SchemaCheck;
-import org.apache.syncope.core.persistence.validation.entity.SchemaNameCheck;
-
-@MappedSuperclass
-@SchemaCheck
-@SchemaNameCheck
 public abstract class AbstractSchema extends AbstractBaseBean {
 
-    public static String enumValuesSeparator = ";";
-
-    private static final long serialVersionUID = -8621028596062054739L;
-
-    @Id
-    private String name;
-
-    @Column(nullable = false)
-    @Enumerated(STRING)
-    private AttributeSchemaType type;
-
-    @Column(nullable = false)
-    private String mandatoryCondition;
-
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer multivalue;
-
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer uniqueConstraint;
-
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer readonly;
-
-    @Column(nullable = true)
-    private String conversionPattern;
-
-    @Column(nullable = true)
-    private String validatorClass;
-
-    @Column(nullable = true)
-    @Lob
-    private String enumerationValues;
-
-    @Column(nullable = true)
-    @Lob
-    private String enumerationKeys;
-
-    @Transient
-    private AbstractValidator validator;
-
-    public AbstractSchema() {
-        super();
-
-        type = AttributeSchemaType.String;
-        mandatoryCondition = Boolean.FALSE.toString();
-        multivalue = getBooleanAsInteger(false);
-        uniqueConstraint = getBooleanAsInteger(false);
-        readonly = getBooleanAsInteger(false);
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(final String name) {
-        this.name = name;
-    }
-
-    public AttributeSchemaType getType() {
-        return type;
-    }
-
-    public void setType(final AttributeSchemaType type) {
-        this.type = type;
-    }
-
-    public String getMandatoryCondition() {
-        return mandatoryCondition;
-    }
-
-    public void setMandatoryCondition(final String mandatoryCondition) {
-        this.mandatoryCondition = mandatoryCondition;
-    }
-
-    public boolean isMultivalue() {
-        return isBooleanAsInteger(multivalue);
-    }
-
-    public void setMultivalue(boolean multivalue) {
-        this.multivalue = getBooleanAsInteger(multivalue);
-    }
-
-    public boolean isUniqueConstraint() {
-        return isBooleanAsInteger(uniqueConstraint);
-    }
-
-    public void setUniqueConstraint(final boolean uniquevalue) {
-        this.uniqueConstraint = getBooleanAsInteger(uniquevalue);
-    }
-
-    public boolean isReadonly() {
-        return isBooleanAsInteger(readonly);
-    }
-
-    public void setReadonly(final boolean readonly) {
-        this.readonly = getBooleanAsInteger(readonly);
-    }
-
-    public AbstractValidator getValidator() {
-        if (validator != null) {
-            return validator;
-        }
-
-        if (getValidatorClass() != null && getValidatorClass().length() > 0) {
-            try {
-                Constructor validatorConstructor = Class.forName(getValidatorClass()).getConstructor(
-                        new Class[] {getClass().getSuperclass()});
-                validator = (AbstractValidator) validatorConstructor.newInstance(this);
-            } catch (Exception e) {
-                LOG.error("Could not instantiate validator of type " + getValidatorClass()
-                        + ", reverting to " + BasicValidator.class.getSimpleName(), e);
-            }
-        }
-
-        if (validator == null) {
-            validator = new BasicValidator(this);
-        }
-
-        return validator;
-    }
-
-    public String getValidatorClass() {
-        return validatorClass;
-    }
-
-    public void setValidatorClass(final String validatorClass) {
-        this.validatorClass = validatorClass;
-    }
-
-    public String getEnumerationValues() {
-        return enumerationValues;
-    }
-
-    public void setEnumerationValues(final String enumerationValues) {
-        this.enumerationValues = enumerationValues;
-    }
-
-    public String getEnumerationKeys() {
-        return enumerationKeys;
-    }
-
-    public void setEnumerationKeys(String enumerationKeys) {
-        this.enumerationKeys = enumerationKeys;
-    }
-
-    public String getConversionPattern() {
-        if (!getType().isConversionPatternNeeded()) {
-            LOG.debug("Conversion pattern is not needed: {}'s type is {}", this, getType());
-        }
-
-        return conversionPattern;
-    }
+    private static final long serialVersionUID = 2251957673265528044L;
 
-    public void setConversionPattern(final String conversionPattern) {
-        if (!getType().isConversionPatternNeeded()) {
-            LOG.warn("Conversion pattern will be ignored: " + "this attribute type is " + getType());
-        }
+    public abstract String getName();
 
-        this.conversionPattern = conversionPattern;
-    }
+    public abstract void setName(String name);
 }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSysInfo.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSysInfo.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSysInfo.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractSysInfo.java Thu Oct 10 14:37:56 2013
@@ -24,7 +24,7 @@ import javax.persistence.EntityListeners
 import javax.persistence.MappedSuperclass;
 import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
-import org.apache.syncope.core.util.SysInfoListener;
+import org.apache.syncope.core.persistence.SysInfoListener;
 
 /**
  * Abstract wrapper for common system information.
@@ -37,9 +37,8 @@ public abstract class AbstractSysInfo ex
 
     /**
      * Username of the user that has created this profile.
-     * <p>
-     * Cannot be used a reference to an existing user for two main reasons: the creator can be the user <tt>admin</tt>;
-     * the creator could have been removed.
+     * <br/>
+     * Reference to existing user cannot be used: the creator can either be <tt>admin</tt> or was deleted.
      */
     @Column(nullable = false)
     private String creator;
@@ -53,21 +52,20 @@ public abstract class AbstractSysInfo ex
 
     /**
      * Username of the user that has performed the last modification to this profile.
-     * <p>
-     * This field cannot be null: at creation time it have to be initialized with the creator username.
-     * <p>
-     * The modifier can be the user itself whether the last performed change has been a self-modification.
-     * <p>
-     * Cannot be used a reference to an existing user for two main reasons: the modifier can be the user <tt>admin</tt>;
-     * the modifier could have been removed.
+     * <br/>
+     * This field cannot be null: at creation time it needs to be initialized with the creator username.
+     * <br/>
+     * The modifier can be the user itself if the last performed change was a self-modification.
+     * <br/>
+     * Reference to existing user cannot be used: the creator can either be <tt>admin</tt> or was deleted.
      */
     @Column(nullable = false)
     private String lastModifier;
 
     /**
      * Last change date.
-     * <p>
-     * This field cannot be null: at creation time it has to be initialized with <tt>creationDate</tt> field value.
+     * <br/>
+     * This field cannot be null: at creation time it needs to be initialized with <tt>creationDate</tt> field value.
      */
     @Column(nullable = false)
     @Temporal(TemporalType.TIMESTAMP)

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractVirAttr.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractVirAttr.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractVirAttr.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractVirAttr.java Thu Oct 10 14:37:56 2013
@@ -37,33 +37,34 @@ public abstract class AbstractVirAttr ex
     protected Long id;
 
     @Transient
-    protected List<String> values;
+    protected List<String> values = new ArrayList<String>();
 
     public Long getId() {
         return id;
     }
 
-    public void setValues(final List<String> values) {
-        this.values = values;
+    public List<String> getValues() {
+        return values;
     }
 
-    public void addValue(final String value) {
-        if (values == null) {
-            values = new ArrayList<String>();
-        }
+    public boolean addValue(final String value) {
+        return !values.contains(value) && values.add(value);
+    }
 
-        if (!values.contains(value)) {
-            values.add(value);
-        }
+    public boolean removeValue(final String value) {
+        return values.remove(value);
     }
 
-    public abstract List<String> getValues();
+    public void setValues(final List<String> values) {
+        this.values.clear();
+        if (values != null && !values.isEmpty()) {
+            this.values.addAll(values);
+        }
+    }
 
     public abstract <T extends AbstractAttributable> T getOwner();
 
     public abstract <T extends AbstractAttributable> void setOwner(T owner);
 
-    public abstract <T extends AbstractVirSchema> T getVirtualSchema();
-
-    public abstract <T extends AbstractVirSchema> void setVirtualSchema(T derivedSchema);
+    public abstract <T extends AbstractVirSchema> T getSchema();
 }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractVirSchema.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractVirSchema.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractVirSchema.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractVirSchema.java Thu Oct 10 14:37:56 2013
@@ -29,7 +29,7 @@ import org.apache.syncope.core.persisten
 
 @MappedSuperclass
 @SchemaNameCheck
-public abstract class AbstractVirSchema extends AbstractBaseBean {
+public abstract class AbstractVirSchema extends AbstractSchema {
 
     @Id
     private String name;
@@ -45,10 +45,12 @@ public abstract class AbstractVirSchema 
         readonly = getBooleanAsInteger(false);
     }
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public void setName(final String name) {
         this.name = name;
     }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttr.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttr.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttr.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttr.java Thu Oct 10 14:37:56 2013
@@ -21,10 +21,10 @@ package org.apache.syncope.core.persiste
 import java.util.ArrayList;
 import java.util.List;
 import javax.persistence.CascadeType;
+import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.Id;
-import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
@@ -32,7 +32,7 @@ import javax.validation.Valid;
 import org.apache.syncope.core.persistence.beans.AbstractAttr;
 import org.apache.syncope.core.persistence.beans.AbstractAttrValue;
 import org.apache.syncope.core.persistence.beans.AbstractAttributable;
-import org.apache.syncope.core.persistence.beans.AbstractSchema;
+import org.apache.syncope.core.persistence.beans.AbstractNormalSchema;
 
 @Entity
 public class MAttr extends AbstractAttr {
@@ -45,9 +45,9 @@ public class MAttr extends AbstractAttr 
     @ManyToOne(fetch = FetchType.EAGER)
     private Membership owner;
 
-    @ManyToOne(fetch = FetchType.EAGER)
-    @JoinColumn(name = "schema_name")
-    private MSchema schema;
+    @Column(nullable = false)
+    @OneToOne(cascade = CascadeType.MERGE)
+    private MAttrTemplate template;
 
     @OneToMany(cascade = CascadeType.MERGE, orphanRemoval = true, mappedBy = "attribute")
     @Valid
@@ -81,18 +81,18 @@ public class MAttr extends AbstractAttr 
         this.owner = (Membership) owner;
     }
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public <T extends AbstractSchema> T getSchema() {
-        return (T) schema;
+    public MAttrTemplate getTemplate() {
+        return template;
+    }
+
+    public void setTemplate(final MAttrTemplate template) {
+        this.template = template;
     }
 
+    @SuppressWarnings("unchecked")
     @Override
-    public <T extends AbstractSchema> void setSchema(final T schema) {
-        if (!(schema instanceof MSchema)) {
-            throw new ClassCastException("schema is expected to be typed MSchema: " + schema.getClass().getName());
-        }
-        this.schema = (MSchema) schema;
+    public <T extends AbstractNormalSchema> T getSchema() {
+        return template == null ? null : (T) template.getSchema();
     }
 
     @Override
@@ -125,7 +125,6 @@ public class MAttr extends AbstractAttr 
     @SuppressWarnings("unchecked")
     @Override
     public <T extends AbstractAttrValue> void setValues(final List<T> attributeValues) {
-
         this.values.clear();
         if (attributeValues != null && !attributeValues.isEmpty()) {
             for (T mav : attributeValues) {

Added: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttrTemplate.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttrTemplate.java?rev=1531003&view=auto
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttrTemplate.java (added)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttrTemplate.java Thu Oct 10 14:37:56 2013
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.syncope.core.persistence.beans.membership;
+
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import org.apache.syncope.core.persistence.beans.AbstractAttrTemplate;
+import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
+
+@Entity
+public class MAttrTemplate extends AbstractAttrTemplate<MSchema> {
+
+    private static final long serialVersionUID = -3424574558427502145L;
+
+    @ManyToOne
+    private SyncopeRole owner;
+
+    @ManyToOne
+    @JoinColumn(name = "schema_name")
+    private MSchema schema;
+
+    @Override
+    public MSchema getSchema() {
+        return schema;
+    }
+
+    @Override
+    public void setSchema(final MSchema schema) {
+        this.schema = schema;
+    }
+
+    @Override
+    public SyncopeRole getOwner() {
+        return owner;
+    }
+
+    @Override
+    public void setOwner(final SyncopeRole owner) {
+        this.owner = owner;
+    }
+}

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttrTemplate.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttrTemplate.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttrTemplate.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttrUniqueValue.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttrUniqueValue.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttrUniqueValue.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttrUniqueValue.java Thu Oct 10 14:37:56 2013
@@ -25,7 +25,7 @@ import javax.persistence.ManyToOne;
 import javax.persistence.OneToOne;
 import org.apache.syncope.core.persistence.beans.AbstractAttr;
 import org.apache.syncope.core.persistence.beans.AbstractAttrUniqueValue;
-import org.apache.syncope.core.persistence.beans.AbstractSchema;
+import org.apache.syncope.core.persistence.beans.AbstractNormalSchema;
 
 @Entity
 public class MAttrUniqueValue extends AbstractAttrUniqueValue {
@@ -63,12 +63,12 @@ public class MAttrUniqueValue extends Ab
 
     @SuppressWarnings("unchecked")
     @Override
-    public <T extends AbstractSchema> T getSchema() {
+    public <T extends AbstractNormalSchema> T getSchema() {
         return (T) schema;
     }
 
     @Override
-    public <T extends AbstractSchema> void setSchema(final T schema) {
+    public <T extends AbstractNormalSchema> void setSchema(final T schema) {
         if (!(schema instanceof MSchema)) {
             throw new ClassCastException("expected type MSchema, found: " + schema.getClass().getName());
         }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MDerAttr.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MDerAttr.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MDerAttr.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MDerAttr.java Thu Oct 10 14:37:56 2013
@@ -18,9 +18,11 @@
  */
 package org.apache.syncope.core.persistence.beans.membership;
 
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
 import javax.persistence.Entity;
-import javax.persistence.FetchType;
 import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
 import org.apache.syncope.core.persistence.beans.AbstractAttributable;
 import org.apache.syncope.core.persistence.beans.AbstractDerAttr;
 import org.apache.syncope.core.persistence.beans.AbstractDerSchema;
@@ -33,8 +35,9 @@ public class MDerAttr extends AbstractDe
     @ManyToOne
     private Membership owner;
 
-    @ManyToOne(fetch = FetchType.EAGER)
-    private MDerSchema derivedSchema;
+    @Column(nullable = false)
+    @OneToOne(cascade = CascadeType.MERGE)
+    private MDerAttrTemplate template;
 
     @SuppressWarnings("unchecked")
     @Override
@@ -50,17 +53,17 @@ public class MDerAttr extends AbstractDe
         this.owner = (Membership) owner;
     }
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public <T extends AbstractDerSchema> T getDerivedSchema() {
-        return (T) derivedSchema;
+    public MDerAttrTemplate getTemplate() {
+        return template;
+    }
+
+    public void setTemplate(final MDerAttrTemplate template) {
+        this.template = template;
     }
 
+    @SuppressWarnings("unchecked")
     @Override
-    public <T extends AbstractDerSchema> void setDerivedSchema(final T derivedSchema) {
-        if (!(derivedSchema instanceof MDerSchema)) {
-            throw new ClassCastException("expected type MDerSchema, found: " + derivedSchema.getClass().getName());
-        }
-        this.derivedSchema = (MDerSchema) derivedSchema;
+    public <T extends AbstractDerSchema> T getSchema() {
+        return template == null ? null : (T) template.getSchema();
     }
 }

Added: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MDerAttrTemplate.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MDerAttrTemplate.java?rev=1531003&view=auto
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MDerAttrTemplate.java (added)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MDerAttrTemplate.java Thu Oct 10 14:37:56 2013
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.syncope.core.persistence.beans.membership;
+
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import org.apache.syncope.core.persistence.beans.AbstractAttrTemplate;
+import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
+
+@Entity
+public class MDerAttrTemplate extends AbstractAttrTemplate<MDerSchema> {
+
+    private static final long serialVersionUID = -3424574558427502145L;
+
+    @ManyToOne
+    private SyncopeRole owner;
+
+    @ManyToOne
+    @JoinColumn(name = "schema_name")
+    private MDerSchema schema;
+
+    @Override
+    public MDerSchema getSchema() {
+        return schema;
+    }
+
+    @Override
+    public void setSchema(final MDerSchema schema) {
+        this.schema = schema;
+    }
+
+    @Override
+    public SyncopeRole getOwner() {
+        return owner;
+    }
+
+    @Override
+    public void setOwner(final SyncopeRole owner) {
+        this.owner = owner;
+    }
+}

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MDerAttrTemplate.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MDerAttrTemplate.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MDerAttrTemplate.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MSchema.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MSchema.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MSchema.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MSchema.java Thu Oct 10 14:37:56 2013
@@ -20,11 +20,11 @@ package org.apache.syncope.core.persiste
 
 import javax.persistence.Cacheable;
 import javax.persistence.Entity;
-import org.apache.syncope.core.persistence.beans.AbstractSchema;
+import org.apache.syncope.core.persistence.beans.AbstractNormalSchema;
 
 @Entity
 @Cacheable
-public class MSchema extends AbstractSchema {
+public class MSchema extends AbstractNormalSchema {
 
     private static final long serialVersionUID = -8053736450044590651L;
 

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MVirAttr.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MVirAttr.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MVirAttr.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MVirAttr.java Thu Oct 10 14:37:56 2013
@@ -20,9 +20,11 @@ package org.apache.syncope.core.persiste
 
 import java.util.Collections;
 import java.util.List;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
 import javax.persistence.Entity;
-import javax.persistence.FetchType;
 import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
 import org.apache.syncope.core.persistence.beans.AbstractAttributable;
 import org.apache.syncope.core.persistence.beans.AbstractVirAttr;
 import org.apache.syncope.core.persistence.beans.AbstractVirSchema;
@@ -35,8 +37,9 @@ public class MVirAttr extends AbstractVi
     @ManyToOne
     private Membership owner;
 
-    @ManyToOne(fetch = FetchType.EAGER)
-    private MVirSchema virtualSchema;
+    @Column(nullable = false)
+    @OneToOne(cascade = CascadeType.MERGE)
+    private MVirAttrTemplate template;
 
     @SuppressWarnings("unchecked")
     @Override
@@ -53,22 +56,37 @@ public class MVirAttr extends AbstractVi
         this.owner = (Membership) owner;
     }
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public <T extends AbstractVirSchema> T getVirtualSchema() {
-        return (T) virtualSchema;
+    public MVirAttrTemplate getTemplate() {
+        return template;
+    }
+
+    public void setTemplate(final MVirAttrTemplate template) {
+        this.template = template;
     }
 
+    @SuppressWarnings("unchecked")
     @Override
-    public <T extends AbstractVirSchema> void setVirtualSchema(final T virtualSchema) {
-        if (!(virtualSchema instanceof MVirSchema)) {
-            throw new ClassCastException("expected type MVirSchema, found: " + virtualSchema.getClass().getName());
-        }
-        this.virtualSchema = (MVirSchema) virtualSchema;
+    public <T extends AbstractVirSchema> T getSchema() {
+        return template == null ? null : (T) template.getSchema();
     }
 
     @Override
     public List<String> getValues() {
         return Collections.emptyList();
     }
+
+    @Override
+    public boolean addValue(final String value) {
+        return false;
+    }
+
+    @Override
+    public boolean removeValue(final String value) {
+        return false;
+    }
+
+    @Override
+    public void setValues(final List<String> values) {
+        // do nothing
+    }
 }

Added: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MVirAttrTemplate.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MVirAttrTemplate.java?rev=1531003&view=auto
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MVirAttrTemplate.java (added)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MVirAttrTemplate.java Thu Oct 10 14:37:56 2013
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.syncope.core.persistence.beans.membership;
+
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import org.apache.syncope.core.persistence.beans.AbstractAttrTemplate;
+import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
+
+@Entity
+public class MVirAttrTemplate extends AbstractAttrTemplate<MVirSchema> {
+
+    private static final long serialVersionUID = -3424574558427502145L;
+
+    @ManyToOne
+    private SyncopeRole owner;
+
+    @ManyToOne
+    @JoinColumn(name = "schema_name")
+    private MVirSchema schema;
+
+    @Override
+    public MVirSchema getSchema() {
+        return schema;
+    }
+
+    @Override
+    public void setSchema(final MVirSchema schema) {
+        this.schema = schema;
+    }
+
+    @Override
+    public SyncopeRole getOwner() {
+        return owner;
+    }
+
+    @Override
+    public void setOwner(final SyncopeRole owner) {
+        this.owner = owner;
+    }
+}

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MVirAttrTemplate.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MVirAttrTemplate.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MVirAttrTemplate.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/Membership.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/Membership.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/Membership.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/Membership.java Thu Oct 10 14:37:56 2013
@@ -40,7 +40,7 @@ import org.apache.syncope.core.persisten
 
 @Entity
 @Table(uniqueConstraints =
-@UniqueConstraint(columnNames = {"syncopeUser_id", "syncopeRole_id"}))
+        @UniqueConstraint(columnNames = {"syncopeUser_id", "syncopeRole_id"}))
 public class Membership extends AbstractAttributable {
 
     private static final long serialVersionUID = 5030106264797289469L;
@@ -56,22 +56,22 @@ public class Membership extends Abstract
 
     @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
     @Valid
-    private List<MAttr> attributes;
+    private List<MAttr> attrs;
 
     @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
     @Valid
-    private List<MDerAttr> derivedAttributes;
+    private List<MDerAttr> derAttrs;
 
     @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
     @Valid
-    private List<MVirAttr> virtualAttributes;
+    private List<MVirAttr> virAttrs;
 
     public Membership() {
         super();
 
-        attributes = new ArrayList<MAttr>();
-        derivedAttributes = new ArrayList<MDerAttr>();
-        virtualAttributes = new ArrayList<MVirAttr>();
+        attrs = new ArrayList<MAttr>();
+        derAttrs = new ArrayList<MDerAttr>();
+        virAttrs = new ArrayList<MVirAttr>();
     }
 
     @Override
@@ -101,95 +101,132 @@ public class Membership extends Abstract
     }
 
     @Override
-    public <T extends AbstractAttr> boolean addAttribute(final T attribute) {
-        if (!(attribute instanceof MAttr)) {
-            throw new ClassCastException("attribute is expected to be typed MAttr: " + attribute.getClass().getName());
+    public <T extends AbstractAttr> boolean addAttr(final T attr) {
+        if (!(attr instanceof MAttr)) {
+            throw new ClassCastException("attribute is expected to be typed MAttr: " + attr.getClass().getName());
         }
-        return attributes.add((MAttr) attribute);
+        return attrs.add((MAttr) attr);
     }
 
     @Override
-    public <T extends AbstractAttr> boolean removeAttribute(final T attribute) {
-        if (!(attribute instanceof MAttr)) {
-            throw new ClassCastException("attribute is expected to be typed MAttr: " + attribute.getClass().getName());
+    public <T extends AbstractAttr> boolean removeAttr(final T attr) {
+        if (!(attr instanceof MAttr)) {
+            throw new ClassCastException("attribute is expected to be typed MAttr: " + attr.getClass().getName());
         }
-        return attributes.remove((MAttr) attribute);
+        return attrs.remove((MAttr) attr);
     }
 
     @Override
-    public List<? extends AbstractAttr> getAttributes() {
-        return attributes;
+    public List<? extends AbstractAttr> getAttrs() {
+        return attrs;
     }
 
     @SuppressWarnings("unchecked")
     @Override
-    public void setAttributes(final List<? extends AbstractAttr> attributes) {
-        this.attributes.clear();
-        if (attributes != null && !attributes.isEmpty()) {
-            this.attributes.addAll((List<MAttr>) attributes);
+    public void setAttrs(final List<? extends AbstractAttr> attrs) {
+        this.attrs.clear();
+        if (attrs != null && !attrs.isEmpty()) {
+            for (AbstractAttr attr : attrs) {
+                addAttr(attr);
+            }
         }
     }
 
     @Override
-    public <T extends AbstractDerAttr> boolean addDerivedAttribute(final T derAttr) {
+    public <T extends AbstractDerAttr> boolean addDerAttr(final T derAttr) {
         if (!(derAttr instanceof MDerAttr)) {
             throw new ClassCastException("attribute is expected to be typed MDerAttr: " + derAttr.getClass().getName());
         }
-        return derivedAttributes.add((MDerAttr) derAttr);
+
+        if (getSyncopeRole() != null && derAttr.getSchema() != null) {
+            MDerAttrTemplate found = null;
+            for (MDerAttrTemplate template : getSyncopeRole().findInheritedTemplates(MDerAttrTemplate.class)) {
+                if (derAttr.getSchema().equals(template.getSchema())) {
+                    found = template;
+                }
+            }
+            if (found != null) {
+                ((MDerAttr) derAttr).setTemplate(found);
+                return derAttrs.add((MDerAttr) derAttr);
+            }
+        }
+
+        LOG.warn("Attribute not added because either role was not yet set, "
+                + "schema was not specified or no template for that schema is available");
+        return false;
     }
 
     @Override
-    public <T extends AbstractDerAttr> boolean removeDerivedAttribute(final T derAttr) {
+    public <T extends AbstractDerAttr> boolean removeDerAttr(final T derAttr) {
         if (!(derAttr instanceof MDerAttr)) {
             throw new ClassCastException("attribute is expected to be typed MDerAttr: " + derAttr.getClass().getName());
         }
 
-        return derivedAttributes.remove((MDerAttr) derAttr);
+        return derAttrs.remove((MDerAttr) derAttr);
     }
 
     @Override
-    public List<? extends AbstractDerAttr> getDerivedAttributes() {
-        return derivedAttributes;
+    public List<? extends AbstractDerAttr> getDerAttrs() {
+        return derAttrs;
     }
 
     @SuppressWarnings("unchecked")
     @Override
-    public void setDerivedAttributes(final List<? extends AbstractDerAttr> derivedAttributes) {
-        this.derivedAttributes.clear();
-        if (derivedAttributes != null && !derivedAttributes.isEmpty()) {
-            this.derivedAttributes.addAll((List<MDerAttr>) derivedAttributes);
+    public void setDerAttrs(final List<? extends AbstractDerAttr> derAttrs) {
+        this.derAttrs.clear();
+        if (derAttrs != null && !derAttrs.isEmpty()) {
+            for (AbstractDerAttr attr : derAttrs) {
+                addDerAttr(attr);
+            }
         }
     }
 
     @Override
-    public <T extends AbstractVirAttr> boolean addVirtualAttribute(final T virAttr) {
+    public <T extends AbstractVirAttr> boolean addVirAttr(final T virAttr) {
         if (!(virAttr instanceof MVirAttr)) {
             throw new ClassCastException("attribute is expected to be typed MVirAttr: " + virAttr.getClass().getName());
         }
 
-        return virtualAttributes.add((MVirAttr) virAttr);
+        if (getSyncopeRole() != null && virAttr.getSchema() != null) {
+            MVirAttrTemplate found = null;
+            for (MVirAttrTemplate template : getSyncopeRole().findInheritedTemplates(MVirAttrTemplate.class)) {
+                if (virAttr.getSchema().equals(template.getSchema())) {
+                    found = template;
+                }
+            }
+            if (found != null) {
+                ((MVirAttr) virAttr).setTemplate(found);
+                return virAttrs.add((MVirAttr) virAttr);
+            }
+        }
+
+        LOG.warn("Attribute not added because either "
+                + "schema was not specified or no template for that schema is available");
+        return false;
     }
 
     @Override
-    public <T extends AbstractVirAttr> boolean removeVirtualAttribute(final T virAttr) {
+    public <T extends AbstractVirAttr> boolean removeVirAttr(final T virAttr) {
         if (!(virAttr instanceof MVirAttr)) {
             throw new ClassCastException("attribute is expected to be typed MVirAttr: " + virAttr.getClass().getName());
         }
 
-        return virtualAttributes.remove((MVirAttr) virAttr);
+        return virAttrs.remove((MVirAttr) virAttr);
     }
 
     @Override
-    public List<? extends AbstractVirAttr> getVirtualAttributes() {
-        return virtualAttributes;
+    public List<? extends AbstractVirAttr> getVirAttrs() {
+        return virAttrs;
     }
 
     @SuppressWarnings("unchecked")
     @Override
-    public void setVirtualAttributes(final List<? extends AbstractVirAttr> virtualAttributes) {
-        this.virtualAttributes.clear();
-        if (virtualAttributes != null && !virtualAttributes.isEmpty()) {
-            this.virtualAttributes.addAll((List<MVirAttr>) virtualAttributes);
+    public void setVirAttrs(final List<? extends AbstractVirAttr> virAttrs) {
+        this.virAttrs.clear();
+        if (virAttrs != null && !virAttrs.isEmpty()) {
+            for (AbstractVirAttr attr : virAttrs) {
+                addVirAttr(attr);
+            }
         }
     }
 

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttr.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttr.java?rev=1531003&r1=1531002&r2=1531003&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttr.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttr.java Thu Oct 10 14:37:56 2013
@@ -21,10 +21,10 @@ package org.apache.syncope.core.persiste
 import java.util.ArrayList;
 import java.util.List;
 import javax.persistence.CascadeType;
+import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.Id;
-import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
@@ -32,7 +32,7 @@ import javax.validation.Valid;
 import org.apache.syncope.core.persistence.beans.AbstractAttr;
 import org.apache.syncope.core.persistence.beans.AbstractAttrValue;
 import org.apache.syncope.core.persistence.beans.AbstractAttributable;
-import org.apache.syncope.core.persistence.beans.AbstractSchema;
+import org.apache.syncope.core.persistence.beans.AbstractNormalSchema;
 
 @Entity
 public class RAttr extends AbstractAttr {
@@ -45,9 +45,9 @@ public class RAttr extends AbstractAttr 
     @ManyToOne(fetch = FetchType.EAGER)
     private SyncopeRole owner;
 
-    @ManyToOne(fetch = FetchType.EAGER)
-    @JoinColumn(name = "schema_name")
-    private RSchema schema;
+    @Column(nullable = false)
+    @OneToOne(cascade = CascadeType.MERGE)
+    private RAttrTemplate template;
 
     @OneToMany(cascade = CascadeType.MERGE, orphanRemoval = true, mappedBy = "attribute")
     @Valid
@@ -81,18 +81,18 @@ public class RAttr extends AbstractAttr 
         this.owner = (SyncopeRole) owner;
     }
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public <T extends AbstractSchema> T getSchema() {
-        return (T) schema;
+    public RAttrTemplate getTemplate() {
+        return template;
     }
 
+    public void setTemplate(final RAttrTemplate template) {
+        this.template = template;
+    }
+
+    @SuppressWarnings("unchecked")
     @Override
-    public <T extends AbstractSchema> void setSchema(final T schema) {
-        if (!(schema instanceof RSchema)) {
-            throw new ClassCastException("schema is expected to be typed RSchema: " + schema.getClass().getName());
-        }
-        this.schema = (RSchema) schema;
+    public <T extends AbstractNormalSchema> T getSchema() {
+        return template == null ? null : (T) template.getSchema();
     }
 
     @Override

Added: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttrTemplate.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttrTemplate.java?rev=1531003&view=auto
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttrTemplate.java (added)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttrTemplate.java Thu Oct 10 14:37:56 2013
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.syncope.core.persistence.beans.role;
+
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import org.apache.syncope.core.persistence.beans.AbstractAttrTemplate;
+
+@Entity
+public class RAttrTemplate extends AbstractAttrTemplate<RSchema> {
+
+    private static final long serialVersionUID = -3424574558427502145L;
+
+    @ManyToOne
+    private SyncopeRole owner;
+
+    @ManyToOne
+    @JoinColumn(name = "schema_name")
+    private RSchema schema;
+
+    @Override
+    public RSchema getSchema() {
+        return schema;
+    }
+
+    @Override
+    public void setSchema(final RSchema schema) {
+        this.schema = schema;
+    }
+
+    @Override
+    public SyncopeRole getOwner() {
+        return owner;
+    }
+
+    @Override
+    public void setOwner(final SyncopeRole owner) {
+        this.owner = owner;
+    }
+}