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