diff options
Diffstat (limited to 'ridljar/com/sun/star/lib/uno/helper/UnoUrl.java')
-rw-r--r-- | ridljar/com/sun/star/lib/uno/helper/UnoUrl.java | 401 |
1 files changed, 401 insertions, 0 deletions
diff --git a/ridljar/com/sun/star/lib/uno/helper/UnoUrl.java b/ridljar/com/sun/star/lib/uno/helper/UnoUrl.java new file mode 100644 index 000000000..8bb4d2643 --- /dev/null +++ b/ridljar/com/sun/star/lib/uno/helper/UnoUrl.java @@ -0,0 +1,401 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +package com.sun.star.lib.uno.helper; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.HashMap; + +/** + * Object representation and parsing of Uno Urls, + * which allow to locate a named Uno object in a + * different process. A Uno Url consists of the + * specification of a connection, protocol and + * rootOid delimited with a ';'. + * The syntax of a Uno Url is + * + * <code> + * [uno:]connection-type,parameters;protocol-name,parameters;objectname"; + * </code> + * + * An example Uno Url will look like this: + * + * <code> + * socket,host=localhost,port=2002;urp;StarOffice.ServiceManager + * </code> + * + * For more information about Uno Url please consult + * <a href="http://udk.openoffice.org/common/man/spec/uno-url.html"> + * http://udk.openoffice.org/common/man/spec/uno-url.html</a> + * + * Usage: + * + * <code> + * UnoUrl url = UnoUrl.parseUnoUrl("socket,host=localhost,port=2002;urp;StarOffice.ServiceManager"); + * </code> + */ +public class UnoUrl { + + private static final String FORMAT_ERROR = + "syntax: [uno:]connection-type,parameters;protocol-name,parameters;objectname"; + + private static final String VALUE_CHAR_SET = "!$&'()*+-./:?@_~"; + private static final String OID_CHAR_SET = VALUE_CHAR_SET + ",="; + + private final UnoUrlPart connection; + private final UnoUrlPart protocol; + private final String rootOid; + + private static class UnoUrlPart { + + private final String partTypeName; + private final HashMap<String,String> partParameters; + private final String uninterpretedParameterString; + + public UnoUrlPart( + String uninterpretedParameterString, + String partTypeName, + HashMap<String,String> partParameters) { + this.uninterpretedParameterString = uninterpretedParameterString; + this.partTypeName = partTypeName; + this.partParameters = partParameters; + } + + public String getPartTypeName() { + return partTypeName; + } + + public HashMap<String,String> getPartParameters() { + return partParameters; + } + + public String getUninterpretedParameterString() { + return uninterpretedParameterString; + } + + public String getUninterpretedString() { + StringBuffer buf = new StringBuffer(partTypeName); + if (uninterpretedParameterString.length() > 0) { + buf.append(','); + buf.append(uninterpretedParameterString); + } + return buf.toString(); + } + } + + private UnoUrl( + UnoUrlPart connectionPart, + UnoUrlPart protocolPart, + String rootOid) { + this.connection = connectionPart; + this.protocol = protocolPart; + this.rootOid = rootOid; + } + + /** + * Returns the name of the connection of this + * Uno Url. Encoded characters are not allowed. + * + * @return The connection name as string. + */ + public String getConnection() { + return connection.getPartTypeName(); + } + + /** + * Returns the name of the protocol of this + * Uno Url. Encoded characters are not allowed. + * + * @return The protocol name as string. + */ + public String getProtocol() { + return protocol.getPartTypeName(); + } + + /** + * Return the object name. Encoded character are + * not allowed. + * + * @return The object name as String. + */ + public String getRootOid() { + return rootOid; + } + + /** + * Returns the protocol parameters as + * a Hashmap with key/value pairs. Encoded + * characters like '%41' are decoded. + * + * @return a HashMap with key/value pairs for protocol parameters. + */ + public HashMap<String,String> getProtocolParameters() { + return protocol.getPartParameters(); + } + + /** + * Returns the connection parameters as + * a Hashmap with key/value pairs. Encoded + * characters like '%41' are decoded. + * + * @return a HashMap with key/value pairs for connection parameters. + */ + public HashMap<String,String> getConnectionParameters() { + return connection.getPartParameters(); + } + + /** + * Returns the raw specification of the protocol + * parameters. Encoded characters like '%41' are + * not decoded. + * + * @return The uninterpreted protocol parameters as string. + */ + public String getProtocolParametersAsString() { + return protocol.getUninterpretedParameterString(); + } + + /** + * Returns the raw specification of the connection + * parameters. Encoded characters like '%41' are + * not decoded. + * + * @return The uninterpreted connection parameters as string. + */ + public String getConnectionParametersAsString() { + return connection.getUninterpretedParameterString(); + } + + /** + * Returns the raw specification of the protocol + * name and parameters. Encoded characters like '%41' are + * not decoded. + * + * @return The uninterpreted protocol name and parameters as string. + */ + public String getProtocolAndParametersAsString() { + return protocol.getUninterpretedString(); + } + + /** + * Returns the raw specification of the connection + * name and parameters. Encoded characters like '%41' are + * not decoded. + * + * @return The uninterpreted connection name and parameters as string. + */ + public String getConnectionAndParametersAsString() { + return connection.getUninterpretedString(); + } + + private static String decodeUTF8(String s) + throws com.sun.star.lang.IllegalArgumentException { + + if (!s.contains("%")) { + return s; + } + try { + int length = s.length(); + ByteBuffer bb = ByteBuffer.allocate(length); + for (int i = 0; i < length; i++) { + int ch = s.charAt(i); + + if (ch == '%') { + if (i+3 > length) + throw new com.sun.star.lang.IllegalArgumentException( + "Incomplete trailing escape (%) pattern"); + try { + ch = Integer.parseInt(s.substring(i+1,i+3),16); + } catch (NumberFormatException e) { + throw new com.sun.star.lang.IllegalArgumentException(e); + } + if (ch < 0) + throw new com.sun.star.lang.IllegalArgumentException( + "Illegal hex characters in escape (%) pattern - negative value"); + i+=2; + } + + bb.put((byte) (ch & 0xFF)); + } + + byte[] bytes = new byte[bb.position()]; + System.arraycopy(bb.array(), 0, bytes, 0, bytes.length); + return new String(bytes, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new com.sun.star.lang.IllegalArgumentException(e, + "Couldn't convert parameter string to UTF-8 string"); + } + } + + private static HashMap<String,String> buildParamHashMap(String paramString) + throws com.sun.star.lang.IllegalArgumentException { + HashMap<String,String> params = new HashMap<String,String>(); + + int pos = 0; + + while (true) { + char c = ','; + + StringBuffer sb = new StringBuffer(); + while ((pos < paramString.length()) + && ((c = paramString.charAt(pos++)) != '=')) { + sb.append(c); + } + String aKey = sb.toString(); + + sb = new StringBuffer(); + while ((pos < paramString.length()) + && ((c = paramString.charAt(pos++)) != ',') + && c != ';') { + sb.append(c); + } + String aValue = sb.toString(); + + if ((aKey.length() > 0) && (aValue.length() > 0)) { + + if (!isAlphaNumeric(aKey)) { + throw new com.sun.star.lang.IllegalArgumentException( + "The parameter key '" + + aKey + + "' may only consist of alpha numeric ASCII characters."); + } + + if (!isValidString(aValue, VALUE_CHAR_SET + "%")) { + throw new com.sun.star.lang.IllegalArgumentException( + "The parameter value for key '" + aKey + "' contains illegal characters."); + } + + params.put(aKey, decodeUTF8(aValue)); + } + + if ((pos >= paramString.length()) || (c != ',')) + break; + + } + + return params; + } + + private static UnoUrlPart parseUnoUrlPart(String thePart) + throws com.sun.star.lang.IllegalArgumentException { + String partName; + String theParamPart; + int index = thePart.indexOf(','); + if (index != -1) { + partName = thePart.substring(0, index).trim(); + theParamPart = thePart.substring(index + 1).trim(); + } else { + partName = thePart; + theParamPart = ""; + } + + if (!isAlphaNumeric(partName)) { + throw new com.sun.star.lang.IllegalArgumentException( + "The part name '" + + partName + + "' may only consist of alpha numeric ASCII characters."); + } + + HashMap<String,String> params = buildParamHashMap(theParamPart); + + return new UnoUrlPart(theParamPart, partName, params); + } + + private static boolean isAlphaNumeric(String s) { + return isValidString(s, null); + } + + private static boolean isValidString(String identifier, String validCharSet) { + + int len = identifier.length(); + + for (int i = 0; i < len; i++) { + + int ch = identifier.charAt(i); + + boolean isValidChar = + ('A' <= ch && ch <= 'Z') + || ('a' <= ch && ch <= 'z') + || ('0' <= ch && ch <= '9'); + + if (!isValidChar && (validCharSet != null)) { + isValidChar = (validCharSet.indexOf(ch) != -1); + } + + if (!isValidChar) + return false; + } + + return true; + } + + /** + * Parses the given Uno Url and returns + * an in memory object representation. + * + * @param unoUrl The given uno URl as string. + * @return Object representation of class UnoUrl. + * @throws IllegalArgumentException if Url cannot be parsed. + */ + public static UnoUrl parseUnoUrl(String unoUrl) + throws com.sun.star.lang.IllegalArgumentException { + + String url = unoUrl; + + int index = url.indexOf(':'); + if (index != -1) { + String unoStr = url.substring(0, index).trim(); + if (!"uno".equals(unoStr)) { + throw new com.sun.star.lang.IllegalArgumentException( + "Uno Urls must start with 'uno:'. " + FORMAT_ERROR); + } + } + + url = url.substring(index + 1).trim(); + + index = url.indexOf(';'); + if (index == -1) { + throw new com.sun.star.lang.IllegalArgumentException("'"+unoUrl+"' is an invalid Uno Url. " + FORMAT_ERROR); + } + + String connection = url.substring(0, index).trim(); + url = url.substring(index + 1).trim(); + + UnoUrlPart connectionPart = parseUnoUrlPart(connection); + + index = url.indexOf(';'); + if (index == -1) { + throw new com.sun.star.lang.IllegalArgumentException("'"+unoUrl+"' is an invalid Uno Url. " + FORMAT_ERROR); + } + + String protocol = url.substring(0, index).trim(); + url = url.substring(index + 1).trim(); + + UnoUrlPart protocolPart = parseUnoUrlPart(protocol); + + String rootOid = url.trim(); + if (!isValidString(rootOid, OID_CHAR_SET)) { + throw new com.sun.star.lang.IllegalArgumentException( + "Root OID '"+ rootOid + "' contains illegal characters."); + } + + return new UnoUrl(connectionPart, protocolPart, rootOid); + + } + +} |