/*******************************************************************************
* Copyright (c) 2000, 2003 Advanced Systems Concepts, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* David Orme (ASC) - Initial implementation
******************************************************************************/
package com.swtworkbench.community.xswt.layoutbuilder;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.swtworkbench.community.xswt.ClassBuilder;
import com.swtworkbench.community.xswt.XSWT;
import com.swtworkbench.community.xswt.XSWTException;
import com.swtworkbench.community.xswt.dataparser.DataParser;
import com.swtworkbench.community.xswt.metalogger.Logger;
/**
* Class LayoutBuilder. A place to put methods that are common to all
* ILayoutBuilder implementations.
*
* @author daveo
*/
public abstract class LayoutBuilder implements ILayoutBuilder {
protected DataParser dataParser = null;
protected XSWT xswt = null;
public LayoutBuilder(XSWT xswt) {
this.dataParser = xswt.getDataParser();
this.xswt = xswt;
xswt.setLayoutBuilder(this);
}
protected void fireSetProperty(Object o, String name, Object value, boolean processed) {
xswt.fireSetProperty(name, value, o, processed);
}
protected class ConstructorInfo {
public Constructor constructor = null;
public Class[] paramTypes = null;
public Object[] args = null;
}
/**
* Method getConstructorInfo. Finds a constructor that can construct the given class
* using the given arguments.
*
* Note that class array does not contain public constructor.
*
* @param valueType The Class to construct
* @param argList A LinkedList of Strings where each String is in XSWT parameter format.
* @return A ConstructorInfo describing the selected constructor and the parsed arguments
* @throws XSWTException
*/
protected ConstructorInfo getConstructorInfo(Class valueType, List argList) throws XSWTException {
ConstructorInfo result = new ConstructorInfo();
Constructor[] constructors = valueType.getConstructors();
for (int i = 0; i < constructors.length; i++) {
result.constructor = constructors[i];
result.paramTypes = result.constructor.getParameterTypes();
if (argList.size() != result.paramTypes.length)
// TODO: We cannot just simply continue, this is the most common mistakes when people write XSWT.
// TODO: At least some feedback to inform the mismatch
// DJO: You *have* to 'continue' becuase you don't know
// that the next constructor you see won't be the right one.
// Maybe set a flag or keep track of near misses in order
// to generate more helpful error messages...
continue;
result.args = new Object[argList.size()];
try {
// Try to convert all the arguments to appropriate types
Iterator argIter = argList.iterator();
for (int arg=0; arg<result.args.length; ++arg) {
String argStr = (String)argIter.next();
result.args[arg] = dataParser.parse(argStr, result.paramTypes[arg]);
}
// If we succeeded, theOne is the one
break;
//}catch (XSWTException e1) {
// throw e1;
} catch (Exception e) {
// TODO: message() or debug()?
Logger.log().debug(LayoutBuilder.class, "Error in parsing "+ valueType + ": "+e);
// If we didn't succeed, try the next constructor...
result.constructor = null;
result.args = null;
continue;
}
}
return result;
}
/**
* Method resolveAttributeSetMethod. Return a Method object representing
* the set method referred to by an attribute property on the specified object.
*
* @param obj The object on which the method should be found
* @param methodName The method name in XSWT syntax
* @param propertyType The property's type or null if this isn't known
* @return The Method[] found or null if none found.
*/
public Method[] resolveAttributeSetMethod(Object obj, String methodName, Class propertyType) {
Class klass = null;
try {
klass = getClass(obj);
} catch (XSWTException e) {
return null;
}
String[] setters = ReflectionSupport.getSetMethodNames(methodName);
Method[] methods = ReflectionSupport.resolvePropertySetter(klass, setters, propertyType);
return methods;
}
/* (non-Javadoc)
* @see com.swtworkbench.community.xswt.layoutbuilder.ILayoutBuilder#resolveAttributeGetMethod(java.lang.Object, java.lang.String, java.lang.Class)
*/
public Method resolveAttributeGetMethod(Object obj, String methodName) {
try {
Class klass = getClass(obj);
return ReflectionSupport.resolveAttributeGetMethod(klass, methodName);
} catch (XSWTException e) {
}
return null;
}
protected ClassBuilder getClassBuilder() {
return xswt.classBuilder;
}
protected Object parseData(String valueSource, Class klass) throws XSWTException {
XSWTException xe = null;
Object result = null;
try {
result = dataParser.parse(valueSource, klass);
} catch (XSWTException e) {
xe = e;
}
if (result == null && xe != null) {
throw xe;
}
return result;
}
/* (non-Javadoc)
* @see com.swtworkbench.community.xswt.layoutbuilder.LayoutBuilder#namedObject(java.lang.Object)
*/
public Object namedObject(Object obj) throws XSWTException {
return obj;
}
public abstract Class getClass(Object obj) throws XSWTException;
}