View Javadoc
1   /*
2    * #%L
3    * wcm.io
4    * %%
5    * Copyright (C) 2017 wcm.io
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   *
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package io.wcm.handler.url.impl;
21  
22  import java.util.concurrent.TimeUnit;
23  
24  import org.apache.sling.api.resource.Resource;
25  import org.apache.sling.caconfig.resource.ConfigurationResourceResolver;
26  import org.jetbrains.annotations.Nullable;
27  import org.osgi.service.component.annotations.Component;
28  import org.osgi.service.component.annotations.Reference;
29  import org.slf4j.Logger;
30  import org.slf4j.LoggerFactory;
31  
32  import com.github.benmanes.caffeine.cache.Cache;
33  import com.github.benmanes.caffeine.cache.Caffeine;
34  
35  import io.wcm.handler.url.SiteRootDetector;
36  import io.wcm.wcm.commons.util.Path;
37  
38  /**
39   * Implements {@link SiteRootDetector}.
40   */
41  @Component(service = SiteRootDetector.class)
42  public class SiteRootDetectorImpl implements SiteRootDetector {
43  
44    private static final int INVALID_SITE_ROOT_LEVEL = -1;
45  
46    @Reference
47    private ConfigurationResourceResolver configurationResourceResolver;
48  
49    private static final Logger log = LoggerFactory.getLogger(SiteRootDetectorImpl.class);
50  
51    // cache resolving of site root level per resource path
52    private final Cache<String, Integer> cache = Caffeine.newBuilder()
53        .expireAfterWrite(1, TimeUnit.MINUTES)
54        .maximumSize(10000)
55        .build();
56  
57    @Override
58    public int getSiteRootLevel(@Nullable Resource contextResource) {
59      if (contextResource == null) {
60        return INVALID_SITE_ROOT_LEVEL;
61      }
62      return cache.get(contextResource.getPath(), path -> detectSiteRootLevel(contextResource));
63    }
64  
65    private int detectSiteRootLevel(@Nullable Resource contextResource) {
66      if (contextResource != null) {
67        // assumption: inner-most context-aware configuration context path is site root path
68        String siteRootpath = configurationResourceResolver.getContextPath(contextResource);
69        if (siteRootpath != null) {
70          int level = Path.getAbsoluteLevel(siteRootpath, contextResource.getResourceResolver());
71          if (log.isDebugEnabled()) {
72            log.debug("Detect site root level for {}: {}", contextResource.getPath(), level);
73          }
74          return level;
75        }
76      }
77      return INVALID_SITE_ROOT_LEVEL;
78    }
79  
80  }