/******************************************************************************* * Copyright (c) 2007, 2011 Association for Decentralized Information Management in * Industry THTH ry. * 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: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.databoard.binding.classfactory; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.simantics.databoard.binding.error.BindingConstructionException; import org.simantics.databoard.binding.factory.TypeRepository; import org.simantics.databoard.binding.reflection.BindingRequest; import org.simantics.databoard.type.Datatype; /** * Creates class for a type. * * @author toni.kalajainen */ public class TypeClassFactory { /** * Map of failed constructions. */ Map failures = new HashMap(); /** * Map that contains in incomplete constructions. */ Map inprogress = new HashMap(); /** * Repository where successful constructions are placed. */ TypeRepository repository; List subFactories = new ArrayList(); public TypeClassFactory() { repository = new TypeRepository(); } public TypeClassFactory(TypeRepository repository) { this.repository = repository; } public void addFactory(TypeClassSubFactory factory) { if (!subFactories.contains(factory)) { this.subFactories.add(factory); } } public void addFactoryFirst(TypeClassSubFactory factory) { if (!subFactories.contains(factory)) { this.subFactories.add(0, factory); } } public BindingRequest getClass(Datatype type) throws BindingConstructionException { Datatype progress = inprogress.get(type); if (progress != null) { synchronized(progress) {} } if (failures.containsKey(type)) throw failures.get(type); if (repository.containsType(type)) return repository.getRequestForType(type); // Start construction synchronized(type) { inprogress.put(type, type); try { BindingRequest br = null; for ( TypeClassSubFactory sf : subFactories ) { br = sf.construct(this, type); if ( br != null ) break; } if (br==null) throw new BindingConstructionException("Failed to create BindingRequest for type "+type); repository.put(type, br); return br; } catch (RuntimeException e) { failures.put(type, new BindingConstructionException(e)); throw e; } catch (BindingConstructionException bce) { failures.put(type, bce); throw bce; } finally { inprogress.remove(type); } } } public TypeRepository getRepository() { return repository; } }