diff --git a/all/pom.xml b/all/pom.xml index 3ba2783..6df334b 100644 --- a/all/pom.xml +++ b/all/pom.xml @@ -9,7 +9,7 @@ com.exadel.etoolbox etoolbox-link-inspector - 2.0.2 + 2.0.3 ../pom.xml diff --git a/core/pom.xml b/core/pom.xml index 3416e24..25ff3d3 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -5,7 +5,7 @@ com.exadel.etoolbox etoolbox-link-inspector - 2.0.2 + 2.0.3 ../pom.xml etoolbox-link-inspector.core diff --git a/core/src/main/java/com/exadel/etoolbox/linkinspector/core/services/resolvers/InternalLinkResolverImpl.java b/core/src/main/java/com/exadel/etoolbox/linkinspector/core/services/resolvers/InternalLinkResolverImpl.java index c648ef6..b2425f8 100644 --- a/core/src/main/java/com/exadel/etoolbox/linkinspector/core/services/resolvers/InternalLinkResolverImpl.java +++ b/core/src/main/java/com/exadel/etoolbox/linkinspector/core/services/resolvers/InternalLinkResolverImpl.java @@ -57,6 +57,7 @@ public class InternalLinkResolverImpl implements Resolver { private String internalLinksHost; private boolean enabled; + private boolean checkAsExternal; @Reference private Resolver externalLinkResolver; @@ -66,6 +67,7 @@ public class InternalLinkResolverImpl implements Resolver { private void activate(InternalLinkResolverConfig config) { this.enabled = config.enabled(); this.internalLinksHost = config.internalLinksHost(); + this.checkAsExternal = config.checkAsExternal(); } /** @@ -102,7 +104,7 @@ public void validate(Result result, ResourceResolver resourceResolver) { return; } Status status = checkLink(result.getValue(), resourceResolver); - if (status.getCode() == HttpStatus.SC_NOT_FOUND && StringUtils.isNotBlank(internalLinksHost)) { + if ((status.getCode() == HttpStatus.SC_NOT_FOUND || checkAsExternal) && StringUtils.isNotBlank(internalLinksHost)) { String prefix = StringUtils.startsWithAny(internalLinksHost, HTTP_SCHEMA, HTTPS_SCHEMA) ? EMPTY : HTTPS_SCHEMA; String origin = StringUtils.stripEnd(internalLinksHost, "/"); SlingUriBuilder slingUri = SlingUriBuilder.parse(result.getValue(), resourceResolver); diff --git a/core/src/main/java/com/exadel/etoolbox/linkinspector/core/services/resolvers/configs/InternalLinkResolverConfig.java b/core/src/main/java/com/exadel/etoolbox/linkinspector/core/services/resolvers/configs/InternalLinkResolverConfig.java index 8f162f8..c658015 100644 --- a/core/src/main/java/com/exadel/etoolbox/linkinspector/core/services/resolvers/configs/InternalLinkResolverConfig.java +++ b/core/src/main/java/com/exadel/etoolbox/linkinspector/core/services/resolvers/configs/InternalLinkResolverConfig.java @@ -30,6 +30,12 @@ ) boolean enabled() default true; + @AttributeDefinition( + name = "Check Internal Links over Network", + description = "Check internal links by sending network requests. Internal links host should be specified for this to work properly" + ) + boolean checkAsExternal() default false; + @AttributeDefinition( name = "Internal Links Host", description = "Host to be used for verifying internal links. " + diff --git a/core/src/main/java/com/exadel/etoolbox/linkinspector/core/services/util/SlingUri.java b/core/src/main/java/com/exadel/etoolbox/linkinspector/core/services/util/SlingUri.java deleted file mode 100644 index a9462e7..0000000 --- a/core/src/main/java/com/exadel/etoolbox/linkinspector/core/services/util/SlingUri.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.exadel.etoolbox.linkinspector.core.services.util; - -import java.net.URI; -import java.util.Map; -import java.util.function.Consumer; -import org.apache.sling.api.request.RequestPathInfo; -import org.apache.sling.api.resource.Resource; -import org.osgi.annotation.versioning.ProviderType; - -@ProviderType -public interface SlingUri extends RequestPathInfo { - URI toUri(); - - String toString(); - - String getScheme(); - - String getUserInfo(); - - String getHost(); - - int getPort(); - - String getResourcePath(); - - String getSelectorString(); - - String[] getSelectors(); - - String getExtension(); - - Map getPathParameters(); - - String getSuffix(); - - String getPath(); - - String getQuery(); - - String getFragment(); - - String getSchemeSpecificPart(); - - Resource getSuffixResource(); - - boolean isPath(); - - boolean isAbsolutePath(); - - boolean isRelativePath(); - - boolean isAbsolute(); - - boolean isOpaque(); - - default SlingUri adjust(Consumer builderConsumer) { - SlingUriBuilder builder = SlingUriBuilder.createFrom(this); - builderConsumer.accept(builder); - return builder.build(); - } -} diff --git a/core/src/main/java/com/exadel/etoolbox/linkinspector/core/services/util/SlingUriBuilder.java b/core/src/main/java/com/exadel/etoolbox/linkinspector/core/services/util/SlingUriBuilder.java index c054087..d9d779a 100644 --- a/core/src/main/java/com/exadel/etoolbox/linkinspector/core/services/util/SlingUriBuilder.java +++ b/core/src/main/java/com/exadel/etoolbox/linkinspector/core/services/util/SlingUriBuilder.java @@ -1,17 +1,11 @@ package com.exadel.etoolbox.linkinspector.core.services.util; import lombok.extern.slf4j.Slf4j; -import org.apache.sling.api.SlingHttpServletRequest; -import org.apache.sling.api.request.RequestPathInfo; -import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.osgi.annotation.versioning.ProviderType; -import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -20,24 +14,6 @@ @ProviderType @Slf4j public class SlingUriBuilder { - private static final String HTTPS_SCHEME = "https"; - private static final int HTTPS_DEFAULT_PORT = 443; - private static final String HTTP_SCHEME = "http"; - private static final int HTTP_DEFAULT_PORT = 80; - private static final String FILE_SCHEME = "file"; - static final String CHAR_HASH = "#"; - static final String CHAR_QM = "?"; - static final char CHAR_AMP = '&'; - static final char CHAR_AT = '@'; - static final char CHAR_SEMICOLON = ';'; - static final char CHAR_EQUALS = '='; - static final char CHAR_SINGLEQUOTE = '\''; - static final String CHAR_COLON = ":"; - static final String CHAR_DOT = "."; - static final String CHAR_SLASH = "/"; - static final String SELECTOR_DOT_REGEX = "\\.(?!\\.?/)"; - static final String PATH_PARAMETERS_REGEX = ";([a-zA-z0-9]+)=(?:\\'([^']*)\\'|([^/]+))"; - static final String BEST_EFFORT_INVALID_URI_MATCHER = "^(?:([^:#@]+):)?(?://(?:([^@#]+)@)?([^/#:]+)(?::([0-9]+))?)?(?:([^?#]+))?(?:\\?([^#]*))?(?:#(.*))?$"; private String scheme = null; private String userInfo = null; private String host = null; @@ -51,39 +27,11 @@ public class SlingUriBuilder { private String query = null; private String fragment = null; private ResourceResolver resourceResolver = null; - private boolean isBuilt = false; public static SlingUriBuilder create() { return new SlingUriBuilder(); } - public static SlingUriBuilder createFrom(SlingUri slingUri) { - return create().setScheme(slingUri.getScheme()).setUserInfo(slingUri.getUserInfo()).setHost(slingUri.getHost()).setPort(slingUri.getPort()).setResourcePath(slingUri.getResourcePath()).setPathParameters(slingUri.getPathParameters()).setSelectors(slingUri.getSelectors()).setExtension(slingUri.getExtension()).setSuffix(slingUri.getSuffix()).setQuery(slingUri.getQuery()).setFragment(slingUri.getFragment()).setSchemeSpecificPart(slingUri.isOpaque() ? slingUri.getSchemeSpecificPart() : null).setResourceResolver(slingUri instanceof SlingUriBuilder.ImmutableSlingUri ? ((SlingUriBuilder.ImmutableSlingUri)slingUri).getData().resourceResolver : null); - } - - public static SlingUriBuilder createFrom(Resource resource) { - return create().setResourcePath(resource.getPath()).setResourceResolver(resource.getResourceResolver()); - } - - public static SlingUriBuilder createFrom(RequestPathInfo requestPathInfo) { - Resource suffixResource = requestPathInfo.getSuffixResource(); - return create().setResourceResolver(suffixResource != null ? suffixResource.getResourceResolver() : null).setResourcePath(requestPathInfo.getResourcePath()).setSelectors(requestPathInfo.getSelectors()).setExtension(requestPathInfo.getExtension()).setSuffix(requestPathInfo.getSuffix()); - } - - public static SlingUriBuilder createFrom(SlingHttpServletRequest request) { - ResourceResolver resourceResolver = request.getResourceResolver(); - SlingUriBuilder uriBuilder = createFrom(request.getRequestPathInfo()).setResourceResolver(resourceResolver).setScheme(request.getScheme()).setHost(request.getServerName()).setPort(request.getServerPort()).setQuery(request.getQueryString()); - String resourcePath = uriBuilder.getResourcePath(); - if (resourcePath != null) { - String mappedResourcePath = resourceResolver.map(request, resourcePath); - if (!resourcePath.equals(mappedResourcePath) && request.getPathInfo().startsWith(mappedResourcePath)) { - uriBuilder.setResourcePath(mappedResourcePath); - } - } - - return uriBuilder; - } - public static SlingUriBuilder createFrom(URI uri, ResourceResolver resourceResolver) { String path = uri.getRawPath(); boolean pathExists = isNotBlank(path); @@ -252,24 +200,6 @@ public SlingUriBuilder setSelectors(String[] selectors) { } } - public SlingUriBuilder addSelector(String selector) { - if (this.schemeSpecificPart == null && this.resourcePath != null) { - this.selectors.add(selector); - return this; - } else { - return this; - } - } - - public SlingUriBuilder removeSelector(String selector) { - if (this.schemeSpecificPart == null && this.resourcePath != null) { - this.selectors.remove(selector); - return this; - } else { - return this; - } - } - public SlingUriBuilder setExtension(String extension) { if (this.schemeSpecificPart == null && this.resourcePath != null) { this.extension = extension; @@ -279,21 +209,6 @@ public SlingUriBuilder setExtension(String extension) { } } - public SlingUriBuilder setPathParameter(String key, String value) { - if (this.schemeSpecificPart == null && this.resourcePath != null) { - this.pathParameters.put(key, value); - return this; - } else { - return this; - } - } - - public SlingUriBuilder setPathParameters(Map pathParameters) { - this.pathParameters.clear(); - this.pathParameters.putAll(pathParameters); - return this; - } - public SlingUriBuilder setSuffix(String suffix) { if (this.schemeSpecificPart == null && this.resourcePath != null) { if (suffix != null && !suffix.startsWith("/")) { @@ -316,33 +231,6 @@ public SlingUriBuilder setQuery(String query) { } } - public SlingUriBuilder addQueryParameter(String parameterName, String value) { - if (this.schemeSpecificPart != null) { - return this; - } else { - try { - this.query = (this.query == null ? "" : this.query + '&') + URLEncoder.encode(parameterName, StandardCharsets.UTF_8.name()) + "=" + URLEncoder.encode(value, StandardCharsets.UTF_8.name()); - return this; - } catch (UnsupportedEncodingException e) { - throw new IllegalStateException("Encoding not supported: " + StandardCharsets.UTF_8, e); - } - } - } - - public SlingUriBuilder setQueryParameters(Map queryParameters) { - if (this.schemeSpecificPart != null) { - return this; - } else { - this.setQuery((String)null); - - for(Map.Entry parameter : queryParameters.entrySet()) { - this.addQueryParameter((String)parameter.getKey(), (String)parameter.getValue()); - } - - return this; - } - } - public SlingUriBuilder setFragment(String fragment) { this.fragment = fragment; return this; @@ -358,163 +246,23 @@ public SlingUriBuilder setSchemeSpecificPart(String schemeSpecificPart) { return this; } - public SlingUriBuilder removeSchemeAndAuthority() { - this.setScheme((String)null); - this.setUserInfo((String)null); - this.setHost((String)null); - this.setPort(-1); - return this; - } - - public SlingUriBuilder useSchemeAndAuthority(SlingUri slingUri) { - this.setScheme(slingUri.getScheme()); - this.setUserInfo(slingUri.getUserInfo()); - this.setHost(slingUri.getHost()); - this.setPort(slingUri.getPort()); - return this; - } - - public String getResourcePath() { - return this.resourcePath; - } - - public String getSelectorString() { - return !this.selectors.isEmpty() ? String.join(".", this.selectors) : null; - } - - public String[] getSelectors() { - return (String[])this.selectors.toArray(new String[this.selectors.size()]); - } - public String getExtension() { return this.extension; } - public Map getPathParameters() { - return this.pathParameters; - } - - public String getSuffix() { - return this.suffix; - } - - public Resource getSuffixResource() { - return isNotBlank(this.suffix) && this.resourceResolver != null ? this.resourceResolver.getResource(this.suffix) : null; - } - public String getPath() { return this.assemblePath(true); } - public String getSchemeSpecificPart() { - return this.isOpaque() ? this.schemeSpecificPart : this.toStringInternal(false, false); - } - public String getQuery() { return this.query; } - public String getFragment() { - return this.fragment; - } - - public String getScheme() { - return this.scheme; - } - - public String getHost() { - return this.host; - } - - public int getPort() { - return this.port; - } - - public String getUserInfo() { - return this.userInfo; - } - - public SlingUriBuilder useSchemeAndAuthority(URI uri) { - this.useSchemeAndAuthority(createFrom(uri, this.resourceResolver).build()); - return this; - } - public SlingUriBuilder setResourceResolver(ResourceResolver resourceResolver) { this.resourceResolver = resourceResolver; return this; } - public SlingUri build() { - if (this.isBuilt) { - throw new IllegalStateException("SlingUriBuilder.build() may only be called once per builder instance"); - } else { - this.isBuilt = true; - return new SlingUriBuilder.ImmutableSlingUri(); - } - } - - public String toString() { - return this.toStringInternal(true, true); - } - - public boolean isPath() { - return isBlank(this.scheme) && isBlank(this.host) && isNotBlank(this.resourcePath); - } - - public boolean isAbsolutePath() { - return this.isPath() && this.resourcePath.startsWith("/"); - } - - public boolean isRelativePath() { - return this.isPath() && !this.resourcePath.startsWith("/"); - } - - public boolean isAbsolute() { - return this.scheme != null; - } - - public boolean isOpaque() { - return this.scheme != null && this.schemeSpecificPart != null; - } - - private String toStringInternal(boolean includeScheme, boolean includeFragment) { - StringBuilder requestUri = new StringBuilder(); - if (includeScheme && this.isAbsolute()) { - requestUri.append(this.scheme + ":"); - } - - if (this.host != null) { - requestUri.append("//"); - if (isNotBlank(this.userInfo)) { - requestUri.append(this.userInfo + '@'); - } - - requestUri.append(this.host); - if (this.port > 0 && (!"http".equals(this.scheme) || this.port != 80) && (!"https".equals(this.scheme) || this.port != 443)) { - requestUri.append(":"); - requestUri.append(this.port); - } - } - - if (this.schemeSpecificPart != null) { - requestUri.append(this.schemeSpecificPart); - } - - if (this.resourcePath != null) { - requestUri.append(this.assemblePath(true)); - } - - if (this.query != null) { - requestUri.append("?" + this.query); - } - - if (includeFragment && this.fragment != null) { - requestUri.append("#" + this.fragment); - } - - return requestUri.toString(); - } - private void setPathWithDefinedResourcePosition(String path, int firstDotPositionAfterResourcePath) { this.setResourcePath(path.substring(0, firstDotPositionAfterResourcePath)); int firstSlashAfterFirstDotPosition = path.indexOf("/", firstDotPositionAfterResourcePath); @@ -590,232 +338,6 @@ private String assemblePath(boolean includePathParamters) { } } - private class ImmutableSlingUri implements SlingUri { - private ImmutableSlingUri() { - } - - public String getResourcePath() { - return this.getData().getResourcePath(); - } - - public String getSelectorString() { - return this.getData().getSelectorString(); - } - - public String[] getSelectors() { - return this.getData().getSelectors(); - } - - public String getExtension() { - return this.getData().getExtension(); - } - - public Map getPathParameters() { - return Collections.unmodifiableMap(this.getData().getPathParameters()); - } - - public String getSuffix() { - return this.getData().getSuffix(); - } - - public String getPath() { - return this.getData().getPath(); - } - - public String getSchemeSpecificPart() { - return this.getData().getSchemeSpecificPart(); - } - - public String getQuery() { - return this.getData().getQuery(); - } - - public String getFragment() { - return this.getData().getFragment(); - } - - public String getScheme() { - return this.getData().getScheme(); - } - - public String getHost() { - return this.getData().getHost(); - } - - public int getPort() { - return this.getData().getPort(); - } - - public Resource getSuffixResource() { - return this.getData().getSuffixResource(); - } - - public String getUserInfo() { - return this.getData().getUserInfo(); - } - - public boolean isOpaque() { - return this.getData().isOpaque(); - } - - public boolean isPath() { - return this.getData().isPath(); - } - - public boolean isAbsolutePath() { - return this.getData().isAbsolutePath(); - } - - public boolean isRelativePath() { - return this.getData().isRelativePath(); - } - - public boolean isAbsolute() { - return this.getData().isAbsolute(); - } - - public String toString() { - return this.getData().toString(); - } - - public URI toUri() { - String uriString = this.toString(); - - try { - return new URI(uriString); - } catch (URISyntaxException e) { - throw new IllegalStateException("Invalid Sling URI: " + uriString, e); - } - } - - private SlingUriBuilder getData() { - return SlingUriBuilder.this; - } - - public int hashCode() { - int prime = 31; - int result = 1; - result = 31 * result + (SlingUriBuilder.this.extension == null ? 0 : SlingUriBuilder.this.extension.hashCode()); - result = 31 * result + (SlingUriBuilder.this.fragment == null ? 0 : SlingUriBuilder.this.fragment.hashCode()); - result = 31 * result + (SlingUriBuilder.this.host == null ? 0 : SlingUriBuilder.this.host.hashCode()); - result = 31 * result + SlingUriBuilder.this.pathParameters.hashCode(); - result = 31 * result + SlingUriBuilder.this.port; - result = 31 * result + (SlingUriBuilder.this.query == null ? 0 : SlingUriBuilder.this.query.hashCode()); - result = 31 * result + (SlingUriBuilder.this.resourcePath == null ? 0 : SlingUriBuilder.this.resourcePath.hashCode()); - result = 31 * result + (SlingUriBuilder.this.scheme == null ? 0 : SlingUriBuilder.this.scheme.hashCode()); - result = 31 * result + SlingUriBuilder.this.schemeSpecificPart == null ? 0 : SlingUriBuilder.this.schemeSpecificPart.hashCode(); - result = 31 * result + SlingUriBuilder.this.selectors.hashCode(); - result = 31 * result + (SlingUriBuilder.this.suffix == null ? 0 : SlingUriBuilder.this.suffix.hashCode()); - result = 31 * result + (SlingUriBuilder.this.userInfo == null ? 0 : SlingUriBuilder.this.userInfo.hashCode()); - return result; - } - - public boolean equals(Object obj) { - if (this == obj) { - return true; - } else if (obj == null) { - return false; - } else if (this.getClass() != obj.getClass()) { - return false; - } else { - SlingUriBuilder.ImmutableSlingUri other = (SlingUriBuilder.ImmutableSlingUri)obj; - if (SlingUriBuilder.this.extension == null) { - if (other.getData().extension != null) { - return false; - } - } else if (!SlingUriBuilder.this.extension.equals(other.getData().extension)) { - return false; - } - - if (SlingUriBuilder.this.fragment == null) { - if (other.getData().fragment != null) { - return false; - } - } else if (!SlingUriBuilder.this.fragment.equals(other.getData().fragment)) { - return false; - } - - if (SlingUriBuilder.this.host == null) { - if (other.getData().host != null) { - return false; - } - } else if (!SlingUriBuilder.this.host.equals(other.getData().host)) { - return false; - } - - if (SlingUriBuilder.this.pathParameters == null) { - if (other.getData().pathParameters != null) { - return false; - } - } else if (!SlingUriBuilder.this.pathParameters.equals(other.getData().pathParameters)) { - return false; - } - - if (SlingUriBuilder.this.port != other.getData().port) { - return false; - } else { - if (SlingUriBuilder.this.query == null) { - if (other.getData().query != null) { - return false; - } - } else if (!SlingUriBuilder.this.query.equals(other.getData().query)) { - return false; - } - - if (SlingUriBuilder.this.resourcePath == null) { - if (other.getData().resourcePath != null) { - return false; - } - } else if (!SlingUriBuilder.this.resourcePath.equals(other.getData().resourcePath)) { - return false; - } - - if (SlingUriBuilder.this.scheme == null) { - if (other.getData().scheme != null) { - return false; - } - } else if (!SlingUriBuilder.this.scheme.equals(other.getData().scheme)) { - return false; - } - - if (SlingUriBuilder.this.schemeSpecificPart == null) { - if (other.getData().schemeSpecificPart != null) { - return false; - } - } else if (!SlingUriBuilder.this.schemeSpecificPart.equals(other.getData().schemeSpecificPart)) { - return false; - } - - if (SlingUriBuilder.this.selectors == null) { - if (other.getData().selectors != null) { - return false; - } - } else if (!SlingUriBuilder.this.selectors.equals(other.getData().selectors)) { - return false; - } - - if (SlingUriBuilder.this.suffix == null) { - if (other.getData().suffix != null) { - return false; - } - } else if (!SlingUriBuilder.this.suffix.equals(other.getData().suffix)) { - return false; - } - - if (SlingUriBuilder.this.userInfo == null) { - if (other.getData().userInfo != null) { - return false; - } - } else if (!SlingUriBuilder.this.userInfo.equals(other.getData().userInfo)) { - return false; - } - - return true; - } - } - } - } - private class ResourcePathIterator implements Iterator { private String nextPath; diff --git a/pom.xml b/pom.xml index 50ba72c..74805bd 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.exadel.etoolbox etoolbox-link-inspector pom - 2.0.2 + 2.0.3 EToolbox Link Inspector Searches and modifies broken links and other textual patterns in AEM repositories https://github.com/exadel-inc/etoolbox-link-inspector diff --git a/ui.apps.structure/pom.xml b/ui.apps.structure/pom.xml index d72d677..ef38b29 100644 --- a/ui.apps.structure/pom.xml +++ b/ui.apps.structure/pom.xml @@ -8,7 +8,7 @@ com.exadel.etoolbox etoolbox-link-inspector - 2.0.2 + 2.0.3 ../pom.xml diff --git a/ui.apps/pom.xml b/ui.apps/pom.xml index 4e12e34..d124726 100644 --- a/ui.apps/pom.xml +++ b/ui.apps/pom.xml @@ -8,7 +8,7 @@ com.exadel.etoolbox etoolbox-link-inspector - 2.0.2 + 2.0.3 ../pom.xml diff --git a/ui.config/pom.xml b/ui.config/pom.xml index ac6041c..4ab7d3e 100644 --- a/ui.config/pom.xml +++ b/ui.config/pom.xml @@ -8,7 +8,7 @@ com.exadel.etoolbox etoolbox-link-inspector - 2.0.2 + 2.0.3 ../pom.xml diff --git a/ui.content/pom.xml b/ui.content/pom.xml index d787683..73b1874 100644 --- a/ui.content/pom.xml +++ b/ui.content/pom.xml @@ -8,7 +8,7 @@ com.exadel.etoolbox etoolbox-link-inspector - 2.0.2 + 2.0.3 ../pom.xml diff --git a/ui.content/src/main/content/META-INF/vault/filter.xml b/ui.content/src/main/content/META-INF/vault/filter.xml index 020ce05..f91b9d3 100644 --- a/ui.content/src/main/content/META-INF/vault/filter.xml +++ b/ui.content/src/main/content/META-INF/vault/filter.xml @@ -16,14 +16,14 @@ - - + + - + - + \ No newline at end of file