/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright 2007 - 2009 Pentaho Corporation. All rights reserved. * */ package org.pentaho.platform.plugin.services.security.userrole.ldap.transform; import java.util.HashSet; import java.util.Set; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.SearchResult; import org.apache.commons.collections.Transformer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.pentaho.platform.plugin.services.messages.Messages; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * Extracts the value of the token <code>tokenName</code> from the attribute * <code>attributeName</code>. Ignores attribute value if value is not of * type <code>String</code>. Returns the entire attribute value if * <code>tokenName</code> is not specified. * <p> * <strong>Note: This transformer can produce more than one output (in the form * of a collection) per single input. Any client of this class should merge the * results (e.g. <code>collection.addAll(collection)</code>) into an existing * collection.</strong> * </p> * * <p> * Transformer input: <code>SearchResult</code> instance * </p> * <p> * Transformer output: <code>Collection</code> of <code>String</code> * instances * </p> * TODO refactor into searchresulttoattributelist, * attributelisttosingleattribute, attributestringtoattributesubstring * * @author mlowery */ public class SearchResultToAttrValueList implements Transformer, InitializingBean { // ~ Static fields/initializers ============================================ private static final Log logger = LogFactory.getLog(SearchResultToAttrValueList.class); // ~ Instance fields ======================================================= private String attributeName; private String tokenName; // ~ Constructors ========================================================== public SearchResultToAttrValueList(final String attributeName) { this(attributeName, null); } public SearchResultToAttrValueList(final String attributeName, final String tokenName) { super(); this.attributeName = attributeName; this.tokenName = tokenName; } // ~ Methods =============================================================== /** * Assumes that <code>src</code> consists of name-value pairs linked via * <code>'='</code> and each pair separated by <code>','</code>. * * @param src * the source string * @param inTokenName * the name part of the name-value pair whose value will be * returned * @return the value part of the name-value pair whose name part is * <code>tokenName</code> */ protected String extract(final String src, final String inTokenName) { if (SearchResultToAttrValueList.logger.isDebugEnabled()) { SearchResultToAttrValueList.logger.debug(Messages.getInstance().getString( "SearchResultToAttrValueList.DEBUG_LOOKING_FOR_SUBSTRING", inTokenName, src)); //$NON-NLS-1$ } String[] tokens = src.split(","); //$NON-NLS-1$ for (String rdnString : tokens) { String[] rdnTokens = rdnString.split("="); //$NON-NLS-1$ if (rdnTokens[0].trim().equals(inTokenName)) { if (SearchResultToAttrValueList.logger.isDebugEnabled()) { SearchResultToAttrValueList.logger.debug(Messages.getInstance().getString( "SearchResultToAttrValueList.DEBUG_EXTRACTED_TOKEN", rdnTokens[1].trim())); //$NON-NLS-1$ } return rdnTokens[1].trim(); } } if (SearchResultToAttrValueList.logger.isDebugEnabled()) { SearchResultToAttrValueList.logger.debug(Messages.getInstance().getString( "SearchResultToAttrValueList.DEBUG_TOKEN_NOT_FOUND", inTokenName, src)); //$NON-NLS-1$ } return null; } public void afterPropertiesSet() throws Exception { Assert.hasLength(attributeName); } public Object transform(final Object obj) { Object transformed = obj; if (obj instanceof SearchResult) { transformed = new HashSet(); Set valueSet = (Set) transformed; SearchResult res = (SearchResult) obj; if (SearchResultToAttrValueList.logger.isDebugEnabled()) { SearchResultToAttrValueList.logger .debug(Messages.getInstance() .getString( "SearchResultToAttrValueList.DEBUG_ATTRIBUTES_FROM_SEARCHRESULT", (null != res.getAttributes()) ? res.getAttributes().toString() : "null")); //$NON-NLS-1$ //$NON-NLS-2$ } Attribute attr = res.getAttributes().get(attributeName); if (SearchResultToAttrValueList.logger.isDebugEnabled()) { SearchResultToAttrValueList.logger .debug(Messages.getInstance() .getString( "SearchResultToAttrValueList.DEBUG_ATTRIBUTE_VALUE", attributeName, (null != attr) ? attr.toString() : "null")); //$NON-NLS-1$ //$NON-NLS-2$ } if (attr != null) { // check for null as node might not have attribute we're looking for try { NamingEnumeration values = attr.getAll(); while (values.hasMore()) { // if tokenName was specified, extract from value; otherwise // store value unchanged Object value = values.next(); if (StringUtils.hasLength(tokenName)) { if ((null != value) && (value instanceof String)) { String tokenValue = extract((String) value, tokenName); if (null != tokenValue) { valueSet.add(tokenValue); } } else { if (SearchResultToAttrValueList.logger.isWarnEnabled()) { SearchResultToAttrValueList.logger.warn(Messages.getInstance() .getString("SearchResultToAttrValueList.WARN_ATTRIBUTE_NOT_A_STRING")); //$NON-NLS-1$ } } } else { if (null != value) { valueSet.add(value.toString()); } } } } catch (NamingException e) { if (SearchResultToAttrValueList.logger.isErrorEnabled()) { SearchResultToAttrValueList.logger.error(Messages.getInstance() .getErrorString("SearchResultToAttrValueList.ERROR_0001_NAMING_EXCEPTION"), e); //$NON-NLS-1$ } } } return transformed; } return transformed; } }