YumPackageName { public static YumPackageName fromString(final String packageSpec) { String spec = packageSpec; Optional<String> epoch = Optional.empty(); String name = null; int epochColon = spec.indexOf(':'); if (epochColon >= 0) { Matcher epochMatcher = EPOCH_PATTERN.matcher(spec.substring(0, epochColon)); if (!epochMatcher.find()) { throw new IllegalArgumentException("Unexpected epoch format: " + packageSpec); } name = epochMatcher.group(2); epoch = Optional.of(epochMatcher.group(3)); spec = spec.substring(epochColon + 1); } Optional<String> architecture = Optional.empty(); Matcher architectureMatcher = ARCHITECTURE_PATTERN.matcher(spec); if (architectureMatcher.find()) { architecture = Optional.of(architectureMatcher.group(1)); spec = spec.substring(0, architectureMatcher.start()); } Optional<String> version = Optional.empty(); Optional<String> release = Optional.empty(); Matcher matcher = NAME_VER_REL_PATTERN.matcher(spec); if (matcher.find()) { spec = matcher.group(2); if (spec == null) { if (name == null) { throw new IllegalArgumentException("No package name was found: " + packageSpec); } spec = name; } else if (name != null) { throw new IllegalArgumentException("Ambiguous package names were found for " + packageSpec + ": '" + name + "' and '" + spec + "'"); } version = Optional.of(matcher.group(3)); release = Optional.of(matcher.group(4)); } if (!NAME_PATTERN.matcher(spec).find()) { throw new IllegalArgumentException("Bad package name in " + packageSpec + ": '" + spec + "'"); } name = spec; return new YumPackageName(epoch, name, version, release, architecture); } private  YumPackageName(Optional<String> epoch,
                           String name,
                           Optional<String> version,
                           Optional<String> release,
                           Optional<String> architecture); static YumPackageName fromString(final String packageSpec); static Optional<YumPackageName> parseString(final String packageSpec); Optional<String> getEpoch(); String getName(); Optional<String> getVersion(); Optional<String> getRelease(); Optional<String> getArchitecture(); String toName(); String toVersionLockName(); boolean isSubsetOf(YumPackageName other); @Override boolean equals(Object o); @Override int hashCode();  }
@Test public void failParsingOfPackageNameWithEpochAndArchitecture() { try { YumPackageName.fromString("epoch:docker-engine-selinux-1.12.6-1.el7.x86_64"); fail(); } catch (IllegalArgumentException e) { assertThat(e.getMessage(), containsStringIgnoringCase("epoch")); } }