[teiid-commits] teiid SVN: r4511 - in trunk: common-core/src/test/java/org/teiid/core/util and 3 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Wed Oct 3 15:05:35 EDT 2012


Author: shawkins
Date: 2012-10-03 15:05:34 -0400 (Wed, 03 Oct 2012)
New Revision: 4511

Modified:
   trunk/common-core/src/main/java/org/teiid/core/util/StringUtil.java
   trunk/common-core/src/test/java/org/teiid/core/util/TestStringUtil.java
   trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/IQueryToLdapSearchParser.java
   trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPDirectCreateUpdateDeleteQueryExecution.java
   trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPDirectSearchQueryExecution.java
   trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPExecutionFactory.java
   trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPPlugin.java
   trunk/connectors/translator-ldap/src/main/resources/org/teiid/translator/ldap/i18n.properties
   trunk/connectors/translator-ldap/src/test/java/org/teiid/translator/ldap/TestIQueryToLdapSearchParser.java
   trunk/connectors/translator-ldap/src/test/java/org/teiid/translator/ldap/TestLDAPDirectQueryExecution.java
Log:
TEIID-2177 adding ldap canned queries

Modified: trunk/common-core/src/main/java/org/teiid/core/util/StringUtil.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/util/StringUtil.java	2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/common-core/src/main/java/org/teiid/core/util/StringUtil.java	2012-10-03 19:05:34 UTC (rev 4511)
@@ -109,18 +109,6 @@
         return LINE_SEPARATOR;
     }
 
-    /**
-     * Utility to return a string enclosed in ''.
-     * Creation date: (12/2/99 12:05:10 PM)
-     */
-    public static String enclosedInSingleQuotes(String aString) {
-    	StringBuffer sb = new StringBuffer();
-    	sb.append(SINGLE_QUOTE);
-    	sb.append(aString);
-    	sb.append(SINGLE_QUOTE);
-    	return sb.toString();
-    }
-
 	/**
 	 * Join string pieces and separate with a delimiter.  Similar to the perl function of
 	 * the same name.  If strings or delimiter are null, null is returned.  Otherwise, at
@@ -131,7 +119,7 @@
 	 * @param delimiter Delimiter to put between string pieces
 	 * @return One merged string
 	 */
