View Javadoc

1   package com.atlassian.plugin.manager;
2   
3   import static com.atlassian.plugin.manager.PluginPersistentState.Util.RESTART_STATE_SEPARATOR;
4   import static com.atlassian.plugin.manager.PluginPersistentState.Util.buildStateKey;
5   
6   import com.atlassian.plugin.ModuleDescriptor;
7   import com.atlassian.plugin.Plugin;
8   import com.atlassian.plugin.PluginRestartState;
9   
10  import java.util.HashMap;
11  import java.util.HashSet;
12  import java.util.Map;
13  import java.util.Set;
14  
15  /**
16   * Interface that represents a configuration state for plugins and plugin modules. The configuration state (enabled
17   * or disabled) is separate from the plugins and modules themselves because a plugin may have multiple
18   * states depending on the context.
19   * @since 2.2.0
20   * @author anatoli
21   *
22   */
23  public interface PluginPersistentState
24  {
25      /**
26       * Get the map of all states.
27       * @return The map that maps plugins and modules' keys to a state (Boolean.True/Boolean.False). State stored in this map represents only 
28       *         the <i>differences</i> between the current state and the default state configured in the plugin(module).
29       */
30      Map<String, Boolean> getMap();
31  
32      /**
33       * Whether or not a plugin is enabled, calculated from it's current state AND default state.
34       */
35      boolean isEnabled(final Plugin plugin);
36  
37      /**
38       * Whether or not a given plugin module is enabled in this state, calculated from it's current state AND default state.
39       */
40      boolean isEnabled(final ModuleDescriptor<?> pluginModule);
41  
42      /**
43       * Get state map of the given plugin and its modules
44       * @param plugin
45       * @return The map that maps the plugin and its modules' keys to plugin state (Boolean.TRUE/Boolean.FALSE). State stored in this map represents only 
46       *         the <i>differences</i> between the current state and the default state configured in the plugin(module).
47       */
48      Map<String, Boolean> getPluginStateMap(final Plugin plugin);
49  
50      /**
51       * Gets whether the plugin is expected to be upgraded, installed, or removed on next restart
52       *
53       * @param pluginKey The plugin to query
54       * @return The state of the plugin on restart
55       */
56      PluginRestartState getPluginRestartState(String pluginKey);
57  
58      /**
59       * Builder for {@link PluginPersistentState} instances.
60       * <p>
61       * This class is <strong>not thread safe</strong>. It should
62       * only be used in a method local context.
63       * 
64       * @since 2.3.0
65       */
66      public static final class Builder
67      {
68          public static Builder create()
69          {
70              return new Builder();
71          }
72  
73          public static Builder create(final PluginPersistentState state)
74          {
75              return new Builder(state);
76          }
77  
78          private final Map<String, Boolean> map = new HashMap<String, Boolean>();
79  
80          Builder()
81          {}
82  
83          Builder(final PluginPersistentState state)
84          {
85              map.putAll(state.getMap());
86          }
87  
88          public PluginPersistentState toState()
89          {
90              return new DefaultPluginPersistentState(map, true);
91          }
92  
93          public Builder setEnabled(final ModuleDescriptor<?> pluginModule, final boolean isEnabled)
94          {
95              setEnabled(pluginModule.getCompleteKey(), pluginModule.isEnabledByDefault(), isEnabled);
96              return this;
97          }
98  
99          public Builder setEnabled(final Plugin plugin, final boolean isEnabled)
100         {
101             setEnabled(plugin.getKey(), plugin.isEnabledByDefault(), isEnabled);
102             return this;
103         }
104 
105         private Builder setEnabled(final String completeKey, final boolean enabledByDefault, final boolean isEnabled)
106         {
107             if (isEnabled == enabledByDefault)
108             {
109                 map.remove(completeKey);
110             }
111             else
112             {
113                 map.put(completeKey, isEnabled);
114             }
115             return this;
116         }
117 
118         /**
119          * reset all plugin's state.
120          */
121         public Builder setState(final PluginPersistentState state)
122         {
123             map.clear();
124             map.putAll(state.getMap());
125             return this;
126         }
127 
128         /**
129          * Add the plugin state.
130          */
131         public Builder addState(final Map<String, Boolean> state)
132         {
133             map.putAll(state);
134             return this;
135         }
136 
137         /**
138          * Remove a plugin's state.
139          */
140         public Builder removeState(final String key)
141         {
142             map.remove(key);
143             return this;
144         }
145 
146         public Builder setPluginRestartState(final String pluginKey, final PluginRestartState state)
147         {
148             // Remove existing state, if any
149             for (final PluginRestartState st : PluginRestartState.values())
150             {
151                 map.remove(buildStateKey(pluginKey, st));
152             }
153 
154             if (state != PluginRestartState.NONE)
155             {
156                 map.put(buildStateKey(pluginKey, state), true);
157             }
158             return this;
159         }
160 
161         public Builder clearPluginRestartState()
162         {
163             final Set<String> keys = new HashSet<String>(map.keySet());
164             for (final String key : keys)
165             {
166                 if (key.contains(RESTART_STATE_SEPARATOR))
167                 {
168                     map.remove(key);
169                 }
170             }
171             return this;
172         }
173     }
174 
175     static class Util
176     {
177         static final String RESTART_STATE_SEPARATOR = "--";
178 
179         static String buildStateKey(final String pluginKey, final PluginRestartState state)
180         {
181             final StringBuilder sb = new StringBuilder();
182             sb.append(state.name());
183             sb.append(RESTART_STATE_SEPARATOR);
184             sb.append(pluginKey);
185             return sb.toString();
186         }
187     }
188 }