Added WildcardPermission default,no-arg constructor (protected - not public) for use by subclasses.  Added new 'DomainPermission' subclass for those that wish to use type-safe permissions (work in progress)

git-svn-id: https://svn.apache.org/repos/asf/incubator/jsecurity/trunk@767232 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/core/src/main/java/org/apache/ki/authz/permission/DomainPermission.java b/core/src/main/java/org/apache/ki/authz/permission/DomainPermission.java
new file mode 100644
index 0000000..885f5fd
--- /dev/null
+++ b/core/src/main/java/org/apache/ki/authz/permission/DomainPermission.java
@@ -0,0 +1,85 @@
+package org.apache.ki.authz.permission;

+

+import org.apache.ki.util.StringUtils;

+

+/**

+ * Provides a base Permission class from which type-safe/domain-specific subclasses may extend.  Can be used

+ * as a base class for JPA/Hibernate persisted permissions that wish to store the parts of the permission string

+ * in separate columns (e.g. 'domain', 'actions' and 'targets' columns), which can be used in querying

+ * strategies.

+ *

+ * @author Les Hazlewood

+ * @since 1.0

+ */

+public abstract class DomainPermission extends WildcardPermission {

+

+    private String domain;

+    private String actions;

+    private String targets;

+

+    /** Creates a domain permission with *all* actions for *all* targets; */

+    public DomainPermission() {

+        setParts(getDomain(getClass()), null, null);

+    }

+

+    public DomainPermission(String actions) {

+        setParts(getDomain(getClass()), actions, null);

+    }

+

+    public DomainPermission(String actions, String targets) {

+        setParts(getDomain(getClass()), actions, targets);

+    }

+

+    protected void setParts(String domain, String actions, String targets) {

+        if (!StringUtils.hasText(domain)) {

+            throw new IllegalArgumentException("domain argument cannot be null or empty.");

+        }

+        StringBuilder sb = new StringBuilder(domain);

+

+        if (!StringUtils.hasText(actions)) {

+            if (StringUtils.hasText(targets)) {

+                sb.append(PART_DIVIDER_TOKEN).append(WILDCARD_TOKEN);

+            }

+        } else {

+            sb.append(PART_DIVIDER_TOKEN).append(actions);

+        }

+        if (targets != null) {

+            sb.append(PART_DIVIDER_TOKEN).append(targets);

+        }

+        setParts(sb.toString());

+    }

+

+    protected String getDomain(Class<? extends DomainPermission> clazz) {

+        String domain = clazz.getSimpleName().toLowerCase();

+        //strip any trailing 'permission' text from the name (as all subclasses should have been named):

+        int index = domain.lastIndexOf("permission");

+        if (index != -1) {

+            domain = domain.substring(0, index);

+        }

+        return domain;

+    }

+

+    public String getDomain() {

+        return domain;

+    }

+

+    protected void setDomain(String domain) {

+        this.domain = domain;

+    }

+

+    public String getActions() {

+        return actions;

+    }

+

+    protected void setActions(String actions) {

+        this.actions = actions;

+    }

+

+    public String getTargets() {

+        return targets;

+    }

+

+    protected void setTargets(String targets) {

+        this.targets = targets;

+    }

+}

diff --git a/core/src/main/java/org/apache/ki/authz/permission/WildcardPermission.java b/core/src/main/java/org/apache/ki/authz/permission/WildcardPermission.java
index 52e61d7..e25a1bf 100644
--- a/core/src/main/java/org/apache/ki/authz/permission/WildcardPermission.java
+++ b/core/src/main/java/org/apache/ki/authz/permission/WildcardPermission.java
@@ -125,6 +125,18 @@
     /*--------------------------------------------
     |         C O N S T R U C T O R S           |
     ============================================*/
+    /**
+     * Default no-arg constructor for subclasses only - end-user developers instantiating Permission instances must
+     * provide a wildcard string at a minimum, since Permission instances are immutable once instantiated.
+     * <p/>
+     * Note that the WildcardPermission class is very robust and typically subclasses are not necessary unless you
+     * wish to create type-safe Permission objects that would be used in your application, such as perhaps a
+     * {@code UserPermission}, {@code SystemPermission}, {@code PrinterPermission}, etc.  If you want such type-safe
+     * permission usage, consider subclassing the {@link DomainPermission DomainPermission} class for your needs.
+     */
+    protected WildcardPermission() {
+    }
+
     public WildcardPermission(String wildcardString) {
         this(wildcardString, DEFAULT_CASE_SENSITIVE);
     }
@@ -149,15 +161,12 @@
         this.parts = new ArrayList<Set<String>>();
         for (String part : parts) {
             Set<String> subparts = CollectionUtils.asSet(part.split(SUBPART_DIVIDER_TOKEN));
-
             if (!caseSensitive) {
                 subparts = lowercase(subparts);
             }
-
             if (subparts.isEmpty()) {
                 throw new IllegalArgumentException("Wildcard string cannot contain parts with only dividers. Make sure permission strings are properly formatted.");
             }
-
             this.parts.add(subparts);
         }
 
@@ -197,22 +206,17 @@
 
         int i = 0;
         for (Set<String> otherPart : otherParts) {
-
             // If this permission has less parts than the other permission, everything after the number of parts contained
             // in this permission is automatically implied, so return true
             if (getParts().size() - 1 < i) {
                 return true;
-
             } else {
                 Set<String> part = getParts().get(i);
-
                 if (!part.contains(WILDCARD_TOKEN) && !part.containsAll(otherPart)) {
                     return false;
                 }
-
                 i++;
             }
-
         }
 
         // If this permission has more parts than the other parts, only imply it if all of the other parts are wildcards