/* * 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 org.apache.activemq.artemis.utils.uri; import java.net.URI; import java.net.URISyntaxException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class URIFactory<T, P> { private URI defaultURI; private final Map<String, URISchema<T, P>> schemas = new ConcurrentHashMap<>(); public URI getDefaultURI() { return defaultURI; } public void setDefaultURI(URI uri) { this.defaultURI = uri; } public void registerSchema(URISchema<T, P> schemaFactory) { schemas.put(schemaFactory.getSchemaName(), schemaFactory); schemaFactory.setFactory(this); } public void removeSchema(final String schemaName) { schemas.remove(schemaName); } public URI expandURI(String uriString) throws Exception { return normalise(uriString); } public T newObject(URI uri, P param) throws Exception { URISchema<T, P> schemaFactory = schemas.get(uri.getScheme()); if (schemaFactory == null) { throw new NullPointerException("Schema " + uri.getScheme() + " not found"); } return schemaFactory.newObject(uri, param); } public T newObject(String uri, P param) throws Exception { return newObject(new URI(uri), param); } public void populateObject(URI uri, T bean) throws Exception { URISchema<T, P> schemaFactory = schemas.get(uri.getScheme()); if (schemaFactory == null) { throw new NullPointerException("Schema " + uri.getScheme() + " not found"); } schemaFactory.populateObject(uri, bean); } public void populateObject(String uri, T bean) throws Exception { populateObject(new URI(uri), bean); } public URI createSchema(String scheme, T bean) throws Exception { URISchema<T, P> schemaFactory = schemas.get(scheme); if (schemaFactory == null) { throw new NullPointerException("Schema " + scheme + " not found"); } return schemaFactory.newURI(bean); } /* * this method is used to change a string with multiple URI's in it into a valid URI. * for instance it is possible to have the following String * (tcp://localhost:61616,tcp://localhost:5545,tcp://localhost:5555)?somequery * This is an invalid URI so will be changed so that the first URI is used and the * extra ones added as part of the URI fragment, like so * tcp://localhost:61616?someQuery#tcp://localhost:5545,tcp://localhost:5555. * * It is the job of the URISchema implementation to handle these fragments as needed. * */ private URI normalise(String uri) throws URISyntaxException { if (uri.startsWith("(")) { String[] split = uri.split("\\)"); String[] connectorURIS = split[0].substring(split[0].indexOf('(') + 1).split(","); String factoryQuery = split.length > 1 ? split[1] : ""; StringBuilder builder = new StringBuilder(connectorURIS[0]); if (factoryQuery != null && factoryQuery.length() > 0) { if (connectorURIS[0].contains("?")) { builder.append("&").append(factoryQuery.substring(1)); } else { builder.append(factoryQuery); } } if (connectorURIS.length > 1) { builder.append("#"); for (int i = 1; i < connectorURIS.length; i++) { if (i > 1) { builder.append(","); } builder.append(connectorURIS[i]); } } return new URI(builder.toString().replace(";", "&")); } return new URI(uri.replace(";", "&")); } }