001/*-
002 * #%L
003 * Smile CDR - CDR
004 * %%
005 * Copyright (C) 2016 - 2026 Smile CDR, Inc.
006 * %%
007 * All rights reserved.
008 * #L%
009 */
010package ca.cdr.api.security.permission;
011
012import jakarta.annotation.Nonnull;
013import jakarta.annotation.Nullable;
014import org.apache.commons.lang3.StringUtils;
015import org.apache.commons.lang3.Strings;
016
017import java.util.Optional;
018
019/**
020 * A single String which contains a Module ID.
021 * The special character '/' is prohibited, as related permissions use it as a delimiter
022 */
023public class ModuleId extends PermissionArgumentValue implements PermissionArgumentFormat.IModuleIdRestriction {
024
025        public static final String INVALID_METHOD_ARGUMENT_MESSAGE = "ModuleId cannot contain the special character '/'.";
026        private final String myModuleId;
027
028        static final String DELIMITER = "/";
029
030        private ModuleId(String theModuleId) {
031                if (Strings.CI.contains(DELIMITER, theModuleId)) {
032                        throw new IllegalArgumentException(INVALID_METHOD_ARGUMENT_MESSAGE);
033                }
034                myModuleId = theModuleId;
035        }
036
037        public static ModuleId fromNodeIdAndModuleId(String theModuleId) {
038                return new ModuleId(theModuleId);
039        }
040
041        @Override
042        public String getModuleId() {
043                return myModuleId;
044        }
045
046        @Nonnull
047        @Override
048        String getStringValue() {
049                return myModuleId;
050        }
051
052        static final class Format implements PermissionArgumentFormat<ModuleId> {
053                public static final String MISSING_ARGUMENT_MESSAGE =
054                                "Expected permission to contain a module id but the argument is empty.";
055                public static final String INVALID_FORMAT_MESSAGE =
056                                "Invalid format passed for permission. A module id may not contain the special character '/'.";
057
058                @Nonnull
059                public Optional<ModuleId> parse(@Nullable String theArgumentString, @Nonnull IdBuilder theIdBuilder) {
060                        if (StringUtils.isBlank(theArgumentString)) {
061                                throw new IllegalArgumentException(MISSING_ARGUMENT_MESSAGE);
062                        }
063
064                        if (theArgumentString.contains(DELIMITER)) {
065                                throw new IllegalArgumentException(INVALID_FORMAT_MESSAGE);
066                        }
067
068                        return Optional.of(new ModuleId(theArgumentString));
069                }
070
071                @Override
072                public Class<ModuleId> getType() {
073                        return ModuleId.class;
074                }
075
076                @Nonnull
077                @Override
078                public String format(@Nonnull ModuleId theArgument) {
079                        return theArgument.getStringValue();
080                }
081        }
082}