/******************************************************************************* * Copyright (c) 2005, 2006 committers of openArchitectureWare and others. * 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: * committers of openArchitectureWare - initial API and implementation *******************************************************************************/ package org.eclipse.emf.mwe.internal.core.ast.util; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.eclipse.emf.mwe.core.ConfigurationException; import org.eclipse.emf.mwe.core.issues.Issues; import org.eclipse.emf.mwe.core.issues.IssuesImpl; import org.eclipse.emf.mwe.internal.core.ast.AbstractASTBase; import org.eclipse.emf.mwe.internal.core.ast.ComponentAST; import org.eclipse.emf.mwe.internal.core.ast.InclusionAST; import org.eclipse.emf.mwe.internal.core.ast.ReferenceAST; import org.eclipse.emf.mwe.internal.core.ast.SimpleParamAST; import org.eclipse.emf.mwe.internal.core.ast.util.converter.Converter; public class VisitorCreator extends VisitorBase { private VisitorCreator cloneWithBean(final Object newBean) { final VisitorCreator newInst = new VisitorCreator(issues, converter, newBean); newInst.beans = beans; return newInst; } private Map<String, Object> beans = new HashMap<String, Object>(); private Map<Class<?>, Converter<?>> converter = new HashMap<Class<?>, Converter<?>>(); // <Class, // Converter> private Object currentBean = null; private Issues issues = new IssuesImpl(); public VisitorCreator(final Issues issues, final Map<Class<?>, Converter<?>> converter, final Object rootBean) { this.issues = issues; this.converter = converter; currentBean = rootBean; } @Override public Object visitInclusionAST(final InclusionAST cart) { if (cart.getImportedElement() == null) { issues.addError("referenced element not resolved! ", cart); } final Class<?> type = currentBean.getClass(); final Injector inj = InjectorFactory.getInjector(type, cart.getName()); if (inj == null) { issues.addError("no injector could be found in class " + type.getName() + " for property '" + cart.getName() + "'!", cart); return cart; } final Map<String, Object> beansToPass = new HashMap<String, Object>(); if (cart.isInheritAll()) { beansToPass.putAll(this.beans); } for (final Iterator<?> iter = cart.getChildren().iterator(); iter.hasNext();) { final Object o = iter.next(); if (o instanceof InclusionAST) throw new ConfigurationException("Nested inclusions are not supported!"); else if (o instanceof ComponentAST) { final ComponentAST p = (ComponentAST) o; final Object bean = createBean(p, null); beansToPass.put(p.getName(), bean); } else if (o instanceof ReferenceAST) { final ReferenceAST ref = (ReferenceAST) o; if (beans.containsKey(ref.getIdRef())) { beansToPass.put(ref.getName(), beans.get(ref.getIdRef())); } else { issues.addError("No bean with id " + ref.getIdRef() + " found!", ref); } } } final WorkflowContainer wc = new WorkflowContainer(); final VisitorCreator vis = cloneWithBean(wc); vis.beans = beansToPass; final Object importedElement = cart.getImportedElement().accept(vis); setValue(importedElement, cart.getName(), cart); final Injector inj1 = InjectorFactory.getInjector(importedElement.getClass(), "location"); if (inj1 != null) { inj1.setValue(importedElement, cart.getLocation()); } final Injector inj2 = InjectorFactory.getInjector(importedElement.getClass(), "ownLocation"); if (inj2 != null) { inj2.setValue(importedElement, cart.getImportedElement().getLocation()); } if (cart.getId() != null) { beans.put(cart.getId(), importedElement); } return importedElement; } @Override public Object visitComponentAST(final ComponentAST comp) { final Class<?> type = currentBean.getClass(); final Injector inj = InjectorFactory.getInjector(type, comp.getName()); if (inj == null) { issues.addError("no injector could be found in class " + type.getName() + " for property '" + comp.getName() + "'!", comp); return comp; } final Class<?> toLoad = inj.getRequiredType(); final Object bean = createBean(comp, toLoad); if (bean != null) { inj.setValue(currentBean, bean); } return bean; } @SuppressWarnings("all") private Object createBean(final ComponentAST comp, Class<?> toLoad) { Object bean = null; if (comp.getClazz() != null) { toLoad = loader.loadClass(comp.getClazz()); if (toLoad == null) { issues.addError("Class not found: '" + comp.getClazz() + "'", comp); return comp; } } try { bean = toLoad.newInstance(); if (comp.getId() != null) { beans.put(comp.getId(), bean); final Injector inj = InjectorFactory.getInjector(bean.getClass(), "id"); if (inj != null) { inj.setValue(bean, comp.getId()); } } if (comp.getLocation() != null) { final Injector inj = InjectorFactory.getInjector(bean.getClass(), "resource"); if (inj != null) { inj.setValue(bean, comp.getLocation().getResource()); } final Injector inj1 = InjectorFactory.getInjector(bean.getClass(), "location"); if (inj1 != null) { inj1.setValue(bean, comp.getLocation()); } } final VisitorBase vis = cloneWithBean(bean); for (final Iterator<?> iter = comp.getChildren().iterator(); iter.hasNext();) { ((AbstractASTBase) iter.next()).accept(vis); } } catch (final Exception e) { log.error(e.getMessage(), e); issues.addError("Error creating instance of type '" + comp.getClazz() + "' : " + e.getMessage(), comp); } return bean; } private void setValue(final Object value, final String name, final AbstractASTBase ele) { final Injector inj = InjectorFactory.getInjector(currentBean.getClass(), name); if (inj == null) { issues.addError("no setter or adder could be found in class " + currentBean.getClass().getName() + " for '" + name + "'!", ele); } else { inj.setValue(currentBean, value); } } @Override public Object visitReferenceAST(final ReferenceAST ref) { if (beans.containsKey(ref.getIdRef())) { setValue(beans.get(ref.getIdRef()), ref.getName(), ref); return beans.get(ref.getIdRef()); } issues.addError("Couldn't find bean with id " + ref.getIdRef() + " : ", ref); return null; } @SuppressWarnings("rawtypes") @Override public Object visitSimpleParamAST(final SimpleParamAST param) { final Injector inj = InjectorFactory.getInjector(currentBean.getClass(), param.getName()); if (inj == null) { issues.addError("no setter or adder could be found in class " + currentBean.getClass().getName() + " for '" + param.getName() + "'!", param); return null; } final Converter conv = converter.get(inj.getRequiredType()); if (conv == null) { issues.addError("No converter found for " + param + " converting to " + inj.getRequiredType(), param); return null; } final Object val = conv.convert(param.getValue()); inj.setValue(currentBean, val); return val; } }