Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / javaunohelper / com / sun / star / lib / uno / helper / UnoUrl.java
blobe3a3a430f6e20ca66726f5ce78ad8aa1fc146b2f
1 /*
2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 package com.sun.star.lib.uno.helper;
20 import java.io.UnsupportedEncodingException;
21 import java.nio.ByteBuffer;
22 import java.util.HashMap;
24 /**
25 * Object representation and parsing of Uno Urls,
26 * which allow to locate a named Uno object in a
27 * different process. An Uno Url consists of the
28 * specification of a connection, protocol and
29 * rootOid delimited with a ';'.
30 * The syntax of an Uno Url is
32 * <code>
33 * [uno:]connection-type,parameters;protocol-name,parameters;objectname";
34 * </code>
36 * An example Uno Url will look like this:
38 * <code>
39 * socket,host=localhost,port=2002;urp;StarOffice.ServiceManager
40 * </code>
42 * For more information about Uno Url please consult
43 * <a href="http://udk.openoffice.org/common/man/spec/uno-url.html">
44 * http://udk.openoffice.org/common/man/spec/uno-url.html</a>
46 * Usage:
48 * <code>
49 * UnoUrl url = UnoUrl.parseUnoUrl("socket,host=localhost,port=2002;urp;StarOffice.ServiceManager");
50 * </code>
52 public class UnoUrl {
54 private static final String FORMAT_ERROR =
55 "syntax: [uno:]connection-type,parameters;protocol-name,parameters;objectname";
57 private static final String VALUE_CHAR_SET = "!$&'()*+-./:?@_~";
58 private static final String OID_CHAR_SET = VALUE_CHAR_SET + ",=";
60 private final UnoUrlPart connection;
61 private final UnoUrlPart protocol;
62 private final String rootOid;
64 private static class UnoUrlPart {
66 private final String partTypeName;
67 private final HashMap<String,String> partParameters;
68 private final String uninterpretedParameterString;
70 public UnoUrlPart(
71 String uninterpretedParameterString,
72 String partTypeName,
73 HashMap<String,String> partParameters) {
74 this.uninterpretedParameterString = uninterpretedParameterString;
75 this.partTypeName = partTypeName;
76 this.partParameters = partParameters;
79 public String getPartTypeName() {
80 return partTypeName;
83 public HashMap<String,String> getPartParameters() {
84 return partParameters;
87 public String getUninterpretedParameterString() {
88 return uninterpretedParameterString;
91 public String getUninterpretedString() {
92 StringBuffer buf = new StringBuffer(partTypeName);
93 if (uninterpretedParameterString.length() > 0) {
94 buf.append(',');
95 buf.append(uninterpretedParameterString);
97 return buf.toString();
101 private UnoUrl(
102 UnoUrlPart connectionPart,
103 UnoUrlPart protocolPart,
104 String rootOid) {
105 this.connection = connectionPart;
106 this.protocol = protocolPart;
107 this.rootOid = rootOid;
111 * Returns the name of the connection of this
112 * Uno Url. Encoded characters are not allowed.
114 * @return The connection name as string.
116 public String getConnection() {
117 return connection.getPartTypeName();
121 * Returns the name of the protocol of this
122 * Uno Url. Encoded characters are not allowed.
124 * @return The protocol name as string.
126 public String getProtocol() {
127 return protocol.getPartTypeName();
131 * Return the object name. Encoded character are
132 * not allowed.
134 * @return The object name as String.
136 public String getRootOid() {
137 return rootOid;
141 * Returns the protocol parameters as
142 * a Hashmap with key/value pairs. Encoded
143 * characters like '%41' are decoded.
145 * @return a HashMap with key/value pairs for protocol parameters.
147 public HashMap<String,String> getProtocolParameters() {
148 return protocol.getPartParameters();
152 * Returns the connection parameters as
153 * a Hashmap with key/value pairs. Encoded
154 * characters like '%41' are decoded.
156 * @return a HashMap with key/value pairs for connection parameters.
158 public HashMap<String,String> getConnectionParameters() {
159 return connection.getPartParameters();
163 * Returns the raw specification of the protocol
164 * parameters. Encoded characters like '%41' are
165 * not decoded.
167 * @return The uninterpreted protocol parameters as string.
169 public String getProtocolParametersAsString() {
170 return protocol.getUninterpretedParameterString();
174 * Returns the raw specification of the connection
175 * parameters. Encoded characters like '%41' are
176 * not decoded.
178 * @return The uninterpreted connection parameters as string.
180 public String getConnectionParametersAsString() {
181 return connection.getUninterpretedParameterString();
185 * Returns the raw specification of the protocol
186 * name and parameters. Encoded characters like '%41' are
187 * not decoded.
189 * @return The uninterpreted protocol name and parameters as string.
191 public String getProtocolAndParametersAsString() {
192 return protocol.getUninterpretedString();
196 * Returns the raw specification of the connection
197 * name and parameters. Encoded characters like '%41' are
198 * not decoded.
200 * @return The uninterpreted connection name and parameters as string.
202 public String getConnectionAndParametersAsString() {
203 return connection.getUninterpretedString();
206 private static String decodeUTF8(String s)
207 throws com.sun.star.lang.IllegalArgumentException {
209 if (!s.contains("%")) {
210 return s;
212 try {
213 int length = s.length();
214 ByteBuffer bb = ByteBuffer.allocate(length);
215 for (int i = 0; i < length; i++) {
216 int ch = s.charAt(i);
218 if (ch == '%') {
219 if (i+3 > length)
220 throw new com.sun.star.lang.IllegalArgumentException(
221 "Incomplete trailing escape (%) pattern");
222 try {
223 ch = Integer.parseInt(s.substring(i+1,i+3),16);
224 } catch (NumberFormatException e) {
225 throw new com.sun.star.lang.IllegalArgumentException(e);
227 if (ch < 0)
228 throw new com.sun.star.lang.IllegalArgumentException(
229 "Illegal hex characters in escape (%) pattern - negative value");
230 i+=2;
233 bb.put((byte) (ch & 0xFF));
236 byte[] bytes = new byte[bb.position()];
237 System.arraycopy(bb.array(), 0, bytes, 0, bytes.length);
238 return new String(bytes, "UTF-8");
239 } catch (UnsupportedEncodingException e) {
240 throw new com.sun.star.lang.IllegalArgumentException(e,
241 "Couldn't convert parameter string to UTF-8 string");
245 private static HashMap<String,String> buildParamHashMap(String paramString)
246 throws com.sun.star.lang.IllegalArgumentException {
247 HashMap<String,String> params = new HashMap<String,String>();
249 int pos = 0;
251 while (true) {
252 char c = ',';
254 StringBuffer sb = new StringBuffer();
255 while ((pos < paramString.length())
256 && ((c = paramString.charAt(pos++)) != '=')) {
257 sb.append(c);
259 String aKey = sb.toString();
261 sb = new StringBuffer();
262 while ((pos < paramString.length())
263 && ((c = paramString.charAt(pos++)) != ',')
264 && c != ';') {
265 sb.append(c);
267 String aValue = sb.toString();
269 if ((aKey.length() > 0) && (aValue.length() > 0)) {
271 if (!isAlphaNumeric(aKey)) {
272 throw new com.sun.star.lang.IllegalArgumentException(
273 "The parameter key '"
274 + aKey
275 + "' may only consist of alpha numeric ASCII characters.");
278 if (!isValidString(aValue, VALUE_CHAR_SET + "%")) {
279 throw new com.sun.star.lang.IllegalArgumentException(
280 "The parameter value for key '" + aKey + "' contains illegal characters.");
283 params.put(aKey, decodeUTF8(aValue));
286 if ((pos >= paramString.length()) || (c != ','))
287 break;
291 return params;
294 private static UnoUrlPart parseUnoUrlPart(String thePart)
295 throws com.sun.star.lang.IllegalArgumentException {
296 String partName;
297 String theParamPart;
298 int index = thePart.indexOf(',');
299 if (index != -1) {
300 partName = thePart.substring(0, index).trim();
301 theParamPart = thePart.substring(index + 1).trim();
302 } else {
303 partName = thePart;
304 theParamPart = "";
307 if (!isAlphaNumeric(partName)) {
308 throw new com.sun.star.lang.IllegalArgumentException(
309 "The part name '"
310 + partName
311 + "' may only consist of alpha numeric ASCII characters.");
314 HashMap<String,String> params = buildParamHashMap(theParamPart);
316 return new UnoUrlPart(theParamPart, partName, params);
319 private static boolean isAlphaNumeric(String s) {
320 return isValidString(s, null);
323 private static boolean isValidString(String identifier, String validCharSet) {
325 int len = identifier.length();
327 for (int i = 0; i < len; i++) {
329 int ch = identifier.charAt(i);
331 boolean isValidChar =
332 ('A' <= ch && ch <= 'Z')
333 || ('a' <= ch && ch <= 'z')
334 || ('0' <= ch && ch <= '9');
336 if (!isValidChar && (validCharSet != null)) {
337 isValidChar = (validCharSet.indexOf(ch) != -1);
340 if (!isValidChar)
341 return false;
344 return true;
348 * Parses the given Uno Url and returns
349 * an in memory object representation.
351 * @param unoUrl The given uno URl as string.
352 * @return Object representation of class UnoUrl.
353 * @throws IllegalArgumentException if Url cannot be parsed.
355 public static UnoUrl parseUnoUrl(String unoUrl)
356 throws com.sun.star.lang.IllegalArgumentException {
358 String url = unoUrl;
360 int index = url.indexOf(':');
361 if (index != -1) {
362 String unoStr = url.substring(0, index).trim();
363 if (!"uno".equals(unoStr)) {
364 throw new com.sun.star.lang.IllegalArgumentException(
365 "Uno Urls must start with 'uno:'. " + FORMAT_ERROR);
369 url = url.substring(index + 1).trim();
371 index = url.indexOf(';');
372 if (index == -1) {
373 throw new com.sun.star.lang.IllegalArgumentException("'"+unoUrl+"' is an invalid Uno Url. " + FORMAT_ERROR);
376 String connection = url.substring(0, index).trim();
377 url = url.substring(index + 1).trim();
379 UnoUrlPart connectionPart = parseUnoUrlPart(connection);
381 index = url.indexOf(';');
382 if (index == -1) {
383 throw new com.sun.star.lang.IllegalArgumentException("'"+unoUrl+"' is an invalid Uno Url. " + FORMAT_ERROR);
386 String protocol = url.substring(0, index).trim();
387 url = url.substring(index + 1).trim();
389 UnoUrlPart protocolPart = parseUnoUrlPart(protocol);
391 String rootOid = url.trim();
392 if (!isValidString(rootOid, OID_CHAR_SET)) {
393 throw new com.sun.star.lang.IllegalArgumentException(
394 "Root OID '"+ rootOid + "' contains illegal characters.");
397 return new UnoUrl(connectionPart, protocolPart, rootOid);