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

global.namespace.truelicense.api.x500.GenX500PrincipalBuilder Maven / Gradle / Ivy

/*
 * Copyright (C) 2005 - 2019 Schlichtherle IT Services.
 * All rights reserved. Use is subject to license terms.
 */
package global.namespace.truelicense.api.x500;

import global.namespace.truelicense.api.builder.GenBuilder;

import javax.security.auth.x500.X500Principal;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Pattern;

import static java.util.Objects.requireNonNull;

/**
 * A generic builder for an {@link X500Principal}.
 * 

* This abstract class is provided so that sub-classes can easily add methods * which return {@code this} without the need to cast its type by clients. * Example: *

 * {@code
 * class MyBuilder extends GenX500PrincipalBuilder {
 *     MyBuilder addFOO(String value) {
 *         addKeyword("FOO", "1.2.3.4.5.6.7.8.9");
 *         return addAttribute("FOO", value);
 *     }
 * }
 *
 * class MyClient {
 *     X500Principal create() {
 *         return new MyBuilder()
 *                 .addAttribute("CN", "Duke")
 *                 .addFOO("a")
 *                 .build();
 *     }
 * }
 * }
*

* Notice that the call to {@code addFOO} is compilable because the previous * call to {@code addAttribute} is defined to return the generic type parameter * {@code This}. * * @param the type of this generic X.500 principal builder. * @since TrueLicense 2.3 */ public abstract class GenX500PrincipalBuilder> implements GenBuilder { private final Map attributes = new LinkedHashMap<>(), keywords = new HashMap<>(); /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#C C}, value). */ public This addC(String value) { return addAttribute(X500AttributeTypeKeyword.C, value); } /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#CN CN}, value). */ public This addCN(String value) { return addAttribute(X500AttributeTypeKeyword.CN, value); } /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#DC DC}, value). */ public This addDC(String value) { return addAttribute(X500AttributeTypeKeyword.DC, value); } /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#DNQ DNQ}, value). */ public This addDNQ(String value) { return addAttribute(X500AttributeTypeKeyword.DNQ, value); } /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#DNQUALIFIER DNQUALIFIER}, value). */ public This addDNQUALIFIER(String value) { return addAttribute(X500AttributeTypeKeyword.DNQUALIFIER, value); } /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#EMAILADDRESS EMAILADDRESS}, value). */ public This addEMAILADDRESS(String value) { return addAttribute(X500AttributeTypeKeyword.EMAILADDRESS, value); } /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#GENERATION GENERATION}, value). */ public This addGENERATION(String value) { return addAttribute(X500AttributeTypeKeyword.GENERATION, value); } /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#GIVENNAME GIVENNAME}, value). */ public This addGIVENNAME(String value) { return addAttribute(X500AttributeTypeKeyword.GIVENNAME, value); } /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#INITIALS INITIALS}, value). */ public This addINITIALS(String value) { return addAttribute(X500AttributeTypeKeyword.INITIALS, value); } /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#L L}, value). */ public This addL(String value) { return addAttribute(X500AttributeTypeKeyword.L, value); } /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#O O}, value). */ public This addO(String value) { return addAttribute(X500AttributeTypeKeyword.O, value); } /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#OU OU}, value). */ public This addOU(String value) { return addAttribute(X500AttributeTypeKeyword.OU, value); } /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#SERIALNUMBER SERIALNUMBER}, value). */ public This addSERIALNUMBER(String value) { return addAttribute(X500AttributeTypeKeyword.SERIALNUMBER, value); } /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#ST ST}, value). */ public This addST(String value) { return addAttribute(X500AttributeTypeKeyword.ST, value); } /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#STREET STREET}, value). */ public This addSTREET(String value) { return addAttribute(X500AttributeTypeKeyword.STREET, value); } /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#SURNAME SURNAME}, value). */ public This addSURNAME(String value) { return addAttribute(X500AttributeTypeKeyword.SURNAME, value); } /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#T T}, value). */ public This addT(String value) { return addAttribute(X500AttributeTypeKeyword.T, value); } /** * Equivalent to * addAttribute({@link X500AttributeTypeKeyword#UID UID}, value). */ public This addUID(String value) { return addAttribute(X500AttributeTypeKeyword.UID, value); } /** * Adds an X.500 attribute to the distinguished name. * * @param keyword the attribute type keyword. * @param value the nullable, unquoted and unescaped attribute value. * @return {@code this} */ public This addAttribute(X500AttributeTypeKeyword keyword, String value) { return addAttribute(keyword.name(), value); } /** * Adds an X.500 attribute to the distinguished name. * * @param type the attribute type, * which can be referenced by a keyword or its OID. * @param value the nullable, unquoted and unescaped attribute value. * @return {@code this} * @see #addKeyword */ @SuppressWarnings("unchecked") public This addAttribute(final String type, final String value) { requireNonNull(type); if (null != value) attributes.put(type, value); else attributes.remove(type); return (This) this; } /** * Adds a mapping from a keyword to an Object Identifier (OID). * * @param keyword the attribute type keyword. * @param oid the nullable OID. * @return {@code this} */ @SuppressWarnings("unchecked") public This addKeyword(final String keyword, final String oid) { requireNonNull(keyword); if (null != oid) keywords.put(keyword, oid); else keywords.remove(keyword); return (This) this; } /** * Returns the X.500 principal with the distinguished name as built from * the sequence of attribute type and value pairs. * * @throws IllegalArgumentException if an attribute type is unknown or its * keyword mapping is invalid. */ public X500Principal build() { final DistinguishedNameAssembler dna = new DistinguishedNameAssembler(); for (Map.Entry e : attributes.entrySet()) dna.appendAttribute(e.getKey(), e.getValue()); return new X500Principal(dna.toString(), keywords); } private static final class DistinguishedNameAssembler { private static final String QUOTED_CHARACTERS_SEQUENCE = ",+<>;"; private static final Pattern QUOTED_CHARACTERS_PATTERN = Pattern.compile(".*[" + QUOTED_CHARACTERS_SEQUENCE + "].*"); private final StringBuilder dname = new StringBuilder(); void appendAttribute(final String type, final String value) { // See http://www.ietf.org/rfc/rfc2253.txt delimitAttribute(); dname.append(type).append('='); final boolean nq = needsQuoting(value); if (nq) dname.append('"'); dname.append(escapeBackslashAndQuote(value)); if (nq) dname.append('"'); } private void delimitAttribute() { if (0 < dname.length()) dname.append(','); } private static boolean needsQuoting(String value) { return !value.equals(value.trim()) || value.startsWith("#") || QUOTED_CHARACTERS_PATTERN.matcher(value).matches(); } private static String escapeBackslashAndQuote(String value) { return value.replace("\\", "\\\\").replace("\"", "\\\""); } @Override public String toString() { return dname.toString(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy