[teiid-commits] teiid SVN: r2939 - in trunk/connectors/translator-ldap/src/main: resources/org/teiid/translator/ldap and 1 other directory.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Thu Feb 24 19:30:45 EST 2011


Author: shawkins
Date: 2011-02-24 19:30:45 -0500 (Thu, 24 Feb 2011)
New Revision: 2939

Modified:
   trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPSearchDetails.java
   trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPSyncQueryExecution.java
   trunk/connectors/translator-ldap/src/main/resources/org/teiid/translator/ldap/i18n.properties
Log:
TEIID-217 adding multivalued-concat handling

Modified: trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPSearchDetails.java
===================================================================
--- trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPSearchDetails.java	2011-02-24 22:00:56 UTC (rev 2938)
+++ trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPSearchDetails.java	2011-02-25 00:30:45 UTC (rev 2939)
@@ -32,6 +32,7 @@
 
 import org.teiid.logging.LogConstants;
 import org.teiid.logging.LogManager;
+import org.teiid.metadata.Column;
 
 
 
@@ -49,7 +50,7 @@
 //	private LdapSortKey[] netscapeKeys;
 	// If limit is set to -1, this means no limit (return all rows)
 	private long limit;
-	private ArrayList elementList;
+	private ArrayList<Column> elementList;
 	
 	/**
 	 * Constructor
@@ -108,7 +109,7 @@
 	 * get the element list
 	 * @return the element list
 	 */
