1 package com.atlassian.plugin.util;
2
3 import com.atlassian.plugin.ModuleDescriptor;
4 import com.atlassian.plugin.Plugin;
5 import com.atlassian.plugin.descriptors.RequiresRestart;
6 import com.google.common.collect.Sets;
7 import org.apache.commons.lang.Validate;
8 import org.dom4j.Element;
9
10 import java.util.HashSet;
11 import java.util.Set;
12
13 /**
14 * General plugin utility methods
15 *
16 * @since 2.1
17 */
18 public class PluginUtils
19 {
20 public static final String ATLASSIAN_DEV_MODE = "atlassian.dev.mode";
21
22 /**
23 * System property for storing and retrieving the time the plugin system will wait for the enabling of a plugin in
24 * seconds
25 * @since 2.3.6
26 */
27 public static final String ATLASSIAN_PLUGINS_ENABLE_WAIT = "atlassian.plugins.enable.wait";
28
29 /**
30 * Used to customise the size of the LRU cache for batch web resources.
31 * This effectively controls how many files will be created
32 * by the file cache. Providing a negative number results in undefined behaviour.
33 * @since 2.13.0
34 */
35 public static final String WEBRESOURCE_FILE_CACHE_SIZE = new String("atlassian.webresource.file.cache.size");
36
37 /**
38 * Used to disable the file cache should that be desired. Setting this value to true will disable the
39 * file caching completely for all places it is used.
40 * @since 2.13.0
41 */
42 public static final String WEBRESOURCE_DISABLE_FILE_CACHE = new String("atlassian.webresource.file.cache.disable");
43
44
45 /**
46 * Determines if a plugin requires a restart after being installed at runtime. Looks for the annotation
47 * {@link RequiresRestart} on the plugin's module descriptors.
48 *
49 * @param plugin The plugin that was just installed at runtime, but not yet enabled
50 * @return True if a restart is required
51 * @since 2.1
52 */
53 public static boolean doesPluginRequireRestart(final Plugin plugin)
54 {
55 //PLUG-451: When in dev mode, plugins should not require a restart.
56 if (Boolean.getBoolean(ATLASSIAN_DEV_MODE))
57 {
58 return false;
59 }
60
61 for (final ModuleDescriptor<?> descriptor : plugin.getModuleDescriptors())
62 {
63 if (descriptor.getClass().getAnnotation(RequiresRestart.class) != null)
64 {
65 return true;
66 }
67 }
68 return false;
69 }
70
71 /**
72 * Gets a list of all the module keys in a plugin that require restart. Looks for the annotation
73 * {@link RequiresRestart} on the plugin's module descriptors.
74 *
75 * @param plugin The plugin
76 * @return A unique set of module keys
77 * @since 2.5.0
78 */
79 public static Set<String> getPluginModulesThatRequireRestart(final Plugin plugin)
80 {
81 Set<String> keys = new HashSet<String>();
82 for (final ModuleDescriptor<?> descriptor : plugin.getModuleDescriptors())
83 {
84 if (descriptor.getClass().getAnnotation(RequiresRestart.class) != null)
85 {
86 keys.add(descriptor.getKey());
87 }
88 }
89 return keys;
90 }
91
92 /**
93 * Determines if a module element applies to the current application by matching the 'application' attribute
94 * to the set of keys. If the application is specified, but isn't in the set, we return false
95 * @param element The module element
96 * @param keys The set of application keys
97 * @return True if it should apply, false otherwise
98 * @since 2.2.0
99 */
100 public static boolean doesModuleElementApplyToApplication(Element element, Set<String> keys)
101 {
102 Validate.notNull(keys);
103 Validate.notNull(element);
104 String keyList = element.attributeValue("application");
105 if (keyList == null) {
106 return true;
107 }
108 final String[] split = keyList.split("\\s*,[,\\s]*");
109 if (split.length == 0 || (split.length == 1 && split[0].trim().length() == 0)) {
110 return true;
111 }
112 for (final String key : split) {
113 if (keys.contains(key)) {
114 return true;
115 }
116 }
117 return false;
118 }
119
120 /**
121 * @return The default enabling waiting period in seconds
122 * @since 2.3.6
123 */
124 public static int getDefaultEnablingWaitPeriod()
125 {
126 return Integer.parseInt(System.getProperty(ATLASSIAN_PLUGINS_ENABLE_WAIT, "60"));
127 }
128 }