/* * JBoss, Home of Professional Open Source. * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. Some portions may be licensed * to Red Hat, Inc. under one or more contributor license agreements. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. */ package org.teiid.translator.ldap; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.StringTokenizer; import javax.naming.NamingException; import javax.naming.directory.BasicAttribute; import javax.naming.directory.BasicAttributes; import javax.naming.directory.DirContext; import javax.naming.directory.ModificationItem; import javax.naming.ldap.LdapContext; import org.teiid.language.Argument; import org.teiid.translator.DataNotAvailableException; import org.teiid.translator.ExecutionContext; import org.teiid.translator.ProcedureExecution; import org.teiid.translator.TranslatorException; public class LDAPDirectCreateUpdateDeleteQueryExecution implements ProcedureExecution { private static final String ATTRIBUTES = "attributes"; //$NON-NLS-1$ private List<Argument> arguments; protected LdapContext ldapConnection; 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, 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 firstToken = null; StringTokenizer st = new StringTokenizer(query, ";"); //$NON-NLS-1$ if (st.hasMoreTokens()) { firstToken = st.nextToken(); } 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$ } catch (NamingException ne) { throw new TranslatorException(ne, LDAPPlugin.Util.getString("LDAPUpdateExecution.createContextError",ne.getExplanation()));//$NON-NLS-1$ } 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; } catch (NamingException ne) { throw new TranslatorException(ne, LDAPPlugin.Util.getString("LDAPUpdateExecution.deleteFailed",theDN,ne.getExplanation()));//$NON-NLS-1$ } catch (Exception e) { throw new TranslatorException(e, LDAPPlugin.Util.getString("LDAPUpdateExecution.deleteFailedUnexpected",theDN));//$NON-NLS-1$ } } 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); 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); } try { ldapCtx.createSubcontext(theDN, attrs); this.updateCount = 1; } catch (NamingException ne) { throw new TranslatorException(ne, LDAPPlugin.Util.getString("LDAPUpdateExecution.insertFailed", theDN, ne.getExplanation()));//$NON-NLS-1$ } catch (Exception e) { throw new TranslatorException(e,LDAPPlugin.Util.getString("LDAPUpdateExecution.insertFailedUnexpected", theDN));//$NON-NLS-1$ } } 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); 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) { updateMods[i++] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, ba); } try { ldapCtx.modifyAttributes(theDN, updateMods); this.updateCount = 1; } catch (NamingException ne) { throw new TranslatorException(ne, LDAPPlugin.Util.getString("LDAPUpdateExecution.updateFailed", theDN, ne.getExplanation()));//$NON-NLS-1$ } catch (Exception e) { throw new TranslatorException(e, LDAPPlugin.Util.getString("LDAPUpdateExecution.updateFailedUnexpected",theDN));//$NON-NLS-1$ } } } private String getDN(StringTokenizer st) throws TranslatorException { if (!st.hasMoreTokens()) { throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12010)); } return st.nextToken(); } 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>(); if(st.hasMoreElements()) { String var = st.nextToken(); int index = var.indexOf('='); if (index == -1) { throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12011)); } 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 = 0; while(attrTokens.hasMoreElements()) { String name = attrTokens.nextToken().trim(); if (arguments.size() <= attrCount) { throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12012, name)); } Argument argument = arguments.get(attrCount++); Object anObj = null; if (argument.getArgumentValue().getValue() != null) { anObj = IQueryToLdapSearchParser.getLiteralString(argument.getArgumentValue()); } attributes.add(new BasicAttribute(name, anObj)); } } else { throw new TranslatorException(LDAPPlugin.Util.gs(LDAPPlugin.Event.TEIID12011)); } } return attributes; } @Override public List<?> getOutputParameterValues() throws TranslatorException { return null; } @Override public List<?> next() throws TranslatorException, DataNotAvailableException { if (this.updateCount != -1) { 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; } return null; } @Override public void close() { } @Override public void cancel() throws TranslatorException { } }