View Javadoc
1   /*
2    * Copyright 2016 Function1. All Rights Reserved.
3    *
4    * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
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  
17  package tools.gsf.config.inject;
18  
19  import COM.FutureTense.Interfaces.ICS;
20  import com.fatwire.assetapi.data.AssetData;
21  import com.fatwire.assetapi.data.AssetId;
22  import org.slf4j.Logger;
23  import org.slf4j.LoggerFactory;
24  import tools.gsf.facade.assetapi.AssetAccessTemplate;
25  import tools.gsf.facade.assetapi.AssetIdUtils;
26  import tools.gsf.facade.assetapi.asset.CurrentAsset;
27  import tools.gsf.facade.assetapi.asset.ScatteredAsset;
28  import tools.gsf.facade.assetapi.asset.ScatteredAssetAccessTemplate;
29  import tools.gsf.facade.assetapi.asset.TemplateAsset;
30  import tools.gsf.facade.assetapi.asset.TemplateAssetAccess;
31  
32  import java.lang.reflect.Field;
33  
34  /**
35   * @author Tony Field
36   * @since 2016-08-24
37   */
38  public class CurrentAssetInjector implements Injector {
39      private static final Logger LOG = LoggerFactory.getLogger(CurrentAssetInjector.class);
40  
41      private final ICS ics;
42      private final TemplateAssetAccess taa;
43      private final ScatteredAssetAccessTemplate saa;
44      private final AssetAccessTemplate aat;
45  
46      public CurrentAssetInjector(ICS ics, TemplateAssetAccess taa, ScatteredAssetAccessTemplate saa, AssetAccessTemplate aat) {
47          this.ics = ics;
48          this.taa = taa;
49          this.saa = saa;
50          this.aat = aat;
51      }
52  
53      @Override
54      public void inject(Object dependent) {
55          if (dependent == null) {
56              throw new IllegalArgumentException("dependent cannot be null.");
57          }
58          Class<?> c = dependent.getClass();
59          while (c != Object.class && c != null) {
60              for (final Field field : c.getDeclaredFields()) {
61                  if (field.isAnnotationPresent(CurrentAsset.class)) {
62                      String[] attributes = field.getAnnotation(CurrentAsset.class).attributes();
63                      AssetId id = _getAssetId(field);
64                      Object dependency = readAsset(id, attributes, field.getType());
65                      _injectIntoField(field, dependent, dependency, id);
66                  }
67              }
68              c = c.getSuperclass();
69          }
70      }
71  
72      private AssetId _getAssetId(Field field) {
73          AssetId id;
74          try {
75              id = AssetIdUtils.currentId(ics);
76          } catch (IllegalArgumentException e) {
77              throw new InjectionException("Could not inject current asset into field " + field.getName() + " because current asset could not be found", e);
78          }
79          return id;
80      }
81  
82  
83      protected Object readAsset(AssetId id, String[] attributes, Class assetDataType) {
84          Object dependency;
85          if (TemplateAsset.class.equals(assetDataType)) {
86              dependency = taa.read(id, attributes);
87          } else if (ScatteredAsset.class.equals(assetDataType)) {
88              dependency = saa.read(id, attributes);
89          } else if (AssetData.class.equals(assetDataType)) {
90              dependency = aat.readAsset(id, attributes);
91          } else {
92              throw new InjectionException("Unsupported field type " + assetDataType);
93          }
94          return dependency;
95      }
96  
97      private void _injectIntoField(Field field, Object dependent, Object dependency, AssetId id) {
98          try {
99              LOG.debug("Injecting current asset {} into field {} for {}", id, field.getName(), dependent.getClass().getName());
100             field.setAccessible(true);
101             field.set(dependent, dependency);
102         } catch (final IllegalArgumentException | IllegalAccessException e) {
103             throw new InjectionException("Exception injecting current asset" + id + " into field " + field.getName(), e);
104         }
105     }
106 }