@Override public HttpResponse handle( Item item, ItemGroup<?> destination, AtomicReference<Item> newItem, List<? extends RelocationHandler> chain) throws IOException, InterruptedException { if (!(destination instanceof DirectlyModifiableTopLevelItemGroup)) { return chain.isEmpty() ? null : chain.get(0).handle(item, destination, newItem, chain.subList(1, chain.size())); } Item result = doMove(item, (DirectlyModifiableTopLevelItemGroup) destination); newItem.set(result); // AbstractItem.getUrl does weird magic here which winds up making it redirect to the old // location, so inline the correct part of this method. return HttpResponses.redirectViaContextPath(result.getParent().getUrl() + result.getShortUrl()); }
/** Computes the relative path from the current page to the given item. */ public static String getRelativeLinkTo(Item p) { Map<Object, String> ancestors = new HashMap<Object, String>(); View view = null; StaplerRequest request = Stapler.getCurrentRequest(); for (Ancestor a : request.getAncestors()) { ancestors.put(a.getObject(), a.getRelativePath()); if (a.getObject() instanceof View) view = (View) a.getObject(); } String path = ancestors.get(p); if (path != null) return path; Item i = p; String url = ""; while (true) { ItemGroup ig = i.getParent(); url = i.getShortUrl() + url; if (ig == Hudson.getInstance()) { assert i instanceof TopLevelItem; if (view != null && view.contains((TopLevelItem) i)) { // if p and the current page belongs to the same view, then return a relative path return ancestors.get(view) + '/' + url; } else { // otherwise return a path from the root Hudson return request.getContextPath() + '/' + p.getUrl(); } } path = ancestors.get(ig); if (path != null) return path + '/' + url; assert ig instanceof Item; // if not, ig must have been the Hudson instance i = (Item) ig; } }