All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.fge.filesystem.posix.ModeParser Maven / Gradle / Ivy

package com.github.fge.filesystem.posix;

import com.github.fge.filesystem.exceptions.InvalidModeInstructionException;

import javax.annotation.ParametersAreNonnullByDefault;
import java.nio.file.attribute.PosixFilePermission;
import java.util.EnumSet;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;

/**
 * A parser for chmod-like posix mode change instructions
 *
 * 

Such instructions are, for instance, {@code "u+r,go-w"}.

* *

What is currently supported:

* *
    *
  • who: any combination of {@code u}, {@code g} and {@code o}; an empty * string is equivalent to {@code ugo}; {@code a} is NOT supported;
  • *
  • operation type: {@code +} and {@code -}; {@code =} is NOT supported; *
  • *
  • what: any combination of {@code r}, {@code w} and {@code x}; {@code * X} is NOT supported.
  • *
*/ @ParametersAreNonnullByDefault public final class ModeParser { private static final Pattern COMMA = Pattern.compile(","); private ModeParser() { throw new Error("nice try!"); } /** * Build a permission change object from an instruction string * * @param instructions the instructions * @return a permission change object * @throws InvalidModeInstructionException instruction string is invalid * @throws UnsupportedOperationException an unsupported instruction was * encountered while parsin */ public static PermissionsSet buildPermissionsSet(final String instructions) { Objects.requireNonNull(instructions); final Set toAdd = EnumSet.noneOf(PosixFilePermission.class); final Set toRemove = EnumSet.noneOf(PosixFilePermission.class); parse(instructions, toAdd, toRemove); return new PermissionsSet(toAdd, toRemove); } // Visible for testing static void parse(final String instructions, final Set toAdd, final Set toRemove) { for(final String instruction: COMMA.split(instructions)) parseOne(instruction,toAdd,toRemove); } // Visible for testing static void parseOne(final String instruction, final Set toAdd, final Set toRemove) { final int plus = instruction.indexOf('+'); final int minus = instruction.indexOf('-'); if (plus < 0 && minus < 0) throw new InvalidModeInstructionException(instruction); final String who; final String what; final Set set; if (plus >= 0) { who = plus == 0 ? "ugo" : instruction.substring(0, plus); what = instruction.substring(plus + 1); set = toAdd; } else { // If it's not plusIndex it's minusIndex who = minus == 0 ? "ugo" : instruction.substring(0, minus); what = instruction.substring(minus + 1); set = toRemove; } if(what.isEmpty()) throw new InvalidModeInstructionException(instruction); modifySet(who, what, set, instruction); } private static void modifySet(final String who, final String what, final Set set, final String instruction) { final int whoLength = who.length(); final int whatLength = what.length(); int whoOrdinal, whatOrdinal; for (int i = 0; i < whoLength; i++) { whoOrdinal = 0; switch(who.charAt(i)) { case 'o': whoOrdinal++; /* fall through */ case 'g': whoOrdinal++; /* fall through */ case 'u': break; case 'a': throw new UnsupportedOperationException(instruction); default: throw new InvalidModeInstructionException(instruction); } for (int j = 0; j < whatLength; j++) { whatOrdinal = 3 * whoOrdinal; switch(what.charAt(j)) { case 'x': whatOrdinal++; /* fall through */ case 'w': whatOrdinal++; /* fall through */ case 'r': break; case 'X': throw new UnsupportedOperationException(instruction); default: throw new InvalidModeInstructionException(instruction); } //add to set set.add(PosixModes.PERMISSIONS[whatOrdinal]); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy