View Javadoc

1   package com.atlassian.plugin.manager;
2   
3   import com.atlassian.plugin.util.concurrent.CopyOnWriteMap;
4   import com.atlassian.plugin.manager.PluginPersistentState;
5   import com.atlassian.plugin.PluginRestartState;
6   import com.atlassian.plugin.Plugin;
7   import com.atlassian.plugin.ModuleDescriptor;
8   
9   import org.apache.commons.collections.CollectionUtils;
10  import org.apache.commons.collections.Predicate;
11  
12  import java.io.Serializable;
13  import java.util.*;
14  
15  /**
16   * <p/>
17   * <p>The state stored in this object represents only the <i>differences</i> between the desired state
18   * and the default state configured in the plugin. So if "getPluginState()" or "getPluginModuleState()" return
19   * null, then the manager should assume that the default state applies instead.
20   * <p>
21   * Please note that this class is not threadsafe.  Access to instances should be synchronised.
22   */
23  public class DefaultPluginPersistentState implements Serializable, PluginPersistentState
24  {
25      private final Map<String, Boolean> map;
26      private static final String RESTART_STATE_SEPARATOR = "--";
27  
28      public DefaultPluginPersistentState()
29      {
30          this(Collections.<String, Boolean>emptyMap());
31      }
32  
33      public DefaultPluginPersistentState(final Map<String, Boolean> map)
34      {
35          this.map = CopyOnWriteMap.newHashMap(map);
36      }
37  
38      public DefaultPluginPersistentState(final PluginPersistentState state)
39      {
40          map = CopyOnWriteMap.newHashMap(state.getMap());
41      }
42  
43      /* (non-Javadoc)
44       * @see com.atlassian.plugin.PluginPersistentState#getState(java.lang.String)
45       */
46      public Boolean getState(final String key)
47      {
48          return map.get(key);
49      }
50  
51      /* (non-Javadoc)
52       * @see com.atlassian.plugin.PluginPersistentState#getMap()
53       */
54      public Map<String, Boolean> getMap()
55      {
56          return Collections.unmodifiableMap(map);
57      }
58  
59      /* (non-Javadoc)
60       * @see com.atlassian.plugin.PluginPersistentState#isEnabled(com.atlassian.plugin.Plugin)
61       */
62      public boolean isEnabled(final Plugin plugin)
63      {
64          final Boolean bool = getState(plugin.getKey());
65          return (bool == null) ? plugin.isEnabledByDefault() : bool.booleanValue();
66      }
67  
68      /* (non-Javadoc)
69       * @see com.atlassian.plugin.PluginPersistentState#isEnabled(com.atlassian.plugin.ModuleDescriptor)
70       */
71      public boolean isEnabled(final ModuleDescriptor<?> pluginModule)
72      {
73          if (pluginModule == null)
74          {
75              return false;
76          }
77  
78          final Boolean bool = getState(pluginModule.getCompleteKey());
79          return (bool == null) ? pluginModule.isEnabledByDefault() : bool.booleanValue();
80      }
81  
82      public void setEnabled(final ModuleDescriptor<?> pluginModule, boolean isEnabled)
83      {
84          setEnabled(pluginModule.getCompleteKey(), pluginModule.isEnabledByDefault(), isEnabled);
85      }
86  
87      public void setEnabled(final Plugin plugin, boolean isEnabled)
88      {
89          setEnabled(plugin.getKey(), plugin.isEnabledByDefault(), isEnabled);
90      }
91      
92      private void setEnabled(final String completeKey, boolean enabledByDefault, boolean isEnabled)
93      {
94          if (isEnabled == enabledByDefault)
95          {
96              map.remove(completeKey);
97          }
98          else
99          {
100             map.put(completeKey, isEnabled);
101         }
102     }
103 
104     /**
105      * reset all plugin's state.
106      */
107     public void setState(final PluginPersistentState state)
108     {
109         map.clear();
110         map.putAll(state.getMap());
111     }
112 
113     /**
114      * Add the plugin state.
115      */
116     public void addState(final Map<String, Boolean> state)
117     {
118         map.putAll(state);
119     }
120 
121     /**
122      * Remove a plugin's state.
123      */
124     public void removeState(final String key)
125     {
126         map.remove(key);
127     }
128 
129     /* (non-Javadoc)
130      * @see com.atlassian.plugin.PluginPersistentState#getPluginStateMap(com.atlassian.plugin.Plugin)
131      */
132     public Map<String, Boolean> getPluginStateMap(final Plugin plugin)
133     {
134         final Map<String, Boolean> state = new HashMap<String, Boolean>(getMap());
135         CollectionUtils.filter(state.keySet(), new StringStartsWith(plugin.getKey()));
136         return state;
137     }
138 
139     public PluginRestartState getPluginRestartState(String pluginKey)
140     {
141         for (PluginRestartState state : PluginRestartState.values())
142         {
143             if (map.containsKey(buildStateKey(pluginKey, state)))
144             {
145                 return state;
146             }
147         }
148         return PluginRestartState.NONE;
149     }
150 
151     public void setPluginRestartState(String pluginKey, PluginRestartState state)
152     {
153         if (state == PluginRestartState.NONE)
154         {
155             for (PluginRestartState st : PluginRestartState.values())
156             {
157                 map.remove(buildStateKey(pluginKey, st));
158             }
159         }
160         else
161         {
162             map.put(buildStateKey(pluginKey, state), true);
163         }
164     }
165 
166     private static String buildStateKey(String pluginKey, PluginRestartState state)
167     {
168         StringBuilder sb = new StringBuilder();
169         sb.append(state.name());
170         sb.append(RESTART_STATE_SEPARATOR);
171         sb.append(pluginKey);
172         return sb.toString();
173     }
174 
175     public void clearPluginRestartState()
176     {
177         Set<String> keys = new HashSet<String>(getMap().keySet());
178         for (String key : keys)
179         {
180             if (key.contains(RESTART_STATE_SEPARATOR))
181             {
182                 map.remove(key);
183             }
184         }
185     }
186 
187     private static class StringStartsWith implements Predicate
188     {
189         private final String prefix;
190 
191         public StringStartsWith(final String keyPrefix)
192         {
193             prefix = keyPrefix;
194         }
195 
196         public boolean evaluate(final Object object)
197         {
198             final String str = (String) object;
199             return str.startsWith(prefix);
200         }
201     }
202 }