/* * 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.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.util.HashMap; import java.util.Map; public abstract class URISchema<T, P> { public abstract String getSchemaName(); public T newObject(URI uri, P param) throws Exception { return newObject(uri, null, param); } public void populateObject(URI uri, T bean) throws Exception { BeanSupport.setData(uri, bean, parseQuery(uri.getQuery(), null)); } public URI newURI(T bean) throws Exception { return internalNewURI(bean); } private URIFactory<T, P> parentFactory; void setFactory(URIFactory<T, P> factory) { this.parentFactory = factory; } protected URIFactory<T, P> getFactory() { return parentFactory; } protected String getHost(URI uri) { URI defaultFactory = getDefaultURI(); if (defaultFactory != null && uri.getHost() == null && defaultFactory.getScheme().equals(uri.getScheme())) { uri = defaultFactory; } return uri.getHost(); } protected URI getDefaultURI() { URIFactory<T, P> factory = getFactory(); if (factory == null) { return null; } else { return factory.getDefaultURI(); } } protected int getPort(URI uri) { URI defaultFactory = getDefaultURI(); if (defaultFactory != null && uri.getPort() < 0 && defaultFactory.getScheme().equals(uri.getScheme())) { uri = defaultFactory; } return uri.getPort(); } /** * It will create a new Object for the URI selected schema. * the propertyOverrides is used to replace whatever was defined on the URL string * * @param uri The URI * @param propertyOverrides used to replace whatever was defined on the URL string * @return new Object * @throws Exception On error */ public T newObject(URI uri, Map<String, String> propertyOverrides, P param) throws Exception { return internalNewObject(uri, parseQuery(uri.getQuery(), propertyOverrides), param); } protected abstract T internalNewObject(URI uri, Map<String, String> query, P param) throws Exception; /** * This is the default implementation. * Sub classes are should provide a proper implementation for their schemas. */ protected URI internalNewURI(T bean) throws Exception { String query = BeanSupport.getData(null, bean); return new URI(getSchemaName(), null, "//", query, null); } public static Map<String, String> parseQuery(String uri, Map<String, String> propertyOverrides) throws URISyntaxException { try { Map<String, String> rc = new HashMap<>(); if (uri != null && !uri.isEmpty()) { String[] parameters = uri.split("&"); for (String parameter : parameters) { int p = parameter.indexOf("="); if (p >= 0) { String name = BeanSupport.decodeURI(parameter.substring(0, p)); String value = BeanSupport.decodeURI(parameter.substring(p + 1)); rc.put(name, value); } else { if (!parameter.trim().isEmpty()) { rc.put(parameter, null); } } } } if (propertyOverrides != null) { for (Map.Entry<String, String> entry : propertyOverrides.entrySet()) { rc.put(entry.getKey(), entry.getValue()); } } return rc; } catch (UnsupportedEncodingException e) { throw (URISyntaxException) new URISyntaxException(e.toString(), "Invalid encoding").initCause(e); } } protected String printQuery(Map<String, String> query) { StringBuffer buffer = new StringBuffer(); for (Map.Entry<String, String> entry : query.entrySet()) { buffer.append(entry.getKey() + "=" + entry.getValue()); buffer.append("\n"); } return buffer.toString(); } }