View Javadoc
1   package org.argeo.naming;
2   
3   import java.io.UnsupportedEncodingException;
4   import java.net.URI;
5   import java.net.URLDecoder;
6   import java.nio.charset.StandardCharsets;
7   import java.time.Instant;
8   import java.time.OffsetDateTime;
9   import java.time.ZoneOffset;
10  import java.time.ZonedDateTime;
11  import java.time.format.DateTimeFormatter;
12  import java.time.format.DateTimeParseException;
13  import java.time.temporal.ChronoField;
14  import java.util.Calendar;
15  import java.util.GregorianCalendar;
16  import java.util.LinkedHashMap;
17  import java.util.LinkedList;
18  import java.util.List;
19  import java.util.Map;
20  
21  public class NamingUtils {
22  	/** As per https://tools.ietf.org/html/rfc4517#section-3.3.13 */
23  	private final static DateTimeFormatter utcLdapDate = DateTimeFormatter.ofPattern("uuuuMMddHHmmssX")
24  			.withZone(ZoneOffset.UTC);
25  
26  	/** @return null if not parseable */
27  	public static Instant ldapDateToInstant(String ldapDate) {
28  		try {
29  			return OffsetDateTime.parse(ldapDate, utcLdapDate).toInstant();
30  		} catch (DateTimeParseException e) {
31  			return null;
32  		}
33  	}
34  
35  	/** @return null if not parseable */
36  	public static ZonedDateTime ldapDateToZonedDateTime(String ldapDate) {
37  		try {
38  			return OffsetDateTime.parse(ldapDate, utcLdapDate).toZonedDateTime();
39  		} catch (DateTimeParseException e) {
40  			return null;
41  		}
42  	}
43  
44  	public static Calendar ldapDateToCalendar(String ldapDate) {
45  		OffsetDateTime instant = OffsetDateTime.parse(ldapDate, utcLdapDate);
46  		GregorianCalendar calendar = new GregorianCalendar();
47  		calendar.set(Calendar.DAY_OF_MONTH, instant.get(ChronoField.DAY_OF_MONTH));
48  		calendar.set(Calendar.MONTH, instant.get(ChronoField.MONTH_OF_YEAR));
49  		calendar.set(Calendar.YEAR, instant.get(ChronoField.YEAR));
50  		return calendar;
51  	}
52  
53  	public static String instantToLdapDate(ZonedDateTime instant) {
54  		return utcLdapDate.format(instant.withZoneSameInstant(ZoneOffset.UTC));
55  	}
56  
57  	public static String getQueryValue(Map<String, List<String>> query, String key) {
58  		if (!query.containsKey(key))
59  			return null;
60  		List<String> val = query.get(key);
61  		if (val.size() == 1)
62  			return val.get(0);
63  		else
64  			throw new IllegalArgumentException("There are " + val.size() + " value(s) for " + key);
65  	}
66  
67  	public static Map<String, List<String>> queryToMap(URI uri) {
68  		return queryToMap(uri.getQuery());
69  	}
70  
71  	private static Map<String, List<String>> queryToMap(String queryPart) {
72  		try {
73  			final Map<String, List<String>> query_pairs = new LinkedHashMap<String, List<String>>();
74  			if (queryPart == null)
75  				return query_pairs;
76  			final String[] pairs = queryPart.split("&");
77  			for (String pair : pairs) {
78  				final int idx = pair.indexOf("=");
79  				final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8.name())
80  						: pair;
81  				if (!query_pairs.containsKey(key)) {
82  					query_pairs.put(key, new LinkedList<String>());
83  				}
84  				final String value = idx > 0 && pair.length() > idx + 1
85  						? URLDecoder.decode(pair.substring(idx + 1), StandardCharsets.UTF_8.name())
86  						: null;
87  				query_pairs.get(key).add(value);
88  			}
89  			return query_pairs;
90  		} catch (UnsupportedEncodingException e) {
91  			throw new IllegalArgumentException("Cannot convert " + queryPart + " to map", e);
92  		}
93  	}
94  
95  	private NamingUtils() {
96  
97  	}
98  
99  	public static void main(String args[]) {
100 		ZonedDateTime now = ZonedDateTime.now().withZoneSameInstant(ZoneOffset.UTC);
101 		String str = utcLdapDate.format(now);
102 		System.out.println(str);
103 		utcLdapDate.parse(str);
104 		utcLdapDate.parse("19520512000000Z");
105 	}
106 }