code: public static String getCanonicalName(ItemGroup context, String path) {
          String[] c = context.getFullName().split("/");
          String[] p = path.split("/");
  
          Stack<String> name = new Stack<>();
          for (int i=0; i<c.length;i++) {
              if (i==0 && c[i].equals("")) continue;
              name.push(c[i]);
          }
          for (int i=0; i<p.length;i++) {
              if (i==0 && p[i].equals("")) {
                  // Absolute path starting with a "/"
                  name.clear();
                  continue;
              }
              if (p[i].equals("..")) {
                  if (name.size() == 0) {
                      throw new IllegalArgumentException(String.format(
                              "Illegal relative path '%s' within context '%s'", path, context.getFullName()
                      ));
                  }
                  name.pop();
                  continue;
              }
              if (p[i].equals(".")) {
                  continue;
              }
              name.push(p[i]);
          }
          return StringUtils.join(name, '/');
      }
docs: Computes the canonical full name of a relative path in an {@link ItemGroup} context, handling relative
  positions ".." and "." as absolute path starting with "/". The resulting name is the item fullName from Jenkins
  root.