Index: AbstractIdeaMojo.java =================================================================== --- AbstractIdeaMojo.java (revision 564066) +++ AbstractIdeaMojo.java (working copy) @@ -40,8 +40,8 @@ import org.apache.maven.project.MavenProject; import org.apache.maven.project.ProjectBuildingException; import org.apache.maven.project.artifact.InvalidDependencyVersionException; +import org.codehaus.plexus.util.xml.Xpp3Dom; import org.codehaus.plexus.util.StringUtils; -import org.codehaus.plexus.util.xml.Xpp3Dom; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; @@ -50,14 +50,7 @@ import java.io.File; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * @author Edwin Punzalan @@ -211,21 +204,56 @@ */ protected String toRelative( File basedir, String absolutePath ) { - String relative; + // Get character arrays for the paths and find the equal prefixes. + final char[] basedirChars = StringUtils.replace(basedir.getAbsolutePath(), "\\", "/").toCharArray(); + final char[] absolutePathChars = StringUtils.replace(absolutePath, "\\", "/").toCharArray(); + int firstUnequalCharPos = 0; + for (; firstUnequalCharPos < Math.min(basedirChars.length, absolutePathChars.length); ++firstUnequalCharPos) + { + if (basedirChars[firstUnequalCharPos] != absolutePathChars[firstUnequalCharPos]) + { + break; + } + } - if ( absolutePath.startsWith( basedir.getAbsolutePath() ) - && absolutePath.length() > basedir.getAbsolutePath().length() ) + // Build a relative path if the paths share an ancestor directory. + final String relativePath; + if (0 == firstUnequalCharPos) { - relative = absolutePath.substring( basedir.getAbsolutePath().length() + 1 ); + relativePath = absolutePath; } else { - relative = absolutePath; + // If basedir and absolutePath are both subdirectories of a common parent, then we will have to ".." to + // that parent and concatenate the unequal part of absolutePath. + final StringBuffer relativePathBuffer = new StringBuffer(); + if (firstUnequalCharPos < basedirChars.length || '/' != absolutePathChars[firstUnequalCharPos]) + { + for (int i = firstUnequalCharPos; i < basedirChars.length; ++i) + { + if ('/' == basedirChars[i] && i < basedirChars.length - 1) + { + relativePathBuffer.append("../"); + } + } + relativePathBuffer.append("../"); + } + + // We've now appended enough ".." elements to get us to the common directory. Now append the unequal + // part of absolutePath, from the last separator character in the equal part. + int lastSeparatorIndex = firstUnequalCharPos; + for (; lastSeparatorIndex >= 0; --lastSeparatorIndex) + { + if ('/' == absolutePathChars[lastSeparatorIndex]) + { + break; + } + } + relativePathBuffer.append(absolutePathChars, lastSeparatorIndex + 1, absolutePathChars.length - + lastSeparatorIndex - 1); + relativePath = relativePathBuffer.toString(); } - - relative = StringUtils.replace( relative, "\\", "/" ); - - return relative; + return relativePath; } /**