package com.github.gquintana.metrics.sql; /* * #%L * Metrics SQL * %% * Copyright (C) 2014 Open-Source * %% * Licensed 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. * #L% */ import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.github.gquintana.metrics.proxy.CGLibProxyFactory; import com.github.gquintana.metrics.proxy.AbstractProxyFactory; import com.github.gquintana.metrics.proxy.CachingProxyFactory; import com.github.gquintana.metrics.proxy.ReflectProxyFactory; import com.github.gquintana.metrics.util.MetricRegistryHolder; import com.github.gquintana.metrics.util.StaticMetricRegistryHolder; /** * Driver URL. * Parses URL and extract properties */ class DriverUrl { public static final String URL_PREFIX="jdbc:metrics:"; private final String rawUrl; private final String cleanUrl; private final String databaseType; private final Properties properties; public DriverUrl(String rawUrl, String cleanUrl, String databaseType, Properties properties) { this.rawUrl = rawUrl; this.cleanUrl = cleanUrl; this.databaseType = databaseType; this.properties = properties; } private static final Pattern PATTERN = Pattern.compile("^jdbc:metrics:(([\\w]+):[^?;]+)(?:([?;])(.*))?$"); private static Properties parseProperties(String urlProps, String propSep, StringBuilder cleanUrlBuilder) { Properties properties = new Properties(); boolean first=true; for(String sProp:urlProps.split(propSep)) { if (sProp.startsWith("metrics_")) { String[] subProp=sProp.split("="); properties.put(subProp[0], subProp[1]); } else { if (first) { first=false; } else { cleanUrlBuilder.append(propSep); } cleanUrlBuilder.append(sProp); } } return properties; } public static DriverUrl parse(String rawUrl) { Matcher matcher = PATTERN.matcher(rawUrl); StringBuilder cleanUrlBuilder = new StringBuilder("jdbc:"); Properties properties = null; String dbType; String cleanUrl; if (matcher.matches()) { // mysql://localhost:3306/sakila cleanUrlBuilder.append(matcher.group(1)); // mysql dbType = matcher.group(2); // ? or ; String sep = matcher.group(3); String sProps = matcher.group(4); if (sep!=null && sProps!=null) { cleanUrlBuilder.append(sep); if (sep.equals("?")) { properties = parseProperties(sProps, "&", cleanUrlBuilder); } else if (sep.equals(";")) { properties = parseProperties(sProps, ";", cleanUrlBuilder); } cleanUrl = cleanUrlBuilder.toString(); if (cleanUrl.endsWith(sep)) { cleanUrl = cleanUrl.substring(0, cleanUrl.length() - sep.length()); } } else{ cleanUrl = cleanUrlBuilder.toString(); } } else { throw new IllegalArgumentException("Missing prefix "+URL_PREFIX); } return new DriverUrl(rawUrl, cleanUrl, dbType, properties); } public String getRawUrl() { return rawUrl; } public String getCleanUrl() { return cleanUrl; } public String getDatabaseType() { return databaseType; } public Properties getProperties() { return properties; } public <T> T getProperty(String key, Class<T> type) { if (properties == null) { return null; } String sVal = properties.getProperty(key); if (sVal == null) { return null; } else if (type.equals(String.class)) { return type.cast(sVal); } else if (type.equals(Class.class)) { try { return type.cast(Class.forName(sVal)); } catch (ClassNotFoundException classNotFoundException) { throw new IllegalArgumentException("Property "+sVal+" is not a valid class", classNotFoundException); } } else { throw new IllegalArgumentException("Property type "+type+" not supported"); } } public <T> T getProperty(String key, Class<T> type, T def) { T val = getProperty(key, type); if (val == null) { val = def; } return val; } public Class<? extends Driver> getDriverClass() { return getProperty("metrics_driver", Class.class); } public Class<? extends AbstractProxyFactory> getProxyFactoryClass() { Class<? extends AbstractProxyFactory> factoryClass; String s = getProperty("metrics_proxy_factory", String.class); if (s==null || s.equals("reflect")) { factoryClass = ReflectProxyFactory.class; } else if (s.equalsIgnoreCase("cglib")) { factoryClass = CGLibProxyFactory.class; } else if (s.equalsIgnoreCase("caching")) { factoryClass = CachingProxyFactory.class; } else { factoryClass = getProperty("metrics_proxy_factory", Class.class); } return factoryClass; } /** * @return Class extending {@link MetricNamingStrategy} */ public Class<? extends MetricNamingStrategy> getNamingStrategyClass() { return getProperty("metrics_naming_strategy", Class.class, DefaultMetricNamingStrategy.class); } /** * @return Class extending {@link MetricNamingStrategy} */ public Class<? extends MetricRegistryHolder> getRegistryHolderClass() { return getProperty("metrics_registry_holder", Class.class, StaticMetricRegistryHolder.class); } /** * @return Connection factory name */ public String getName() { return getProperty("metrics_name", String.class, databaseType+"_driver"); } }