View Javadoc
1   /*
2    * #%L
3    * wcm.io
4    * %%
5    * Copyright (C) 2014 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.Set;
23  
24  import org.apache.commons.lang3.ObjectUtils;
25  import org.apache.commons.lang3.StringUtils;
26  import org.apache.sling.api.resource.Resource;
27  import org.jetbrains.annotations.NotNull;
28  import org.jetbrains.annotations.Nullable;
29  
30  import com.day.cq.wcm.api.Page;
31  
32  import io.wcm.handler.url.UrlBuilder;
33  import io.wcm.handler.url.UrlMode;
34  import io.wcm.handler.url.VanityMode;
35  
36  /**
37   * Default implementation or {@link UrlBuilder}.
38   */
39  final class UrlBuilderImpl implements UrlBuilder {
40  
41    private final UrlHandlerImpl urlHandler;
42    private final String path;
43    private final Resource resource;
44    private final Page page;
45  
46    private String selectors;
47    private String extension;
48    private String suffix;
49    private String queryString;
50    private Set<String> inheritableParameterNames;
51    private String fragment;
52    private UrlMode urlMode;
53    private VanityMode vanityMode;
54    private boolean disableSuffixSelector;
55  
56    /**
57     * @param path Path for URL (without any hostname, scheme, extension, suffix etc.)
58     * @param urlHandler Url handler instance
59     */
60    UrlBuilderImpl(String path, UrlHandlerImpl urlHandler) {
61      this.path = path;
62      this.resource = null;
63      this.page = null;
64      this.urlHandler = urlHandler;
65    }
66  
67    /**
68     * @param resource Resource
69     * @param urlHandler Url handler instance
70     */
71    UrlBuilderImpl(Resource resource, UrlHandlerImpl urlHandler) {
72      this.path = resource != null ? resource.getPath() : null;
73      this.resource = resource;
74      this.page = null;
75      this.urlHandler = urlHandler;
76    }
77  
78    /**
79     * @param page Page
80     * @param urlHandler Url handler instance
81     */
82    UrlBuilderImpl(Page page, UrlHandlerImpl urlHandler) {
83      this.path = page != null ? page.getPath() : null;
84      this.resource = null;
85      this.page = page;
86      this.urlHandler = urlHandler;
87    }
88  
89    @Override
90    public @NotNull UrlBuilder selectors(@Nullable String value) {
91      this.selectors = value;
92      return this;
93    }
94  
95    @Override
96    public @NotNull UrlBuilder extension(@Nullable String value) {
97      this.extension = value;
98      return this;
99    }
100 
101   @Override
102   public @NotNull UrlBuilder suffix(@Nullable String value) {
103     this.suffix = value;
104     return this;
105   }
106 
107   @Override
108   public @NotNull UrlBuilder queryString(@Nullable String value) {
109     this.queryString = value;
110     this.inheritableParameterNames = null;
111     return this;
112   }
113 
114   @Override
115   public @NotNull UrlBuilder queryString(@Nullable String value, @NotNull Set<String> inheritableParamNames) {
116     this.queryString = value;
117     this.inheritableParameterNames = inheritableParamNames;
118     return this;
119   }
120 
121   @Override
122   public @NotNull UrlBuilder fragment(@Nullable String value) {
123     this.fragment = value;
124     return this;
125   }
126 
127   @Override
128   public @NotNull UrlBuilder urlMode(@Nullable UrlMode value) {
129     this.urlMode = value;
130     return this;
131   }
132 
133   @Override
134   public @NotNull UrlBuilder vanityMode(@Nullable VanityMode value) {
135     this.vanityMode = value;
136     return this;
137   }
138 
139 
140   @Override
141   public @NotNull UrlBuilder disableSuffixSelector(boolean value) {
142     this.disableSuffixSelector = value;
143     return this;
144   }
145 
146   private String build(boolean externalize) {
147     String pathToUse = path;
148     VanityMode vanityModeToUse = ObjectUtils.defaultIfNull(vanityMode, urlHandler.getDefaultVanityMode());
149     if (page != null && (vanityModeToUse == VanityMode.ALWAYS || (externalize && vanityModeToUse == VanityMode.EXTERNALIZE))) {
150       pathToUse = StringUtils.defaultString(page.getVanityUrl(), path);
151     }
152 
153     String url = urlHandler.buildUrl(pathToUse, selectors, extension, suffix, disableSuffixSelector);
154     if (StringUtils.isNotEmpty(queryString) || inheritableParameterNames != null) {
155       url = urlHandler.appendQueryString(url, queryString, inheritableParameterNames);
156     }
157     if (StringUtils.isNotEmpty(fragment)) {
158       url = urlHandler.setFragment(url, fragment);
159     }
160     return url;
161   }
162 
163   @Override
164   public String build() {
165     return build(false);
166   }
167 
168   @Override
169   public String buildExternalLinkUrl() {
170     return buildExternalLinkUrl(null);
171   }
172 
173   @Override
174   public String buildExternalLinkUrl(@Nullable Page targetPage) {
175     Page targetPageToUse = targetPage;
176     if (targetPageToUse == null) {
177       targetPageToUse = page;
178     }
179     if (targetPageToUse == null && resource != null) {
180       targetPageToUse = resource.adaptTo(Page.class);
181     }
182     String url = build(true);
183     return urlHandler.externalizeLinkUrl(url, targetPageToUse, urlMode);
184   }
185 
186   @Override
187   public String buildExternalResourceUrl() {
188     return buildExternalResourceUrl(null);
189   }
190 
191   @Override
192   public String buildExternalResourceUrl(@Nullable Resource targetResource) {
193     Resource targetResourceToUse = targetResource;
194     if (targetResourceToUse == null) {
195       targetResourceToUse = resource;
196     }
197     if (targetResourceToUse == null && page != null) {
198       targetResourceToUse = page.adaptTo(Resource.class);
199     }
200     String url = build(true);
201     return urlHandler.externalizeResourceUrl(url, targetResourceToUse, urlMode);
202   }
203 
204 }