]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/binding/factory/BindingRepository.java
ba24353712c7f90f415b4b2652f7699dba5b27d0
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / binding / factory / BindingRepository.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2018 Association for Decentralized Information Management in
3  * Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *     Semantum Oy - gitlab #82
12  *******************************************************************************/
13 package org.simantics.databoard.binding.factory;
14
15 import java.util.HashMap;
16 import java.util.Map;
17 import java.util.Map.Entry;
18
19 import org.simantics.databoard.binding.Binding;
20 import org.simantics.databoard.binding.reflection.BindingRequest;
21 import org.simantics.databoard.type.Datatype;
22
23 public class BindingRepository {
24         
25         /**
26          * This map contains all the bindings
27          */
28         Map<BindingRequest, Binding> requestMap;
29         
30         /**
31          * This map contains bindings for non-generic classes. 
32          */
33         Map<Class<?>, Binding> classMap;
34         
35         public BindingRepository() {            
36                 requestMap = new HashMap<BindingRequest, Binding>();
37                 classMap = new HashMap<Class<?>, Binding>();
38         }
39         
40         public BindingRepository(Map<BindingRequest, Binding> requests) {
41                 this.requestMap = requests;
42                 for (Entry<BindingRequest, Binding> e : requests.entrySet()) {
43                         if ( isClassRequest( e.getKey() ) ) {
44                                 classMap.put(e.getKey().getClazz(), e.getValue());
45                         }
46                 }
47         }
48         
49         /**
50          * Get binding for a class. May return the class if it is in the class map.
51          * If not, the user should try request map with some arguments (component bindings)
52          * 
53          * @param clazz
54          * @return binding
55          */
56         public synchronized Binding get(Class<?> clazz) {
57                 return classMap.get( clazz );
58         }
59         
60         /**
61          * Get binding for a binding request
62          * 
63          * @param request
64          * @return binding or null
65          */
66         public synchronized Binding get( BindingRequest request ) {
67                 return requestMap.get( request );
68         }
69         
70         /**
71          * Adds binding to the repository. If the request has no arguments, the 
72          * class is added to classMap, and is available with class request.  
73          * 
74          * @param request
75          * @param binding
76          */
77         public synchronized void put( BindingRequest request, Binding binding ) {
78                 if ( isClassRequest(request) ) {
79                         classMap.put( request.getClazz(), binding );
80                 }
81                 requestMap.put( request, binding );
82         }
83         
84         public synchronized void remove(Binding binding) {
85                 for (Entry<BindingRequest, Binding> e : requestMap.entrySet()) {
86                         if (e.getValue() == binding) {
87                                 requestMap.remove(e.getValue());
88                                 break;
89                         }
90                 }
91                 
92                 for (Entry<Class<?>, Binding> e : classMap.entrySet()) {
93                         if (e.getValue() == binding) {
94                                 classMap.remove(e.getValue());
95                                 break;
96                         }
97                 }
98 }
99         
100         public synchronized boolean containsRequest( BindingRequest request ) {
101                 return requestMap.containsKey( request );
102         }
103         
104         /**
105          * Checks if repository contains a class without arguments
106          * 
107          * @param clazz 
108          * @return true if contains class (without args)
109          */
110         public synchronized boolean containsClass( Class<?> clazz ) {
111                 return classMap.containsKey( clazz );
112         }
113         
114         public synchronized void clear() {
115                 requestMap.clear();
116                 classMap.clear();
117         }
118
119         /**
120          * {@link Datatype} class has annotations but it can be considered a "class
121          * request" as it is a fundamental building block of Databoard and it has a
122          * fixed structure. Therefore {@link #classMap} is allowed to contain a cached
123          * Datatype.class -> Binding mapping.
124          */
125         private static final String DATATYPE_CLASS_NAME = Datatype.class.getName();
126
127         boolean isClassRequest( BindingRequest request )
128         {
129                 return (request.className != null
130                                 && ((request.annotations==null || request.annotations.length==0)
131                                                 || DATATYPE_CLASS_NAME.equals(request.className))
132                                 );
133         }
134
135 }