View Javadoc

1   package com.atlassian.plugin.metadata;
2   
3   import com.atlassian.plugin.ModuleDescriptor;
4   import com.atlassian.plugin.Plugin;
5   import com.atlassian.plugin.descriptors.CannotDisable;
6   import net.jcip.annotations.Immutable;
7   
8   import static com.google.common.base.Preconditions.checkNotNull;
9   
10  /**
11   * A default implementation that uses the {@link com.atlassian.plugin.metadata.ClasspathFilePluginMetadata}
12   * plugin metadata implementation to resolve the application provided plugin metadata.
13   *
14   * @since 2.6
15   */
16  @Immutable
17  public final class DefaultPluginMetadataManager implements PluginMetadataManager
18  {
19      private final PluginMetadata metadata;
20  
21      /**
22       * Production ctor. Loads from the class path.
23       */
24      public DefaultPluginMetadataManager()
25      {
26          this(new ClasspathFilePluginMetadata());
27      }
28  
29      /**
30       * Test ctor.
31       */
32      DefaultPluginMetadataManager(final PluginMetadata metadata)
33      {
34          this.metadata = checkNotNull(metadata, "metadata");
35      }
36  
37      /**
38       * <p>A plugin is determined to be non-user if
39       * {@link com.atlassian.plugin.Plugin#isBundledPlugin()} is true or if the
40       * host application has indicated to the plugins system that a plugin was
41       * provided by it.</p>
42       *
43       * <p><strong>NOTE:</strong> If a user has upgraded a bundled plugin then the
44       * decision of whether it is user installed plugin is determined by if the
45       * application has indicated to the plugins system that a plugin was
46       * provided or not.</p>
47       */
48      public boolean isUserInstalled(final Plugin plugin)
49      {
50          checkNotNull(plugin, "plugin");
51          // It is user installed if it has not been marked as provided by the
52          // application and it was not bundled.
53          return !plugin.isBundledPlugin() && !metadata.applicationProvided(plugin);
54      }
55  
56      /**
57       * A plugin is determined to be &quot;system&quot; if
58       * {@link #isUserInstalled(com.atlassian.plugin.Plugin)} is false.
59       */
60      public boolean isSystemProvided(Plugin plugin)
61      {
62          return !isUserInstalled(plugin);
63      }
64  
65      /**
66       * A plugin is determined to be optional if the host application has not
67       * indicated to the plugins system that it is required or if any of its
68       * modules have been flagged as not optional.
69       */
70      public boolean isOptional(final Plugin plugin)
71      {
72          checkNotNull(plugin, "plugin");
73          // If the application has marked the plugin as required then we know we
74          // are required
75          if (!optionalAccordingToHostApplication(plugin))
76          {
77              return false;
78          }
79  
80          // We need to check if any of the plugins modules are not optional
81          for (final ModuleDescriptor<?> moduleDescriptor : plugin.getModuleDescriptors())
82          {
83              if (!optionalAccordingToHostApplication(moduleDescriptor))
84              {
85                  return false;
86              }
87          }
88          return true;
89      }
90  
91      /**
92       * A module is determined to be optional if the host application has not
93       * indicated to the plugins system that it is required. If the call to
94       * {@code isOptional} with the module descriptor's plugin is {@code false},
95       * then this method will also return {@code false}. Also if the module
96       * descriptor is annotated with
97       * {@link com.atlassian.plugin.descriptors.CannotDisable} then it can not be
98       * optional.
99       */
100     public boolean isOptional(final ModuleDescriptor<?> moduleDescriptor)
101     {
102         checkNotNull(moduleDescriptor, "moduleDescriptor");
103         // It is not optional if the host application has marked it as required
104         if (!optionalAccordingToHostApplication(moduleDescriptor))
105         {
106             return false;
107         }
108 
109         // A module can not be optional if it is marked 
110         // by the CannotDisable annotation
111         if (!optionalAccordingToModuleDescriptorType(moduleDescriptor))
112         {
113             return false;
114         }
115 
116         // A module can only be optional if its parent plugin is not declared by
117         // the host application as required
118         return optionalAccordingToHostApplication(moduleDescriptor.getPlugin());
119     }
120 
121     private boolean optionalAccordingToHostApplication(final Plugin plugin)
122     {
123         return !metadata.required(plugin);
124     }
125 
126     private boolean optionalAccordingToHostApplication(final ModuleDescriptor<?> moduleDescriptor)
127     {
128         return !metadata.required(moduleDescriptor);
129     }
130 
131     private boolean optionalAccordingToModuleDescriptorType(final ModuleDescriptor<?> moduleDescriptor)
132     {
133         return !moduleDescriptor.getClass().isAnnotationPresent(CannotDisable.class);
134     }
135 }