View Javadoc

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