Commit 91da6b0a authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

More work on vcard mapping.

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@5639 b35dd754-fafc-0310-a699-88a17e54d16e
parent b36c3638
...@@ -16,9 +16,12 @@ import org.dom4j.io.OutputFormat; ...@@ -16,9 +16,12 @@ import org.dom4j.io.OutputFormat;
import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.util.XMLWriter; import org.jivesoftware.util.XMLWriter;
import org.jivesoftware.wildfire.ldap.LdapManager;
import org.jivesoftware.wildfire.ldap.LdapVCardProvider;
import java.io.IOException; import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.Iterator;
/** /**
* Bean that stores the vcard mapping. It is also responsible for saving the mapping * Bean that stores the vcard mapping. It is also responsible for saving the mapping
...@@ -53,7 +56,6 @@ public class LdapUserProfile { ...@@ -53,7 +56,6 @@ public class LdapUserProfile {
private String businessMobile = ""; private String businessMobile = "";
private String businessFax = ""; private String businessFax = "";
private String businessPager = ""; private String businessPager = "";
private String businessWebPage = "";
public String getName() { public String getName() {
return name; return name;
...@@ -255,14 +257,6 @@ public class LdapUserProfile { ...@@ -255,14 +257,6 @@ public class LdapUserProfile {
this.businessPager = businessPager; this.businessPager = businessPager;
} }
public String getBusinessWebPage() {
return businessWebPage;
}
public void setBusinessWebPage(String businessWebPage) {
this.businessWebPage = businessWebPage;
}
/** /**
* Sets default mapping values when using an Active Directory server. * Sets default mapping values when using an Active Directory server.
*/ */
...@@ -281,7 +275,7 @@ public class LdapUserProfile { ...@@ -281,7 +275,7 @@ public class LdapUserProfile {
homeMobile = ""; homeMobile = "";
homeFax = ""; homeFax = "";
homePager = ""; homePager = "";
businessStreet = "{postalAddress}"; businessStreet = "{streetAddress}";
businessCity = "{l}"; businessCity = "{l}";
businessState = "{st}"; businessState = "{st}";
businessZip = "{postalCode}"; businessZip = "{postalCode}";
...@@ -292,7 +286,6 @@ public class LdapUserProfile { ...@@ -292,7 +286,6 @@ public class LdapUserProfile {
businessMobile = "{mobile}"; businessMobile = "{mobile}";
businessFax = "{facsimileTelephoneNumber}"; businessFax = "{facsimileTelephoneNumber}";
businessPager = "{pager}"; businessPager = "{pager}";
businessWebPage = "";
} }
/** /**
...@@ -324,7 +317,6 @@ public class LdapUserProfile { ...@@ -324,7 +317,6 @@ public class LdapUserProfile {
businessMobile = "{mobile}"; businessMobile = "{mobile}";
businessFax = ""; businessFax = "";
businessPager = "{pager}"; businessPager = "{pager}";
businessWebPage = "";
} }
/** /**
...@@ -386,7 +378,7 @@ public class LdapUserProfile { ...@@ -386,7 +378,7 @@ public class LdapUserProfile {
subelement.addElement("REGION").setText(businessState.trim()); subelement.addElement("REGION").setText(businessState.trim());
} }
if (businessZip != null && businessZip.trim().length() > 0) { if (businessZip != null && businessZip.trim().length() > 0) {
subelement.addElement("PCODE").setText(homeZip.trim()); subelement.addElement("PCODE").setText(businessZip.trim());
} }
if (businessCountry != null && businessCountry.trim().length() > 0) { if (businessCountry != null && businessCountry.trim().length() > 0) {
subelement.addElement("CTRY").setText(businessCountry.trim()); subelement.addElement("CTRY").setText(businessCountry.trim());
...@@ -402,7 +394,6 @@ public class LdapUserProfile { ...@@ -402,7 +394,6 @@ public class LdapUserProfile {
if (homeMobile != null && homeMobile.trim().length() > 0) { if (homeMobile != null && homeMobile.trim().length() > 0) {
subelement = vCard.addElement("TEL"); subelement = vCard.addElement("TEL");
subelement.addElement("HOME"); subelement.addElement("HOME");
subelement.addElement("VOICE");
subelement.addElement("CELL"); subelement.addElement("CELL");
subelement.addElement("NUMBER").setText(homeMobile.trim()); subelement.addElement("NUMBER").setText(homeMobile.trim());
} }
...@@ -431,7 +422,6 @@ public class LdapUserProfile { ...@@ -431,7 +422,6 @@ public class LdapUserProfile {
if (businessMobile != null && businessMobile.trim().length() > 0) { if (businessMobile != null && businessMobile.trim().length() > 0) {
subelement = vCard.addElement("TEL"); subelement = vCard.addElement("TEL");
subelement.addElement("WORK"); subelement.addElement("WORK");
subelement.addElement("VOICE");
subelement.addElement("CELL"); subelement.addElement("CELL");
subelement.addElement("NUMBER").setText(businessMobile.trim()); subelement.addElement("NUMBER").setText(businessMobile.trim());
} }
...@@ -453,9 +443,10 @@ public class LdapUserProfile { ...@@ -453,9 +443,10 @@ public class LdapUserProfile {
if (businessJobTitle != null && businessJobTitle.trim().length() > 0) { if (businessJobTitle != null && businessJobTitle.trim().length() > 0) {
vCard.addElement("TITLE").setText(businessJobTitle.trim()); vCard.addElement("TITLE").setText(businessJobTitle.trim());
} }
// TODO Add job department // Add job department
// TODO Add web page if (businessDepartment != null && businessDepartment.trim().length() > 0) {
vCard.addElement("ORG").addElement("ORGUNIT").setText(businessDepartment.trim());
}
// Generate content to store in property // Generate content to store in property
String vcardXML; String vcardXML;
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
...@@ -474,6 +465,13 @@ public class LdapUserProfile { ...@@ -474,6 +465,13 @@ public class LdapUserProfile {
sb.append("<![CDATA[").append(vcardXML).append("]]>"); sb.append("<![CDATA[").append(vcardXML).append("]]>");
// Save mapping as an XML property // Save mapping as an XML property
JiveGlobals.setXMLProperty("ldap.vcard-mapping", sb.toString()); JiveGlobals.setXMLProperty("ldap.vcard-mapping", sb.toString());
// Set that the vcard provider is LdapVCardProvider
JiveGlobals.setXMLProperty("provider.vcard.className", LdapVCardProvider.class.getName());
// Save duplicated fields in LdapManager (should be removed in the future)
LdapManager.getInstance().setNameField(name.replaceAll("(\\{)([\\d\\D]+)(})", "$2"));
LdapManager.getInstance().setEmailField(email.replaceAll("(\\{)([\\d\\D]+)(})", "$2"));
} }
/** /**
...@@ -489,6 +487,11 @@ public class LdapUserProfile { ...@@ -489,6 +487,11 @@ public class LdapUserProfile {
} }
try { try {
// Remove CDATA wrapping element
if (xmlProperty.startsWith("<![CDATA[")) {
xmlProperty = xmlProperty.substring(9, xmlProperty.length()-3);
}
// Parse XML
Document document = DocumentHelper.parseText(xmlProperty); Document document = DocumentHelper.parseText(xmlProperty);
Element vCard = document.getRootElement(); Element vCard = document.getRootElement();
...@@ -512,7 +515,88 @@ public class LdapUserProfile { ...@@ -512,7 +515,88 @@ public class LdapUserProfile {
if (element != null) { if (element != null) {
birthday = element.getTextTrim(); birthday = element.getTextTrim();
} }
// TODO add rest of fields // Parse addresses
Iterator addresses = vCard.elementIterator("ADR");
while (addresses.hasNext()) {
element = (Element) addresses.next();
if (element.element("HOME") != null) {
if (element.element("STREET") != null) {
homeStreet = element.elementTextTrim("STREET");
}
if (element.element("LOCALITY") != null) {
homeCity = element.elementTextTrim("LOCALITY");
}
if (element.element("REGION") != null) {
homeState = element.elementTextTrim("REGION");
}
if (element.element("PCODE") != null) {
homeZip = element.elementTextTrim("PCODE");
}
if (element.element("CTRY") != null) {
homeCountry = element.elementTextTrim("CTRY");
}
}
else if (element.element("WORK") != null) {
if (element.element("STREET") != null) {
businessStreet = element.elementTextTrim("STREET");
}
if (element.element("LOCALITY") != null) {
businessCity = element.elementTextTrim("LOCALITY");
}
if (element.element("REGION") != null) {
businessState = element.elementTextTrim("REGION");
}
if (element.element("PCODE") != null) {
businessZip = element.elementTextTrim("PCODE");
}
if (element.element("CTRY") != null) {
businessCountry = element.elementTextTrim("CTRY");
}
}
}
// Parse telephones
Iterator telephones = vCard.elementIterator("TEL");
while (telephones.hasNext()) {
element = (Element) telephones.next();
if (element.element("HOME") != null) {
if (element.element("VOICE") != null) {
homePhone = element.elementTextTrim("NUMBER");
}
else if (element.element("CELL") != null) {
homeMobile = element.elementTextTrim("NUMBER");
}
else if (element.element("FAX") != null) {
homeFax = element.elementTextTrim("NUMBER");
}
else if (element.element("PAGER") != null) {
homePager = element.elementTextTrim("NUMBER");
}
}
else if (element.element("WORK") != null) {
if (element.element("VOICE") != null) {
businessPhone = element.elementTextTrim("NUMBER");
}
else if (element.element("CELL") != null) {
businessMobile = element.elementTextTrim("NUMBER");
}
else if (element.element("FAX") != null) {
businessFax = element.elementTextTrim("NUMBER");
}
else if (element.element("PAGER") != null) {
businessPager = element.elementTextTrim("NUMBER");
}
}
}
element = vCard.element("TITLE");
if (element != null) {
businessJobTitle = element.getTextTrim();
}
element = vCard.element("ORG");
if (element != null) {
if (element.element("ORGUNIT") != null) {
businessDepartment = element.elementTextTrim("ORGUNIT");
}
}
} }
catch (DocumentException e) { catch (DocumentException e) {
Log.error("Error loading vcard mappings from property", e); Log.error("Error loading vcard mappings from property", e);
......
...@@ -10,12 +10,16 @@ ...@@ -10,12 +10,16 @@
package org.jivesoftware.util; package org.jivesoftware.util;
import java.beans.*; import javax.servlet.http.HttpServletRequest;
import java.awt.Color; import java.awt.*;
import java.util.*; import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*;
/** /**
* A utility class that provides methods that are useful for dealing with * A utility class that provides methods that are useful for dealing with
...@@ -43,11 +47,10 @@ public class BeanUtils { ...@@ -43,11 +47,10 @@ public class BeanUtils {
* @param bean the JavaBean to set properties on. * @param bean the JavaBean to set properties on.
* @param properties String name/value pairs of the properties to set. * @param properties String name/value pairs of the properties to set.
*/ */
public static void setProperties(Object bean, Map properties) { public static void setProperties(Object bean, Map<String, String> properties) {
try { try {
// Loop through all the property names in the Map // Loop through all the property names in the Map
for (Iterator iter = properties.keySet().iterator(); iter.hasNext();) { for (String propName : properties.keySet()) {
String propName = (String)iter.next();
try { try {
// Create a property descriptor for the named property. If // Create a property descriptor for the named property. If
// the bean doesn't have the named property, an // the bean doesn't have the named property, an
...@@ -58,9 +61,9 @@ public class BeanUtils { ...@@ -58,9 +61,9 @@ public class BeanUtils {
Class propertyType = descriptor.getPropertyType(); Class propertyType = descriptor.getPropertyType();
// Get the value of the property by converting it from a // Get the value of the property by converting it from a
// String to the correct object type. // String to the correct object type.
Object value = decode(propertyType, (String)properties.get(propName)); Object value = decode(propertyType, properties.get(propName));
// Set the value of the bean. // Set the value of the bean.
descriptor.getWriteMethod().invoke(bean, new Object[] { value }); descriptor.getWriteMethod().invoke(bean, value);
} }
catch (IntrospectionException ie) { catch (IntrospectionException ie) {
// Ignore. This exception means that the key in the map // Ignore. This exception means that the key in the map
...@@ -78,6 +81,53 @@ public class BeanUtils { ...@@ -78,6 +81,53 @@ public class BeanUtils {
} }
} }
/**
* Sets the properties of a Java Bean based on the request's properties. Because
* this method has to know how to convert a String value into the correct type
* for the bean, only a few bean property types are supported. They are: String,
* boolean, int, long, float, double, Color, and Class.<p>
*
* If key/value pairs exist in the Map that don't correspond to properties
* of the bean, they will be ignored.
*
* @param bean the JavaBean to set properties on.
* @param request the HTTP request.
*/
public static void setProperties(Object bean, HttpServletRequest request) {
for (Enumeration propNames = request.getParameterNames(); propNames.hasMoreElements();) {
String propName = (String) propNames.nextElement();
try {
// Create a property descriptor for the named property. If
// the bean doesn't have the named property, an
// Introspection will be thrown.
PropertyDescriptor descriptor = new PropertyDescriptor(
propName, bean.getClass());
// Load the class type of the property.
Class propertyType = descriptor.getPropertyType();
// Get the value of the property by converting it from a
// String to the correct object type.
Object value = decode(propertyType, request.getParameter(propName));
// Set the value of the bean.
descriptor.getWriteMethod().invoke(bean, value);
}
catch (IntrospectionException ie) {
// Ignore. This exception means that the key in the map
// does not correspond to a property of the bean.
}
catch (InvocationTargetException ite) {
// Ignore. This exception most often occurs when a
// value in the map is null and the target method doesn't
// support null properties.
}
catch (IllegalAccessException e) {
Log.error(e);
}
catch (Exception e) {
Log.error(e);
}
}
}
/** /**
* Gets the properties from a Java Bean and returns them in a Map of String * Gets the properties from a Java Bean and returns them in a Map of String
* name/value pairs. Because this method has to know how to convert a * name/value pairs. Because this method has to know how to convert a
...@@ -88,8 +138,8 @@ public class BeanUtils { ...@@ -88,8 +138,8 @@ public class BeanUtils {
* @param bean a Java Bean to get properties from. * @param bean a Java Bean to get properties from.
* @return a Map of all properties as String name/value pairs. * @return a Map of all properties as String name/value pairs.
*/ */
public static Map getProperties(Object bean) { public static Map<String, String> getProperties(Object bean) {
Map properties = new HashMap(); Map<String, String> properties = new HashMap<String, String>();
try { try {
BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass()); BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
// Loop through all properties of the bean. // Loop through all properties of the bean.
...@@ -98,7 +148,7 @@ public class BeanUtils { ...@@ -98,7 +148,7 @@ public class BeanUtils {
for (int i=0; i<names.length; i++) { for (int i=0; i<names.length; i++) {
// Determine the property name. // Determine the property name.
String name = descriptors[i].getName(); String name = descriptors[i].getName();
Class type = descriptors[i].getPropertyType(); //Class type = descriptors[i].getPropertyType();
// Decode the property value using the property type and // Decode the property value using the property type and
// encoded String value. // encoded String value.
Object value = descriptors[i].getReadMethod().invoke(bean,(java.lang.Object[]) null); Object value = descriptors[i].getReadMethod().invoke(bean,(java.lang.Object[]) null);
...@@ -122,6 +172,7 @@ public class BeanUtils { ...@@ -122,6 +172,7 @@ public class BeanUtils {
* *
* @param beanClass the Class of the JavaBean. * @param beanClass the Class of the JavaBean.
* @return the PropertyDescriptor array for the specified Java Bean Class. * @return the PropertyDescriptor array for the specified Java Bean Class.
* @throws java.beans.IntrospectionException
*/ */
public static PropertyDescriptor[] getPropertyDescriptors(Class beanClass) public static PropertyDescriptor[] getPropertyDescriptors(Class beanClass)
throws IntrospectionException throws IntrospectionException
...@@ -147,6 +198,7 @@ public class BeanUtils { ...@@ -147,6 +198,7 @@ public class BeanUtils {
* supported, null will be returned. * supported, null will be returned.
* *
* @param value an Object to encode in a String representation. * @param value an Object to encode in a String representation.
* @return the encoded bean.
*/ */
private static String encode(Object value) { private static String encode(Object value) {
if (value instanceof String) { if (value instanceof String) {
...@@ -185,6 +237,7 @@ public class BeanUtils { ...@@ -185,6 +237,7 @@ public class BeanUtils {
* @param type the type of the property. * @param type the type of the property.
* @param value the encode String value to decode. * @param value the encode String value to decode.
* @return the String value decoded into the specified type. * @return the String value decoded into the specified type.
* @throws Exception
*/ */
private static Object decode(Class type, String value) throws Exception { private static Object decode(Class type, String value) throws Exception {
if (type.getName().equals("java.lang.String")) { if (type.getName().equals("java.lang.String")) {
......
...@@ -76,13 +76,13 @@ public class LdapManager { ...@@ -76,13 +76,13 @@ public class LdapManager {
} }
public String put(String key, String value) { public String put(String key, String value) {
JiveGlobals.setProperty(key, value); JiveGlobals.setXMLProperty(key, value);
// Always return null since XMLProperties doesn't support the normal semantics. // Always return null since XMLProperties doesn't support the normal semantics.
return null; return null;
} }
public String remove(Object key) { public String remove(Object key) {
JiveGlobals.deleteProperty((String)key); JiveGlobals.deleteXMLProperty((String)key);
// Always return null since XMLProperties doesn't support the normal semantics. // Always return null since XMLProperties doesn't support the normal semantics.
return null; return null;
} }
...@@ -175,11 +175,13 @@ public class LdapManager { ...@@ -175,11 +175,13 @@ public class LdapManager {
this.properties = properties; this.properties = properties;
String host = properties.get("ldap.host"); String host = properties.get("ldap.host");
// Parse the property and check if many hosts were defined. Hosts can be separated if (host != null) {
// by commas or white spaces // Parse the property and check if many hosts were defined. Hosts can be separated
StringTokenizer st = new StringTokenizer(host, " ,\t\n\r\f"); // by commas or white spaces
while (st.hasMoreTokens()) { StringTokenizer st = new StringTokenizer(host, " ,\t\n\r\f");
hosts.add(st.nextToken()); while (st.hasMoreTokens()) {
hosts.add(st.nextToken());
}
} }
String portStr = properties.get("ldap.port"); String portStr = properties.get("ldap.port");
port = 389; port = 389;
......
...@@ -10,27 +10,25 @@ ...@@ -10,27 +10,25 @@
package org.jivesoftware.wildfire.ldap; package org.jivesoftware.wildfire.ldap;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import org.dom4j.Attribute;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.DocumentHelper; import org.dom4j.DocumentHelper;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.Node; import org.dom4j.Node;
import org.jivesoftware.wildfire.vcard.VCardProvider;
import org.jivesoftware.util.AlreadyExistsException; import org.jivesoftware.util.AlreadyExistsException;
import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.util.NotFoundException; import org.jivesoftware.util.NotFoundException;
import org.jivesoftware.wildfire.vcard.VCardProvider;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/** /**
* Read-only LDAP provider for vCards.Configuration consists of adding a provider:<p/> * Read-only LDAP provider for vCards.Configuration consists of adding a provider:<p/>
* *
...@@ -229,14 +227,12 @@ public class LdapVCardProvider implements VCardProvider { ...@@ -229,14 +227,12 @@ public class LdapVCardProvider implements VCardProvider {
Node node = element.node(i); Node node = element.node(i);
if (node instanceof Element) { if (node instanceof Element) {
Element emement = (Element) node; Element emement = (Element) node;
Attribute attr = emement.attribute("attrs"); String[] attrs = emement.getTextTrim().split(",");
if (attr != null) { for (String string : attrs) {
String[] attrs = attr.getStringValue().split(","); // Remove enclosing {}
for (String string : attrs) { string = string.replaceAll("(\\{)([\\d\\D]+)(})", "$2");
Log.debug("VCardTemplate: found attribute " Log.debug("VCardTemplate: found attribute " + string);
+ string); set.add(string);
set.add(string);
}
} }
treeWalk(emement, set); treeWalk(emement, set);
} }
...@@ -266,17 +262,17 @@ public class LdapVCardProvider implements VCardProvider { ...@@ -266,17 +262,17 @@ public class LdapVCardProvider implements VCardProvider {
Node node = element.node(i); Node node = element.node(i);
if (node instanceof Element) { if (node instanceof Element) {
Element emement = (Element) node; Element emement = (Element) node;
Attribute attr = emement.attribute("attrs");
if (attr != null) { String[] attrs = emement.getTextTrim().split(",");
String[] attrs = attr.getStringValue().split(","); Object[] values = new String[attrs.length];
Object[] values = new String[attrs.length]; String format = emement.getStringValue();
for (int j = 0; j < attrs.length; j++) { for (int j = 0; j < attrs.length; j++) {
values[j] = map.get(attrs[j]); // Remove enclosing {}
} String attrib = attrs[j].replaceAll("(\\{)([\\d\\D]+)(})", "$2");
emement.remove(attr); values[j] = map.get(attrib);
emement.setText(MessageFormat.format(emement format = format.replaceFirst("(\\{)([\\d\\D]+)(})", "$1" + j + "$3");
.getStringValue(), values));
} }
emement.setText(MessageFormat.format(format, values));
treeWalk(emement, map); treeWalk(emement, map);
} }
} }
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment