All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.star.lib.uno.helper.UnoUrl Maven / Gradle / Ivy

Go to download

Allows the boostrapping of a ServicemManager and gives access to the native component loader.

The newest version!
/**************************************************************
 * 
 * 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
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



package com.sun.star.lib.uno.helper;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Vector;

/**
 * Object representation and parsing of Uno Urls,
 * which allow to locate a named Uno object in a 
 * different process. An Uno Url consists of the 
 * specification of a connection, protocol and 
 * rootOid delimited with a ';'.
 * The syntax of an Uno Url is
 * 
 * 
 * [uno:]connection-type,parameters;protocol-name,parameters;objectname";
 * 
 * 
 * An example Uno Url will look like this:
 * 
 * 
 * socket,host=localhost,port=2002;urp;StarOffice.ServiceManager
 * 
 * 
 * For more information about Uno Url please consult
 * 
 * http://udk.openoffice.org/common/man/spec/uno-url.html
 * 
 * Usage:
 * 
 * 
 *   UnoUrl url = UnoUrl.parseUnoUrl("socket,host=localhost,port=2002;urp;StarOffice.ServiceManager");
 * 
 *
 * @author Joerg Brunsmann
 */
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 UnoUrlPart connection;
	private UnoUrlPart protocol;
	private String rootOid;

	static private class UnoUrlPart {

		private String partTypeName;
		private HashMap partParameters;
		private String uninterpretedParameterString;

		public UnoUrlPart(
			String uninterpretedParameterString,
			String partTypeName,
			HashMap partParameters) {
			this.uninterpretedParameterString = uninterpretedParameterString;
			this.partTypeName = partTypeName;
			this.partParameters = partParameters;
		}

		public String getPartTypeName() {
			return partTypeName;
		}

		public HashMap 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 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 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 int hexToInt(int ch)
		throws com.sun.star.lang.IllegalArgumentException {
		int c = Character.toLowerCase((char) ch);
		boolean isDigit = ('0' <= c && c <= '9');
		boolean isValidChar = ('a' <= c && c <= 'f') || isDigit;

		if (!isValidChar)
			throw new com.sun.star.lang.IllegalArgumentException(
				"Invalid UTF-8 hex byte '" + c + "'.");

		return isDigit ? ch - '0' : 10 + ((char) c - 'a') & 0xF;
	}

	private static String decodeUTF8(String s)
		throws com.sun.star.lang.IllegalArgumentException {
		Vector v = new Vector();

		for (int i = 0; i < s.length(); i++) {
			int ch = s.charAt(i);

			if (ch == '%') {
				int hb = hexToInt(s.charAt(++i));
				int lb = hexToInt(s.charAt(++i));
				ch = (hb << 4) | lb;
			}

			v.addElement(new Integer(ch));
		}

		int size = v.size();
		byte[] bytes = new byte[size];
		for (int i = 0; i < size; i++) {
			Integer anInt = (Integer) v.elementAt(i);
			bytes[i] = (byte) (anInt.intValue() & 0xFF);
		}

		try {
			return new String(bytes, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			throw new com.sun.star.lang.IllegalArgumentException(
				"Couldn't convert parameter string to UTF-8 string:" + e.getMessage());
		}
	}

	private static HashMap buildParamHashMap(String paramString)
		throws com.sun.star.lang.IllegalArgumentException {
		HashMap params = new HashMap();

		int pos = 0;

		while (true) {
			char c = ',';
			String aKey = "";
			String aValue = "";

			while ((pos < paramString.length())
				&& ((c = paramString.charAt(pos++)) != '=')) {
				aKey += c;
			}

			while ((pos < paramString.length())
				&& ((c = paramString.charAt(pos++)) != ',')
				&& c != ';') {
				aValue += c;
			}

			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 = thePart;
		String theParamPart = "";
		int index = thePart.indexOf(",");
		if (index != -1) {
			partName = thePart.substring(0, index).trim();
			theParamPart = thePart.substring(index + 1).trim();
		}

		if (!isAlphaNumeric(partName)) {
			throw new com.sun.star.lang.IllegalArgumentException(
				"The part name '"
					+ partName
					+ "' may only consist of alpha numeric ASCII characters.");
		}

		HashMap 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);

	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy