1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: UnoUrl.java,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 package com
.sun
.star
.lib
.uno
.helper
;
32 import java
.io
.UnsupportedEncodingException
;
33 import java
.util
.HashMap
;
34 import java
.util
.Vector
;
37 * Object representation and parsing of Uno Urls,
38 * which allow to locate a named Uno object in a
39 * different process. An Uno Url consists of the
40 * specification of a connection, protocol and
41 * rootOid delimited with a ';'.
42 * The syntax of an Uno Url is
45 * [uno:]connection-type,parameters;protocol-name,parameters;objectname";
48 * An example Uno Url will look like this:
51 * socket,host=localhost,port=2002;urp;StarOffice.ServiceManager
54 * For more information about Uno Url please consult
55 * <a href="http://udk.openoffice.org/common/man/spec/uno-url.html">
56 * http://udk.openoffice.org/common/man/spec/uno-url.html</a>
61 * UnoUrl url = UnoUrl.parseUnoUrl("socket,host=localhost,port=2002;urp;StarOffice.ServiceManager");
64 * @author Joerg Brunsmann
68 private static final String FORMAT_ERROR
=
69 "syntax: [uno:]connection-type,parameters;protocol-name,parameters;objectname";
71 private static final String VALUE_CHAR_SET
= "!$&'()*+-./:?@_~";
72 private static final String OID_CHAR_SET
= VALUE_CHAR_SET
+ ",=";
74 private UnoUrlPart connection
;
75 private UnoUrlPart protocol
;
76 private String rootOid
;
78 static private class UnoUrlPart
{
80 private String partTypeName
;
81 private HashMap partParameters
;
82 private String uninterpretedParameterString
;
85 String uninterpretedParameterString
,
87 HashMap partParameters
) {
88 this.uninterpretedParameterString
= uninterpretedParameterString
;
89 this.partTypeName
= partTypeName
;
90 this.partParameters
= partParameters
;
93 public String
getPartTypeName() {
97 public HashMap
getPartParameters() {
98 return partParameters
;
101 public String
getUninterpretedParameterString() {
102 return uninterpretedParameterString
;
105 public String
getUninterpretedString() {
106 StringBuffer buf
= new StringBuffer(partTypeName
);
107 if (uninterpretedParameterString
.length() > 0) {
109 buf
.append(uninterpretedParameterString
);
111 return buf
.toString();
116 UnoUrlPart connectionPart
,
117 UnoUrlPart protocolPart
,
119 this.connection
= connectionPart
;
120 this.protocol
= protocolPart
;
121 this.rootOid
= rootOid
;
125 * Returns the name of the connection of this
126 * Uno Url. Encoded characters are not allowed.
128 * @return The connection name as string.
130 public String
getConnection() {
131 return connection
.getPartTypeName();
135 * Returns the name of the protocol of this
136 * Uno Url. Encoded characters are not allowed.
138 * @return The protocol name as string.
140 public String
getProtocol() {
141 return protocol
.getPartTypeName();
145 * Return the object name. Encoded character are
148 * @return The object name as String.
150 public String
getRootOid() {
155 * Returns the protocol parameters as
156 * a Hashmap with key/value pairs. Encoded
157 * characters like '%41' are decoded.
159 * @return a HashMap with key/value pairs for protocol parameters.
161 public HashMap
getProtocolParameters() {
162 return protocol
.getPartParameters();
166 * Returns the connection parameters as
167 * a Hashmap with key/value pairs. Encoded
168 * characters like '%41' are decoded.
170 * @return a HashMap with key/value pairs for connection parameters.
172 public HashMap
getConnectionParameters() {
173 return connection
.getPartParameters();
177 * Returns the raw specification of the protocol
178 * parameters. Encoded characters like '%41' are
181 * @return The uninterpreted protocol parameters as string.
183 public String
getProtocolParametersAsString() {
184 return protocol
.getUninterpretedParameterString();
188 * Returns the raw specification of the connection
189 * parameters. Encoded characters like '%41' are
192 * @return The uninterpreted connection parameters as string.
194 public String
getConnectionParametersAsString() {
195 return connection
.getUninterpretedParameterString();
199 * Returns the raw specification of the protocol
200 * name and parameters. Encoded characters like '%41' are
203 * @return The uninterpreted protocol name and parameters as string.
205 public String
getProtocolAndParametersAsString() {
206 return protocol
.getUninterpretedString();
210 * Returns the raw specification of the connection
211 * name and parameters. Encoded characters like '%41' are
214 * @return The uninterpreted connection name and parameters as string.
216 public String
getConnectionAndParametersAsString() {
217 return connection
.getUninterpretedString();
220 private static int hexToInt(int ch
)
221 throws com
.sun
.star
.lang
.IllegalArgumentException
{
222 int c
= Character
.toLowerCase((char) ch
);
223 boolean isDigit
= ('0' <= c
&& c
<= '9');
224 boolean isValidChar
= ('a' <= c
&& c
<= 'f') || isDigit
;
227 throw new com
.sun
.star
.lang
.IllegalArgumentException(
228 "Invalid UTF-8 hex byte '" + c
+ "'.");
230 return isDigit ? ch
- '0' : 10 + ((char) c
- 'a') & 0xF;
233 private static String
decodeUTF8(String s
)
234 throws com
.sun
.star
.lang
.IllegalArgumentException
{
235 Vector v
= new Vector();
237 for (int i
= 0; i
< s
.length(); i
++) {
238 int ch
= s
.charAt(i
);
241 int hb
= hexToInt(s
.charAt(++i
));
242 int lb
= hexToInt(s
.charAt(++i
));
246 v
.addElement(new Integer(ch
));
250 byte[] bytes
= new byte[size
];
251 for (int i
= 0; i
< size
; i
++) {
252 Integer anInt
= (Integer
) v
.elementAt(i
);
253 bytes
[i
] = (byte) (anInt
.intValue() & 0xFF);
257 return new String(bytes
, "UTF-8");
258 } catch (UnsupportedEncodingException e
) {
259 throw new com
.sun
.star
.lang
.IllegalArgumentException(
260 "Couldn't convert parameter string to UTF-8 string:" + e
.getMessage());
264 private static HashMap
buildParamHashMap(String paramString
)
265 throws com
.sun
.star
.lang
.IllegalArgumentException
{
266 HashMap params
= new HashMap();
275 while ((pos
< paramString
.length())
276 && ((c
= paramString
.charAt(pos
++)) != '=')) {
280 while ((pos
< paramString
.length())
281 && ((c
= paramString
.charAt(pos
++)) != ',')
286 if ((aKey
.length() > 0) && (aValue
.length() > 0)) {
288 if (!isAlphaNumeric(aKey
)) {
289 throw new com
.sun
.star
.lang
.IllegalArgumentException(
290 "The parameter key '"
292 + "' may only consist of alpha numeric ASCII characters.");
295 if (!isValidString(aValue
, VALUE_CHAR_SET
+ "%")) {
296 throw new com
.sun
.star
.lang
.IllegalArgumentException(
297 "The parameter value for key '" + aKey
+ "' contains illegal characters.");
300 params
.put(aKey
, decodeUTF8(aValue
));
303 if ((pos
>= paramString
.length()) || (c
!= ','))
311 private static UnoUrlPart
parseUnoUrlPart(String thePart
)
312 throws com
.sun
.star
.lang
.IllegalArgumentException
{
313 String partName
= thePart
;
314 String theParamPart
= "";
315 int index
= thePart
.indexOf(",");
317 partName
= thePart
.substring(0, index
).trim();
318 theParamPart
= thePart
.substring(index
+ 1).trim();
321 if (!isAlphaNumeric(partName
)) {
322 throw new com
.sun
.star
.lang
.IllegalArgumentException(
325 + "' may only consist of alpha numeric ASCII characters.");
328 HashMap params
= buildParamHashMap(theParamPart
);
330 return new UnoUrlPart(theParamPart
, partName
, params
);
333 private static boolean isAlphaNumeric(String s
) {
334 return isValidString(s
, null);
337 private static boolean isValidString(String identifier
, String validCharSet
) {
339 int len
= identifier
.length();
341 for (int i
= 0; i
< len
; i
++) {
343 int ch
= identifier
.charAt(i
);
345 boolean isValidChar
=
346 ('A' <= ch
&& ch
<= 'Z')
347 || ('a' <= ch
&& ch
<= 'z')
348 || ('0' <= ch
&& ch
<= '9');
350 if (!isValidChar
&& (validCharSet
!= null)) {
351 isValidChar
= (validCharSet
.indexOf(ch
) != -1);
362 * Parses the given Uno Url and returns
363 * an in memory object representation.
365 * @param unoUrl The given uno URl as string.
366 * @return Object representation of class UnoUrl.
367 * @throws IllegalArgumentException if Url cannot be parsed.
369 public static UnoUrl
parseUnoUrl(String unoUrl
)
370 throws com
.sun
.star
.lang
.IllegalArgumentException
{
374 int index
= url
.indexOf(':');
376 String unoStr
= url
.substring(0, index
).trim();
377 if (!"uno".equals(unoStr
)) {
378 throw new com
.sun
.star
.lang
.IllegalArgumentException(
379 "Uno Urls must start with 'uno:'. " + FORMAT_ERROR
);
383 url
= url
.substring(index
+ 1).trim();
385 index
= url
.indexOf(';');
387 throw new com
.sun
.star
.lang
.IllegalArgumentException("'"+unoUrl
+"' is an invalid Uno Url. " + FORMAT_ERROR
);
390 String connection
= url
.substring(0, index
).trim();
391 url
= url
.substring(index
+ 1).trim();
393 UnoUrlPart connectionPart
= parseUnoUrlPart(connection
);
395 index
= url
.indexOf(';');
397 throw new com
.sun
.star
.lang
.IllegalArgumentException("'"+unoUrl
+"' is an invalid Uno Url. " + FORMAT_ERROR
);
400 String protocol
= url
.substring(0, index
).trim();
401 url
= url
.substring(index
+ 1).trim();
403 UnoUrlPart protocolPart
= parseUnoUrlPart(protocol
);
405 String rootOid
= url
.trim();
406 if (!isValidString(rootOid
, OID_CHAR_SET
)) {
407 throw new com
.sun
.star
.lang
.IllegalArgumentException(
408 "Root OID '"+ rootOid
+ "' contains illegal characters.");
411 return new UnoUrl(connectionPart
, protocolPart
, rootOid
);