/******************************************************************************* * Copyright (c) 2010-2014 SAP AG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * SAP AG - initial API and implementation *******************************************************************************/ package org.eclipse.skalli.services.extension; import java.util.HashMap; import java.util.Map; import java.util.regex.MatchResult; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.text.StrLookup; import org.apache.commons.lang.text.StrSubstitutor; import org.eclipse.skalli.model.EntityBase; import org.eclipse.skalli.model.ExtensibleEntityBase; import org.eclipse.skalli.model.Project; import org.eclipse.skalli.model.PropertyName; import org.eclipse.skalli.model.User; /** * Utility for mapping strings matching a given regular expression pattern * into other strings specified by a template that may contain placeholders. * <p> * The {@link MatchResult#group(int) groups} of the match result are available * as placeholders <tt>${1},${2},...</tt>. Some methods of this class take a * <code>userId</code> as input parameter, which is mapped to the placeholder * <tt>${userId}</tt>. Furthermore, custom properties can be specified that * are mapped to placeholders with their respective keys. * <p> * The mapping can be performed in the context of an {@link EntityBase entity}, * e.g. a {@link Project project}. The properties of that entity are mapped * to placeholders of the form <tt>${propertyName}</tt>, where <tt>propertyName</tt> * is the identifier of the property as declared by the corresponding {@link PropertyName} * annotation.<br> * For {@link ExtensibleEntityBase extensible entities}, properties of the extensions * are mapped to placeholders of the form <tt>${extension.propertyName}</tt>, where * <tt>extension</tt> is the {@link ExtensionService#getShortName() short name} * of the extension to which the property belongs. Example: <tt>${devInf.scmLocations}</tt>. */ public class PropertyMapper { private PropertyMapper() { } /** * Returns <code>true</code>, if the string matches the given * {@link Pattern regular expression}. * * @param s the string to check. * @param pattern the regular expression to apply. */ public static boolean matches(String s, String pattern) { Pattern regex = Pattern.compile(pattern); Matcher matcher = regex.matcher(s); return matcher.matches(); } /** * Returns <code>true</code>, if the string matches the given * regular expression pattern. * * @param s the string to check. * @param pattern the regular expression to apply. */ public static boolean matches(String s, Pattern pattern) { Matcher matcher = pattern.matcher(s); return matcher.matches(); } /** * Converts a string by applying the given <code>template</code>, if it matches * the given {@link Pattern regular expression}. If specified, the <code>uniqueId</code>, * e.g. a project's symbolic name, is mapped to the placeholder <tt>${0}</tt>. The * placeholders <tt>${1},${2},...</tt> provide the {@link MatchResult#group(int) groups} * of the match result. * * @param s the string to check. * @param pattern the regular expression to apply. * @param template the template to use for the mapping. * @param uniqueId some unique identifier to map to placeholder <tt>${0}</tt>. * * @return the mapped string, or <code>null</code>, if the string did not match the * given regular expression. */ public static String convert(String s, String pattern, String template, String uniqueId) { Map<String,Object> properties = new HashMap<String,Object>(); if (StringUtils.isNotBlank(uniqueId)) { properties.put("0", uniqueId); //$NON-NLS-1$ } return convert(s, pattern, template, null, properties); } /** * Converts a string by applying the given <code>template</code>, if it matches * the given regular expression. If specified, the <code>uniqueId</code>, * e.g. a project's symbolic name, is mapped to the placeholder <tt>${0}</tt>. The * placeholders <tt>${1},${2},...</tt> provide the {@link MatchResult#group(int) groups} * of the match result. * * @param s the string to check. * @param pattern the regular expression to apply. * @param template the template to use for the mapping. * @param uniqueId some unique identifier to map to placeholder <tt>${0}</tt>. * * @return the mapped string, or <code>null</code>, if the string did not match the * given regular expression. */ public static String convert(String s, Pattern pattern, String template, String uniqueId) { Map<String,Object> properties = new HashMap<String,Object>(); if (StringUtils.isNotBlank(uniqueId)) { properties.put("0", uniqueId); //$NON-NLS-1$ } return convert(s, pattern, template, null, properties); } /** * Converts a string by applying the given <code>template</code>, if it matches * the given {@link Pattern regular expression}. The properties of the entity, if specified, are mapped to * placeholders of the form <tt>${propertyName}</tt>. * Properties of extensions of the entity, if any, are mapped to placeholders of the form * <tt>${extension.propertyName}</tt>. * The placeholders <tt>${1},${2},...</tt> provide the {@link MatchResult#group(int) groups} * of the match result. * * @param s the string to check. * @param pattern the regular expression to apply. * @param template the template to use for the mapping. * @param entity any (extensible) entity. * * @return the mapped string, or <code>null</code>, if the string did not match the * given regular expression. */ public static String convert(String s, String pattern, String template, EntityBase entity) { return convert(s, pattern, template, entity, (Map<String, Object>)null); } /** * Converts a string by applying the given <code>template</code>, if it matches * the given regular expression. The properties of the entity, if specified, are mapped to * placeholders of the form <tt>${propertyName}</tt>. * Properties of extensions of the entity, if any, are mapped to placeholders of the form * <tt>${extension.propertyName}</tt>. * The placeholders <tt>${1},${2},...</tt> provide the {@link MatchResult#group(int) groups} * of the match result. * * @param s the string to check. * @param pattern the regular expression to apply. * @param template the template to use for the mapping. * @param entity any (extensible) entity. * * @return the mapped string, or <code>null</code>, if the string did not match the * given regular expression. */ public static String convert(String s, Pattern pattern, String template, EntityBase entity) { return convert(s, pattern, template, entity, (Map<String, Object>)null); } /** * Converts a string by applying the given <code>template</code>, if it matches * the given {@link Pattern regular expression}. If specified, the <code>userId</code> * parameter, is mapped to the placeholder <tt>${userId}</tt>. The properties of * the entity, if specified, are mapped to placeholders of the form <tt>${propertyName}</tt>. * Properties of extensions of the entity, if any, are mapped to placeholders of the form * <tt>${extension.propertyName}</tt>. * The placeholders <tt>${1},${2},...</tt> provide the {@link MatchResult#group(int) groups} * of the match result. * * @param s the string to check. * @param pattern the regular expression to apply. * @param template the template to use for the mapping. * @param entity any (extensible) entity. * @param userId the unique identifier of a user. * * @return the mapped string, or <code>null</code>, if the string did not match the * given regular expression. */ public static String convert(String s, String pattern, String template, EntityBase entity, String userId) { Map<String,Object> properties = new HashMap<String,Object>(); if (StringUtils.isNotBlank(userId)) { properties.put(User.PROPERTY_USERID, userId); } return convert(s, pattern, template, entity, properties); } /** * Converts a string by applying the given <code>template</code>, if it matches * the given regular expression. If specified, the <code>userId</code> * parameter, is mapped to the placeholder <tt>${userId}</tt>. The properties of * the entity, if specified, are mapped to placeholders of the form <tt>${propertyName}</tt>. * Properties of extensions of the entity, if any, are mapped to placeholders of the form * <tt>${extension.propertyName}</tt>. * The placeholders <tt>${1},${2},...</tt> provide the {@link MatchResult#group(int) groups} * of the match result. * * @param s the string to check. * @param pattern the regular expression to apply. * @param template the template to use for the mapping. * @param entity any (extensible) entity. * @param userId the unique identifier of a user. * * @return the mapped string, or <code>null</code>, if the string did not match the * given regular expression. */ public static String convert(String s, Pattern pattern, String template, EntityBase entity, String userId) { Map<String,Object> properties = new HashMap<String,Object>(); if (StringUtils.isNotBlank(userId)) { properties.put(User.PROPERTY_USERID, userId); } return convert(s, pattern, template, entity, properties); } /** * Converts a string by applying the given <code>template</code>, if it matches * the given {@link Pattern regular expression}. The properties of the entity, if specified, are mapped to * placeholders of the form <tt>${propertyName}</tt>. * Properties of extensions of the entity, if any, are mapped to placeholders of the form * <tt>${extension.propertyName}</tt>. * The custom properties, if specified, are mapped to placeholders with their respective keys, * e.g. property with key <tt>"prop"</tt> is mapped to the placeholder <tt>${prop}</tt>. * The placeholders <tt>${1},${2},...</tt> provide the {@link MatchResult#group(int) groups} * of the match result. * * @param s the string to check. * @param pattern the regular expression to apply. * @param template the template to use for the mapping. * @param entity any (extensible) entity. * @param properties additional properties. * * @return the mapped string, or <code>null</code>, if the string did not match the * given regular expression. */ public static String convert(String s, String pattern, String template, EntityBase entity, Map<String,Object> properties) { if (pattern == null) { return null; } Pattern regex = Pattern.compile(pattern); return convert(s, regex, template, entity, properties); } /** * Converts a string by applying the given <code>template</code>, if it matches * the given regular expression. The properties of the entity, if specified, are mapped to * placeholders of the form <tt>${propertyName}</tt>. * Properties of extensions of the entity, if any, are mapped to placeholders of the form * <tt>${extension.propertyName}</tt>. * The custom properties, if specified, are mapped to placeholders with their respective keys, * e.g. property with key <tt>"prop"</tt> is mapped to the placeholder <tt>${prop}</tt>. * The placeholders <tt>${1},${2},...</tt> provide the {@link MatchResult#group(int) groups} * of the match result. * * @param s the string to check. * @param pattern the regular expression to apply. * @param template the template to use for the mapping. * @param entity any (extensible) entity. * @param properties additional properties. * * @return the mapped string, or <code>null</code>, if the string did not match the * given regular expression. */ public static String convert(String s, Pattern pattern, String template, EntityBase entity, Map<String,Object> properties) { if (s == null || pattern == null) { return null; } Matcher matcher = pattern.matcher(s); if (!matcher.matches()) { return null; } if (properties == null) { properties = new HashMap<String,Object>(); } // put the project ID as property ${0} if (entity instanceof Project) { properties.put("0", ((Project)entity).getProjectId()); //$NON-NLS-1$ } // put the groups found by the matcher as properties ${1}, ${2}, ... for (int i = 1; i <= matcher.groupCount(); i++) { properties.put(Integer.toString(i), matcher.group(i)); } StrLookup propertyResolver = new PropertyLookup(entity, properties); StrSubstitutor subst = new StrSubstitutor(propertyResolver); return subst.replace(template); } }