1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package tools.gsf.config.inject;
17
18 import COM.FutureTense.Interfaces.ICS;
19 import COM.FutureTense.Util.ftErrors;
20 import com.fatwire.assetapi.data.AssetId;
21 import com.openmarket.xcelerate.asset.AssetIdImpl;
22 import org.apache.commons.lang3.StringUtils;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25 import tools.gsf.facade.assetapi.AssetIdWithSite;
26 import tools.gsf.mapping.AssetName;
27 import tools.gsf.mapping.AssetNameImpl;
28 import tools.gsf.mapping.Mapping;
29 import tools.gsf.mapping.MappingService;
30 import tools.gsf.mapping.MappingValue;
31 import tools.gsf.runtime.CSRuntimeException;
32
33 import java.lang.annotation.Annotation;
34 import java.lang.reflect.Field;
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.Map;
38
39
40
41
42
43 public final class MappingInjector implements Injector {
44 private static final Logger LOG = LoggerFactory.getLogger("tools.gsf.config.inject.MappingInjector");
45
46 private final ICS ics;
47 private final MappingService mappingService;
48
49 public MappingInjector(ICS ics, MappingService mappingService) {
50 this.ics = ics;
51 this.mappingService = mappingService;
52 }
53
54 @Override
55 public void inject(Object dependent) {
56 if (dependent == null) {
57 throw new IllegalArgumentException("object cannot be null.");
58 }
59 String pagename = ics.GetVar("pagename");
60 if (pagename == null) {
61 throw new IllegalArgumentException("pagename cannot be identified");
62 }
63 final Field[] fields = findFieldsWithAnnotation(dependent, Mapping.class);
64 if (fields.length > 0) {
65 AssetIdWithSite id = mappingService.resolveMapped(pagename);
66 if (id != null) {
67 final Map<String, MappingValue> map = mappingService.readMapping(id);
68 for (final Field field : fields) {
69 injectIntoField(dependent, map, field, id);
70 }
71 } else {
72 LOG.warn("Cannot determine eid / tid for current code element (CSElement / Template) based on pagename '" + pagename + "', @Mapping annotations will be ignored.");
73 }
74 }
75 }
76
77 private static void injectIntoField(final Object object, final Map<String, MappingValue> map, final Field field,
78 final AssetIdWithSite id) throws SecurityException {
79
80 final Mapping ifr = field.getAnnotation(Mapping.class);
81
82 String name = ifr.value();
83 if (StringUtils.isBlank(name)) {
84 name = field.getName();
85 }
86
87 final MappingValue value = map.get(name);
88 if (value == null) {
89 throw new CSRuntimeException("Can't find a value for mapping " + name + " for asset " + id, ftErrors.badparams);
90 }
91 Object injectionValue;
92
93 if (MappingValue.class.isAssignableFrom(field.getType())) {
94 injectionValue = value;
95 } else if (AssetId.class.isAssignableFrom(field.getType()) && value.getType() == MappingValue.Type.asset) {
96 injectionValue = new AssetIdImpl(value.getLeft(), Long.parseLong(value.getRight()));
97 } else if (AssetName.class.isAssignableFrom(field.getType()) && value.getType() == MappingValue.Type.assetname) {
98 injectionValue = new AssetNameImpl(value.getLeft(), value.getRight());
99 } else {
100 injectionValue = value.getValue();
101 final Mapping.Match what = ifr.match();
102 switch (what) {
103 case left:
104 injectionValue = value.getLeft();
105 break;
106 case right:
107 injectionValue = value.getRight();
108 break;
109 case all:
110 break;
111 default:
112 break;
113 }
114 }
115 if (injectionValue == null) {
116 throw new CSRuntimeException("No value found to map '" + field.getType().getName() + "' into the field '"
117 + field.getName() + "' for an action " + object.getClass().getName(), ftErrors.badparams);
118 }
119 field.setAccessible(true);
120 LOG.debug("Injecting {} into field {} of type {} for {}", injectionValue.getClass().getName(), field.getName(), field.getType().getName(), object.getClass().getName());
121 try {
122 field.set(object, injectionValue);
123 } catch (final IllegalArgumentException e) {
124 throw new CSRuntimeException("IllegalArgumentException injecting " + injectionValue + " into field " + field.getName(), ftErrors.exceptionerr, e);
125 } catch (final IllegalAccessException e) {
126 throw new CSRuntimeException("IllegalAccessException injecting " + injectionValue + " into field " + field.getName(), ftErrors.exceptionerr, e);
127 }
128 }
129
130
131
132
133
134
135
136
137
138 private static Field[] findFieldsWithAnnotation(final Object object,
139 final Class<? extends Annotation> annnotationClass) {
140 if (object == null) {
141 throw new IllegalArgumentException("object must not be null.");
142 }
143 if (annnotationClass == null) {
144 throw new IllegalArgumentException("clazz must not be null.");
145 }
146 final List<Field> x = new ArrayList<>();
147 Class<?> c = object.getClass();
148 while (c != Object.class && c != null) {
149 for (final Field field : c.getDeclaredFields()) {
150 if (field.isAnnotationPresent(annnotationClass)) {
151 x.add(field);
152 }
153 }
154 c = c.getSuperclass();
155 }
156 return x.toArray(new Field[x.size()]);
157 }
158 }