1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 package org.devacfr.maven.skins.reflow; 20 21 import java.net.URI; 22 23 import javax.annotation.Nonnull; 24 import javax.annotation.Nullable; 25 26 import org.apache.maven.doxia.site.inheritance.URIPathDescriptor; 27 import org.apache.velocity.tools.config.DefaultKey; 28 29 import com.google.common.base.Strings; 30 31 /** 32 * An Apache Velocity tool that provides utility methods to work with URIs/URLs and links. 33 * 34 * @author Andrius Velykis 35 * @since 1.0 36 */ 37 // instancied by Velocity 38 @SuppressWarnings({ "checkstyle:finalclass", "checkstyle:hideutilityclassconstructor" }) 39 @DefaultKey("uriTool") 40 public class URITool { 41 42 /** 43 * Resolves the link as relative to the base dir URI. 44 * <p> 45 * Relativizes only absolute links, if the link has the same scheme, host and port as the base, it is made into a 46 * relative link as viewed from the base. 47 * </p> 48 * <p> 49 * This is the same method that's used to relativize project links in Maven site. 50 * </p> 51 * 52 * @param baseDirUri 53 * URI that will serve as the base to calculate the relative one 54 * @param link 55 * The link to relativize (make it relative to the base URI if possible) 56 * @return the relative link, if calculated, or the original link if not. 57 * @since 1.0 58 */ 59 @Nullable public static String relativizeLink(@Nullable final String baseDirUri, @Nullable final String link) { 60 // taken from 61 // org.apache.maven.doxia.site.decoration.inheritance.DecorationModelInheritanceAssembler 62 63 if (link == null || baseDirUri == null) { 64 return link; 65 } 66 try { 67 final URIPathDescriptor path = new URIPathDescriptor(baseDirUri, link); 68 return normalisedBaseUrl(path.relativizeLink().toString()); 69 } catch (final IllegalArgumentException e) { 70 return link; 71 } 72 } 73 74 /** 75 * Creates a URI by parsing the given string. 76 * 77 * @param uri 78 * The string to be parsed into a URI 79 * @return Returns the new URI. 80 */ 81 @Nonnull 82 public static URI toURI(@Nonnull final String uri) { 83 return URI.create(uri); 84 } 85 86 /** 87 * @param parentBaseUrl 88 * The base URI. Has to be a valid absolute URI. In addition, the path of the URI should not have any 89 * file part, ie <code>http://maven.apache.org/</code> is valid, 90 * <code>http://maven.apache.org/index.html</code> is not. 91 * @param childBaseUrl 92 * the new base URI. Has to be parsable as a URI. 93 * @return Returns new instance of {@link URLRebaser} allowing to calculate/relative the link as viewed from a 94 * different base. This returns the {@code parentBaseUrl} link if link is absolute. 95 * @see URIPathDescriptor#rebaseLink(String) 96 * @see URLRebaser#rebaseLink(String) 97 */ 98 public static URLRebaser createURLRebaser(@Nullable final String parentBaseUrl, 99 @Nullable final String childBaseUrl) { 100 return new URLRebaser(parentBaseUrl, childBaseUrl); 101 } 102 103 /** 104 * remove url path separator ('/') to the end of path. 105 * 106 * @param baseUrl 107 * a base url 108 * @return Returns a <code>String</code> representing base path instance. 109 */ 110 @Nullable public static String normalisedBaseUrl(@Nullable final String baseUrl) { 111 if (Strings.isNullOrEmpty(baseUrl)) { 112 return baseUrl; 113 } 114 if (baseUrl.endsWith("/")) { 115 return baseUrl.substring(0, baseUrl.length() - 1); 116 } 117 118 return baseUrl; 119 } 120 121 /** 122 * URL rebaser: based on an old and a new path, can rebase a link based on old path to a value based on the new 123 * path. 124 */ 125 public static class URLRebaser { 126 127 /** */ 128 private final String oldPath; 129 130 /** */ 131 private final String newPath; 132 133 /** 134 * Construct a URL rebaser. 135 * 136 * @param oldPath 137 * the old path. The base URI. Has to be a valid absolute URI. In addition, the path of the URI 138 * should not have any file part, ie <code>http://maven.apache.org/</code> is valid, 139 * <code>http://maven.apache.org/index.html</code> is not. 140 * @param newPath 141 * the new base URI. Has to be parsable as a URI. 142 */ 143 protected URLRebaser(@Nullable final String oldPath, @Nullable final String newPath) { 144 this.oldPath = oldPath; 145 this.newPath = newPath; 146 } 147 148 /** 149 * Get the new path. 150 * 151 * @return the new path. 152 */ 153 @Nullable public String getNewPath() { 154 return this.newPath; 155 } 156 157 /** 158 * Get the old path. 159 * 160 * @return the old path. 161 */ 162 @Nullable public String getOldPath() { 163 return this.oldPath; 164 } 165 166 /** 167 * Rebase only affects relative links, a relative link wrt an old base gets translated, so it points to the same 168 * location as viewed from a new base. 169 * 170 * @param link 171 * link to rebase 172 * @return Returns a {@link String} representing link rebased. 173 */ 174 public String rebaseLink(@Nullable final String link) { 175 if (link == null || getOldPath() == null) { 176 return link; 177 } 178 179 if (link.contains("${project.")) { 180 throw new IllegalArgumentException("site.xml late interpolation ${project.*} expression found" 181 + " in link: '" + link + "'. Use early interpolation ${this.*}"); 182 } 183 184 final URIPathDescriptor oldPath = new URIPathDescriptor(getOldPath(), link); 185 186 return oldPath.rebaseLink(getNewPath()).toString(); 187 } 188 } 189 }