/*
* This file is part of the WfMOpen project.
* Copyright (C) 2001-2004 Danet GmbH (www.danet.de), BU BTS.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: UpdateTag.java 1607 2006-09-29 12:32:13Z drmlipp $
*
* $Log$
* Revision 1.2 2005/09/05 09:41:48 drmlipp
* Synchronized with 1.3.2.
*
* Revision 1.1.2.2 2005/09/02 11:24:01 drmlipp
* Added operation attribute for update tag.
*
* Revision 1.1.2.1 2005/09/01 14:47:18 drmlipp
* Got update running.
*
*/
package de.danet.an.util.jellytags.ldap;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.naming.NamingException;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;
import org.apache.commons.jelly.JellyTagException;
import org.apache.commons.jelly.XMLOutput;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import de.danet.an.util.jellytags.ParseTagSupport;
import de.danet.an.util.sax.HandlerStack;
import de.danet.an.util.sax.StackedHandler;
/**
* A tag that executes an LDAP query.
*/
public class UpdateTag extends ParseTagSupport {
private static final org.apache.commons.logging.Log logger
= org.apache.commons.logging.LogFactory.getLog(UpdateTag.class);
private DirContext ldapContext = null;
private String defaultOperation = "replace";
/**
* @return Returns the operation.
*/
public String getOperation() {
return defaultOperation;
}
/**
* @param operation The operation to set.
*/
public void setOperation(String operation) {
this.defaultOperation = operation;
}
/**
* @param context The context to set.
*/
public void setLdapContext(DirContext context) {
this.ldapContext = context;
}
/**
* Execute the tag.
* @param output the query result
* @throws JellyTagException if an error occurs
*/
public void doTag(XMLOutput output) throws JellyTagException {
if (ldapContext == null) {
throw new IllegalStateException
("Attribute \"ldapContext\" must be specified.");
}
try {
HandlerStack handler = new HandlerStack(new ContentHandler ());
getXML (new XMLOutput(handler.contentHandler()));
} catch (SAXException e) {
throw new JellyTagException(e.getException());
}
}
private class ContentHandler extends StackedHandler {
String dn = null;
int defOp;;
String attrName = null;
int attrOp;
Map mods = null;
/* (non-Javadoc)
* @see org.xml.sax.ContentHandler#startElement
*/
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (localName.equals("entry")) {
dn = attributes.getValue("dn");
if (dn == null) {
throw new IllegalArgumentException
("Attribute \"dn\" must be spcified for <entry>");
}
mods = new HashMap ();
defOp = opFromString
(attributes.getValue("operation"),
opFromString (getOperation(), DirContext.REPLACE_ATTRIBUTE));
} else if (localName.equals ("attribute")) {
attrName = attributes.getValue("name");
if (attrName == null) {
throw new IllegalArgumentException
("Attribute \"name\" must be specified for <attribute>");
}
attrOp = opFromString
(attributes.getValue("operation"), defOp);
}
}
/**
* @param op
*/
private int opFromString(String op, int def) {
if (op == null) {
return def;
}
if (op.equals("add")) {
return DirContext.ADD_ATTRIBUTE;
}
if (op.equals ("replace")) {
return DirContext.REPLACE_ATTRIBUTE;
}
if (op.equals ("remove")) {
return DirContext.REMOVE_ATTRIBUTE;
}
throw new IllegalArgumentException
("Invalid operation \"" + op + "\", must be one of"
+ " of \"add\", \"replace\" or \"remove\".");
}
/* (non-Javadoc)
* @see org.xml.sax.ContentHandler#endElement
*/
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (localName.equals("entry")) {
try {
Collection modVals = mods.values();
ldapContext.modifyAttributes
(dn, (ModificationItem[])
modVals.toArray(new ModificationItem[modVals.size()]));
} catch (NamingException e) {
throw new SAXException (e);
}
} else if (localName.equals("attribute")) {
ModificationItem mi = (ModificationItem)mods.get (attrName);
if (mi == null) {
mi = new ModificationItem
(attrOp, new BasicAttribute(attrName));
mods.put (attrName, mi);
}
if (mi.getModificationOp() != attrOp) {
throw new IllegalArgumentException
("All attributes with name \"" + attrName
+ "\" must use the same operation.");
}
if (attrOp != DirContext.REMOVE_ATTRIBUTE) {
mi.getAttribute().add(text());
}
}
}
}
}