/******************************************************************************* * Copyright (c) 2007, 2018 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 * Semantum Oy - gitlab #82 *******************************************************************************/ package org.simantics.databoard.binding.factory; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.reflection.BindingRequest; import org.simantics.databoard.type.Datatype; public class BindingRepository { /** * This map contains all the bindings */ Map requestMap; /** * This map contains bindings for non-generic classes. */ Map, Binding> classMap; public BindingRepository() { requestMap = new HashMap(); classMap = new HashMap, Binding>(); } public BindingRepository(Map requests) { this.requestMap = requests; for (Entry e : requests.entrySet()) { if ( isClassRequest( e.getKey() ) ) { classMap.put(e.getKey().getClazz(), e.getValue()); } } } /** * Get binding for a class. May return the class if it is in the class map. * If not, the user should try request map with some arguments (component bindings) * * @param clazz * @return binding */ public synchronized Binding get(Class clazz) { return classMap.get( clazz ); } /** * Get binding for a binding request * * @param request * @return binding or null */ public synchronized Binding get( BindingRequest request ) { return requestMap.get( request ); } /** * Adds binding to the repository. If the request has no arguments, the * class is added to classMap, and is available with class request. * * @param request * @param binding */ public synchronized void put( BindingRequest request, Binding binding ) { if ( isClassRequest(request) ) { classMap.put( request.getClazz(), binding ); } requestMap.put( request, binding ); } public synchronized void remove(Binding binding) { for (Entry e : requestMap.entrySet()) { if (e.getValue() == binding) { requestMap.remove(e.getValue()); break; } } for (Entry, Binding> e : classMap.entrySet()) { if (e.getValue() == binding) { classMap.remove(e.getValue()); break; } } } public synchronized boolean containsRequest( BindingRequest request ) { return requestMap.containsKey( request ); } /** * Checks if repository contains a class without arguments * * @param clazz * @return true if contains class (without args) */ public synchronized boolean containsClass( Class clazz ) { return classMap.containsKey( clazz ); } public synchronized void clear() { requestMap.clear(); classMap.clear(); } /** * {@link Datatype} class has annotations but it can be considered a "class * request" as it is a fundamental building block of Databoard and it has a * fixed structure. Therefore {@link #classMap} is allowed to contain a cached * Datatype.class -> Binding mapping. */ private static final String DATATYPE_CLASS_NAME = Datatype.class.getName(); boolean isClassRequest( BindingRequest request ) { return (request.className != null && ((request.annotations==null || request.annotations.length==0) || DATATYPE_CLASS_NAME.equals(request.className)) ); } }