blob: ea94cd3c4cb77f5ab1216ecf8874b1bc6f559f99 [file] [log] [blame]
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Source code</title>
<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
</head>
<body>
<main role="main">
<div class="sourceContainer">
<pre><span class="sourceLineNo">001</span><a id="line.1">/*</a>
<span class="sourceLineNo">002</span><a id="line.2"> * Licensed to the Apache Software Foundation (ASF) under one</a>
<span class="sourceLineNo">003</span><a id="line.3"> * or more contributor license agreements. See the NOTICE file</a>
<span class="sourceLineNo">004</span><a id="line.4"> * distributed with this work for additional information</a>
<span class="sourceLineNo">005</span><a id="line.5"> * regarding copyright ownership. The ASF licenses this file</a>
<span class="sourceLineNo">006</span><a id="line.6"> * to you under the Apache License, Version 2.0 (the</a>
<span class="sourceLineNo">007</span><a id="line.7"> * "License"); you may not use this file except in compliance</a>
<span class="sourceLineNo">008</span><a id="line.8"> * with the License. You may obtain a copy of the License at</a>
<span class="sourceLineNo">009</span><a id="line.9"> *</a>
<span class="sourceLineNo">010</span><a id="line.10"> * http://www.apache.org/licenses/LICENSE-2.0</a>
<span class="sourceLineNo">011</span><a id="line.11"> *</a>
<span class="sourceLineNo">012</span><a id="line.12"> * Unless required by applicable law or agreed to in writing,</a>
<span class="sourceLineNo">013</span><a id="line.13"> * software distributed under the License is distributed on an</a>
<span class="sourceLineNo">014</span><a id="line.14"> * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY</a>
<span class="sourceLineNo">015</span><a id="line.15"> * KIND, either express or implied. See the License for the</a>
<span class="sourceLineNo">016</span><a id="line.16"> * specific language governing permissions and limitations</a>
<span class="sourceLineNo">017</span><a id="line.17"> * under the License.</a>
<span class="sourceLineNo">018</span><a id="line.18"> */</a>
<span class="sourceLineNo">019</span><a id="line.19">package org.apache.shiro.authz.permission;</a>
<span class="sourceLineNo">020</span><a id="line.20"></a>
<span class="sourceLineNo">021</span><a id="line.21">import org.apache.shiro.authz.Permission;</a>
<span class="sourceLineNo">022</span><a id="line.22">import org.apache.shiro.util.CollectionUtils;</a>
<span class="sourceLineNo">023</span><a id="line.23">import org.apache.shiro.util.StringUtils;</a>
<span class="sourceLineNo">024</span><a id="line.24"></a>
<span class="sourceLineNo">025</span><a id="line.25">import java.io.Serializable;</a>
<span class="sourceLineNo">026</span><a id="line.26">import java.util.ArrayList;</a>
<span class="sourceLineNo">027</span><a id="line.27">import java.util.Iterator;</a>
<span class="sourceLineNo">028</span><a id="line.28">import java.util.LinkedHashSet;</a>
<span class="sourceLineNo">029</span><a id="line.29">import java.util.List;</a>
<span class="sourceLineNo">030</span><a id="line.30">import java.util.Set;</a>
<span class="sourceLineNo">031</span><a id="line.31"></a>
<span class="sourceLineNo">032</span><a id="line.32">/**</a>
<span class="sourceLineNo">033</span><a id="line.33"> * A &lt;code&gt;WildcardPermission&lt;/code&gt; is a very flexible permission construct supporting multiple levels of</a>
<span class="sourceLineNo">034</span><a id="line.34"> * permission matching. However, most people will probably follow some standard conventions as explained below.</a>
<span class="sourceLineNo">035</span><a id="line.35"> * &lt;p/&gt;</a>
<span class="sourceLineNo">036</span><a id="line.36"> * &lt;h3&gt;Simple Usage&lt;/h3&gt;</a>
<span class="sourceLineNo">037</span><a id="line.37"> * &lt;p/&gt;</a>
<span class="sourceLineNo">038</span><a id="line.38"> * In the simplest form, &lt;code&gt;WildcardPermission&lt;/code&gt; can be used as a simple permission string. You could grant a</a>
<span class="sourceLineNo">039</span><a id="line.39"> * user an &amp;quot;editNewsletter&amp;quot; permission and then check to see if the user has the editNewsletter</a>
<span class="sourceLineNo">040</span><a id="line.40"> * permission by calling</a>
<span class="sourceLineNo">041</span><a id="line.41"> * &lt;p/&gt;</a>
<span class="sourceLineNo">042</span><a id="line.42"> * &lt;code&gt;subject.isPermitted(&amp;quot;editNewsletter&amp;quot;)&lt;/code&gt;</a>
<span class="sourceLineNo">043</span><a id="line.43"> * &lt;p/&gt;</a>
<span class="sourceLineNo">044</span><a id="line.44"> * This is (mostly) equivalent to</a>
<span class="sourceLineNo">045</span><a id="line.45"> * &lt;p/&gt;</a>
<span class="sourceLineNo">046</span><a id="line.46"> * &lt;code&gt;subject.isPermitted( new WildcardPermission(&amp;quot;editNewsletter&amp;quot;) )&lt;/code&gt;</a>
<span class="sourceLineNo">047</span><a id="line.47"> * &lt;p/&gt;</a>
<span class="sourceLineNo">048</span><a id="line.48"> * but more on that later.</a>
<span class="sourceLineNo">049</span><a id="line.49"> * &lt;p/&gt;</a>
<span class="sourceLineNo">050</span><a id="line.50"> * The simple permission string may work for simple applications, but it requires you to have permissions like</a>
<span class="sourceLineNo">051</span><a id="line.51"> * &lt;code&gt;&amp;quot;viewNewsletter&amp;quot;&lt;/code&gt;, &lt;code&gt;&amp;quot;deleteNewsletter&amp;quot;&lt;/code&gt;,</a>
<span class="sourceLineNo">052</span><a id="line.52"> * &lt;code&gt;&amp;quot;createNewsletter&amp;quot;&lt;/code&gt;, etc. You can also grant a user &lt;code&gt;&amp;quot;*&amp;quot;&lt;/code&gt; permissions</a>
<span class="sourceLineNo">053</span><a id="line.53"> * using the wildcard character (giving this class its name), which means they have &lt;em&gt;all&lt;/em&gt; permissions. But</a>
<span class="sourceLineNo">054</span><a id="line.54"> * using this approach there's no way to just say a user has &amp;quot;all newsletter permissions&amp;quot;.</a>
<span class="sourceLineNo">055</span><a id="line.55"> * &lt;p/&gt;</a>
<span class="sourceLineNo">056</span><a id="line.56"> * For this reason, &lt;code&gt;WildcardPermission&lt;/code&gt; supports multiple &lt;em&gt;levels&lt;/em&gt; of permissioning.</a>
<span class="sourceLineNo">057</span><a id="line.57"> * &lt;p/&gt;</a>
<span class="sourceLineNo">058</span><a id="line.58"> * &lt;h3&gt;Multiple Levels&lt;/h3&gt;</a>
<span class="sourceLineNo">059</span><a id="line.59"> * &lt;p/&gt;</a>
<span class="sourceLineNo">060</span><a id="line.60"> * WildcardPermission&lt;/code&gt; also supports the concept of multiple &lt;em&gt;levels&lt;/em&gt;. For example, you could</a>
<span class="sourceLineNo">061</span><a id="line.61"> * restructure the previous simple example by granting a user the permission &lt;code&gt;&amp;quot;newsletter:edit&amp;quot;&lt;/code&gt;.</a>
<span class="sourceLineNo">062</span><a id="line.62"> * The colon in this example is a special character used by the &lt;code&gt;WildcardPermission&lt;/code&gt; that delimits the</a>
<span class="sourceLineNo">063</span><a id="line.63"> * next token in the permission.</a>
<span class="sourceLineNo">064</span><a id="line.64"> * &lt;p/&gt;</a>
<span class="sourceLineNo">065</span><a id="line.65"> * In this example, the first token is the &lt;em&gt;domain&lt;/em&gt; that is being operated on</a>
<span class="sourceLineNo">066</span><a id="line.66"> * and the second token is the &lt;em&gt;action&lt;/em&gt; being performed. Each level can contain multiple values. So you</a>
<span class="sourceLineNo">067</span><a id="line.67"> * could simply grant a user the permission &lt;code&gt;&amp;quot;newsletter:view,edit,create&amp;quot;&lt;/code&gt; which gives them</a>
<span class="sourceLineNo">068</span><a id="line.68"> * access to perform &lt;code&gt;view&lt;/code&gt;, &lt;code&gt;edit&lt;/code&gt;, and &lt;code&gt;create&lt;/code&gt; actions in the &lt;code&gt;newsletter&lt;/code&gt;</a>
<span class="sourceLineNo">069</span><a id="line.69"> * &lt;em&gt;domain&lt;/em&gt;. Then you could check to see if the user has the &lt;code&gt;&amp;quot;newsletter:create&amp;quot;&lt;/code&gt;</a>
<span class="sourceLineNo">070</span><a id="line.70"> * permission by calling</a>
<span class="sourceLineNo">071</span><a id="line.71"> * &lt;p/&gt;</a>
<span class="sourceLineNo">072</span><a id="line.72"> * &lt;code&gt;subject.isPermitted(&amp;quot;newsletter:create&amp;quot;)&lt;/code&gt;</a>
<span class="sourceLineNo">073</span><a id="line.73"> * &lt;p/&gt;</a>
<span class="sourceLineNo">074</span><a id="line.74"> * (which would return true).</a>
<span class="sourceLineNo">075</span><a id="line.75"> * &lt;p/&gt;</a>
<span class="sourceLineNo">076</span><a id="line.76"> * In addition to granting multiple permissions via a single string, you can grant all permission for a particular</a>
<span class="sourceLineNo">077</span><a id="line.77"> * level. So if you wanted to grant a user all actions in the &lt;code&gt;newsletter&lt;/code&gt; domain, you could simply give</a>
<span class="sourceLineNo">078</span><a id="line.78"> * them &lt;code&gt;&amp;quot;newsletter:*&amp;quot;&lt;/code&gt;. Now, any permission check for &lt;code&gt;&amp;quot;newsletter:XXX&amp;quot;&lt;/code&gt;</a>
<span class="sourceLineNo">079</span><a id="line.79"> * will return &lt;code&gt;true&lt;/code&gt;. It is also possible to use the wildcard token at the domain level (or both): so you</a>
<span class="sourceLineNo">080</span><a id="line.80"> * could grant a user the &lt;code&gt;&amp;quot;view&amp;quot;&lt;/code&gt; action across all domains &lt;code&gt;&amp;quot;*:view&amp;quot;&lt;/code&gt;.</a>
<span class="sourceLineNo">081</span><a id="line.81"> * &lt;p/&gt;</a>
<span class="sourceLineNo">082</span><a id="line.82"> * &lt;h3&gt;Instance-level Access Control&lt;/h3&gt;</a>
<span class="sourceLineNo">083</span><a id="line.83"> * &lt;p/&gt;</a>
<span class="sourceLineNo">084</span><a id="line.84"> * Another common usage of the &lt;code&gt;WildcardPermission&lt;/code&gt; is to model instance-level Access Control Lists.</a>
<span class="sourceLineNo">085</span><a id="line.85"> * In this scenario you use three tokens - the first is the &lt;em&gt;domain&lt;/em&gt;, the second is the &lt;em&gt;action&lt;/em&gt;, and</a>
<span class="sourceLineNo">086</span><a id="line.86"> * the third is the &lt;em&gt;instance&lt;/em&gt; you are acting on.</a>
<span class="sourceLineNo">087</span><a id="line.87"> * &lt;p/&gt;</a>
<span class="sourceLineNo">088</span><a id="line.88"> * So for example you could grant a user &lt;code&gt;&amp;quot;newsletter:edit:12,13,18&amp;quot;&lt;/code&gt;. In this example, assume</a>
<span class="sourceLineNo">089</span><a id="line.89"> * that the third token is the system's ID of the newsletter. That would allow the user to edit newsletters</a>
<span class="sourceLineNo">090</span><a id="line.90"> * &lt;code&gt;12&lt;/code&gt;, &lt;code&gt;13&lt;/code&gt;, and &lt;code&gt;18&lt;/code&gt;. This is an extremely powerful way to express permissions,</a>
<span class="sourceLineNo">091</span><a id="line.91"> * since you can now say things like &lt;code&gt;&amp;quot;newsletter:*:13&amp;quot;&lt;/code&gt; (grant a user all actions for newsletter</a>
<span class="sourceLineNo">092</span><a id="line.92"> * &lt;code&gt;13&lt;/code&gt;), &lt;code&gt;&amp;quot;newsletter:view,create,edit:*&amp;quot;&lt;/code&gt; (allow the user to</a>
<span class="sourceLineNo">093</span><a id="line.93"> * &lt;code&gt;view&lt;/code&gt;, &lt;code&gt;create&lt;/code&gt;, or &lt;code&gt;edit&lt;/code&gt; &lt;em&gt;any&lt;/em&gt; newsletter), or</a>
<span class="sourceLineNo">094</span><a id="line.94"> * &lt;code&gt;&amp;quot;newsletter:*:*&lt;/code&gt; (allow the user to perform &lt;em&gt;any&lt;/em&gt; action on &lt;em&gt;any&lt;/em&gt; newsletter).</a>
<span class="sourceLineNo">095</span><a id="line.95"> * &lt;p/&gt;</a>
<span class="sourceLineNo">096</span><a id="line.96"> * To perform checks against these instance-level permissions, the application should include the instance ID in the</a>
<span class="sourceLineNo">097</span><a id="line.97"> * permission check like so:</a>
<span class="sourceLineNo">098</span><a id="line.98"> * &lt;p/&gt;</a>
<span class="sourceLineNo">099</span><a id="line.99"> * &lt;code&gt;subject.isPermitted( &amp;quot;newsletter:edit:13&amp;quot; )&lt;/code&gt;</a>
<span class="sourceLineNo">100</span><a id="line.100"> * &lt;p/&gt;</a>
<span class="sourceLineNo">101</span><a id="line.101"> * There is no limit to the number of tokens that can be used, so it is up to your imagination in terms of ways that</a>
<span class="sourceLineNo">102</span><a id="line.102"> * this could be used in your application. However, the Shiro team likes to standardize some common usages shown</a>
<span class="sourceLineNo">103</span><a id="line.103"> * above to help people get started and provide consistency in the Shiro community.</a>
<span class="sourceLineNo">104</span><a id="line.104"> *</a>
<span class="sourceLineNo">105</span><a id="line.105"> * @since 0.9</a>
<span class="sourceLineNo">106</span><a id="line.106"> */</a>
<span class="sourceLineNo">107</span><a id="line.107">public class WildcardPermission implements Permission, Serializable {</a>
<span class="sourceLineNo">108</span><a id="line.108"></a>
<span class="sourceLineNo">109</span><a id="line.109"> //TODO - JavaDoc methods</a>
<span class="sourceLineNo">110</span><a id="line.110"></a>
<span class="sourceLineNo">111</span><a id="line.111"> /*--------------------------------------------</a>
<span class="sourceLineNo">112</span><a id="line.112"> | C O N S T A N T S |</a>
<span class="sourceLineNo">113</span><a id="line.113"> ============================================*/</a>
<span class="sourceLineNo">114</span><a id="line.114"> protected static final String WILDCARD_TOKEN = "*";</a>
<span class="sourceLineNo">115</span><a id="line.115"> protected static final String PART_DIVIDER_TOKEN = ":";</a>
<span class="sourceLineNo">116</span><a id="line.116"> protected static final String SUBPART_DIVIDER_TOKEN = ",";</a>
<span class="sourceLineNo">117</span><a id="line.117"> protected static final boolean DEFAULT_CASE_SENSITIVE = false;</a>
<span class="sourceLineNo">118</span><a id="line.118"></a>
<span class="sourceLineNo">119</span><a id="line.119"> /*--------------------------------------------</a>
<span class="sourceLineNo">120</span><a id="line.120"> | I N S T A N C E V A R I A B L E S |</a>
<span class="sourceLineNo">121</span><a id="line.121"> ============================================*/</a>
<span class="sourceLineNo">122</span><a id="line.122"> private List&lt;Set&lt;String&gt;&gt; parts;</a>
<span class="sourceLineNo">123</span><a id="line.123"></a>
<span class="sourceLineNo">124</span><a id="line.124"> /*--------------------------------------------</a>
<span class="sourceLineNo">125</span><a id="line.125"> | C O N S T R U C T O R S |</a>
<span class="sourceLineNo">126</span><a id="line.126"> ============================================*/</a>
<span class="sourceLineNo">127</span><a id="line.127"> /**</a>
<span class="sourceLineNo">128</span><a id="line.128"> * Default no-arg constructor for subclasses only - end-user developers instantiating Permission instances must</a>
<span class="sourceLineNo">129</span><a id="line.129"> * provide a wildcard string at a minimum, since Permission instances are immutable once instantiated.</a>
<span class="sourceLineNo">130</span><a id="line.130"> * &lt;p/&gt;</a>
<span class="sourceLineNo">131</span><a id="line.131"> * Note that the WildcardPermission class is very robust and typically subclasses are not necessary unless you</a>
<span class="sourceLineNo">132</span><a id="line.132"> * wish to create type-safe Permission objects that would be used in your application, such as perhaps a</a>
<span class="sourceLineNo">133</span><a id="line.133"> * {@code UserPermission}, {@code SystemPermission}, {@code PrinterPermission}, etc. If you want such type-safe</a>
<span class="sourceLineNo">134</span><a id="line.134"> * permission usage, consider subclassing the {@link DomainPermission DomainPermission} class for your needs.</a>
<span class="sourceLineNo">135</span><a id="line.135"> */</a>
<span class="sourceLineNo">136</span><a id="line.136"> protected WildcardPermission() {</a>
<span class="sourceLineNo">137</span><a id="line.137"> }</a>
<span class="sourceLineNo">138</span><a id="line.138"></a>
<span class="sourceLineNo">139</span><a id="line.139"> public WildcardPermission(String wildcardString) {</a>
<span class="sourceLineNo">140</span><a id="line.140"> this(wildcardString, DEFAULT_CASE_SENSITIVE);</a>
<span class="sourceLineNo">141</span><a id="line.141"> }</a>
<span class="sourceLineNo">142</span><a id="line.142"></a>
<span class="sourceLineNo">143</span><a id="line.143"> public WildcardPermission(String wildcardString, boolean caseSensitive) {</a>
<span class="sourceLineNo">144</span><a id="line.144"> setParts(wildcardString, caseSensitive);</a>
<span class="sourceLineNo">145</span><a id="line.145"> }</a>
<span class="sourceLineNo">146</span><a id="line.146"></a>
<span class="sourceLineNo">147</span><a id="line.147"> protected void setParts(String wildcardString) {</a>
<span class="sourceLineNo">148</span><a id="line.148"> setParts(wildcardString, DEFAULT_CASE_SENSITIVE);</a>
<span class="sourceLineNo">149</span><a id="line.149"> }</a>
<span class="sourceLineNo">150</span><a id="line.150"></a>
<span class="sourceLineNo">151</span><a id="line.151"> protected void setParts(String wildcardString, boolean caseSensitive) {</a>
<span class="sourceLineNo">152</span><a id="line.152"> wildcardString = StringUtils.clean(wildcardString);</a>
<span class="sourceLineNo">153</span><a id="line.153"></a>
<span class="sourceLineNo">154</span><a id="line.154"> if (wildcardString == null || wildcardString.isEmpty()) {</a>
<span class="sourceLineNo">155</span><a id="line.155"> throw new IllegalArgumentException("Wildcard string cannot be null or empty. Make sure permission strings are properly formatted.");</a>
<span class="sourceLineNo">156</span><a id="line.156"> }</a>
<span class="sourceLineNo">157</span><a id="line.157"></a>
<span class="sourceLineNo">158</span><a id="line.158"> if (!caseSensitive) {</a>
<span class="sourceLineNo">159</span><a id="line.159"> wildcardString = wildcardString.toLowerCase();</a>
<span class="sourceLineNo">160</span><a id="line.160"> }</a>
<span class="sourceLineNo">161</span><a id="line.161"></a>
<span class="sourceLineNo">162</span><a id="line.162"> List&lt;String&gt; parts = CollectionUtils.asList(wildcardString.split(PART_DIVIDER_TOKEN));</a>
<span class="sourceLineNo">163</span><a id="line.163"></a>
<span class="sourceLineNo">164</span><a id="line.164"> this.parts = new ArrayList&lt;Set&lt;String&gt;&gt;();</a>
<span class="sourceLineNo">165</span><a id="line.165"> for (String part : parts) {</a>
<span class="sourceLineNo">166</span><a id="line.166"> Set&lt;String&gt; subparts = CollectionUtils.asSet(part.split(SUBPART_DIVIDER_TOKEN));</a>
<span class="sourceLineNo">167</span><a id="line.167"></a>
<span class="sourceLineNo">168</span><a id="line.168"> if (subparts.isEmpty()) {</a>
<span class="sourceLineNo">169</span><a id="line.169"> throw new IllegalArgumentException("Wildcard string cannot contain parts with only dividers. Make sure permission strings are properly formatted.");</a>
<span class="sourceLineNo">170</span><a id="line.170"> }</a>
<span class="sourceLineNo">171</span><a id="line.171"> this.parts.add(subparts);</a>
<span class="sourceLineNo">172</span><a id="line.172"> }</a>
<span class="sourceLineNo">173</span><a id="line.173"></a>
<span class="sourceLineNo">174</span><a id="line.174"> if (this.parts.isEmpty()) {</a>
<span class="sourceLineNo">175</span><a id="line.175"> throw new IllegalArgumentException("Wildcard string cannot contain only dividers. Make sure permission strings are properly formatted.");</a>
<span class="sourceLineNo">176</span><a id="line.176"> }</a>
<span class="sourceLineNo">177</span><a id="line.177"> }</a>
<span class="sourceLineNo">178</span><a id="line.178"></a>
<span class="sourceLineNo">179</span><a id="line.179"> /*--------------------------------------------</a>
<span class="sourceLineNo">180</span><a id="line.180"> | A C C E S S O R S / M O D I F I E R S |</a>
<span class="sourceLineNo">181</span><a id="line.181"> ============================================*/</a>
<span class="sourceLineNo">182</span><a id="line.182"> protected List&lt;Set&lt;String&gt;&gt; getParts() {</a>
<span class="sourceLineNo">183</span><a id="line.183"> return this.parts;</a>
<span class="sourceLineNo">184</span><a id="line.184"> }</a>
<span class="sourceLineNo">185</span><a id="line.185"></a>
<span class="sourceLineNo">186</span><a id="line.186"> /**</a>
<span class="sourceLineNo">187</span><a id="line.187"> * Sets the pre-split String parts of this &lt;code&gt;WildcardPermission&lt;/code&gt;.</a>
<span class="sourceLineNo">188</span><a id="line.188"> * @since 1.3.0</a>
<span class="sourceLineNo">189</span><a id="line.189"> * @param parts pre-split String parts.</a>
<span class="sourceLineNo">190</span><a id="line.190"> */</a>
<span class="sourceLineNo">191</span><a id="line.191"> protected void setParts(List&lt;Set&lt;String&gt;&gt; parts) {</a>
<span class="sourceLineNo">192</span><a id="line.192"> this.parts = parts;</a>
<span class="sourceLineNo">193</span><a id="line.193"> }</a>
<span class="sourceLineNo">194</span><a id="line.194"></a>
<span class="sourceLineNo">195</span><a id="line.195"> /*--------------------------------------------</a>
<span class="sourceLineNo">196</span><a id="line.196"> | M E T H O D S |</a>
<span class="sourceLineNo">197</span><a id="line.197"> ============================================*/</a>
<span class="sourceLineNo">198</span><a id="line.198"></a>
<span class="sourceLineNo">199</span><a id="line.199"> public boolean implies(Permission p) {</a>
<span class="sourceLineNo">200</span><a id="line.200"> // By default only supports comparisons with other WildcardPermissions</a>
<span class="sourceLineNo">201</span><a id="line.201"> if (!(p instanceof WildcardPermission)) {</a>
<span class="sourceLineNo">202</span><a id="line.202"> return false;</a>
<span class="sourceLineNo">203</span><a id="line.203"> }</a>
<span class="sourceLineNo">204</span><a id="line.204"></a>
<span class="sourceLineNo">205</span><a id="line.205"> WildcardPermission wp = (WildcardPermission) p;</a>
<span class="sourceLineNo">206</span><a id="line.206"></a>
<span class="sourceLineNo">207</span><a id="line.207"> List&lt;Set&lt;String&gt;&gt; otherParts = wp.getParts();</a>
<span class="sourceLineNo">208</span><a id="line.208"></a>
<span class="sourceLineNo">209</span><a id="line.209"> int i = 0;</a>
<span class="sourceLineNo">210</span><a id="line.210"> for (Set&lt;String&gt; otherPart : otherParts) {</a>
<span class="sourceLineNo">211</span><a id="line.211"> // If this permission has less parts than the other permission, everything after the number of parts contained</a>
<span class="sourceLineNo">212</span><a id="line.212"> // in this permission is automatically implied, so return true</a>
<span class="sourceLineNo">213</span><a id="line.213"> if (getParts().size() - 1 &lt; i) {</a>
<span class="sourceLineNo">214</span><a id="line.214"> return true;</a>
<span class="sourceLineNo">215</span><a id="line.215"> } else {</a>
<span class="sourceLineNo">216</span><a id="line.216"> Set&lt;String&gt; part = getParts().get(i);</a>
<span class="sourceLineNo">217</span><a id="line.217"> if (!part.contains(WILDCARD_TOKEN) &amp;&amp; !part.containsAll(otherPart)) {</a>
<span class="sourceLineNo">218</span><a id="line.218"> return false;</a>
<span class="sourceLineNo">219</span><a id="line.219"> }</a>
<span class="sourceLineNo">220</span><a id="line.220"> i++;</a>
<span class="sourceLineNo">221</span><a id="line.221"> }</a>
<span class="sourceLineNo">222</span><a id="line.222"> }</a>
<span class="sourceLineNo">223</span><a id="line.223"></a>
<span class="sourceLineNo">224</span><a id="line.224"> // If this permission has more parts than the other parts, only imply it if all of the other parts are wildcards</a>
<span class="sourceLineNo">225</span><a id="line.225"> for (; i &lt; getParts().size(); i++) {</a>
<span class="sourceLineNo">226</span><a id="line.226"> Set&lt;String&gt; part = getParts().get(i);</a>
<span class="sourceLineNo">227</span><a id="line.227"> if (!part.contains(WILDCARD_TOKEN)) {</a>
<span class="sourceLineNo">228</span><a id="line.228"> return false;</a>
<span class="sourceLineNo">229</span><a id="line.229"> }</a>
<span class="sourceLineNo">230</span><a id="line.230"> }</a>
<span class="sourceLineNo">231</span><a id="line.231"></a>
<span class="sourceLineNo">232</span><a id="line.232"> return true;</a>
<span class="sourceLineNo">233</span><a id="line.233"> }</a>
<span class="sourceLineNo">234</span><a id="line.234"></a>
<span class="sourceLineNo">235</span><a id="line.235"> public String toString() {</a>
<span class="sourceLineNo">236</span><a id="line.236"> StringBuilder buffer = new StringBuilder();</a>
<span class="sourceLineNo">237</span><a id="line.237"> for (Set&lt;String&gt; part : parts) {</a>
<span class="sourceLineNo">238</span><a id="line.238"> if (buffer.length() &gt; 0) {</a>
<span class="sourceLineNo">239</span><a id="line.239"> buffer.append(PART_DIVIDER_TOKEN);</a>
<span class="sourceLineNo">240</span><a id="line.240"> }</a>
<span class="sourceLineNo">241</span><a id="line.241"> Iterator&lt;String&gt; partIt = part.iterator();</a>
<span class="sourceLineNo">242</span><a id="line.242"> while(partIt.hasNext()) {</a>
<span class="sourceLineNo">243</span><a id="line.243"> buffer.append(partIt.next());</a>
<span class="sourceLineNo">244</span><a id="line.244"> if (partIt.hasNext()) {</a>
<span class="sourceLineNo">245</span><a id="line.245"> buffer.append(SUBPART_DIVIDER_TOKEN);</a>
<span class="sourceLineNo">246</span><a id="line.246"> }</a>
<span class="sourceLineNo">247</span><a id="line.247"> }</a>
<span class="sourceLineNo">248</span><a id="line.248"> }</a>
<span class="sourceLineNo">249</span><a id="line.249"> return buffer.toString();</a>
<span class="sourceLineNo">250</span><a id="line.250"> }</a>
<span class="sourceLineNo">251</span><a id="line.251"></a>
<span class="sourceLineNo">252</span><a id="line.252"> public boolean equals(Object o) {</a>
<span class="sourceLineNo">253</span><a id="line.253"> if (o instanceof WildcardPermission) {</a>
<span class="sourceLineNo">254</span><a id="line.254"> WildcardPermission wp = (WildcardPermission) o;</a>
<span class="sourceLineNo">255</span><a id="line.255"> return parts.equals(wp.parts);</a>
<span class="sourceLineNo">256</span><a id="line.256"> }</a>
<span class="sourceLineNo">257</span><a id="line.257"> return false;</a>
<span class="sourceLineNo">258</span><a id="line.258"> }</a>
<span class="sourceLineNo">259</span><a id="line.259"></a>
<span class="sourceLineNo">260</span><a id="line.260"> public int hashCode() {</a>
<span class="sourceLineNo">261</span><a id="line.261"> return parts.hashCode();</a>
<span class="sourceLineNo">262</span><a id="line.262"> }</a>
<span class="sourceLineNo">263</span><a id="line.263"></a>
<span class="sourceLineNo">264</span><a id="line.264">}</a>
</pre>
</div>
</main>
</body>
</html>