Uploaded image for project: 'Sling'
  1. Sling
  2. SLING-4926

Sling Models: inject a map of adaptable child resources

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Open
    • Major
    • Resolution: Unresolved
    • Sling Models API 1.1.0
    • None
    • None

    Description

      Iterates over child resources and injects a map with entries <childResourceName, childResource.adaptTo(Target.class)>

      Usage:

      @Model(adptable=Resource.class)
      public class MyModel {
      
        @Inject @Source("adaptable-child-resources-map")
        protected  Map<String, MyAdaptable> childResources;
      }
      

      Quick write up:

      /**
       * AdaptableChildResourcesMapInjector ... injects child resources into a map.put(resource.name(), resource.adaptTo(type))
       *
       * <h2>Usage</h2>
       * <code>protected Map<String, MyAdaptable> injectableMemberField;</code>
       */
      @Component
      @Service
      @Property(name = Constants.SERVICE_RANKING, intValue = 9999)
      public class AdaptableChildResourcesMapInjector implements Injector{
      
          @Override
          public String getName() {
              return "adaptable-child-resources-map";
          }
      
          @Override
          public Object getValue(Object adaptable, String name, Type declaredType, AnnotatedElement annotatedElement,
                              DisposalCallbackRegistry disposalCallbackRegistry) {
      
              Resource res = resourceFromAdaptable(adaptable);
              Class<?> targetType = declaredMapWithValueType(declaredType);
              if ((res != null) && (targetType != null)) {
                  Map<String, Object> result = new HashMap<String, Object>();
      
                  Iterator<Resource> iter = res.listChildren();
                  while ((iter != null) && iter.hasNext()) {
                      Resource next = iter.next();
                      result.put(next.getName(), next.adaptTo(targetType));
                  }
      
                  return result;
              }
      
              return null;
          }
      
          private Resource resourceFromAdaptable(Object adaptable) {
              if (adaptable instanceof Resource) {
                  return (Resource) adaptable;
              } else if (adaptable instanceof Adaptable) {
                  return ((Adaptable) adaptable).adaptTo(Resource.class);
              }
      
              return null;
          }
      
          // Checks if <code>declaredType</code> is a Map<String, {declaredType}> ... returns {declaredType} or 'null'
          protected Class<?> declaredMapWithValueType(Type declaredType) {
              if (declaredType instanceof ParameterizedType) {
                  ParameterizedType type = (ParameterizedType) declaredType;
                  Class<?> rawType = (Class<?>) type.getRawType();
                  Type[] typeArguments = type.getActualTypeArguments();
      
                  if (rawType.equals(Map.class) && (typeArguments.length == 2)
                          && typeArguments[0].equals(String.class)) {
                      // returns the V from Map<K, V>
                      return (Class<?>) typeArguments[1];
                  }
              }
      
              return null;
          }
      
      }
      
      

      wdyt?

      Attachments

        Activity

          People

            Unassigned Unassigned
            haggis David Herges
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated: