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;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.XMLWriter;
import org.jivesoftware.wildfire.ldap.LdapManager;
import org.jivesoftware.wildfire.ldap.LdapVCardProvider;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Iterator;
/**
* Bean that stores the vcard mapping. It is also responsible for saving the mapping
......@@ -53,7 +56,6 @@ public class LdapUserProfile {
private String businessMobile = "";
private String businessFax = "";
private String businessPager = "";
private String businessWebPage = "";
public String getName() {
return name;
......@@ -255,14 +257,6 @@ public class LdapUserProfile {
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.
*/
......@@ -281,7 +275,7 @@ public class LdapUserProfile {
homeMobile = "";
homeFax = "";
homePager = "";
businessStreet = "{postalAddress}";
businessStreet = "{streetAddress}";
businessCity = "{l}";
businessState = "{st}";
businessZip = "{postalCode}";
......@@ -292,7 +286,6 @@ public class LdapUserProfile {
businessMobile = "{mobile}";
businessFax = "{facsimileTelephoneNumber}";
businessPager = "{pager}";
businessWebPage = "";
}
/**
......@@ -324,7 +317,6 @@ public class LdapUserProfile {
businessMobile = "{mobile}";
businessFax = "";
businessPager = "{pager}";
businessWebPage = "";
}
/**
......@@ -386,7 +378,7 @@ public class LdapUserProfile {
subelement.addElement("REGION").setText(businessState.trim());
}
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) {
subelement.addElement("CTRY").setText(businessCountry.trim());
......@@ -402,7 +394,6 @@ public class LdapUserProfile {
if (homeMobile != null && homeMobile.trim().length() > 0) {
subelement = vCard.addElement("TEL");
subelement.addElement("HOME");
subelement.addElement("VOICE");
subelement.addElement("CELL");
subelement.addElement("NUMBER").setText(homeMobile.trim());
}
......@@ -431,7 +422,6 @@ public class LdapUserProfile {
if (businessMobile != null && businessMobile.trim().length() > 0) {
subelement = vCard.addElement("TEL");
subelement.addElement("WORK");
subelement.addElement("VOICE");
subelement.addElement("CELL");
subelement.addElement("NUMBER").setText(businessMobile.trim());
}
......@@ -453,9 +443,10 @@ public class LdapUserProfile {
if (businessJobTitle != null && businessJobTitle.trim().length() > 0) {
vCard.addElement("TITLE").setText(businessJobTitle.trim());
}
// TODO Add job department
// TODO Add web page
// Add job department
if (businessDepartment != null && businessDepartment.trim().length() > 0) {
vCard.addElement("ORG").addElement("ORGUNIT").setText(businessDepartment.trim());
}
// Generate content to store in property
String vcardXML;
StringWriter writer = new StringWriter();
......@@ -474,6 +465,13 @@ public class LdapUserProfile {
sb.append("<![CDATA[").append(vcardXML).append("]]>");
// Save mapping as an XML property
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 {
}
try {
// Remove CDATA wrapping element
if (xmlProperty.startsWith("<![CDATA[")) {
xmlProperty = xmlProperty.substring(9, xmlProperty.length()-3);
}
// Parse XML
Document document = DocumentHelper.parseText(xmlProperty);
Element vCard = document.getRootElement();
......@@ -512,7 +515,88 @@ public class LdapUserProfile {
if (element != null) {
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) {
Log.error("Error loading vcard mappings from property", e);
......
......@@ -10,12 +10,16 @@
package org.jivesoftware.util;
import java.beans.*;
import java.awt.Color;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* A utility class that provides methods that are useful for dealing with
......@@ -43,11 +47,10 @@ public class BeanUtils {
* @param bean the JavaBean to set properties on.
* @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 {
// Loop through all the property names in the Map
for (Iterator iter = properties.keySet().iterator(); iter.hasNext();) {
String propName = (String)iter.next();
for (String propName : properties.keySet()) {
try {
// Create a property descriptor for the named property. If
// the bean doesn't have the named property, an
......@@ -58,9 +61,9 @@ public class BeanUtils {
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, (String)properties.get(propName));
Object value = decode(propertyType, properties.get(propName));
// Set the value of the bean.
descriptor.getWriteMethod().invoke(bean, new Object[] { value });
descriptor.getWriteMethod().invoke(bean, value);
}
catch (IntrospectionException ie) {
// Ignore. This exception means that the key in the map
......@@ -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
* name/value pairs. Because this method has to know how to convert a
......@@ -88,8 +138,8 @@ public class BeanUtils {
* @param bean a Java Bean to get properties from.
* @return a Map of all properties as String name/value pairs.
*/
public static Map getProperties(Object bean) {
Map properties = new HashMap();
public static Map<String, String> getProperties(Object bean) {
Map<String, String> properties = new HashMap<String, String>();
try {
BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
// Loop through all properties of the bean.
......@@ -98,7 +148,7 @@ public class BeanUtils {
for (int i=0; i<names.length; i++) {
// Determine the property name.
String name = descriptors[i].getName();
Class type = descriptors[i].getPropertyType();
//Class type = descriptors[i].getPropertyType();
// Decode the property value using the property type and
// encoded String value.
Object value = descriptors[i].getReadMethod().invoke(bean,(java.lang.Object[]) null);
......@@ -122,6 +172,7 @@ public class BeanUtils {
*
* @param beanClass the Class of the JavaBean.
* @return the PropertyDescriptor array for the specified Java Bean Class.
* @throws java.beans.IntrospectionException
*/
public static PropertyDescriptor[] getPropertyDescriptors(Class beanClass)
throws IntrospectionException
......@@ -147,6 +198,7 @@ public class BeanUtils {
* supported, null will be returned.
*
* @param value an Object to encode in a String representation.
* @return the encoded bean.
*/
private static String encode(Object value) {
if (value instanceof String) {
......@@ -185,6 +237,7 @@ public class BeanUtils {
* @param type the type of the property.
* @param value the encode String value to decode.
* @return the String value decoded into the specified type.
* @throws Exception
*/
private static Object decode(Class type, String value) throws Exception {
if (type.getName().equals("java.lang.String")) {
......
......@@ -76,13 +76,13 @@ public class LdapManager {
}
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.
return null;
}
public String remove(Object key) {
JiveGlobals.deleteProperty((String)key);
JiveGlobals.deleteXMLProperty((String)key);
// Always return null since XMLProperties doesn't support the normal semantics.
return null;
}
......@@ -175,11 +175,13 @@ public class LdapManager {
this.properties = properties;
String host = properties.get("ldap.host");
// Parse the property and check if many hosts were defined. Hosts can be separated
// by commas or white spaces
StringTokenizer st = new StringTokenizer(host, " ,\t\n\r\f");
while (st.hasMoreTokens()) {
hosts.add(st.nextToken());
if (host != null) {
// Parse the property and check if many hosts were defined. Hosts can be separated
// by commas or white spaces
StringTokenizer st = new StringTokenizer(host, " ,\t\n\r\f");
while (st.hasMoreTokens()) {
hosts.add(st.nextToken());
}
}
String portStr = properties.get("ldap.port");
port = 389;
......
......@@ -10,27 +10,25 @@
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.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.jivesoftware.wildfire.vcard.VCardProvider;
import org.jivesoftware.util.AlreadyExistsException;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.NotFoundException;
import org.jivesoftware.wildfire.vcard.VCardProvider;
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/>
*
......@@ -229,14 +227,12 @@ public class LdapVCardProvider implements VCardProvider {
Node node = element.node(i);
if (node instanceof Element) {
Element emement = (Element) node;
Attribute attr = emement.attribute("attrs");
if (attr != null) {
String[] attrs = attr.getStringValue().split(",");
for (String string : attrs) {
Log.debug("VCardTemplate: found attribute "
+ string);
set.add(string);
}
String[] attrs = emement.getTextTrim().split(",");
for (String string : attrs) {
// Remove enclosing {}
string = string.replaceAll("(\\{)([\\d\\D]+)(})", "$2");
Log.debug("VCardTemplate: found attribute " + string);
set.add(string);
}
treeWalk(emement, set);
}
......@@ -266,17 +262,17 @@ public class LdapVCardProvider implements VCardProvider {
Node node = element.node(i);
if (node instanceof Element) {
Element emement = (Element) node;
Attribute attr = emement.attribute("attrs");
if (attr != null) {
String[] attrs = attr.getStringValue().split(",");
Object[] values = new String[attrs.length];
for (int j = 0; j < attrs.length; j++) {
values[j] = map.get(attrs[j]);
}
emement.remove(attr);
emement.setText(MessageFormat.format(emement
.getStringValue(), values));
String[] attrs = emement.getTextTrim().split(",");
Object[] values = new String[attrs.length];
String format = emement.getStringValue();
for (int j = 0; j < attrs.length; j++) {
// Remove enclosing {}
String attrib = attrs[j].replaceAll("(\\{)([\\d\\D]+)(})", "$2");
values[j] = map.get(attrib);
format = format.replaceFirst("(\\{)([\\d\\D]+)(})", "$1" + j + "$3");
}
emement.setText(MessageFormat.format(format, values));
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