package org.simantics.databoard.adapter; import java.util.HashMap; import java.util.Map; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.error.BindingConstructionException; import org.simantics.databoard.binding.error.RuntimeBindingConstructionException; import org.simantics.databoard.type.Datatype; public abstract class NewAdapterFactory { /** * Map of failed constructions. */ protected Map failures = new HashMap(); /** * Map that contains in incomplete constructions. */ protected Map inprogress = new HashMap(); /** * Repository where successful constructions are placed. */ protected Map repository; /** * Create a scheme factory. */ public NewAdapterFactory() { } /** * Create scheme factory that appends constructed bindings to the user given * repository * * @param repository repository where bindings are placed */ public NewAdapterFactory(Map repository) { this.repository = repository; } /** * Get adapter repository * * @return adapter repository */ public Map getRepository() { return repository; } /** * Constructs a binding to comply to datatype request. * This is the method sub-classes implement. * The implementation should use the inprogress -map for construction of * bindings that have component types. * * e.g. * inprogress.put(request, notCompletelyConstructedBinding); * Binding componentBinding = construct( componentRequest ); * notCompletelyConstructedBinding.setChild( componentBinding ); * inprogress.remove(request); * * try-finally is not needed. * * @param request * @return * @throws BindingConstructionException */ protected abstract Binding doConstruct(Datatype request) throws BindingConstructionException; public Binding construct(Datatype request) throws BindingConstructionException { if (failures.containsKey(request)) throw failures.get(request); if (inprogress.containsKey(request)) return inprogress.get(request); if (repository.containsKey(request)) return repository.get(request); // Start construction try { Binding binding = doConstruct(request); repository.put(request, binding); return binding; } catch (BindingConstructionException e) { inprogress.remove( request ); failures.put(request, e); throw e; } } public Binding getBinding(Datatype type) throws BindingConstructionException { return construct(type); } public Binding getBindingUnchecked(Datatype type) throws RuntimeBindingConstructionException { try { return construct(type); } catch (BindingConstructionException e) { throw new RuntimeBindingConstructionException(e); } } }