View Javadoc
1   package com.atlassian.plugin;
2   
3   import com.atlassian.plugin.elements.ResourceDescriptor;
4   import com.atlassian.plugin.elements.ResourceLocation;
5   import com.atlassian.util.concurrent.Assertions;
6   import com.google.common.base.Function;
7   import com.google.common.base.Predicate;
8   import com.google.common.collect.ImmutableList;
9   import com.google.common.collect.Iterables;
10  import com.google.common.collect.Lists;
11  import org.dom4j.Element;
12  
13  import javax.annotation.Nullable;
14  import java.util.Collections;
15  import java.util.HashSet;
16  import java.util.List;
17  import java.util.Set;
18  
19  import static com.atlassian.plugin.util.Assertions.notNull;
20  import static com.google.common.collect.Iterables.filter;
21  
22  /**
23   * An aggregate of all resource descriptors within the given plugin module or
24   * plugin.
25   *
26   * @see com.atlassian.plugin.impl.AbstractPlugin#resources
27   * @see com.atlassian.plugin.descriptors.AbstractModuleDescriptor#resources
28   */
29  public class Resources implements Resourced {
30      public static final Resources EMPTY_RESOURCES = new Resources((Element) null);
31  
32      private final List<ResourceDescriptor> resourceDescriptors;
33  
34      /**
35       * Parses the resource descriptors from the provided plugin XML element and
36       * creates a Resources object containing them.
37       * <p/>
38       * If the module or plugin contains no resource elements, an empty Resources
39       * object will be returned. This method will not return null.
40       *
41       * @param element the plugin or plugin module XML fragment which should not
42       *                be null
43       * @return a Resources object representing the resources in the plugin or
44       * plugin module
45       * @throws PluginParseException     if there are two resources with the same
46       *                                  name and type in this element, or another parse error occurs
47       * @throws IllegalArgumentException if the provided element is null
48       */
49      public static Resources fromXml(final Element element) throws PluginParseException, IllegalArgumentException {
50          if (element == null) {
51              throw new IllegalArgumentException("Cannot parse resources from null XML element");
52          }
53  
54          @SuppressWarnings("unchecked")
55          final List<Element> elements = element.elements("resource");
56  
57          final Set<ResourceDescriptor> templates = new HashSet<ResourceDescriptor>();
58  
59          for (final Element e : elements) {
60              final ResourceDescriptor resourceDescriptor = new ResourceDescriptor(e);
61  
62              if (templates.contains(resourceDescriptor)) {
63                  throw new PluginParseException("Duplicate resource with type '" + resourceDescriptor.getType() + "' and name '" + resourceDescriptor.getName() + "' found");
64              }
65  
66              templates.add(resourceDescriptor);
67          }
68  
69          return new Resources(element);
70      }
71  
72      /**
73       * Private constructor to create a Resources object from XML. Entry via fromXml.
74       *
75       * @param element
76       */
77      private Resources(final Element element) {
78          if (element != null) {
79              this.resourceDescriptors = Lists.newArrayList(Iterables.transform(element.elements("resource"), new Function<Element, ResourceDescriptor>() {
80  
81                  @Override
82                  public ResourceDescriptor apply(@Nullable final Element e) {
83                      return new ResourceDescriptor(e);
84                  }
85              }));
86          } else {
87              this.resourceDescriptors = Collections.emptyList();
88          }
89      }
90  
91      /**
92       * Create a resource object with the given resource descriptors. The
93       * provided list must not be null.
94       *
95       * @param resourceDescriptors the descriptors which are part of this
96       *                            resources object
97       * @throws IllegalArgumentException if the resourceDescriptors list is null
98       * @deprecated Since 3.0.1, use {@link #fromXml(org.dom4j.Element)} instead. This will lazily create the
99       * ResourceDescriptors from the Element, for a memory saving.
100      */
101     @Deprecated
102     public Resources(final Iterable<ResourceDescriptor> resourceDescriptors) throws IllegalArgumentException {
103         Assertions.notNull("Resources cannot be created with a null resources list. Pass empty list instead", resourceDescriptors);
104         this.resourceDescriptors = ImmutableList.<ResourceDescriptor>builder().addAll(resourceDescriptors).build();
105     }
106 
107     public List<ResourceDescriptor> getResourceDescriptors() {
108         return resourceDescriptors;
109     }
110 
111     /**
112      * * @deprecated since 2.5.0 use {@link #getResourceDescriptors()} and
113      * filter as required
114      */
115     @Deprecated
116     public List<ResourceDescriptor> getResourceDescriptors(final String type) {
117         return ImmutableList.<ResourceDescriptor>builder().addAll(filter(getResourceDescriptors(), new TypeFilter(type))).build();
118     }
119 
120     public ResourceLocation getResourceLocation(final String type, final String name) {
121         for (final ResourceDescriptor resourceDescriptor : getResourceDescriptors()) {
122             if (resourceDescriptor.doesTypeAndNameMatch(type, name)) {
123                 return resourceDescriptor.getResourceLocationForName(name);
124             }
125         }
126         return null;
127     }
128 
129     public ResourceDescriptor getResourceDescriptor(final String type, final String name) {
130         for (final ResourceDescriptor resourceDescriptor : getResourceDescriptors()) {
131             if (resourceDescriptor.getType().equalsIgnoreCase(type) && resourceDescriptor.getName().equalsIgnoreCase(name)) {
132                 return resourceDescriptor;
133             }
134         }
135         return null;
136     }
137 
138     public static class TypeFilter implements Predicate<ResourceDescriptor> {
139         private final String type;
140 
141         public TypeFilter(final String type) {
142             this.type = notNull("type", type);
143         }
144 
145         public boolean apply(final ResourceDescriptor input) {
146             // TODO Auto-generated method stub
147             return type.equals(input.getType());
148         }
149     }
150 }