View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.frontend;
20  
21  import java.net.MalformedURLException;
22  import java.net.URI;
23  import java.net.URL;
24  import java.util.ArrayList;
25  import java.util.HashMap;
26  import java.util.List;
27  import java.util.Map;
28  import java.util.Map.Entry;
29  
30  import org.apache.logging.log4j.LogManager;
31  import org.apache.logging.log4j.Logger;
32  
33  /**
34   * 
35   * @author Matthias Eichner
36   */
37  public class MCRURL {
38  
39      static Logger LOGGER = LogManager.getLogger(MCRURL.class);
40  
41      private URL url;
42  
43      private Map<String, List<String>> parameterMap;
44  
45      public MCRURL(String url) throws MalformedURLException {
46          this.url = new URL(url);
47      }
48  
49      public Map<String, List<String>> getParameterMap() {
50          if (this.parameterMap == null) {
51              this.parameterMap = buildParameterMap(this.url);
52          }
53          return parameterMap;
54      }
55  
56      private Map<String, List<String>> buildParameterMap(URL url) {
57          Map<String, List<String>> p = new HashMap<>();
58          String queryString = url.getQuery();
59          if (queryString == null) {
60              return p;
61          }
62          for (String pair : queryString.split("&")) {
63              int eq = pair.indexOf("=");
64              String key = eq >= 0 ? pair.substring(0, eq) : pair;
65              String value = eq >= 0 ? pair.substring(eq + 1) : "";
66              if (p.containsKey(key)) {
67                  p.get(key).add(value);
68              } else {
69                  List<String> valueList = new ArrayList<>();
70                  valueList.add(value);
71                  p.put(key, valueList);
72              }
73          }
74          return p;
75      }
76  
77      private String buildQueryString(Map<String, List<String>> parameterMap) {
78          StringBuilder queryBuilder = new StringBuilder();
79          for (Entry<String, List<String>> entrySet : parameterMap.entrySet()) {
80              String name = entrySet.getKey();
81              for (String value : entrySet.getValue()) {
82                  queryBuilder.append(name).append("=").append(value).append("&");
83              }
84          }
85          String queryString = queryBuilder.toString();
86          return queryString.length() > 0 ? queryString.substring(0, queryString.length() - 1) : "";
87      }
88  
89      private void rebuild() {
90          String query = buildQueryString(this.parameterMap);
91          try {
92              URI uri = this.url.toURI();
93              StringBuilder urlBuffer = new StringBuilder();
94              urlBuffer.append(
95                  new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), uri.getPath(), null, null));
96              if (query != null) {
97                  urlBuffer.append("?").append(query);
98              }
99              if (uri.getFragment() != null) {
100                 urlBuffer.append("#").append(uri.getFragment());
101             }
102             this.url = new URL(urlBuffer.toString());
103             if (this.parameterMap != null) {
104                 // rebuild parameter map
105                 this.parameterMap = buildParameterMap(this.url);
106             }
107         } catch (Exception exc) {
108             LOGGER.error("unable to rebuild url {}", this.url);
109         }
110     }
111 
112     public String getParameter(String name) {
113         List<String> valueList = getParameterMap().get(name);
114         return valueList != null ? valueList.get(0) : null;
115     }
116 
117     public List<String> getParameterValues(String name) {
118         List<String> valueList = getParameterMap().get(name);
119         return valueList != null ? valueList : new ArrayList<>();
120     }
121 
122     public MCRURL addParameter(String name, String value) {
123         StringBuilder urlBuffer = new StringBuilder(this.url.toString());
124         urlBuffer.append(this.url.getQuery() == null ? "?" : "&");
125         urlBuffer.append(name).append("=").append(value);
126         try {
127             this.url = new URL(urlBuffer.toString());
128             if (this.parameterMap != null) {
129                 // rebuild parameter map
130                 this.parameterMap = buildParameterMap(this.url);
131             }
132         } catch (MalformedURLException exc) {
133             LOGGER.error("unable to add parameter ({}={}) to url{}", name, value, this.url);
134         }
135         return this;
136     }
137 
138     public MCRURL removeParameter(String name) {
139         this.getParameterMap().remove(name);
140         rebuild();
141         return this;
142     }
143 
144     public MCRURL removeParameterValue(String name, String value) {
145         List<String> values = this.getParameterMap().get(name);
146         if (values != null) {
147             boolean removed = false;
148             while (values.remove(value)) {
149                 removed = true;
150             }
151             if (removed) {
152                 rebuild();
153             }
154         }
155         return this;
156     }
157 
158     public URL getURL() {
159         return this.url;
160     }
161 
162     @Override
163     public String toString() {
164         return this.url.toString();
165     }
166 
167 }