jaulib v1.3.0
Jau Support Library (C++, Java, ..)
UriQueryProps.java
Go to the documentation of this file.
1/**
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2021 Gothel Software e.K.
4 * Copyright (c) 2012 Gothel Software e.K.
5 * Copyright (c) 2013 JogAmp Community.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26package org.jau.net;
27
28import java.net.URISyntaxException;
29import java.util.HashMap;
30import java.util.Iterator;
31import java.util.Map;
32import java.util.Map.Entry;
33
34/**
35 * Helper class to process URI's query, handled as properties.
36 * <p>
37 * The order of the URI segments (any properties) are <i>not</i> preserved.
38 * </p>
39 * <pre>
40 * URI: [scheme:][//authority][path][?query][#fragment]
41 * w/ authority: [user-info@]host[:port]
42 * Note: 'path' starts w/ fwd slash
43 * </pre>
44 * <p>
45 * Since 2.3.0 renamed from {@code URIQueryProps} to {@code UriQueryProps},
46 * and using {@link Uri} instead of {@link java.net.URI}.
47 * </p>
48 */
49public class UriQueryProps {
50 private static final String QMARK = "?";
51 private static final char ASSIG = '=';
52 private static final String EMPTY = "";
53 private final String query_separator;
54
55 private final HashMap<String, String> properties = new HashMap<String, String>();
56
57 private UriQueryProps(final char querySeparator) {
58 query_separator = String.valueOf(querySeparator);
59 }
60
61 public final Map<String, String> getProperties() { return properties; }
62 public final char getQuerySeparator() { return query_separator.charAt(0); }
63
64 public final Uri.Encoded appendQuery(Uri.Encoded baseQuery) {
65 boolean needsSep = false;
66 final StringBuilder sb = new StringBuilder();
67 if ( null != baseQuery ) {
68 if( baseQuery.startsWith(QMARK) ) {
69 baseQuery = baseQuery.substring(1); // cut off '?'
70 }
71 sb.append(baseQuery.get());
72 if( !baseQuery.endsWith(query_separator) ) {
73 needsSep = true;
74 }
75 }
76 final Iterator<Entry<String, String>> entries = properties.entrySet().iterator();
77 while(entries.hasNext()) {
78 if(needsSep) {
79 sb.append(query_separator);
80 }
81 final Entry<String, String> entry = entries.next();
82 sb.append(entry.getKey());
83 if( EMPTY != entry.getValue() ) {
84 sb.append(ASSIG).append(entry.getValue());
85 }
86 needsSep = true;
87 }
88 return new Uri.Encoded(sb.toString(), Uri.QUERY_LEGAL);
89 }
90
91 public final Uri appendQuery(final Uri base) throws URISyntaxException {
92 return base.getNewQuery( appendQuery( base.query ) );
93 }
94
95 /**
96 *
97 * @param uri
98 * @param querySeparator should be either <i>;</i> or <i>&</i>, <i>;</i> is encouraged due to troubles of escaping <i>&</i>.
99 * @return
100 * @throws IllegalArgumentException if <code>querySeparator</code> is illegal, i.e. neither <i>;</i> nor <i>&</i>
101 */
102 public static final UriQueryProps create(final Uri uri, final char querySeparator) throws IllegalArgumentException {
103 if( ';' != querySeparator && '&' != querySeparator ) {
104 throw new IllegalArgumentException("querySeparator is invalid: "+querySeparator);
105 }
106 final UriQueryProps data = new UriQueryProps(querySeparator);
107 final String q = Uri.decode(uri.query);
108 final int q_l = null != q ? q.length() : -1;
109 int q_e = -1;
110 while(q_e < q_l) {
111 final int q_b = q_e + 1; // next term
112 q_e = q.indexOf(querySeparator, q_b);
113 if(0 == q_e) {
114 // single separator
115 continue;
116 }
117 if(0 > q_e) {
118 // end
119 q_e = q_l;
120 }
121 // n-part
122 final String part = q.substring(q_b, q_e);
123 final int assignment = part.indexOf(ASSIG);
124 if(0 < assignment) {
125 // assignment
126 final String k = part.substring(0, assignment);
127 final String v = part.substring(assignment+1);
128 data.properties.put(k, v);
129 } else {
130 // property key only
131 data.properties.put(part, EMPTY);
132 }
133 }
134 return data;
135 }
136}
Helper class to process URI's query, handled as properties.
static final UriQueryProps create(final Uri uri, final char querySeparator)
final Uri.Encoded appendQuery(Uri.Encoded baseQuery)
final Uri appendQuery(final Uri base)
final Map< String, String > getProperties()
Immutable RFC3986 encoded string.
Definition: Uri.java:301
This class implements an immutable Uri as defined by RFC 2396.
Definition: Uri.java:162
static String decode(final Encoded encoded)
Safe Encoded#decode() call on optional encoded instance.
Definition: Uri.java:577
static final String QUERY_LEGAL
Valid charset for RFC 2396 query, additional to legal alphanum characters.
Definition: Uri.java:258
final Uri getNewQuery(final Encoded newQuery)
Returns a new Uri instance w/ the given new query newQuery.
Definition: Uri.java:1717