org.directwebremoting.convert.XmlBeanConverter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dwr Show documentation
Show all versions of dwr Show documentation
DWR is easy Ajax for Java. It makes it simple to call Java code directly from Javascript.
It gets rid of almost all the boiler plate code between the web browser and your Java code.
The newest version!
/*
* Copyright 2005 Joe Walker
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.directwebremoting.convert;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xmlbeans.XmlObject;
import org.directwebremoting.ConversionException;
import org.directwebremoting.extend.InboundVariable;
import org.directwebremoting.extend.Property;
import org.directwebremoting.extend.PropertyDescriptorProperty;
import org.directwebremoting.extend.ProtocolConstants;
import org.directwebremoting.util.LocalUtil;
/**
* A Converter for Apache XMLBeans.
* @author Joe Walker [joe at getahead dot ltd dot uk]
* @author Matthew Young [matthew dot young at forsakringskassan dot se]
*/
public class XmlBeanConverter extends BeanConverter
{
/* (non-Javadoc)
* @see org.directwebremoting.extend.Converter#convertInbound(java.lang.Class, org.directwebremoting.extend.InboundVariable, org.directwebremoting.extend.InboundContext)
*/
@Override
public Object convertInbound(Class> paramType, InboundVariable data) throws ConversionException
{
if (data == null)
{
return null;
}
String value = data.getValue();
log.debug("handling variable (" + value + ") for class (" + paramType.getName() + ")");
// If the text is null then the whole bean is null
if (value.trim().equals(ProtocolConstants.INBOUND_NULL))
{
return null;
}
if (!value.startsWith(ProtocolConstants.INBOUND_MAP_START) || !value.endsWith(ProtocolConstants.INBOUND_MAP_END))
{
log.warn("Expected object while converting data for " + paramType.getName() + " in " + data.getContext().getCurrentProperty() + ". Passed: " + value);
throw new ConversionException(paramType, "Data conversion error. See logs for more details.");
}
value = value.substring(1, value.length() - 1);
try
{
if (instanceType != null)
{
LocalUtil.classForName(instanceType.getName());
}
else
{
LocalUtil.classForName(paramType.getName());
}
Class>[] innerClasses = paramType.getClasses();
Class> factory = null;
for (Class> aClass : innerClasses)
{
if (aClass.getName().endsWith("Factory"))
{
factory = aClass;
}
}
if (factory == null)
{
log.error("XmlObject.Factory method not found for Class [" + paramType.toString() + "]");
throw new ConversionException(paramType, "XmlObject.Factory method not found");
}
Class>[] emptyArglist = new Class[0];
Method newInstance = factory.getMethod("newInstance", emptyArglist);
Object bean = newInstance.invoke(null, (Object[]) emptyArglist);
if (instanceType != null)
{
data.getContext().addConverted(data, instanceType, bean);
}
else
{
data.getContext().addConverted(data, paramType, bean);
}
Map properties = getPropertyMapFromClass(paramType, false, true);
// Loop through the properties passed in
Map tokens = extractInboundTokens(paramType, value);
for (Entry entry : tokens.entrySet())
{
String key = entry.getKey();
String val = entry.getValue();
log.debug("token entry (" + key + ") with value (" + val + ")");
Property property = properties.get(key);
if (property == null)
{
log.warn("Missing java bean property to match javascript property: " + key + ". For causes see debug level logs:");
log.debug("- The javascript may be refer to a property that does not exist");
log.debug("- You may be missing the correct setter: set" + Character.toTitleCase(key.charAt(0)) + key.substring(1) + "()");
log.debug("- The property may be excluded using include or exclude rules.");
StringBuffer all = new StringBuffer();
for (Iterator pit = properties.keySet().iterator(); pit.hasNext();)
{
all.append(pit.next());
if (pit.hasNext())
{
all.append(',');
}
}
log.debug("Fields exist for (" + all + ").");
continue;
}
Class> propType = property.getPropertyType();
Object output = convert(val, propType, data.getContext(), property);
property.setValue(bean, output);
}
return bean;
}
catch (ConversionException ex)
{
throw ex;
}
catch (Exception ex)
{
throw new ConversionException(paramType, ex);
}
}
/* (non-Javadoc)
* @see org.directwebremoting.convert.BeanConverter#getPropertyMapFromClass(java.lang.Class, boolean, boolean)
*/
@Override
public Map getPropertyMapFromClass(Class> paramType, boolean readRequired, boolean writeRequired) throws ConversionException
{
try
{
if (!XmlObject.class.isAssignableFrom(paramType))
{
throw new ConversionException(paramType, "class (" + paramType.getName() + ") not assignable from XmlObject");
}
Class> beanInterface;
if (paramType.isInterface())
{
beanInterface = paramType;
}
else
{
beanInterface = paramType.getInterfaces()[0];
}
Class> superInterface = (Class>) beanInterface.getGenericInterfaces()[0];
Map properties = new HashMap();
while (XmlObject.class.isAssignableFrom(superInterface))
{
BeanInfo info = Introspector.getBeanInfo(beanInterface);
PropertyDescriptor[] descriptors = info.getPropertyDescriptors();
for (int i = 0; i < descriptors.length; i++)
{
PropertyDescriptor descriptor = descriptors[i];
String name = descriptor.getName();
String type = descriptor.getPropertyType().getName();
// register Enum types
if (type.matches(".*\\$Enum"))
{
getConverterManager().addConverter(type, enumConverter);
}
// We don't marshall getClass()
if ("class".equals(name))
{
continue;
}
// Access rules mean we might not want to do this one
if (!isAllowedByIncludeExcludeRules(name))
{
continue;
}
if (readRequired && descriptor.getReadMethod() == null)
{
continue;
}
if (writeRequired && LocalUtil.getWriteMethod(paramType, descriptor) == null)
{
continue;
}
properties.put(name, new PropertyDescriptorProperty(descriptor));
}
beanInterface = (Class>) beanInterface.getGenericInterfaces()[0];
superInterface = (Class>) beanInterface.getGenericInterfaces()[0];
}
return properties;
}
catch (IntrospectionException ex)
{
throw new ConversionException(paramType, ex);
}
}
/**
* This used to be static, but there's a chance that could fail when there
* is more than 1 DWR servlet in a given context.
*/
private final StringEnumAbstractBaseConverter enumConverter = new StringEnumAbstractBaseConverter();
/**
* The log stream
*/
private static Log log = LogFactory.getLog(XmlBeanConverter.class);
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy