/******************************************************************************* * 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.Field; import java.lang.reflect.Method; import java.util.Iterator; import java.util.LinkedList; import java.util.StringTokenizer; import com.swtworkbench.community.xswt.ClassBuilder; import com.swtworkbench.community.xswt.XSWT; import com.swtworkbench.community.xswt.XSWTException; import com.swtworkbench.community.xswt.codegen.CodeGenerator; /** * Class SWTSourceBuilder. An XSWT LayoutBuilder that generates Java source code * rather than building an actual SWT layout. When the XSWT file has been parsed, * the generated source code is in "source" and can be accessed via the toString() * method on SWTSourceBuilder. * * @author daveo */ public class SWTSourceBuilder extends LayoutBuilder { public SWTSourceBuilder(XSWT xswt) { super(xswt); } // The generated source code private StringBuffer source = new StringBuffer(); /** * The indent string. Defaults to four spaces. */ public static String INDENT = " "; protected void indent() { source.append(INDENT); } protected void emit(String source) { this.source.append(source); } protected void newline() { source.append("\n"); } /* (non-Javadoc) * @see java.lang.Object#toString() */ public String toString() { return source.toString(); } /* (non-Javadoc) * @see com.swtworkbench.community.xswt.layoutbuilder.ILayoutBuilder#construct(java.lang.Class, java.util.LinkedList) */ public Object construct(Class valueType, LinkedList argList, Object contextElement) throws XSWTException { ObjectStub stub = new ObjectStub(valueType.getName()); indent(); emit(stub.className); emit(" "); emit(stub.sourceName); emit(" = new "); emit(stub.className); emit("("); ConstructorInfo constructorInfo = getConstructorInfo(valueType, argList); int i=0; for (Iterator current = argList.iterator(); current.hasNext();) { String xswtSource = (String)current.next(); Object value = constructorInfo.args[i]; if (i > 0) emit (", "); emit(CodeGenerator.getDefault().getCode(value, xswtSource)); ++i; } emit(");"); newline(); return stub; } /* (non-Javadoc) * @see com.swtworkbench.community.xswt.layoutbuilder.ILayoutBuilder#construct(java.lang.String, org.eclipse.swt.widgets.Widget, java.lang.String) */ public Object construct(Class klass, Object parent, int style, String name, Object contextElement) throws XSWTException { ObjectStub stub = new ObjectStub(klass.getName(), name); ObjectStub parentStub; if (parent instanceof ObjectStub) parentStub = (ObjectStub) parent; else parentStub = new ObjectStub("Composite", "xswtParent"); indent(); emit(stub.className); emit(" "); emit(stub.sourceName); emit(" = new "); emit(stub.className); emit("("); emit(parentStub.sourceName); emit(", "); emit(Integer.toString(style)); // emit(getStyle(s)); emit(");"); newline(); return stub; } /** * Method getStyle. * @param style * @return */ private String getStyle(String style) { if (style == "" || style == null) return "SWT.NULL"; StringBuffer result = new StringBuffer(); StringTokenizer bits = new StringTokenizer(style, " |"); int i=0; while (bits.hasMoreTokens()) { if (i > 0) result.append(" | "); String bit = bits.nextToken(); if (bit.indexOf(".") == -1) { result.append("SWT."); } result.append(bit); ++i; } return result.toString(); } /* (non-Javadoc) * @see com.swtworkbench.community.xswt.layoutbuilder.ILayoutBuilder#setField(java.lang.reflect.Field, java.lang.Object, java.lang.Object) */ public void setField(Field field, Object receiver, Object value, Object contextElement) throws XSWTException { ObjectStub stub = (ObjectStub)receiver; indent(); emit(stub.sourceName); emit("."); emit(field.getName()); emit(" = "); emit(CodeGenerator.getDefault().getCode(value, "")); emit(";"); newline(); } /* (non-Javadoc) * @see com.swtworkbench.community.xswt.layoutbuilder.ILayoutBuilder#setField(java.lang.String, java.lang.Object, java.lang.String) */ public boolean setField( String fieldName, Object receiver, String valueSource, Object contextElement) throws XSWTException { try { Class receiverClass = getClass(receiver); Field field = receiverClass.getField(fieldName); Object value = parseData(valueSource, field.getType()); ObjectStub stub = (ObjectStub)receiver; indent(); emit(stub.sourceName); emit("."); emit(field.getName()); emit(" = "); emit(CodeGenerator.getDefault().getCode(value, valueSource)); emit(";"); newline(); return true; } catch (Exception e) { throw new XSWTException("Unable to set field " + fieldName, e, contextElement); } } /* (non-Javadoc) * @see com.swtworkbench.community.xswt.layoutbuilder.ILayoutBuilder#setProperty(java.lang.reflect.Method, java.lang.Object, java.lang.Object) */ public void setProperty(Method setter, Object receiver, Object value, Object contextElement) throws XSWTException { ObjectStub stub = (ObjectStub)receiver; indent(); emit(stub.sourceName); emit("."); emit(setter.getName()); emit("("); emit(CodeGenerator.getDefault().getCode(value, "")); emit(");"); newline(); } /* (non-Javadoc) * @see com.swtworkbench.community.xswt.layoutbuilder.ILayoutBuilder#setProperty(java.lang.String, java.lang.Object, java.lang.String) */ public boolean setProperty( String propertyName, Object receiver, String valueSource, Object contextElement) throws XSWTException { try { Method[] setMethods = resolveAttributeSetMethod(receiver, propertyName, null); if (setMethods == null) return false; Method setMethod = setMethods[0]; Object value = parseData( valueSource, setMethod.getParameterTypes()[0]); ObjectStub stub = (ObjectStub)receiver; indent(); emit(stub.sourceName); emit("."); emit(setMethod.getName()); emit("("); emit(CodeGenerator.getDefault().getCode(value, valueSource)); emit(");"); newline(); return true; } catch (Exception e) { throw new XSWTException("Unable to set property " + propertyName, e, contextElement); } } /* (non-Javadoc) * @see com.swtworkbench.community.xswt.layoutbuilder.ILayoutBuilder#getClass(java.lang.Object) */ public Class getClass(Object obj) throws XSWTException { ObjectStub stub = (ObjectStub)obj; // FIXME: Shouldn't hard-code ClassBuilder reference here... // // Using a static ClassBuilder means that imports are cached // between runs. There also could be threading issues... return ClassBuilder.getDefault().getClass(stub.className); } /* (non-Javadoc) * @see com.swtworkbench.community.xswt.layoutbuilder.ILayoutBuilder#getProperty(java.lang.reflect.Method, java.lang.Object, java.lang.Object) */ public Object getProperty(Method getter, Object receiver, Object value, Object contextElement) throws XSWTException { try { ObjectStub stub = (ObjectStub)receiver; indent(); ObjectStub stub2 = new ObjectStub(getter.getReturnType().getName()); emit(getter.getReturnType().getName()); emit(" " + stub2.sourceName + " = "); emit(stub.sourceName); emit("."); emit(getter.getName()); emit(" ( "); // TODO: How to present value's code? AT present value is always null if (value!=null) emit(value.toString()); emit(");"); newline(); return stub2; } catch (Exception e) { throw new XSWTException("Unable to get " + getter.getName() + " property: ", e, contextElement); } } }