private static void reorderAccessControlEntries()

in src/main/java/org/apache/sling/jcr/base/util/AccessControlUtil.java [741:844]


	private static void reorderAccessControlEntries(AccessControlList acl,
														Principal principal,
														String order)
							throws RepositoryException {
		if (order == null || order.length() == 0) {
			return; //nothing to do
		}
		if (acl instanceof JackrabbitAccessControlList) {
			JackrabbitAccessControlList jacl = (JackrabbitAccessControlList)acl;

			AccessControlEntry[] accessControlEntries = jacl.getAccessControlEntries();
			if (accessControlEntries.length <= 1) {
				return; //only one ACE, so nothing to reorder.
			}

			AccessControlEntry beforeEntry = null;
			if ("first".equals(order)) {
				beforeEntry = accessControlEntries[0];
			} else if ("last".equals(order)) {
				beforeEntry = null;
			} else if (order.startsWith("before ")) {
				String beforePrincipalName = order.substring(7);

				//find the index of the ACE of the 'before' principal
				for (int i=0; i < accessControlEntries.length; i++) {
					if (beforePrincipalName.equals(accessControlEntries[i].getPrincipal().getName())) {
						//found it!
						beforeEntry = accessControlEntries[i];
						break;
					}
				}

				if (beforeEntry == null) {
					//didn't find an ACE that matched the 'before' principal
					throw new IllegalArgumentException("No ACE was found for the specified principal: " + beforePrincipalName);
				}
			} else if (order.startsWith("after ")) {
				String afterPrincipalName = order.substring(6);

				//find the index of the ACE of the 'after' principal
				for (int i = accessControlEntries.length - 1; i >= 0; i--) {
					if (afterPrincipalName.equals(accessControlEntries[i].getPrincipal().getName())) {
						//found it!

						// the 'before' ACE is the next one after the 'after' ACE
						if (i >= accessControlEntries.length - 1) {
							//the after is the last one in the list
							beforeEntry = null;
						} else {
							beforeEntry = accessControlEntries[i + 1];
						}
						break;
					}
				}

				if (beforeEntry == null) {
					//didn't find an ACE that matched the 'after' principal
					throw new IllegalArgumentException("No ACE was found for the specified principal: " + afterPrincipalName);
				}
			} else {
				try {
					int index = Integer.parseInt(order);
					if (index > accessControlEntries.length) {
						//invalid index
						throw new IndexOutOfBoundsException("Index value is too large: " + index);
					}

					if (index == 0) {
						beforeEntry = accessControlEntries[0];
					} else {
						//the index value is the index of the principal.  A principal may have more
						// than one ACEs (deny + grant), so we need to compensate.
						Set<Principal> processedPrincipals = new HashSet<Principal>();
						for (int i = 0; i < accessControlEntries.length; i++) {
							Principal principal2 = accessControlEntries[i].getPrincipal();
							if (processedPrincipals.size() == index &&
									!processedPrincipals.contains(principal2)) {
								//we are now at the correct position in the list
								beforeEntry = accessControlEntries[i];
								break;
							}

							processedPrincipals.add(principal2);
						}
					}
				} catch (NumberFormatException nfe) {
					//not a number.
					throw new IllegalArgumentException("Illegal value for the order parameter: " + order);
				}
			}

			//now loop through the entries to move the affected ACEs to the specified
			// position.
			for (int i = accessControlEntries.length - 1; i >= 0; i--) {
				AccessControlEntry ace = accessControlEntries[i];
				if (principal.equals(ace.getPrincipal())) {
					//this ACE is for the specified principal.
					jacl.orderBefore(ace, beforeEntry);
				}
			}
		} else {
			throw new IllegalArgumentException("The acl must be an instance of JackrabbitAccessControlList");
		}
	}