View Javadoc

1   package com.atlassian.plugin.webresource;
2   
3   import com.atlassian.util.concurrent.LazyReference;
4   import com.google.common.base.Function;
5   import com.google.common.base.Supplier;
6   import com.google.common.base.Suppliers;
7   import com.google.common.cache.CacheBuilder;
8   import com.google.common.cache.CacheLoader;
9   
10  import static com.google.common.base.Preconditions.checkNotNull;
11  
12  /**
13   * The set of identifying information for a resource.
14   */
15  interface ResourceKey
16  {
17      /** @return the complete key of the module containing the resource. */
18      String key();
19      /** @return the name of the resource, including the file type suffix. */
20      String name();
21      /** @return the file type suffix. */
22      String suffix();
23  
24      /**
25       * A ResourceKey, for when we know ahead of time what all the properties are.
26       */
27      class Strict implements ResourceKey
28      {
29          final String key;
30          final String name;
31          final String suffix;
32  
33          Strict(String key, String name, String suffix)
34          {
35              this.key = checkNotNull(key);
36              this.name = checkNotNull(name);
37              this.suffix = checkNotNull(suffix);
38          }
39  
40          public String key()
41          {
42              return key;
43          }
44  
45          public String name()
46          {
47              return name;
48          }
49  
50          public String suffix()
51          {
52              return suffix;
53          }
54          @Override
55          public boolean equals(Object o)
56          {
57              if (!(o instanceof ResourceKey))
58                  return false;
59              return Equality.equal(this, (ResourceKey) o);
60          }
61  
62          @Override
63          public int hashCode()
64          {
65  
66              return Equality.hash(this);
67          }
68      }
69  
70      /**
71       * A resource key, for when one or more of the properties are derived.
72       */
73      class Lazy implements ResourceKey
74      {
75          final Supplier<String> key;
76          final Supplier<String> name;
77          final Supplier<String> suffix;
78  
79          Lazy(Supplier<String> key, Supplier<String> name, Supplier<String> suffix)
80          {
81              this.key = checkNotNull(key);
82              this.name = checkNotNull(name);
83              this.suffix = checkNotNull(suffix);
84          }
85  
86          public String key()
87          {
88              return key.get();
89          }
90  
91          public String name()
92          {
93              return name.get();
94          }
95  
96          public String suffix()
97          {
98              return suffix.get();
99          }
100 
101         @Override
102         public boolean equals(Object o)
103         {
104             if (!(o instanceof ResourceKey))
105                 return false;
106             return Equality.equal(this, (ResourceKey) o);
107         }
108 
109         @Override
110         public int hashCode()
111         {
112             return Equality.hash(this);
113         }
114     }
115 
116     /**
117      * Builds ResourceKeys.
118      */
119     class Builder
120     {
121         /**
122          * Builds a lazy key that will create the resourceName when it is actually required
123          */
124         static ResourceKey lazy(final String completeKey, final Supplier<String> suffix)
125         {
126             return new ResourceKey.Lazy(
127                 Suppliers.ofInstance(completeKey),
128                 new LazyReference<String>()
129                 {
130                     @Override
131                     protected String create()
132                     {
133                         return completeKey + "." + suffix.get();
134                     }
135                 },
136                 suffix
137             );
138         }
139 
140         static final String DEFAULT_RESOURCE_NAME_PREFIX = "batch";
141 
142         static final Function<String, ResourceKey> BATCH_RESOURCE_KEY_CACHE = CacheBuilder.newBuilder().build(
143             CacheLoader.from(new Function<String, ResourceKey>()
144             {
145                 @Override
146                 public ResourceKey apply(String suffix)
147                 {
148                     return new ResourceKey.Strict(DEFAULT_RESOURCE_NAME_PREFIX, DEFAULT_RESOURCE_NAME_PREFIX + "." + suffix, suffix);
149                 }
150             }));
151 
152         /**
153          * Builds a lazy key that will have a resourceName of "batch.[suffix]".
154          * @param suffix
155          * @return
156          */
157         static ResourceKey batch(String suffix)
158         {
159             // PERF: cache these because we would otherwise create hundreds of them, and they're always the same.
160             return BATCH_RESOURCE_KEY_CACHE.apply(suffix);
161         }
162     }
163 
164     /**
165      * Equals and hashcode for any ResourceKey.
166      */
167     class Equality
168     {
169         static boolean equal(ResourceKey left, ResourceKey right)
170         {
171             if (!left.key().equals(right.key()))
172             {
173                 return false;
174             }
175             if (!left.name().equals(right.name()))
176             {
177                 return false;
178             }
179             return left.suffix().equals(right.suffix());
180         }
181 
182         public static int hash(ResourceKey resource)
183         {
184             int result = resource.key().hashCode();
185             result = 31 * result + resource.name().hashCode();
186             result = 31 * result + resource.suffix().hashCode();
187             return result;
188         }
189     }
190 }