001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.isis.extensions.secman.api.permission; 020 021import java.io.Serializable; 022import java.util.Comparator; 023import java.util.List; 024 025import org.apache.isis.applib.annotation.Programmatic; 026import org.apache.isis.applib.util.ObjectContracts; 027import org.apache.isis.applib.util.ToString; 028import org.apache.isis.core.metamodel.services.appfeat.ApplicationFeatureId; 029 030/** 031 * A serializable value object representing an (anonymized) 032 * {@link org.apache.isis.extensions.security.manager.jdo.dom.permission.ApplicationPermission}. 033 * 034 * <p> 035 * Intended for value type arithmetic and also for caching. No user/role information is held because that information 036 * is not required to perform the arithmetic. 037 * </p> 038 */ 039public class ApplicationPermissionValue implements Comparable<ApplicationPermissionValue>, Serializable { 040 041 private static final long serialVersionUID = 1L; 042 043 // -- constructor 044 public ApplicationPermissionValue( 045 final ApplicationFeatureId featureId, 046 final ApplicationPermissionRule rule, 047 final ApplicationPermissionMode mode) { 048 this.featureId = featureId; 049 this.rule = rule; 050 this.mode = mode; 051 } 052 053 054 // -- featureId 055 private final ApplicationFeatureId featureId; 056 @Programmatic 057 public ApplicationFeatureId getFeatureId() { 058 return featureId; 059 } 060 061 062 // -- rule 063 private final ApplicationPermissionRule rule; 064 @Programmatic 065 public ApplicationPermissionRule getRule() { 066 return rule; 067 } 068 069 070 // -- mode 071 private final ApplicationPermissionMode mode; 072 @Programmatic 073 public ApplicationPermissionMode getMode() { 074 return mode; 075 } 076 077 078 // -- implies, refutes 079 @Programmatic 080 public boolean implies(final ApplicationFeatureId featureId, final ApplicationPermissionMode mode) { 081 if(getRule() != ApplicationPermissionRule.ALLOW) { 082 // only allow rules can imply 083 return false; 084 } 085 if(getMode() == ApplicationPermissionMode.VIEWING && mode == ApplicationPermissionMode.CHANGING) { 086 // an "allow viewing" permission does not imply ability to change 087 return false; 088 } 089 090 // determine if this permission is on the path (ie the feature or one of its parents) 091 return onPathOf(featureId); 092 } 093 094 @Programmatic 095 public boolean refutes(final ApplicationFeatureId featureId, final ApplicationPermissionMode mode) { 096 if(getRule() != ApplicationPermissionRule.VETO) { 097 // only veto rules can refute 098 return false; 099 } 100 if(getMode() == ApplicationPermissionMode.CHANGING && mode == ApplicationPermissionMode.VIEWING) { 101 // an "veto changing" permission does not refute ability to view 102 return false; 103 } 104 // determine if this permission is on the path (ie the feature or one of its parents) 105 return onPathOf(featureId); 106 } 107 108 private boolean onPathOf(final ApplicationFeatureId featureId) { 109 110 final List<ApplicationFeatureId> pathIds = featureId.getPathIds(); 111 for (final ApplicationFeatureId pathId : pathIds) { 112 if(getFeatureId().equals(pathId)) { 113 return true; 114 } 115 } 116 117 return false; 118 } 119 120 121 122 // -- Comparators 123 public static final class Comparators { 124 private Comparators(){} 125 public static Comparator<ApplicationPermissionValue> natural() { 126 return new ApplicationPermissionValueComparator(); 127 } 128 129 static class ApplicationPermissionValueComparator implements Comparator<ApplicationPermissionValue>, Serializable { 130 private static final long serialVersionUID = 1L; 131 132 @Override 133 public int compare(final ApplicationPermissionValue o1, final ApplicationPermissionValue o2) { 134 return o1.compareTo(o2); 135 } 136 } 137 } 138 139 140 // -- CONTRACT 141 142 private static final Comparator<ApplicationPermissionValue> comparator = 143 Comparator.comparing(ApplicationPermissionValue::getRule) 144 .thenComparing(ApplicationPermissionValue::getMode) 145 .thenComparing(ApplicationPermissionValue::getFeatureId); 146 147 private static final ToString<ApplicationPermissionValue> toString = 148 ObjectContracts.toString("name", ApplicationPermissionValue::getRule) 149 .thenToString("mode", ApplicationPermissionValue::getMode) 150 .thenToString("featureId", ApplicationPermissionValue::getFeatureId); 151 152 153 @Override 154 public int compareTo(final ApplicationPermissionValue o) { 155 return comparator.compare(this, o); 156 } 157 158 @Override 159 public boolean equals(final Object o) { 160 // not using because trying to be efficient. Premature optimization? 161 // return ObjectContracts.equals(this, obj, propertyNames); 162 if (this == o) return true; 163 if (o == null || getClass() != o.getClass()) return false; 164 165 final ApplicationPermissionValue that = (ApplicationPermissionValue) o; 166 167 if (featureId != null ? !featureId.equals(that.featureId) : that.featureId != null) return false; 168 if (mode != that.mode) return false; 169 if (rule != that.rule) return false; 170 171 return true; 172 } 173 174 @Override 175 public int hashCode() { 176 // not using because trying to be efficient. Premature optimization? 177 // return ObjectContracts.hashCode(this, propertyNames); 178 int result = featureId != null ? featureId.hashCode() : 0; 179 result = 31 * result + (rule != null ? rule.hashCode() : 0); 180 result = 31 * result + (mode != null ? mode.hashCode() : 0); 181 return result; 182 } 183 184 @Override 185 public String toString() { 186 return toString.toString(this); 187 } 188 189 190}