1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.form.fieldtype.registry;
35
36 import info.magnolia.config.registry.AbstractRegistry;
37 import info.magnolia.config.registry.DefinitionMetadataBuilder;
38 import info.magnolia.config.registry.DefinitionProvider;
39 import info.magnolia.config.registry.DefinitionProviderBuilder;
40 import info.magnolia.config.registry.DefinitionType;
41 import info.magnolia.module.ModuleRegistry;
42 import info.magnolia.objectfactory.Components;
43 import info.magnolia.registry.RegistrationException;
44 import info.magnolia.ui.form.field.definition.ConfiguredFieldDefinition;
45 import info.magnolia.ui.form.field.definition.FieldDefinition;
46 import info.magnolia.ui.form.fieldtype.definition.FieldTypeDefinition;
47
48 import java.util.Optional;
49 import java.util.concurrent.ExecutionException;
50 import java.util.concurrent.TimeUnit;
51
52 import javax.inject.Inject;
53 import javax.inject.Singleton;
54
55 import com.google.common.cache.CacheBuilder;
56 import com.google.common.cache.CacheLoader;
57 import com.google.common.cache.LoadingCache;
58
59 import net.sf.cglib.proxy.Enhancer;
60
61
62
63
64 @Singleton
65 public class FieldTypeDefinitionRegistry extends AbstractRegistry<FieldTypeDefinition> {
66
67 private static final DefinitionProvider<FieldTypeDefinition> NULL_DEFINITION_PROVIDER = DefinitionProviderBuilder.<FieldTypeDefinition>newBuilder().build();
68
69 private final LoadingCache<Class, DefinitionProvider<FieldTypeDefinition>> definitionProviderCache =
70 CacheBuilder.newBuilder()
71 .maximumSize(100)
72 .refreshAfterWrite(1000, TimeUnit.MILLISECONDS)
73 .initialCapacity(100)
74 .build(new CacheLoader<Class, DefinitionProvider<FieldTypeDefinition>>() {
75 @Override
76 public DefinitionProvider<FieldTypeDefinition> load(Class key) throws Exception {
77 return resolveMostActualDefinitionProvider(key);
78 }
79 });
80
81 @Inject
82 public FieldTypeDefinitionRegistry(ModuleRegistry moduleRegistry) {
83 super(moduleRegistry);
84 }
85
86
87
88
89 @Deprecated
90 public FieldTypeDefinitionRegistry() {
91 this(Components.getComponent(ModuleRegistry.class));
92 }
93
94 public Optional<DefinitionProvider<FieldTypeDefinition>> getByDefinitionType(Class<? extends FieldDefinition> definitionClass) {
95 try {
96 return Optional.ofNullable(definitionProviderCache.get(definitionClass, () -> resolveMostActualDefinitionProvider(definitionClass)));
97 } catch (ExecutionException e) {
98 return Optional.empty();
99 }
100 }
101
102 public DefinitionProvider<FieldTypeDefinition> resolveMostActualDefinitionProvider(Class<? extends FieldDefinition> definitionClass) throws RegistrationException {
103
104
105 while (Enhancer.isEnhanced(definitionClass)) {
106 definitionClass = (Class<? extends FieldDefinition>) definitionClass.getSuperclass();
107 }
108
109 if (definitionClass.equals(ConfiguredFieldDefinition.class)) {
110
111 throw new RegistrationException("");
112 }
113
114 DefinitionProvider<FieldTypeDefinition> deprecatedFieldTypeDefinition = null;
115 DefinitionProvider<FieldTypeDefinition> nonDeprecatedFieldTypeDefinition = null;
116 for (DefinitionProvider<FieldTypeDefinition> provider : getRegistryMap().values()) {
117 provider = getDecoratedDefinitionProvider(provider);
118 final FieldTypeDefinition fieldTypeDefinition = provider.get();
119 if (definitionClass.equals(fieldTypeDefinition.getDefinitionClass())) {
120
121 if (provider.getDecorators().size() > 0) {
122 return provider;
123 }
124
125
126 if (!provider.getMetadata().getDeprecation().isPresent()) {
127 nonDeprecatedFieldTypeDefinition = provider;
128 } else {
129 deprecatedFieldTypeDefinition = provider;
130 }
131 }
132 }
133
134
135 if (nonDeprecatedFieldTypeDefinition != null) {
136 return nonDeprecatedFieldTypeDefinition;
137 }
138
139
140
141 if (deprecatedFieldTypeDefinition != null) {
142 return deprecatedFieldTypeDefinition;
143 }
144
145 throw new RegistrationException("Could not find fieldType for definition " + definitionClass.getName());
146 }
147
148 public FieldTypeDefinition getByDefinition(Class<? extends FieldDefinition> definitionClass) throws RegistrationException {
149 return getByDefinitionType(definitionClass)
150 .filter(DefinitionProvider::isValid)
151 .map(DefinitionProvider::get)
152 .orElseThrow(() -> new RegistrationException("Field type definition not found or invalid for field definition type: " + definitionClass.getName()));
153 }
154
155
156
157
158 @Deprecated
159 public FieldTypeDefinition get(String id) throws RegistrationException {
160 final FieldTypeDefinition fieldTypeDefinition;
161 try {
162 fieldTypeDefinition = getProvider(id).get();
163 } catch (NoSuchDefinitionException | InvalidDefinitionException e) {
164 throw new RegistrationException(e.getMessage(), e);
165 }
166 return fieldTypeDefinition;
167 }
168
169 @Override
170 public DefinitionType type() {
171 return DefinitionTypes.FIELD_TYPE;
172 }
173
174 @Override
175 public DefinitionMetadataBuilder newMetadataBuilder() {
176 return DefinitionMetadataBuilder.usingNameAsId();
177 }
178 }