/** * Helios, OpenSource Monitoring * Brought to you by the Helios Development Group * * Copyright 2007, Helios Development Group and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. * */ package org.helios.collector.jdbc.binding.provider; import org.apache.log4j.Logger; import java.util.HashSet; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * <p>Title: ProviderToken</p> * <p>Description: Parser and value container utility class for bind variable provider tokens.</p> * <p>Company: Helios Development Group</p> * @author Whitehead (whitehead.nicholas@gmail.com) * @version $LastChangedRevision$ * $HeadURL$ * $Id$ * org.helios.collectors.jdbc.binding.provider.ProviderToken */ public class ProviderToken { /** The provider type key */ private String providerTypeKey = null; /** The provider configuration string */ private String providerConfig = null; /** The provider instance key */ private String instanceKey = null; /** The binder token key */ private String binderTokenKey = null; /** The binder configuration string */ private String binderConfig = null; /** The force no bind tag */ private boolean forceNoBind = false; /** The whole token */ private String providerToken = null; /** Class logger */ private static final Logger LOG = Logger.getLogger(ProviderToken.class); /** The provider token parsing regular expression */ //public static final Pattern BIND_VAR_PATTERN = Pattern.compile("(?:!?\\{(.*?):(.*)+?:(.*?)(?:\\[(\\S+?)(?::(\\S+))?\\])*\\})", Pattern.CASE_INSENSITIVE); //public static final Pattern BIND_VAR_PATTERN = Pattern.compile("(?:!?\\{+?(.*?):(.*)+?:(.*?)?\\})(?:\\[(\\S+?)(?::(\\S+))?\\])?", Pattern.CASE_INSENSITIVE); //public static final Pattern BIND_VAR_PATTERN = Pattern.compile("(?:\\{+?(.*?):(.*?):(.*?)?\\})+?", Pattern.CASE_INSENSITIVE); public static final String providerPattern = "(?:!?\\{+?(.*?):(?:\\(+(.*?)\\)+)?:(.*?)?\\})"; public static final String binderPattern = "(?:\\[(\\S+?)(?::(\\S+))?\\])?"; public static final Pattern BIND_VAR_PATTERN = Pattern.compile(providerPattern + binderPattern, Pattern.CASE_INSENSITIVE); public static void main(String[] args) { try { ProviderToken pt = null; for(int i = 0; i < 1; i++) { //pt = ProviderToken.parse("{MINIMUM:XXX,YYY:A}[Binder:FFF,GGG]"); pt = ProviderToken.parse("tomorrow it will be !{SysTime:(+1d:MM/dd/yyyy HH:mm:ss):AA}"); } System.out.println("Config:" + pt.getProviderConfig()); System.out.println("Instance Key:" + pt.getInstanceKey()); } catch (InvalidProviderTokenFormat e) { e.printStackTrace(); } } /** * Parses the passed provider token and returns a validated ProviderToken instance. * @param token The string token representing a bind provider instance. * @return a validated ProviderToken instance * @throws InvalidProviderTokenFormat thrown if the token cannot be parsed or is invalid. */ public static ProviderToken parse(String token) throws InvalidProviderTokenFormat { if(token==null) throw new InvalidProviderTokenFormat("Passed token was null"); ProviderToken pt = null; Matcher m = BIND_VAR_PATTERN.matcher(token); if(!m.find()) throw new InvalidProviderTokenFormat("No match found for token [" + token + "]"); try { pt = new ProviderToken(m.group(), m.group(1), m.group(2), m.group(3), m.group(4), m.group(5), m.group().startsWith("!")); return pt; } catch (Exception e) { throw new InvalidProviderTokenFormat("Unexpected exception while parsing token [" + token + "]", e); } } /** * Extracts any located tokens in a string. * @param sentence A string potentially contaiing zero, one or more tokens. * @return An array of located tokens. * @throws InvalidProviderTokenFormat */ public static ProviderToken[] process(String sentence) throws InvalidProviderTokenFormat { Set<ProviderToken> tokens = new HashSet<ProviderToken>(); Matcher m = BIND_VAR_PATTERN.matcher(sentence); while(m.find()) { String token = m.group(); if(LOG.isDebugEnabled()) { LOG.debug("process() found token [" + token + "]"); } tokens.add(parse(token)); } return tokens.toArray(new ProviderToken[tokens.size()]); } /** * Creates a new provider token value object. * @param providerToken * @param providerTypeKey * @param providerConfig * @param instanceKey * @param binderTokenKey * @param binderConfig * @!param forceNoBind Indicates the token started with a <code>!</code> meaning it is a forceNoBind. * @throws InvalidProviderTokenFormat */ private ProviderToken(String providerToken, String providerTypeKey, String providerConfig, String instanceKey, String binderTokenKey, String binderConfig, boolean forceNoBind) throws InvalidProviderTokenFormat { if(providerTypeKey==null || providerTypeKey.length() <1) throw new InvalidProviderTokenFormat("No value provided for mandatory field [Provider Type Key]"); if(instanceKey==null) throw new InvalidProviderTokenFormat("No value provided for mandatory field [Instance Key]"); this.providerToken = providerToken; this.providerTypeKey = providerTypeKey; this.instanceKey = instanceKey; this.providerConfig = ("".equals(providerConfig) ? null : providerConfig); this.binderTokenKey = ("".equals(binderTokenKey) ? null : binderTokenKey); this.binderConfig = ("".equals(binderConfig) ? null : binderConfig); if((this.binderConfig!=null && this.binderTokenKey==null) || (this.binderTokenKey!=null && this.binderTokenKey.startsWith(":") && this.binderConfig==null ) ) throw new InvalidProviderTokenFormat("Binder configuration provided with no binder token key"); this.forceNoBind = forceNoBind; } /** * Returns true if a binder has been defined * @return true if a binder has been defined */ public boolean isBinderDefined() { return binderTokenKey!=null; } /** * Returns true if a binder has been defined and has config * @return true if a binder with config has been defined */ public boolean isBinderConfigDefined() { return binderTokenKey!=null && binderConfig != null; } /** * Returns true if the provider has config * @return true if the provider has config */ public boolean isProviderConfigDefined() { return providerConfig != null; } /** * Returns the whole binder token i.e. <code><b>binder token key</b>:<b>binder config</b></code> * @return the binder token */ public String getBinderToken() { if(!isBinderDefined()) throw new RuntimeException("Cannot request binder token when no binder was defined"); return this.binderTokenKey + (this.binderConfig==null ? "" : ":" + this.binderConfig); } /** * The provider type key that uniquely identifies the provider class. * @return the providerTypeKey */ public String getProviderTypeKey() { return providerTypeKey; } /** * The provider implementation specific configuration string. * @return the providerConfig */ public String getProviderConfig() { return providerConfig; } /** * The provider instance key that uniquely identifies a provider instance. * @return the instanceKey */ public String getInstanceKey() { return instanceKey; } /** * The binder type key that unquely identifies the binder class that will override the provider's default binder. * @return the binderTokenKey */ public String getBinderTokenKey() { return binderTokenKey; } /** * The binder implementation specific configuration string. * @return the binderConfig */ public String getBinderConfig() { return binderConfig; } /** * Constructs a <code>String</code> with all attributes in name = value format. * @return a <code>String</code> representation of this object. */ public String toString() { final String TAB = "\n\t"; StringBuilder retValue = new StringBuilder("ProviderToken ["); retValue.append(TAB).append("providerTypeKey=").append(this.providerTypeKey); retValue.append(TAB).append("providerConfig=").append(this.providerConfig); retValue.append(TAB).append("instanceKey=").append(this.instanceKey); retValue.append(TAB).append("binderTokenKey=").append(this.binderTokenKey); retValue.append(TAB).append("binderConfig=").append(this.binderConfig); retValue.append(TAB).append("forceNoBind=").append(this.forceNoBind); retValue.append("\n]"); return retValue.toString(); } /** * Returns true if the provider token indicated a forceNoBind. * @return the forceNoBind */ public boolean isForceNoBind() { return forceNoBind; } /** * @return the providerToken */ public String getProviderToken() { return providerToken; } }