View Javadoc

1   package com.atlassian.plugin.webresource;
2   
3   import com.atlassian.plugin.Plugin;
4   import com.atlassian.plugin.PluginParseException;
5   import com.atlassian.plugin.descriptors.AbstractModuleDescriptor;
6   import com.atlassian.plugin.hostcontainer.HostContainer;
7   import com.atlassian.plugin.web.Condition;
8   import com.atlassian.plugin.web.conditions.ConditionLoadingException;
9   import com.atlassian.plugin.web.descriptors.ConditionElementParser;
10  import com.atlassian.plugin.web.descriptors.ConditionalDescriptor;
11  import org.dom4j.Attribute;
12  import org.dom4j.Element;
13  
14  import java.util.ArrayList;
15  import java.util.Collections;
16  import java.util.HashSet;
17  import java.util.List;
18  import java.util.Set;
19  
20  /**
21   * A way of linking to web 'resources', such as javascript or css.  This allows us to include resources once
22   * on any given page, as well as ensuring that plugins can declare resources, even if they are included
23   * at the bottom of a page.
24   */
25  public class WebResourceModuleDescriptor extends AbstractModuleDescriptor<Void> implements ConditionalDescriptor
26  {
27      private List<String> dependencies = Collections.emptyList();
28      private boolean disableMinification;
29      private Set<String> contexts = Collections.emptySet();
30      private List<WebResourceTransformation> webResourceTransformations = Collections.emptyList();
31      private ConditionElementParser conditionElementParser;
32      private Element element;
33      private Condition condition;
34  
35      public WebResourceModuleDescriptor(final HostContainer hostContainer)
36      {
37          this.conditionElementParser = new ConditionElementParser(new ConditionElementParser.ConditionFactory()
38          {
39              public Condition create(String className, Plugin plugin) throws ConditionLoadingException
40              {
41                  try
42                  {
43                      Class<Condition> conditionClass = plugin.loadClass(className, this.getClass());
44                      return hostContainer.create(conditionClass);
45                  }
46                  catch (ClassNotFoundException e)
47                  {
48                      throw new ConditionLoadingException("Cannot load condition class: " + className, e);
49                  }
50              }
51          });
52      }
53  
54      @Override
55      public void init(final Plugin plugin, final Element element) throws PluginParseException
56      {
57          super.init(plugin, element);
58  
59          final List<String> deps = new ArrayList<String>();
60          for (Element dependency : (List<Element>) element.elements("dependency"))
61          {
62              deps.add(dependency.getTextTrim());
63          }
64          dependencies = Collections.unmodifiableList(deps);
65  
66          final Set<String> ctxs = new HashSet<String>();
67          for (Element contextElement : (List<Element>) element.elements("context"))
68          {
69              ctxs.add(contextElement.getTextTrim());
70          }
71          contexts = Collections.unmodifiableSet(ctxs);
72  
73          final List<WebResourceTransformation> trans = new ArrayList<WebResourceTransformation>();
74          for (Element e : (List<Element>) element.elements("transformation"))
75          {
76              trans.add(new WebResourceTransformation(e));
77          }
78          webResourceTransformations = Collections.unmodifiableList(trans);
79  
80          final Attribute minifiedAttribute = element.attribute("disable-minification");
81          disableMinification = minifiedAttribute == null ? false : Boolean.valueOf(minifiedAttribute.getValue());
82          this.element = element;
83      }
84  
85      /**
86       * As this descriptor just handles resources, you should never call this
87       */
88      @Override
89      public Void getModule()
90      {
91          throw new UnsupportedOperationException("There is no module for Web Resources");
92      }
93  
94      @Override
95      public void enabled()
96      {
97          super.enabled();
98          try
99          {
100             condition = conditionElementParser.makeConditions(plugin, element, ConditionElementParser.CompositeType.AND);
101         }
102         catch (final PluginParseException e)
103         {
104             // is there a better exception to throw?
105             throw new RuntimeException("Unable to enable web resource due to issue processing condition", e);
106         }
107     }
108 
109     @Override
110     public void disabled()
111     {
112         super.disabled();
113         condition = null;
114     }
115 
116     /**
117      * Returns the web resource contexts this resource is associated with.
118      *
119      * @return  the web resource contexts this resource is associated with.
120      * @since 2.5.0
121      */
122     public Set<String> getContexts()
123     {
124         return contexts;
125     }
126 
127     /**
128      * Returns a list of dependencies on other web resources.
129      * @return a list of module complete keys
130      */
131     public List<String> getDependencies()
132     {
133         return dependencies;
134     }
135 
136     public List<WebResourceTransformation> getTransformations()
137     {
138         return webResourceTransformations;
139     }
140 
141     /**
142      * @return <code>true</code> if resource minification should be skipped, <code>false</code> otherwise.
143      */
144     public boolean isDisableMinification()
145     {
146         return disableMinification;
147     }
148 
149     /**
150      * @return The condition to determine if it should be displayed or not
151      * @since 2.7.0
152      */
153     public Condition getCondition()
154     {
155         return condition;
156     }
157 
158     /**
159      * @return True if this web resource should be displayed based on the optional condition
160      * @since 2.7.0
161      */
162     public boolean shouldDisplay()
163     {
164         return condition != null ? condition.shouldDisplay(Collections.<String, Object>emptyMap()) : true;
165     }
166 }