merge the formfield patch from ooo-build
[ooovba.git] / javaunohelper / com / sun / star / lib / uno / helper / UnoUrl.java
blobb46662ab229338b1039a9287dd1f4bac19811fbc
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: UnoUrl.java,v $
10 * $Revision: 1.6 $
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;
36 /**
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
44 * <code>
45 * [uno:]connection-type,parameters;protocol-name,parameters;objectname";
46 * </code>
48 * An example Uno Url will look like this:
50 * <code>
51 * socket,host=localhost,port=2002;urp;StarOffice.ServiceManager
52 * </code>
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>
58 * Usage:
60 * <code>
61 * UnoUrl url = UnoUrl.parseUnoUrl("socket,host=localhost,port=2002;urp;StarOffice.ServiceManager");
62 * </code>
64 * @author Joerg Brunsmann
66 public class UnoUrl {
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;
84 public UnoUrlPart(
85 String uninterpretedParameterString,
86 String partTypeName,
87 HashMap partParameters) {
88 this.uninterpretedParameterString = uninterpretedParameterString;
89 this.partTypeName = partTypeName;
90 this.partParameters = partParameters;
93 public String getPartTypeName() {
94 return partTypeName;
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) {
108 buf.append(',');
109 buf.append(uninterpretedParameterString);
111 return buf.toString();
115 private UnoUrl(
116 UnoUrlPart connectionPart,
117 UnoUrlPart protocolPart,
118 String rootOid) {
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
146 * not allowed.
148 * @return The object name as String.
150 public String getRootOid() {
151 return rootOid;
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
179 * not decoded.
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
190 * not decoded.
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
201 * not decoded.
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
212 * not decoded.
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;
226 if (!isValidChar)
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);
240 if (ch == '%') {
241 int hb = hexToInt(s.charAt(++i));
242 int lb = hexToInt(s.charAt(++i));
243 ch = (hb << 4) | lb;
246 v.addElement(new Integer(ch));
249 int size = v.size();
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);
256 try {
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();
268 int pos = 0;
270 while (true) {
271 char c = ',';
272 String aKey = "";
273 String aValue = "";
275 while ((pos < paramString.length())
276 && ((c = paramString.charAt(pos++)) != '=')) {
277 aKey += c;
280 while ((pos < paramString.length())
281 && ((c = paramString.charAt(pos++)) != ',')
282 && c != ';') {
283 aValue += c;
286 if ((aKey.length() > 0) && (aValue.length() > 0)) {
288 if (!isAlphaNumeric(aKey)) {
289 throw new com.sun.star.lang.IllegalArgumentException(
290 "The parameter key '"
291 + aKey
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 != ','))
304 break;
308 return params;
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(",");
316 if (index != -1) {
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(
323 "The part name '"
324 + partName
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);
354 if (!isValidChar)
355 return false;
358 return true;
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 {
372 String url = unoUrl;
374 int index = url.indexOf(':');
375 if (index != -1) {
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(';');
386 if (index == -1) {
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(';');
396 if (index == -1) {
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);