View Javadoc
1   /**
2    * Copyright 2005-2016 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.data.provider.impl;
17  
18  import java.util.Collection;
19  import java.util.Collections;
20  import java.util.HashMap;
21  import java.util.Map;
22  import java.util.concurrent.ConcurrentHashMap;
23  
24  import org.kuali.rice.krad.data.metadata.DataObjectMetadata;
25  import org.kuali.rice.krad.data.provider.MetadataProvider;
26  
27  /**
28   * Superclass for all metadata providers which contain the basic operations and data structure.
29   *
30   * <p>All each subclass needs to implement is the initializeMetadata method.</p>
31   *
32   * @author Kuali Rice Team (rice.collab@kuali.org)
33   */
34  public abstract class MetadataProviderBase implements MetadataProvider {
35  
36      /**
37       * The map of types to metadata.
38       */
39  	protected ConcurrentHashMap<Class<?>, DataObjectMetadata> masterMetadataMap =
40              new ConcurrentHashMap<Class<?>, DataObjectMetadata>();
41  
42  	/**
43  	 * Performs the initialization of the provider with the given set of types.
44  	 *
45       * <p>
46  	 * If the list is null or empty, the provider is expected to discover the types via other means, or do nothing if
47       * the types cannot be discovered.
48       * </p>
49  	 */
50  	protected abstract void initializeMetadata(Collection<Class<?>> types);
51  
52      /**
53       * {@inheritDoc}
54       */
55  	@Override
56  	public boolean handles(Class<?> type) {
57  		if (type == null) {
58  			return false;
59  		}
60  		if (masterMetadataMap.isEmpty()) {
61  			initializeMetadata(null);
62  		}
63  		return masterMetadataMap.containsKey(type);
64  	}
65  
66      /**
67       * {@inheritDoc}
68       */
69  	@Override
70  	public Collection<Class<?>> getSupportedTypes() {
71  		if (masterMetadataMap.isEmpty()) {
72  			initializeMetadata(null);
73  		}
74  		return masterMetadataMap.keySet();
75  	}
76  
77      /**
78       * {@inheritDoc}
79       */
80  	@Override
81  	public Map<Class<?>, DataObjectMetadata> provideMetadata() {
82  		return provideMetadataForTypes(null);
83  	}
84  
85      /**
86       * {@inheritDoc}
87       */
88  	@Override
89  	public Map<Class<?>, DataObjectMetadata> provideMetadataForTypes(Collection<Class<?>> types) {
90  		if (masterMetadataMap.isEmpty()) {
91  			initializeMetadata(types);
92  			return Collections.unmodifiableMap(masterMetadataMap);
93  		} else if (types == null || types.isEmpty()) {
94  			return Collections.unmodifiableMap(masterMetadataMap);
95  		} else {
96  			HashMap<Class<?>, DataObjectMetadata> subMap = new HashMap<Class<?>, DataObjectMetadata>();
97  
98  			for (Class<?> key : masterMetadataMap.keySet()) {
99  				if (types.contains(key)) {
100 					subMap.put(key, masterMetadataMap.get(key));
101 				}
102 			}
103 			return subMap;
104 		}
105 	}
106 
107     /**
108      * {@inheritDoc}
109      */
110 	@Override
111 	public DataObjectMetadata getMetadataForType(Class<?> dataObjectType) throws IllegalArgumentException {
112 		if (dataObjectType == null) {
113 			throw new IllegalArgumentException("getMetadataForType: NULL passed for the dataObjectType");
114 		}
115 		if (masterMetadataMap.isEmpty()) {
116 			initializeMetadata(null);
117 		}
118 		return masterMetadataMap.get(dataObjectType);
119 	}
120 
121     /**
122      * Determines whether the given class can be persisted.
123      *
124      * @param clazz the class to check for persistability.
125      * @return true if the class is persistable, false otherwise.
126      */
127     protected boolean isClassPersistable(Class<?> clazz) {
128         if (masterMetadataMap.isEmpty()) {
129 			initializeMetadata(null);
130         }
131         return masterMetadataMap.containsKey(clazz);
132     }
133 
134 	/**
135 	 * {@inheritDoc}
136      *
137      * By default, providers are assumed to be able to pull the list of annotated types from somewhere.
138 	 */
139 	@Override
140 	public boolean requiresListOfExistingTypes() {
141 		return false;
142 	}
143 }