-	public ArrayList getElementList() {
+	public ArrayList<Column> getElementList() {
 		return elementList;
 	}
 	

Modified: trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPSyncQueryExecution.java
===================================================================
--- trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPSyncQueryExecution.java	2011-02-24 22:00:56 UTC (rev 2938)
+++ trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPSyncQueryExecution.java	2011-02-25 00:30:45 UTC (rev 2939)
@@ -76,6 +76,7 @@
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
@@ -97,8 +98,9 @@
 import org.teiid.logging.LogConstants;
 import org.teiid.logging.LogManager;
 import org.teiid.metadata.Column;
-import org.teiid.translator.TranslatorException;
 import org.teiid.translator.ResultSetExecution;
+import org.teiid.translator.TranslatorException;
+import org.teiid.translator.TypeFacility;
 
 
 
@@ -108,10 +110,12 @@
  */
 public class LDAPSyncQueryExecution implements ResultSetExecution {
 
+	private static final String delimiter = "?"; //$NON-NLS-1$
+	
 	private LDAPSearchDetails searchDetails;
 	private LdapContext ldapConnection;
 	private LdapContext ldapCtx;
-	private NamingEnumeration searchEnumeration;
+	private NamingEnumeration<?> searchEnumeration;
 	private IQueryToLdapSearchParser parser;
 	private Select query;
 	private LDAPExecutionFactory executionFactory;
@@ -192,18 +196,13 @@
 	/** 
 	 * Set the search controls
 	 */
-	private SearchControls setSearchControls() throws TranslatorException {
+	private SearchControls setSearchControls() {
 		SearchControls ctrls = new SearchControls();
 		//ArrayList modelAttrList = searchDetails.getAttributeList();
-		ArrayList modelAttrList = searchDetails.getElementList();
+		ArrayList<Column> modelAttrList = searchDetails.getElementList();
 		String[] attrs = new String[modelAttrList.size()];
-		Iterator itr = modelAttrList.iterator();
-		int i = 0;
-		while(itr.hasNext()) {
-			attrs[i] = (parser.getNameFromElement((Column)itr.next()));
-			//attrs[i] = (((Attribute)itr.next()).getID();
-			//logger.logTrace("Adding attribute named " + attrs[i] + " to the search list.");
-			i++;
+		for (int i = 0; i < attrs.length; i++) {
+			attrs[i] = (parser.getNameFromElement(modelAttrList.get(i)));
 		}
 
 		ctrls.setSearchScope(searchDetails.getSearchScope());
@@ -285,11 +284,11 @@
 	// it from being used again.
 	// GHH 20080326 - also added return of explanation for generic
 	// NamingException
-	public List next() throws TranslatorException {
+	public List<?> next() throws TranslatorException {
 		try {
 			// The search has been executed, so process up to one batch of
 			// results.
-			List result = null;
+			List<?> result = null;
 			while (result == null && searchEnumeration != null && searchEnumeration.hasMore())
 			{
 				SearchResult searchResult = (SearchResult) searchEnumeration.next();
@@ -316,20 +315,16 @@
 	 */
 	// GHH 20080326 - added fetching of DN of result, for directories that
 	// do not include it as an attribute
-	private List getRow(SearchResult result) throws TranslatorException {
+	private List<?> getRow(SearchResult result) throws TranslatorException {
 		Attributes attrs = result.getAttributes();
 		String resultDN = result.getNameInNamespace(); // added GHH 20080326 
-		ArrayList attributeList = searchDetails.getElementList();
-		List row = new ArrayList();
+		ArrayList<Column> attributeList = searchDetails.getElementList();
+		List<Object> row = new ArrayList<Object>(attributeList.size());
 		
-		if (attrs != null && attrs.size()>0) {
-			Iterator itr = attributeList.iterator();
-			while(itr.hasNext()) {
-				addResultToRow((Column)itr.next(), resultDN, attrs, row);  // GHH 20080326 - added resultDN parameter to call
-			}
-			return row;
+		for (Column col : attributeList) {
+			addResultToRow(col, resultDN, attrs, row);  // GHH 20080326 - added resultDN parameter to call
 		}
-		return null;
+		return row;
 	}
 
 	/**
@@ -344,11 +339,14 @@
 	// value for that column in the result
 	// GHH 20080326 - added handling of ClassCastException when non-string
 	// attribute is returned
-	private void addResultToRow(Column modelElement, String resultDistinguishedName, Attributes attrs, List row) throws TranslatorException {
+	private void addResultToRow(Column modelElement, String resultDistinguishedName, Attributes attrs, List<Object> row) throws TranslatorException {
 
-		String strResult;
+		String strResult = null;
 		String modelAttrName = parser.getNameFromElement(modelElement);
-		Class modelAttrClass = modelElement.getJavaType();
+		Class<?> modelAttrClass = modelElement.getJavaType();
+		
+		String multivalAttr = modelElement.getDefaultValue();
+		
 		if(modelAttrName == null) {
             final String msg = LDAPPlugin.Util.getString("LDAPSyncQueryExecution.nullAttrError"); //$NON-NLS-1$
 			throw new TranslatorException(msg); 
@@ -370,97 +368,86 @@
 				row.add(null);
 			}
 			return;
-		} 
-		// TODO: Currently, if an LDAP entry contains more than one matching
-		// attribute, we only return the first. 
-		// Since attribute order is not guaranteed, this means that we may not
-		// always return the exact same information.
-		// Putting multi-valued attributes into a single row (or multiple rows) requires
-		// some design decisions.
-		// GHH 20080326 - first get attribute as generic object
-		// so we can check to make sure it is a string separately - previously it was just put straight into a string.
+		}
 		Object objResult = null;
 		try {
+			if(TypeFacility.RUNTIME_TYPES.STRING.equals(modelAttrClass) && "multivalued-concat".equalsIgnoreCase(multivalAttr)) { //$NON-NLS-1$
+				// mpw 5/09
+				// Order the multi-valued attrs alphabetically before creating a single string, 
+				// using the delimiter to separate each token
+				ArrayList<String> multivalList = new ArrayList<String>();
+				NamingEnumeration<?> attrNE = resultAttr.getAll();
+				int length = 0;
+				while(attrNE.hasMore()) {
+					String val = (String)attrNE.next();
+					multivalList.add(val);
+					length += ((val==null?0:val.length()) + 1);
+				}
+				Collections.sort(multivalList);
+	
+				StringBuilder multivalSB = new StringBuilder(length);
+				Iterator<String> itr = multivalList.iterator();
+				while(itr.hasNext()) {
+					multivalSB.append(itr.next());
+					if (itr.hasNext()) {
+						multivalSB.append(delimiter);
+					}
+				}
+				row.add(multivalSB.toString());
+				return;
+			}
+			
+			//just a single value
 			objResult = resultAttr.get();
 		} catch (NamingException ne) {
-            final String msg = LDAPPlugin.Util.getString("LDAPSyncQueryExecution.attrValueFetchError",modelAttrName); //$NON-NLS-1$
-            LogManager.logWarning(LogConstants.CTX_CONNECTOR, msg+" : "+ne.getExplanation()); //$NON-NLS-1$
-			throw new TranslatorException(msg+" : "+ne.getExplanation()); //$NON-NLS-1$
+            final String msg = LDAPPlugin.Util.getString("LDAPSyncQueryExecution.attrValueFetchError",modelAttrName) +" : "+ne.getExplanation(); //$NON-NLS-1$m//$NON-NLS-2$
+            LogManager.logWarning(LogConstants.CTX_CONNECTOR, msg);
+			throw new TranslatorException(msg);
 		}
 
-		// GHH 20080326 - if attribute is not a string, just
-		// return an empty string.
+		// GHH 20080326 - if attribute is not a string or empty, just
+		// return null.
 		// TODO - allow return of non-strings (always byte[]) as
-		// MM object.  Perhaps also add directory-specific logic
+		// MM object (or blob).  Perhaps also add directory-specific logic
 		// to deserialize byte[] attributes into Java objects
 		// when appropriate
-		try {
+		if (objResult instanceof String) {
 			strResult = (String)objResult;
-		} catch (ClassCastException cce) {
-			strResult = ""; //$NON-NLS-1$
+			// MPW - 3.9.07 - Also return NULL when attribute is unset or empty string.
+			// There is no way to differentiate between being unset and being the empty string.
+			if(strResult.equals("")) {  //$NON-NLS-1$
+				strResult = null;
+			}
 		}
 
-		// MPW - 3.9.07 - Also return NULL when attribute is unset or empty string.
-		// There is no way to differentiate between being unset and being the empty string.
-		if(strResult.equals("")) {  //$NON-NLS-1$
-			strResult = null;
-		}
-
 		// MPW: 3-11-07: Added support for java.lang.Integer conversion.
-		try {
-			if(modelAttrClass.equals(Class.forName(Integer.class.getName()))) {
-				try {
-					//	Throw an exception if class cast fails.
-					if(strResult != null) {
-						Integer intResult = new Integer(strResult);
-						row.add(intResult);
-					} else {
-						row.add(null);
-					}
-				} catch(NumberFormatException nfe) {
-					throw new TranslatorException(nfe, "Element " + modelAttrName + " is typed as Integer, " + //$NON-NLS-1$ //$NON-NLS-2$
-							"but it's value (" + strResult + ") cannot be converted from string " + //$NON-NLS-1$ //$NON-NLS-2$
-							"to Integer. Please change type to String, or modify the data."); //$NON-NLS-1$
-				}
-			// java.lang.String
-			} else if(modelAttrClass.equals(Class.forName(String.class.getName()))) {
-				row.add(strResult);
-			// java.sql.Timestamp
-			} else if(modelAttrClass.equals(Class.forName(java.sql.Timestamp.class.getName()))) {
-				Map<String, String> p = modelElement.getProperties();
+		if(TypeFacility.RUNTIME_TYPES.TIMESTAMP.equals(modelAttrClass)) {
+			Map<String, String> p = modelElement.getProperties();
 
-				String timestampFormat = p.get("Format"); //$NON-NLS-1$
-				SimpleDateFormat dateFormat;
-				if(timestampFormat == null) {
-					timestampFormat = LDAPConnectorConstants.ldapTimestampFormat;
-					
-				}
-				dateFormat = new SimpleDateFormat(timestampFormat);
-				try {
-					if(strResult != null) {
-						Date dateResult = dateFormat.parse(strResult);
-						Timestamp tsResult = new Timestamp(dateResult.getTime());
-						row.add(tsResult);
-					} else {
-						row.add(null);
-					}
-				} catch(ParseException pe) {
-					throw new TranslatorException(pe, "Timestamp could not be parsed. Please check to ensure the "  //$NON-NLS-1$
-							+ " Format field for attribute "  //$NON-NLS-1$
-							+ modelAttrName + " is configured using SimpleDateFormat conventions."); //$NON-NLS-1$
-				}		
+			String timestampFormat = p.get("Format"); //$NON-NLS-1$
+			SimpleDateFormat dateFormat;
+			if(timestampFormat == null) {
+				timestampFormat = LDAPConnectorConstants.ldapTimestampFormat;
 				
+			}
+			dateFormat = new SimpleDateFormat(timestampFormat);
+			try {
+				if(strResult != null) {
+					Date dateResult = dateFormat.parse(strResult);
+					Timestamp tsResult = new Timestamp(dateResult.getTime());
+					row.add(tsResult);
+				} else {
+					row.add(null);
+				}
+			} catch(ParseException pe) {
+				throw new TranslatorException(pe, LDAPPlugin.Util.getString("LDAPSyncQueryExecution.timestampParseFailed", modelAttrName)); //$NON-NLS-1$
+			}		
+			
 			//	TODO: Extend support for more types in the future.
 			// Specifically, add support for byte arrays, since that's actually supported
 			// in the underlying data source.
-			} else {
-				throw new TranslatorException("Base type " + modelAttrClass.toString()  //$NON-NLS-1$
-						+ " is not supported in the LDAP connector. "  //$NON-NLS-1$
-						+ " Please modify the base model to use a supported type."); //$NON-NLS-1$
-			}
-		} catch(ClassNotFoundException cne) {
-            final String msg = LDAPPlugin.Util.getString("LDAPSyncQueryExecution.supportedClassNotFoundError"); //$NON-NLS-1$
-			throw new TranslatorException(cne, msg); 
+		} else {
+			row.add(strResult); //the Teiid type conversion logic will handle refine from here if necessary
 		}
 	}
 	

Modified: trunk/connectors/translator-ldap/src/main/resources/org/teiid/translator/ldap/i18n.properties
===================================================================
--- trunk/connectors/translator-ldap/src/main/resources/org/teiid/translator/ldap/i18n.properties	2011-02-24 22:00:56 UTC (rev 2938)
+++ trunk/connectors/translator-ldap/src/main/resources/org/teiid/translator/ldap/i18n.properties	2011-02-25 00:30:45 UTC (rev 2939)
@@ -59,4 +59,5 @@
 LDAPUpdateExecution.criteriaRHSNotLiteralError=right side of equals comparison against DN is not a literal - must be a string literal
 LDAPUpdateExecution.criteriaRHSNotStringError=right side of equals comparison against DN is not a string - must be a string literal
 LDAPUpdateExecution.closeContextError=LDAP error occurred during attempt to close context : {0}
-					
+LDAPSyncQueryExecution.timestampParseFailed=Timestamp could not be parsed. Please check to ensure the Format field for attribute {0} is configured using SimpleDateFormat conventions.
+



More information about the teiid-commits mailing list