/*******************************************************************************
* Copyright (c) 2012 Google, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Google, Inc. - initial API and implementation
*******************************************************************************/
package com.windowtester.swt.gef.codegen;
import java.util.Iterator;
import java.util.List;
import com.windowtester.codegen.assembly.unit.ClassUnit;
import com.windowtester.codegen.assembly.unit.ImportUnit;
import com.windowtester.codegen.generator.ICodegenAdvisor;
import com.windowtester.codegen.generator.LocatorJavaStringFactory;
import com.windowtester.codegen.generator.PluggableCodeGenerator;
import com.windowtester.codegen.util.IBuildPathUpdater;
import com.windowtester.internal.runtime.IWidgetIdentifier;
import com.windowtester.internal.runtime.locator.IdentifierAdapter;
import com.windowtester.recorder.event.ISemanticEvent;
import com.windowtester.recorder.event.IUISemanticEvent;
import com.windowtester.recorder.event.user.SemanticWidgetSelectionEvent;
import com.windowtester.runtime.gef.Position;
import com.windowtester.runtime.gef.internal.locator.DelegatingLocator;
import com.windowtester.runtime.gef.internal.locator.provisional.api.AnchorLocator;
import com.windowtester.runtime.gef.internal.locator.provisional.api.ResizeHandleLocator;
import com.windowtester.runtime.gef.locator.FigureCanvasLocator;
import com.windowtester.runtime.gef.locator.FigureCanvasXYLocator;
import com.windowtester.runtime.gef.locator.FigureClassLocator;
import com.windowtester.runtime.gef.locator.IFigureLocator;
import com.windowtester.runtime.gef.locator.LRLocator;
import com.windowtester.runtime.gef.locator.NamedEditPartFigureLocator;
import com.windowtester.runtime.gef.locator.NamedFigureLocator;
import com.windowtester.runtime.gef.locator.PaletteItemLocator;
import com.windowtester.runtime.locator.ILocator;
import com.windowtester.runtime.locator.IWidgetLocator;
import com.windowtester.runtime.locator.XYLocator;
import com.windowtester.runtime.swt.locator.eclipse.ActiveEditorLocator;
/**
* Codegen support for GEF locators.
*/
public class GEFCodegenerator implements ICodegenAdvisor {
public static final String GEF_RUNTIME_PLUGIN_ID = "com.windowtester.swt.runtime.gef";
//an accessor to upstream codegen functionality
private class StringFactory extends LocatorJavaStringFactory {
private String figureCanvasXYtoString(FigureCanvasXYLocator locator) {
StringBuffer sb = new StringBuffer();
appendCons(sb, locator);
appendXY(sb, locator);
optionallyAppendScope(sb, locator);
appendClose(sb);
return sb.toString();
}
public String figureCanvasToString(FigureCanvasLocator locator) {
StringBuffer sb = new StringBuffer();
appendCons(sb, locator);
IWidgetLocator scope = adaptToScopeLocator(locator);
//note optionallyAppendScope wrongly prepends a ", " ...
if (locator != null && !( scope instanceof ActiveEditorLocator))
sb.append(toJavaString(scope));
appendClose(sb);
return sb.toString();
}
private void appendClose(StringBuffer sb) {
sb.append(")");
}
private void appendXY(StringBuffer sb, FigureCanvasXYLocator locator) {
sb.append(locator.x()).append(", ").append(locator.y());
}
public String lrLocatorToString(LRLocator locator) {
StringBuffer sb = new StringBuffer();
appendCons(sb, locator);
appendIndex(sb, locator);
appendIndexedLocator(sb, locator);
appendClose(sb);
return sb.toString();
}
//TODO: consider a new interface IPositioningLocator so we can collapse these methods...
public String anchorLocatorToString(AnchorLocator locator) {
StringBuffer sb = new StringBuffer();
appendCons(sb, locator);
appendPosition(sb, locator);
appendOwner(sb, locator);
appendClose(sb);
return sb.toString();
}
public String resizeLocatorToString(ResizeHandleLocator locator) {
StringBuffer sb = new StringBuffer();
appendCons(sb, locator);
appendPosition(sb, locator);
appendOwner(sb, locator);
appendClose(sb);
return sb.toString();
}
public String namedEditPartLocatorToString(NamedEditPartFigureLocator locator) {
StringBuffer sb = new StringBuffer();
appendCons(sb, locator);
sb.append('"' + locator.getEditPartId() + '"');
appendClose(sb);
return sb.toString();
}
public String namedFigureLocatorToString(NamedFigureLocator locator) {
StringBuffer sb = new StringBuffer();
appendCons(sb, locator);
sb.append('"' + locator.getFigureId() + '"');
appendClose(sb);
return sb.toString();
}
private void appendOwner(StringBuffer sb, ResizeHandleLocator locator) {
sb.append(", ").append(toJavaString(locator.getOwner()));
}
private void appendPosition(StringBuffer sb, ResizeHandleLocator locator) {
sb.append("Position." + locator.getPosition());
}
private void appendPosition(StringBuffer sb, AnchorLocator locator) {
sb.append("Position." + locator.getPosition());
}
private void appendOwner(StringBuffer sb, AnchorLocator locator) {
sb.append(", ").append(toJavaString(locator.getOwner()));
}
private void appendIndexedLocator(StringBuffer sb, LRLocator locator) {
sb.append(toJavaString(locator.getLocator()));
}
private void appendIndex(StringBuffer sb, LRLocator locator) {
sb.append(locator.getIndex()).append(", ");
}
public String figureClassToString(FigureClassLocator locator) {
ClassUnit classUnit = getLocatorMap().get(locator);
if (classUnit == null)
return null;
return "new " + classUnit.getName() + "()";
}
}
private final StringFactory helper = new StringFactory();
private final InnerLocatorMap locatorMap = new InnerLocatorMap();
protected StringFactory getStringFactory() {
return helper;
}
protected InnerLocatorMap getLocatorMap() {
return locatorMap;
}
/* (non-Javadoc)
* @see com.windowtester.codegen.generator.ICodegenParticipant#toJavaString(com.windowtester.runtime.locator.ILocator)
*/
public String toJavaString(ILocator locator) {
if (locator instanceof FigureCanvasXYLocator)
return getStringFactory().figureCanvasXYtoString((FigureCanvasXYLocator)locator);
if (locator instanceof FigureCanvasLocator)
return getStringFactory().figureCanvasToString((FigureCanvasLocator)locator);
if (locator instanceof LRLocator)
return getStringFactory().lrLocatorToString((LRLocator)locator);
if (locator instanceof FigureClassLocator)
return getStringFactory().figureClassToString((FigureClassLocator)locator);
if (locator instanceof AnchorLocator)
return getStringFactory().anchorLocatorToString((AnchorLocator) locator);
if (locator instanceof ResizeHandleLocator)
return getStringFactory().resizeLocatorToString((ResizeHandleLocator)locator);
if (locator instanceof NamedEditPartFigureLocator)
return getStringFactory().namedEditPartLocatorToString((NamedEditPartFigureLocator)locator);
if (locator instanceof NamedFigureLocator)
return getStringFactory().namedFigureLocatorToString((NamedFigureLocator)locator);
return null;
}
public void handleSelection(ISemanticEvent event, PluggableCodeGenerator generator, Advice advice) {
if (!(event instanceof SemanticWidgetSelectionEvent))
return;
SemanticWidgetSelectionEvent selection = (SemanticWidgetSelectionEvent)event;
IWidgetIdentifier locator = selection.getHierarchyInfo();
handleLocator(locator, generator, advice);
}
private void handleLocator(IWidgetIdentifier locator, PluggableCodeGenerator generator, Advice advice) {
/*
* TODO: this conditional logic is a mess --- this should be revisited and fixed.
*/
if (locator == null)
return;
if (locator instanceof IdentifierAdapter) {
ILocator adapted = ((IdentifierAdapter)locator).getLocator();
if (adapted instanceof LRLocator) {
addImportForClass(generator, LRLocator.class);
handleLocator(getParent(adapted), generator, advice);
return;
}
if (adapted instanceof FigureClassLocator) {
handleFigureClassLocator((FigureClassLocator)adapted, generator);
//advice.override();
return;
}
if (adapted instanceof AnchorLocator) {
handleAnchorLocator((AnchorLocator)adapted, generator, advice);
}
if (adapted instanceof ResizeHandleLocator) {
handleResizeLocator((ResizeHandleLocator)adapted, generator, advice);
}
}
if (locator instanceof FigureClassLocator) {
handleFigureClassLocator((FigureClassLocator)locator, generator);
//advice.override();
} else {
handleLocator(getParent(locator), generator, advice);
}
}
private void handleResizeLocator(ResizeHandleLocator locator,
PluggableCodeGenerator generator, Advice advice) {
addImportForClass(generator, Position.class);
handleLocator(new IdentifierAdapter(locator.getOwner()), generator, advice);
}
private void handleAnchorLocator(AnchorLocator locator, PluggableCodeGenerator generator, Advice advice) {
addImportForClass(generator, Position.class);
handleLocator(new IdentifierAdapter(locator.getOwner()), generator, advice);
}
private void handleFigureClassLocator(FigureClassLocator locator, PluggableCodeGenerator generator) {
generator.getTestBuilder().addClass(getLocatorMap().get(locator));
addImportForClass(generator, FigureClassLocator.class);
}
private void addImportForClass(PluggableCodeGenerator generator, Class cls) {
generator.getTestBuilder().addImport(new ImportUnit(cls.getName()));
}
private static IWidgetIdentifier getParent(Object locator) {
if (locator instanceof LRLocator)
return new IdentifierAdapter(((LRLocator)locator).getLocator());
return null;
}
/* (non-Javadoc)
* @see com.windowtester.codegen.generator.ICodegenAdvisor#addPluginDependencies(java.util.List, com.windowtester.codegen.util.IBuildPathUpdater)
*/
public void addPluginDependencies(List events, IBuildPathUpdater updater) throws Exception {
for (Iterator iterator = events.iterator(); iterator.hasNext();) {
ISemanticEvent event = (ISemanticEvent) iterator.next();
if (isGEFEvent(event)) {
updater.addPluginDependency(GEF_RUNTIME_PLUGIN_ID);
return; //only need to add it once!
}
}
}
//TODO: verify this...
private boolean isGEFEvent(ISemanticEvent event) {
if (!(event instanceof IUISemanticEvent))
return false;
IUISemanticEvent semantic = (IUISemanticEvent)event;
IWidgetIdentifier widget = semantic.getHierarchyInfo();
return isGEFRelated(widget);
}
private boolean isGEFRelated(IWidgetIdentifier widget) {
//this is a bit clumsy...
if (widget == null)
return false;
if (!(widget instanceof IdentifierAdapter))
return false;
ILocator locator = ((IdentifierAdapter)widget).getLocator();
if (isGEFLocator(locator))
return true;
if (locator instanceof XYLocator)
return isGEFLocator(((XYLocator)locator).locator());
return false;
}
private boolean isGEFLocator(ILocator locator) {
if (locator instanceof IFigureLocator)
return true;
if (locator instanceof FigureCanvasXYLocator)
return true;
if (locator instanceof PaletteItemLocator)
return true;
if (locator instanceof DelegatingLocator)
return true;
return false;
}
}