/*! * 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 (c) 2002-2013 Pentaho Corporation.. All rights reserved. */ package org.pentaho.platform.plugin.services.security.userrole.ldap.transform; 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; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.SearchResult; import java.util.HashSet; import java.util.Set; /** * 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; } }