-	public static String join(List strings, String delimiter) {
+	public static String join(List<String> strings, String delimiter) {
 		if(strings == null || delimiter == null) {
 			return null;
 		}
@@ -147,7 +135,7 @@
 		// put the piece and a delimiter after it.  An iterator is used to walk the list.
 		int most = strings.size()-1;
 		if(strings.size() > 1) {
-			Iterator iter = strings.iterator();
+			Iterator<String> iter = strings.iterator();
 			for(int i=0; i<most; i++) {            
 				str.append(iter.next());
 				str.append(delimiter);
@@ -215,64 +203,6 @@
         return l;
     }
     
-    /**
-     * Break a string into pieces based on matching the full delimiter string in the text.
-     * The delimiter is not included in the returned strings.
-     * @param target The text to break up.
-     * @param delimiter The sub-string which is used to break the target.
-     * @return List of String from the target.
-     */
-    public static List<String> splitOnEntireString(String target, String delimiter) {
-        ArrayList<String> result = new ArrayList<String>();
-        if (delimiter.length() > 0) {
-            int index = 0;
-            int indexOfNextMatch = target.indexOf(delimiter);
-            while (indexOfNextMatch > -1) {
-                result.add(target.substring(index, indexOfNextMatch));
-                index = indexOfNextMatch + delimiter.length();
-                indexOfNextMatch = target.indexOf(delimiter, index);
-            }
-            if (index <= target.length()) {
-                result.add(target.substring(index));
-            }
-        } else {
-            result.add(target);
-        }
-        return result;
-    }
-
-	/**
-	 * Split a string into pieces based on delimiters preserving spaces in
-     * quoted substring as on element in the returned list.   The delimiters are
-     * not included in the returned strings.
-	 * @see #join
-	 *
-	 * @param str Full string
-	 * @param splitter Characters to split on
-	 * @return List of String pieces from full string
-	 */
-	public static List splitPreservingQuotedSubstring(String str, String splitter) {
-		ArrayList l = new ArrayList();
-		StringTokenizer tokens = new StringTokenizer(str, splitter);
-        StringBuffer token = new StringBuffer();
-		while(tokens.hasMoreTokens()) {
-            token.setLength(0);
-            token.append(tokens.nextToken());
-            if ( token.charAt(0) == '"' ) {
-                token.deleteCharAt(0);
-                while ( tokens.hasMoreTokens() ) {
-                    token.append(Constants.SPACE + tokens.nextToken()); 
-                    if ( token.charAt(token.length() -1) == '"' ) {
-                        token.deleteCharAt(token.length() - 1);
-                        break;
-                    }
-                }
-            }
-			l.add(token.toString().trim());
-		}
-		return l;				
-	}
-	
 	/*
 	 * Replace a single occurrence of the search string with the replace string
 	 * in the source string. If any of the strings is null or the search string
@@ -353,10 +283,10 @@
         if (strLength > maxCharPerLine) {
             StringBuffer sb = new StringBuffer(str.length()+(strLength/maxCharPerLine)+1);
             strLength = 0;
-            List tokens = StringUtil.split(str,Constants.SPACE);
-            Iterator itr = tokens.iterator();
+            List<String> tokens = StringUtil.split(str,Constants.SPACE);
+            Iterator<String> itr = tokens.iterator();
             while (itr.hasNext()) {
-                String token = (String) itr.next();
+                String token = itr.next();
                 if ( strLength+token.length() > maxCharPerLine ) {
 //                    sb.append(getLineSeparator());
                     sb.append(Constants.NEW_LINE);
@@ -389,36 +319,6 @@
 		return l;
     }
     
-    /**
-     * Return the number of tokens in a string that are seperated by the delimiter.
-     *
-     * @param str String to be tokenized
-     * @param delimiter Characters which are delimit tokens
-     * @return Number of tokens seperated by the delimiter
-     */
-    public static int getTokenCount(String str, String delimiter) {
-        StringTokenizer tokens = new StringTokenizer(str, delimiter);
-        return tokens.countTokens();
-    }    
-    
-    /**
-     * Return the number of occurrences of token string that occurs in input string.
-     * Note: token is case sensitive.
-     * 
-     * @param input
-     * @param token
-     * @return int
-     */
-    public static int occurrences(String input, String token) {
-        int num = 0;
-        int index = input.indexOf(token);
-        while (index >= 0) {
-            num++;
-            index = input.indexOf(token, index+1);
-        }
-        return num;
-    }
-
 	/**
 	 * Return the last token in the string.
 	 *
@@ -473,32 +373,6 @@
      * <li>"SQLIndexT" is converted to "SQL Index T"</li>
      * <li>"SQLIndex T" is converted to "SQL Index T"</li>
      * <li>"SQLIndex t" is converted to "SQL Index T"</li>
-	 *
-	 * @param str String to be converted; may be null
-     * @return the displayable form of <code>str</code>, or an empty string if
-     * <code>str</code> is either null or zero-length; never null
-	 */
-	public static String computeDisplayableForm(String str) {
-        return computeDisplayableForm(str, Constants.EMPTY_STRING);
-    }
-
-	/**
-	 * Compute a displayable form of the specified string.  This algorithm
-     * attempts to create a string that contains words that begin with uppercase
-     * characters and that are separated by a single space.  For example,
-     * the following are the outputs of some sample inputs:
-     * <li>"aName" is converted to "A Name"</li>
-     * <li>"Name" is converted to "Name"</li>
-     * <li>"NAME" is converted to "NAME"</li>
-     * <li>"theName" is converted to "The Name"</li>
-     * <li>"theBIGName" is converted to "The BIG Name"</li>
-     * <li>"the BIG Name" is converted to "The BIG Name"</li>
-     * <li>"the big Name" is converted to "The Big Name"</li>
-     * <li>"theBIG" is converted to "The BIG"</li>
-     * <li>"SQLIndex" is converted to "SQL Index"</li>
-     * <li>"SQLIndexT" is converted to "SQL Index T"</li>
-     * <li>"SQLIndex T" is converted to "SQL Index T"</li>
-     * <li>"SQLIndex t" is converted to "SQL Index T"</li>
      * <p>
      * An exception is "MetaMatrix", which is always treated as a single word
      * </p>
@@ -572,33 +446,6 @@
         return newName.toString();
     }
 
-    /**
-	 * @since 3.0
-	 */
-    public static String computeDisplayableFormOfConstant(final String text) {
-        return computeDisplayableFormOfConstant(text, Constants.EMPTY_STRING);
-    }
-
-    /**
-     * @since 3.0
-     */
-    public static String computeDisplayableFormOfConstant(final String text, final String defaultValue) {
-        if (text == null  ||  text.length() == 0) {
-            return defaultValue;
-        }
-        final StringBuffer buf = new StringBuffer();
-        String token;
-        for (final StringTokenizer iter = new StringTokenizer(text, "_");  iter.hasMoreTokens();) { //$NON-NLS-1$
-            token = iter.nextToken().toLowerCase();
-            if (buf.length() > 0) {
-                buf.append(' ');
-            }
-            buf.append(Character.toUpperCase(token.charAt(0)));
-            buf.append(token.substring(1));
-        }
-        return buf.toString();
-    }
-
     public static String computePluralForm(String str) {
         return computePluralForm(str, Constants.EMPTY_STRING);
     }
@@ -786,28 +633,6 @@
     }
 
     /**
-     * Removes extraneous whitespace from a string. By it's nature, it will be trimmed also. 
-     * @param raw
-     * @return
-     * @since 5.0
-     */
-    public static String collapseWhitespace(String raw) {
-        StringBuffer rv = new StringBuffer(raw.length());
-
-        StringTokenizer izer = new StringTokenizer(raw, " "); //$NON-NLS-1$
-        while (izer.hasMoreTokens()) {
-            String tok = izer.nextToken();
-            // Added one last check here so we don't append a "space" on the end of the string
-            rv.append(tok);
-            if( izer.hasMoreTokens() ) {
-                rv.append(' ');
-            }
-        } // endwhile
-
-        return rv.toString();
-    }
-    
-    /**
      * If input == null OR input.length() < desiredLength, pad to desiredLength with spaces.  
      * If input.length() > desiredLength, chop at desiredLength.
      * @param input Input text
@@ -1012,4 +837,32 @@
 		}
 	}
 	
+	public static List<String> tokenize(String str, char delim) {
+		ArrayList<String> result = new ArrayList<String>();
+		StringBuilder current = new StringBuilder();
+		boolean escaped = false;
+		for (int i = 0; i < str.length(); i++) {
+			char c = str.charAt(i);
+			if (c == delim) {
+				if (escaped) {
+					current.append(c);
+					escaped = false;
+				} else {
+					escaped = true;
+				}
+			} else {
+				if (escaped && current.length() > 0) {
+					result.add(current.toString());
+					current.setLength(0);
+					escaped = false;
+				}
+				current.append(c);
+			}
+		}
+		if (current.length()>0) {
+			result.add(current.toString());
+		}
+		return result;
+	}
+	
 }

Modified: trunk/common-core/src/test/java/org/teiid/core/util/TestStringUtil.java
===================================================================
--- trunk/common-core/src/test/java/org/teiid/core/util/TestStringUtil.java	2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/common-core/src/test/java/org/teiid/core/util/TestStringUtil.java	2012-10-03 19:05:34 UTC (rev 4511)
@@ -37,12 +37,6 @@
  */
 public class TestStringUtil {
 
-	//  ********* H E L P E R   M E T H O D S  *********
-	public void helpTestEncloseInSingleQuotes(String input, String expectedResult){
-	    String result = StringUtil.enclosedInSingleQuotes(input);
-	    assertEquals("Unexpected encloseInSignleQuotes result", expectedResult, result ); //$NON-NLS-1$
-	}
-
 	public void helpTestComputeDisplayableForm(String input, String expectedResult){
 	    String result = StringUtil.computeDisplayableForm(input, input);
 	    assertEquals("Unexpected ComputeDisplayableForm result", expectedResult, result ); //$NON-NLS-1$
@@ -73,11 +67,6 @@
 	    assertEquals("Unexpected TruncString result", expectedResult, result ); //$NON-NLS-1$
 	}
 
-	//  ********* T E S T   S U I T E   M E T H O D S  *********
-	@Test public void testEncloseInSingleQuotes() {
-	    helpTestEncloseInSingleQuotes("testString", "\'testString\'"); //$NON-NLS-1$ //$NON-NLS-2$
-	}
-
 	@Test public void testComputeDisplayableForm1() {
 	    helpTestComputeDisplayableForm("testString", "Test String"); //$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -228,41 +217,6 @@
 		assertEquals(" are 7 tokens.", tokens.get(6)); //$NON-NLS-1$
     }
 
-    @Test public void testSplitOnEntireString() {
-        List<String> result = StringUtil.splitOnEntireString("thisNEXTcanNEXTbe", "NEXT"); //$NON-NLS-1$ //$NON-NLS-2$
-        assertEquals(3, result.size());
-        assertEquals("this", result.get(0)); //$NON-NLS-1$
-        assertEquals("can", result.get(1)); //$NON-NLS-1$
-        assertEquals("be", result.get(2)); //$NON-NLS-1$
-
-    }
-
-    @Test public void testSplitOnEntireStringEmptyString() {
-        List<String> result = StringUtil.splitOnEntireString("", "NEXT"); //$NON-NLS-1$ //$NON-NLS-2$
-        assertEquals(1, result.size());
-        assertEquals("", result.get(0)); //$NON-NLS-1$
-    }
-
-    @Test public void testSplitOnEntireStringEntireStringIsDelimiter() {
-        List<String> result = StringUtil.splitOnEntireString("NEXT", "NEXT"); //$NON-NLS-1$ //$NON-NLS-2$
-        assertEquals(2, result.size());
-        assertEquals("", result.get(0)); //$NON-NLS-1$
-        assertEquals("", result.get(1)); //$NON-NLS-1$
-    }
-
-    @Test public void testSplitOnEntireStringEmptyDelimiter() {
-        List<String> result = StringUtil.splitOnEntireString("test", ""); //$NON-NLS-1$ //$NON-NLS-2$
-        assertEquals(1, result.size());
-        assertEquals("test", result.get(0)); //$NON-NLS-1$
-    }
-
-    @Test public void testSplitOnEntireStringEndsWithDelimiter() {
-        List<String> result = StringUtil.splitOnEntireString("testNEXT", "NEXT"); //$NON-NLS-1$ //$NON-NLS-2$
-        assertEquals(2, result.size());
-        assertEquals("test", result.get(0)); //$NON-NLS-1$
-        assertEquals("", result.get(1)); //$NON-NLS-1$
-    }
-
     @Test public void testIndexOfIgnoreCase() {
         String text = "test"; //$NON-NLS-1$
         assertEquals(-1,StringUtil.indexOfIgnoreCase(null,text));

Modified: trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/IQueryToLdapSearchParser.java
===================================================================
--- trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/IQueryToLdapSearchParser.java	2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/IQueryToLdapSearchParser.java	2012-10-03 19:05:34 UTC (rev 4511)
@@ -45,12 +45,12 @@
 import javax.naming.directory.SearchControls;
 import javax.naming.ldap.SortKey;
 
+import org.teiid.core.util.StringUtil;
 import org.teiid.language.*;
 import org.teiid.language.Comparison.Operator;
 import org.teiid.language.SortSpecification.Ordering;
 import org.teiid.logging.LogConstants;
 import org.teiid.logging.LogManager;
-import org.teiid.metadata.AbstractMetadataRecord;
 import org.teiid.metadata.Column;
 import org.teiid.metadata.Datatype;
 import org.teiid.metadata.Table;
@@ -70,7 +70,6 @@
 	private static final String SEARCH_SCOPE = "search-scope";//$NON-NLS-1$
 	private static final String CRITERIA = "filter";//$NON-NLS-1$
 	private static final String CONTEXT_NAME = "context-name";//$NON-NLS-1$	
-	public static final String TEIID_NATIVE_QUERY = AbstractMetadataRecord.RELATIONAL_URI + "native-query"; //$NON-NLS-1$
 	LDAPExecutionFactory executionFactory;
 	
 	/**
@@ -119,50 +118,43 @@
 		}
 		
 		LDAPSearchDetails sd = null;
-		Table table = ((NamedTable)fItm).getMetadataObject();			
-		String nativeQuery = table.getProperty(TEIID_NATIVE_QUERY, false);
-    	if (nativeQuery != null) {
-    		sd =  buildRequest(nativeQuery);
-    	}
-    	else {
-			String contextName = getContextNameFromFromItem(fItm);
-			int searchScope = getSearchScopeFromFromItem(fItm);
-			// GHH 20080326 - added check for RESTRICT parameter in
-			// NameInSource of from item
-			String classRestriction = getRestrictToNamedClass(fItm);
-					
-			// Parse the WHERE clause.
-			// Create an equivalent LDAP search filter.
-			List<String> searchStringList = new LinkedList<String>();
-			searchStringList = getSearchFilterFromWhereClause(query.getWhere(), searchStringList);
-			StringBuilder filterBuilder = new StringBuilder();
-			for (String string : searchStringList) {
-				filterBuilder.append(string);
-			}
-			// GHH 20080326 - if there is a class restriction,
-			// add it to the search filter
-			if (classRestriction != null && classRestriction.trim().length()>0) {
-				filterBuilder.insert(0, "(&").append("(objectClass=").append(classRestriction).append("))");  //$NON-NLS-1$  //$NON-NLS-2$  //$NON-NLS-3$
-			}
-			
-			// Parse the ORDER BY clause.
-			// Create an ordered sort list.
-			OrderBy orderBy = query.getOrderBy();
-			// Referenced the JNDI standard...arguably, this should not be done inside this
-			// class, and we should make our own key class. In practice, this makes things simpler.
-			SortKey[] sortKeys = getSortKeysFromOrderByClause(orderBy);
-			
-			// Parse LIMIT clause. 
-			// Note that offsets are not supported.
-			Limit limit = query.getLimit();
-			long countLimit = -1;
-			if(limit != null) {
-				countLimit = limit.getRowLimit();
-			}
-			
-			// Create Search Details
-			sd = new LDAPSearchDetails(contextName, searchScope, filterBuilder.toString(), sortKeys, countLimit, elementList, 0);
-    	}
+		String contextName = getContextNameFromFromItem(fItm);
+		int searchScope = getSearchScopeFromFromItem(fItm);
+		// GHH 20080326 - added check for RESTRICT parameter in
+		// NameInSource of from item
+		String classRestriction = getRestrictToNamedClass(fItm);
+				
+		// Parse the WHERE clause.
+		// Create an equivalent LDAP search filter.
+		List<String> searchStringList = new LinkedList<String>();
+		searchStringList = getSearchFilterFromWhereClause(query.getWhere(), searchStringList);
+		StringBuilder filterBuilder = new StringBuilder();
+		for (String string : searchStringList) {
+			filterBuilder.append(string);
+		}
+		// GHH 20080326 - if there is a class restriction,
+		// add it to the search filter
+		if (classRestriction != null && classRestriction.trim().length()>0) {
+			filterBuilder.insert(0, "(&").append("(objectClass=").append(classRestriction).append("))");  //$NON-NLS-1$  //$NON-NLS-2$  //$NON-NLS-3$
+		}
+		
+		// Parse the ORDER BY clause.
+		// Create an ordered sort list.
+		OrderBy orderBy = query.getOrderBy();
+		// Referenced the JNDI standard...arguably, this should not be done inside this
+		// class, and we should make our own key class. In practice, this makes things simpler.
+		SortKey[] sortKeys = getSortKeysFromOrderByClause(orderBy);
+		
+		// Parse LIMIT clause. 
+		// Note that offsets are not supported.
+		Limit limit = query.getLimit();
+		long countLimit = -1;
+		if(limit != null) {
+			countLimit = limit.getRowLimit();
+		}
+		
+		// Create Search Details
+		sd = new LDAPSearchDetails(contextName, searchScope, filterBuilder.toString(), sortKeys, countLimit, elementList, 0);
 		// Search Details logging	    	
 		sd.printDetailsToLog();
 		return sd;
@@ -371,42 +363,33 @@
 				expressionName = mdIDElement.getName();
 			}
 		} else if(e instanceof Literal) {
-			try {
-				if(((Literal)e).getType().equals(Class.forName(Timestamp.class.getName()))) {
-					LogManager.logTrace(LogConstants.CTX_CONNECTOR, "Found an expression that uses timestamp; converting to LDAP string format."); //$NON-NLS-1$
-					Timestamp ts = (Timestamp)((Literal)e).getValue();
-					Date dt = new Date(ts.getTime());
-					//TODO: Fetch format if provided.
-					SimpleDateFormat sdf = new SimpleDateFormat(LDAPConnectorConstants.ldapTimestampFormat);
-					expressionName = sdf.format(dt);
-					LogManager.logTrace(LogConstants.CTX_CONNECTOR, "Timestamp to stsring is: " + expressionName); //$NON-NLS-1$
-				}
-				else {
-					expressionName = ((Literal)e).getValue().toString();
-				}
-			} catch (ClassNotFoundException cce) {
-	            final String msg = LDAPPlugin.Util.getString("IQueryToLdapSearchParser.timestampClassNotFoundError"); //$NON-NLS-1$
-				throw new TranslatorException(cce, msg); 
-			}
-				
+			expressionName = getExpressionString((Literal)e);
 		} else {
-			if(e instanceof AggregateFunction) {
-				LogManager.logError(LogConstants.CTX_CONNECTOR, LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12001)); 
-			} else if(e instanceof Function) {
-				LogManager.logError(LogConstants.CTX_CONNECTOR, LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12005)); 
-			} else if(e instanceof ScalarSubquery) {
-				LogManager.logError(LogConstants.CTX_CONNECTOR, LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12006)); 
-			} else if (e instanceof SearchedCase) {
-				LogManager.logError(LogConstants.CTX_CONNECTOR, LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12007)); 
-			}
-            final String msg = LDAPPlugin.Util.getString("IQueryToLdapSearchParser.unsupportedElementError"); //$NON-NLS-1$
+            final String msg = LDAPPlugin.Util.getString("IQueryToLdapSearchParser.unsupportedElementError", e.getClass().getSimpleName()); //$NON-NLS-1$
 			throw new TranslatorException(msg + e.toString()); 
 		}
 		expressionName = escapeReservedChars(expressionName);
 		return expressionName;
 	}
+
+	static String getExpressionString(Literal l) {
+		if(l.getValue() instanceof Timestamp) {
+			LogManager.logTrace(LogConstants.CTX_CONNECTOR, "Found an expression that uses timestamp; converting to LDAP string format."); //$NON-NLS-1$
+			Timestamp ts = (Timestamp)l.getValue();
+			Date dt = new Date(ts.getTime());
+			//TODO: Fetch format if provided.
+			SimpleDateFormat sdf = new SimpleDateFormat(LDAPConnectorConstants.ldapTimestampFormat);
+			String expressionName = sdf.format(dt);
+			LogManager.logTrace(LogConstants.CTX_CONNECTOR, "Timestamp to string is: " + expressionName); //$NON-NLS-1$
+			return expressionName;
+		}
+		if (l.getValue() != null) {
+			return l.getValue().toString();
+		}
+		return "null";  //$NON-NLS-1$
+	}
 	
-	private String escapeReservedChars(String expr) {
+	static String escapeReservedChars(String expr) {
 		StringBuffer sb = new StringBuffer();
         for (int i = 0; i < expr.length(); i++) {
             char curChar = expr.charAt(i);
@@ -617,23 +600,21 @@
         return expr.getMetadataObject();
     }
 	
-	public LDAPSearchDetails buildRequest(String query) {
+	public LDAPSearchDetails buildRequest(String query) throws TranslatorException {
 		ArrayList<String> attributes = new ArrayList<String>();
 		ArrayList<Column> columns = new ArrayList<Column>();
 		String contextName = null;
 		String criteria = ""; //$NON-NLS-1$
 		String searchScope = this.executionFactory.getSearchDefaultScope().name();
 		int timeLimit = 0;
-		long countLimit = 0;
-		
-		StringTokenizer st = new StringTokenizer(query, ";"); //$NON-NLS-1$
-		while (st.hasMoreTokens()) {
-			String var = st.nextToken();
+		long countLimit = -1;
+		List<String> parts = StringUtil.tokenize(query, ';');
+		for (String var : parts) {
 			int index = var.indexOf('=');
 			if (index == -1) {
-				continue;
+				throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12013, var));
 			}
-			String key = var.substring(0, index).trim().toLowerCase();
+			String key = var.substring(0, index).trim();
 			String value = var.substring(index+1).trim();
 			
 			if (key.equalsIgnoreCase(CONTEXT_NAME)) {
@@ -665,6 +646,8 @@
 					column.setDatatype(type, true);
 					columns.add(column);
 				}
+			} else {
+				throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12013, var));
 			}
 		}
 		

Modified: trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPDirectCreateUpdateDeleteQueryExecution.java
===================================================================
--- trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPDirectCreateUpdateDeleteQueryExecution.java	2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPDirectCreateUpdateDeleteQueryExecution.java	2012-10-03 19:05:34 UTC (rev 4511)
@@ -22,6 +22,7 @@
 package org.teiid.translator.ldap;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.StringTokenizer;
 
@@ -45,27 +46,29 @@
 	protected LDAPExecutionFactory executionFactory;
 	protected ExecutionContext executionContext;
 	private int updateCount = -1;
+	private boolean returnsArray = true;
+	private String query;
 	
-	public LDAPDirectCreateUpdateDeleteQueryExecution(List<Argument> arguments, LDAPExecutionFactory factory, ExecutionContext executionContext, LdapContext connection) {
+	public LDAPDirectCreateUpdateDeleteQueryExecution(List<Argument> arguments, LDAPExecutionFactory factory, ExecutionContext executionContext, LdapContext connection, String query, boolean returnsArray) {
 		this.arguments = arguments;
 		this.executionFactory = factory;
 		this.executionContext = executionContext;
 		this.ldapConnection = connection;
+		this.query = query;
+		this.returnsArray = returnsArray;
 	}
 	
 	@Override
 	public void execute() throws TranslatorException {
-		String query = (String)arguments.get(0).getArgumentValue().getValue();
 		String firstToken = null;
 		
 		StringTokenizer st = new StringTokenizer(query, ";"); //$NON-NLS-1$
 		if (st.hasMoreTokens()) {
 			firstToken = st.nextToken();
-			if (!firstToken.equalsIgnoreCase("create") && !firstToken.equalsIgnoreCase("update") && !firstToken.equalsIgnoreCase("delete")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-				throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12009));
-			}
 		}
-		
+		if (firstToken == null || (!firstToken.equalsIgnoreCase("create") && !firstToken.equalsIgnoreCase("update") && !firstToken.equalsIgnoreCase("delete"))) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12009));
+		}		
 		LdapContext ldapCtx = null;
 		try {
 			ldapCtx = (LdapContext)this.ldapConnection.lookup("");  //$NON-NLS-1$
@@ -75,6 +78,9 @@
 
 		if (firstToken.equalsIgnoreCase("delete")) { // //$NON-NLS-1$
 			String theDN = getDN(st); // the token after the marker is always DN
+			if (st.hasMoreTokens()) {
+				throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12013, st.nextToken()));
+			}
 			try {
 				ldapCtx.destroySubcontext(theDN);
 				this.updateCount = 1;
@@ -86,7 +92,10 @@
 		}
 		else if (firstToken.equalsIgnoreCase("create")) { //$NON-NLS-1$
 			String theDN = getDN(st); // the token after the marker is always DN
-			ArrayList<BasicAttribute> attributes = getAttributes(st, this.arguments);
+			ArrayList<BasicAttribute> attributes = getAttributes(st);
+			if (st.hasMoreTokens()) {
+				throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12013, st.nextToken()));
+			}
 			BasicAttributes attrs = new BasicAttributes();
 			for (BasicAttribute ba:attributes) {
 				attrs.put(ba);
@@ -102,7 +111,10 @@
 		}
 		else if (firstToken.equalsIgnoreCase("update")) { //$NON-NLS-1$
 			String theDN = getDN(st); // the token after the marker is always DN
-			ArrayList<BasicAttribute> attributes = getAttributes(st, this.arguments);
+			ArrayList<BasicAttribute> attributes = getAttributes(st);
+			if (st.hasMoreTokens()) {
+				throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12013, st.nextToken()));
+			}
 			ModificationItem[] updateMods = new ModificationItem[attributes.size()];
 			int i=0;
 			for (BasicAttribute ba:attributes) {
@@ -117,7 +129,6 @@
 				throw new TranslatorException(e, LDAPPlugin.Util.getString("LDAPUpdateExecution.updateFailedUnexpected",theDN));//$NON-NLS-1$
 			}			
 		}
-		
 	}
 	
 	private String getDN(StringTokenizer st) throws TranslatorException {
@@ -127,26 +138,26 @@
 		return st.nextToken();
 	}
 
-	private ArrayList<BasicAttribute> getAttributes(StringTokenizer st, List<Argument> arguments) throws TranslatorException {
+	private ArrayList<BasicAttribute> getAttributes(StringTokenizer st) throws TranslatorException {
 		if (!st.hasMoreTokens()) {
 			throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12011));
 		}
 		
 		ArrayList<BasicAttribute> attributes = new ArrayList<BasicAttribute>();
 		
-		while(st.hasMoreElements()) {
+		if(st.hasMoreElements()) {
 			String var = st.nextToken();
 			
 			int index = var.indexOf('=');
 			if (index == -1) {
-				continue;
+				throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12011));
 			}
-			String key = var.substring(0, index).trim().toLowerCase();
+			String key = var.substring(0, index).trim();
 			String value = var.substring(index+1).trim();
 			
 			if (key.equalsIgnoreCase(ATTRIBUTES)) {
 				StringTokenizer attrTokens = new StringTokenizer(value, ","); //$NON-NLS-1$
-				int attrCount = 1;
+				int attrCount = 0;
 				while(attrTokens.hasMoreElements()) {
 					String name = attrTokens.nextToken().trim();
 					if (arguments.size() <= attrCount) {
@@ -156,7 +167,8 @@
 					Object  anObj = argument.getArgumentValue().getValue();
 					attributes.add(new BasicAttribute(name, anObj));
 				}
-				
+			} else {
+				throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12011));
 			}
 		}
 		return attributes;
@@ -170,10 +182,12 @@
 	@Override
 	public List<?> next() throws TranslatorException, DataNotAvailableException {
 		if (this.updateCount != -1) {
-			Object[] columns = new Object[1];
-			columns[0] = this.updateCount;
-			List<Object[]> row = new ArrayList<Object[]>(1);
-			row.add(columns);
+			List<Object> row = Arrays.asList((Object)Integer.valueOf(this.updateCount));
+			if (returnsArray) {
+				Object[] columns = new Object[1];
+				columns[0] = this.updateCount;
+				row.set(0, columns);
+			}
 			this.updateCount = -1;
 			return row;
 		}

Modified: trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPDirectSearchQueryExecution.java
===================================================================
--- trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPDirectSearchQueryExecution.java	2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPDirectSearchQueryExecution.java	2012-10-03 19:05:34 UTC (rev 4511)
@@ -28,6 +28,7 @@
 import javax.naming.ldap.LdapContext;
 
 import org.teiid.language.Argument;
+import org.teiid.language.visitor.SQLStringVisitor;
 import org.teiid.translator.DataNotAvailableException;
 import org.teiid.translator.ExecutionContext;
 import org.teiid.translator.ProcedureExecution;
@@ -35,16 +36,26 @@
 
 public class LDAPDirectSearchQueryExecution extends LDAPSyncQueryExecution implements ProcedureExecution {
 	
-	private List<Argument> arguments;
+	private String query;
+	private boolean returnsArray = true;
 	
-	public LDAPDirectSearchQueryExecution(List<Argument> arguments, LDAPExecutionFactory factory, ExecutionContext executionContext, LdapContext connection) {
+	public LDAPDirectSearchQueryExecution(List<Argument> arguments, LDAPExecutionFactory factory, ExecutionContext executionContext, LdapContext connection, String query, boolean returnsArray) {
 		super(null, factory, executionContext, connection);
-		this.arguments = arguments;
+		//perform substitution
+		StringBuilder sb = new StringBuilder();
+		SQLStringVisitor.parseNativeQueryParts(query.substring(7), arguments, sb, new SQLStringVisitor.Substitutor() {
+			
+			@Override
+			public void substitute(Argument arg, StringBuilder builder, int index) {
+				builder.append(IQueryToLdapSearchParser.escapeReservedChars(IQueryToLdapSearchParser.getExpressionString(arg.getArgumentValue())));
+			}
+		});
+		this.query = sb.toString();
+		this.returnsArray = returnsArray;
 	}
 	
 	@Override
 	public void execute() throws TranslatorException {
-		String query = (String)arguments.get(0).getArgumentValue().getValue();
 		IQueryToLdapSearchParser parser = new IQueryToLdapSearchParser(this.executionFactory);
 		LDAPSearchDetails details = parser.buildRequest(query);
 		// Create and configure the new search context.
@@ -67,9 +78,12 @@
 		if (vals == null) {
 			return null;
 		}
-		List<Object[]> row = new ArrayList<Object[]>(1);
-		row.add(vals.toArray(new Object[vals.size()]));
-		return row;
+		if (returnsArray) {
+			List<Object[]> row = new ArrayList<Object[]>(1);
+			row.add(vals.toArray(new Object[vals.size()]));
+			return row;
+		}
+		return vals;
 	}
 	
 	@Override

Modified: trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPExecutionFactory.java
===================================================================
--- trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPExecutionFactory.java	2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPExecutionFactory.java	2012-10-03 19:05:34 UTC (rev 4511)
@@ -27,9 +27,11 @@
 import javax.resource.cci.ConnectionFactory;
 
 import org.teiid.language.Argument;
+import org.teiid.language.Call;
 import org.teiid.language.Command;
 import org.teiid.language.QueryExpression;
 import org.teiid.language.Select;
+import org.teiid.language.visitor.SQLStringVisitor;
 import org.teiid.metadata.RuntimeMetadata;
 import org.teiid.translator.ExecutionContext;
 import org.teiid.translator.ExecutionFactory;
@@ -108,12 +110,26 @@
 	public ProcedureExecution createDirectExecution(List<Argument> arguments,Command command, ExecutionContext executionContext,RuntimeMetadata metadata, LdapContext context) throws TranslatorException {
 		String query = (String) arguments.get(0).getArgumentValue().getValue();
 		if (query.startsWith("search;")) { //$NON-NLS-1$
-			return new LDAPDirectSearchQueryExecution(arguments, this, executionContext, context);
+			return new LDAPDirectSearchQueryExecution(arguments.subList(1, arguments.size()), this, executionContext, context, query, true);
 		}
-		return new LDAPDirectCreateUpdateDeleteQueryExecution(arguments, this, executionContext, context);
+		return new LDAPDirectCreateUpdateDeleteQueryExecution(arguments.subList(1, arguments.size()), this, executionContext, context, query, true);
 	}	
 	
 	@Override
+	public ProcedureExecution createProcedureExecution(Call command,
+			ExecutionContext executionContext, RuntimeMetadata metadata,
+			LdapContext connection) throws TranslatorException {
+		String nativeQuery = command.getMetadataObject().getProperty(SQLStringVisitor.TEIID_NATIVE_QUERY, false);
+    	if (nativeQuery != null) {
+    		if (nativeQuery.startsWith("search;")) { //$NON-NLS-1$
+    			return new LDAPDirectSearchQueryExecution(command.getArguments(), this, executionContext, connection, nativeQuery, false);
+    		}
+    		return new LDAPDirectCreateUpdateDeleteQueryExecution(command.getArguments(), this, executionContext, connection, nativeQuery, false);
+    	}
+    	throw new TranslatorException("Missing native-query extension metadata."); //$NON-NLS-1$
+	}
+	
+	@Override
     public boolean supportsCompareCriteriaEquals() {
 		return true;
 	}

Modified: trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPPlugin.java
===================================================================
--- trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPPlugin.java	2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/connectors/translator-ldap/src/main/java/org/teiid/translator/ldap/LDAPPlugin.java	2012-10-03 19:05:34 UTC (rev 4511)
@@ -39,17 +39,14 @@
     public static final BundleUtil Util = new BundleUtil(PLUGIN_ID, PLUGIN_ID + ".i18n", ResourceBundle.getBundle(PLUGIN_ID + ".i18n")); //$NON-NLS-1$ //$NON-NLS-2$
 
     public static enum Event implements BundleUtil.Event {
-    	TEIID12001, // unsupported capability
     	TEIID12002, // search failed
     	TEIID12003, // close context
     	TEIID12004, // attribute fetch error
-    	TEIID12005,
-    	TEIID12006,
-    	TEIID12007,
     	TEIID12008,
     	TEIID12009,
     	TEIID12010,
     	TEIID12011,
-    	TEIID12012,
+    	TEIID12012, 
+    	TEIID12013,
     }
 }

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	2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/connectors/translator-ldap/src/main/resources/org/teiid/translator/ldap/i18n.properties	2012-10-03 19:05:34 UTC (rev 4511)
@@ -25,8 +25,7 @@
 IQueryToLdapSearchParser.baseContextNameError=Base context name (DN) not specified in Name In Source or connector properties.
 IQueryToLdapSearchParser.groupCountExceededError=Query contained from clause that did not have exactly and only one group. Query not supported.
 IQueryToLdapSearchParser.criteriaNotParsableError=Compound criteria operator was not parsable.
-IQueryToLdapSearchParser.timestampClassNotFoundError=Timestamp class was not found.
-IQueryToLdapSearchParser.unsupportedElementError=Encountered an element type that is not supported. Revise the capabilities.
+IQueryToLdapSearchParser.unsupportedElementError=Encountered an {0} that is not supported. Revise the capabilities.
 IQueryToLdapSearchParser.missingNISError=An element (or expression) found in the query's compare criteria was missing a NameInSource definition (or name). Please ensure the name in source is defined for each element.
 IQueryToLdapSearchParser.criteriaNotSupportedError=Encountered a criteria that is not supported.
 IQueryToLdapSearchParser.searchDetailsLoggingError=Error writing LDAP search details to log
@@ -62,13 +61,10 @@
 
 ldap_error=Ldap error while processing next batch of results
 
-TEIID12001=Received IAggregate, but it is not supported. Check capabilities.
-TEIID12005=Received IFunction, but it is not supported. Check capabilties.
-TEIID12006=Received IScalarSubquery, but it is not supported. Check capabilties.
-TEIID12007=Received ISearchedCaseExpression, but it is not supported. Check capabilties.
 TEIID12002=Attempted to search context: {0}
 TEIID12008=LDAP Search results exceeded size limit. Results may be incomplete.
 TEIID12009=Unknown LDAP Request; the query string must start with [search|create|update|delete]
 TEIID12010=The DN is not defined; DN should be the token after the marker tokens [search|create|update|delete]
 TEIID12011=attributes are not defined; use "attributes=..." form using the comma delimited to specify all the names.
-TEIID12012=create/update operation did not find the value for attribute {0}; Each attribute value is defined as the separate parameter in the procedure call.
\ No newline at end of file
+TEIID12012=create/update operation did not find the value for attribute {0}; Each attribute value is defined as the separate parameter in the procedure call.
+TEIID12013=unknown option: {0}
\ No newline at end of file

Modified: trunk/connectors/translator-ldap/src/test/java/org/teiid/translator/ldap/TestIQueryToLdapSearchParser.java
===================================================================
--- trunk/connectors/translator-ldap/src/test/java/org/teiid/translator/ldap/TestIQueryToLdapSearchParser.java	2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/connectors/translator-ldap/src/test/java/org/teiid/translator/ldap/TestIQueryToLdapSearchParser.java	2012-10-03 19:05:34 UTC (rev 4511)
@@ -35,10 +35,10 @@
 import org.teiid.language.Command;
 import org.teiid.language.Select;
 import org.teiid.metadata.Column;
-import org.teiid.metadata.Column.SearchType;
 import org.teiid.metadata.MetadataStore;
 import org.teiid.metadata.Schema;
 import org.teiid.metadata.Table;
+import org.teiid.metadata.Column.SearchType;
 import org.teiid.query.metadata.CompositeMetadataStore;
 import org.teiid.query.metadata.QueryMetadataInterface;
 import org.teiid.query.metadata.TransformationMetadata;
@@ -246,25 +246,6 @@
         		expectedCountLimit, expectedSearchScope, expectedSortKeys);
     }
     
-    public void testNativeQueryExtension() throws Exception {
-        LDAPSearchDetails searchDetails = helpGetSearchDetails("SELECT * FROM LdapModel.Employee"); //$NON-NLS-1$
-        
-        String expectedContextName = "corporate"; //$NON-NLS-1$
-        String expectedContextFilter = "(objectClass=*)"; //$NON-NLS-1$
-        
-        List expectedAttrNameList = new ArrayList();
-        expectedAttrNameList.add("uid"); //$NON-NLS-1$
-        expectedAttrNameList.add("cn"); //$NON-NLS-1$
-        
-        long expectedCountLimit = 5;
-        int expectedSearchScope = SearchControls.ONELEVEL_SCOPE;
-        SortKey[] expectedSortKeys = null;
-        
-        helpTestSearchDetails(searchDetails, expectedContextName, expectedContextFilter, expectedAttrNameList,
-        		expectedCountLimit, expectedSearchScope, expectedSortKeys);
-        
-    }    
-
 	private LDAPSearchDetails helpGetSearchDetails(String queryString) throws TranslatorException {
     	QueryMetadataInterface metadata = exampleLdap();
     	
@@ -312,19 +293,6 @@
             cols.get(i).setSearchType(SearchType.Unsearchable);
         }
         
-        Table employees = RealMetadataFactory.createPhysicalGroup("Employee", ldapModel); //$NON-NLS-1$
-        List<Column> employeeCols = RealMetadataFactory.createElements(employees, elemNames, elemTypes);
-        for(int i=0; i<2; i++) {
-            Column obj = employeeCols.get(i);
-            obj.setNameInSource(nameInSource[i]);
-        }
-        
-        // Set column-specific properties
-        for(int i=1; i<2; i++) {
-        	employeeCols.get(i).setSearchType(SearchType.Unsearchable);
-        } 
-        employees.setProperty(IQueryToLdapSearchParser.TEIID_NATIVE_QUERY, "context-name=corporate;filter=(objectClass=*);count-limit=5;timout=6;search-scope=ONELEVEL_SCOPE;attributes=uid,cn"); //$NON-NLS-1$
-        
         // Create the facade from the store
         return new TransformationMetadata(null, new CompositeMetadataStore(metadataStore), null, RealMetadataFactory.SFM.getSystemFunctions(), null);
     }    

Modified: trunk/connectors/translator-ldap/src/test/java/org/teiid/translator/ldap/TestLDAPDirectQueryExecution.java
===================================================================
--- trunk/connectors/translator-ldap/src/test/java/org/teiid/translator/ldap/TestLDAPDirectQueryExecution.java	2012-10-03 16:54:06 UTC (rev 4510)
+++ trunk/connectors/translator-ldap/src/test/java/org/teiid/translator/ldap/TestLDAPDirectQueryExecution.java	2012-10-03 19:05:34 UTC (rev 4511)
@@ -21,8 +21,7 @@
  */
 package org.teiid.translator.ldap;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
 
 import java.math.BigDecimal;
 
@@ -38,6 +37,7 @@
 import org.teiid.cdk.unittest.FakeTranslationFactory;
 import org.teiid.language.Command;
 import org.teiid.metadata.RuntimeMetadata;
+import org.teiid.translator.Execution;
 import org.teiid.translator.ExecutionContext;
 import org.teiid.translator.TranslatorException;
 
@@ -54,7 +54,7 @@
     }	
     
     @Test public void testSearch() throws Exception {
-        String input = "exec native('search;context-name=corporate;filter=(objectClass=*);count-limit=5;timout=6;search-scope=ONELEVEL_SCOPE;attributes=uid,cn')"; 
+        String input = "exec native('search;context-name=corporate;filter=(objectClass=*);count-limit=5;timeout=6;search-scope=ONELEVEL_SCOPE;attributes=uid,cn')"; 
 
         TranslationUtility util = FakeTranslationFactory.getInstance().getExampleTranslationUtility();
         Command command = util.parseCommand(input);
@@ -71,13 +71,37 @@
         assertEquals("corporate", details.getContextName());
         assertEquals("(objectClass=*)", details.getContextFilter());
         assertEquals(5, details.getCountLimit());
+        assertEquals(6, details.getTimeLimit());
         assertEquals(1, details.getSearchScope());
         assertEquals(2, details.getElementList().size());
         assertEquals("uid", details.getElementList().get(0).getName());
         assertEquals("cn", details.getElementList().get(1).getName());
-    }    
+    }
     
-    @Test public void testWithoutMarker() throws Exception {
+    @Test public void testSearchDefaultsAndEscaping() throws Exception {
+        String input = "exec native('search;context-name=corporate;filter=(;;)')"; 
+
+        TranslationUtility util = FakeTranslationFactory.getInstance().getExampleTranslationUtility();
+        Command command = util.parseCommand(input);
+        ExecutionContext ec = Mockito.mock(ExecutionContext.class);
+        RuntimeMetadata rm = Mockito.mock(RuntimeMetadata.class);
+        LdapContext connection = Mockito.mock(LdapContext.class);
+        LdapContext ctx = Mockito.mock(LdapContext.class);
+        Mockito.stub(connection.lookup("corporate")).toReturn(ctx);
+        
+        LDAPDirectSearchQueryExecution execution = (LDAPDirectSearchQueryExecution)TRANSLATOR.createExecution(command, ec, rm, connection);
+        execution.execute();
+        LDAPSearchDetails details = execution.getDelegate().getSearchDetails();
+        
+        assertEquals("corporate", details.getContextName());
+        assertEquals("(;)", details.getContextFilter());
+        assertEquals(-1, details.getCountLimit());
+        assertEquals(0, details.getTimeLimit());
+        assertEquals(1, details.getSearchScope());
+        assertEquals(0, details.getElementList().size());
+    } 
+    
+    @Test(expected=TranslatorException.class) public void testWithoutMarker() throws Exception {
         String input = "exec native('context-name=corporate;filter=(objectClass=*);count-limit=5;timout=6;search-scope=ONELEVEL_SCOPE;attributes=uid,cn')"; 
 
         TranslationUtility util = FakeTranslationFactory.getInstance().getExampleTranslationUtility();
@@ -88,12 +112,9 @@
         LdapContext ctx = Mockito.mock(LdapContext.class);
         Mockito.stub(connection.lookup("corporate")).toReturn(ctx);
         
-        try {
-			LDAPDirectSearchQueryExecution execution = (LDAPDirectSearchQueryExecution)TRANSLATOR.createExecution(command, ec, rm, connection);
-			execution.execute();
-			fail("the above should have thrown exception");
-		} catch (ClassCastException e) {
-		}
+		Execution execution = TRANSLATOR.createExecution(command, ec, rm, connection);
+		assertTrue(!(execution instanceof LDAPDirectSearchQueryExecution));
+		execution.execute();
     }    
     
     @Test public void testDelete() throws Exception {
@@ -167,7 +188,7 @@
 		assertEquals(new BigDecimal("3.0"), createItemArgument.getValue().get("three").get());
     }
     
-    @Test public void testCreateFail() throws Exception {
+    @Test(expected=TranslatorException.class) public void testCreateFail() throws Exception {
         String input = "exec native('create;uid=doe,ou=people,o=teiid.org;attributes=one,two,three', 'one')"; 
 
         TranslationUtility util = FakeTranslationFactory.getInstance().getExampleTranslationUtility();
@@ -178,11 +199,7 @@
         LdapContext ctx = Mockito.mock(LdapContext.class);
         Mockito.stub(connection.lookup("")).toReturn(ctx);
         
-        try {
-			LDAPDirectCreateUpdateDeleteQueryExecution execution = (LDAPDirectCreateUpdateDeleteQueryExecution)TRANSLATOR.createExecution(command, ec, rm, connection);
-			execution.execute();
-			fail("should have failed because there are not enough values");
-		} catch (TranslatorException e) {
-		}
+		LDAPDirectCreateUpdateDeleteQueryExecution execution = (LDAPDirectCreateUpdateDeleteQueryExecution)TRANSLATOR.createExecution(command, ec, rm, connection);
+		execution.execute();
     }    
 }



More information about the teiid-commits mailing list