View Javadoc

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