throws IOException, RendererException {
String fragmentName = destination.getName();
// Create an anchor tag for this fragment
FraglinkAttributes a = new FraglinkAttributes();
MarinerURL rootPageURL = pageContext.getRootPageURL(true);
String inclusionPath =
pageContext.getDeviceLayoutContext().getInclusionPath();
// Get the key to the current fragmentation state.
int currentKey = pageContext.getFragmentationIndex();
if (toEnclosing) {
if (logger.isDebugEnabled()) {
logger.debug("Generating link to enclosing fragment");
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("Generating link to enclosed fragment");
}
}
String requestValue;
PageGenerationCache pageGenerationCache
= pageContext.getPageGenerationCache();
RuntimeDeviceLayout deviceLayout =
pageContext.getDeviceLayout();
String defaultFragmentName = deviceLayout.getDefaultFragmentName();
boolean isDefault = true;
if (defaultFragmentName == null
|| !fragmentName.equals(defaultFragmentName)) {
isDefault = false;
}
// If we are generating a link to the enclosing fragment and this is
// the top inclusion then we do not need to add a vfrag value to the
// URL.
if (toEnclosing && inclusionPath == null && isDefault) {
if (logger.isDebugEnabled()) {
logger.debug("Returning to default top level fragment");
}
requestValue = null;
} else {
// The change to apply to the fragmentation state.
FragmentationState.Change change;
// If the enclosing fragment is the default fragment for the layout
// then discard the information about it, this reduces the number
// of possible fragmentation states for a particular layout which
// reduces the memory usage.
change = new FragmentationState.FragmentChange(inclusionPath,
fragmentName,
toEnclosing,
isDefault);
if (logger.isDebugEnabled()) {
logger.debug("Change to be applied is " + change);
}
int changeIndex = pageGenerationCache.
getFragmentationStateChangeIndex(change);
requestValue = PageGenerationCache.
makeFragmentChangeSpecifier(currentKey, changeIndex);
}
if (logger.isDebugEnabled()) {
logger.debug("URL before is "
+ rootPageURL.getExternalForm());
}
if (requestValue == null) {
rootPageURL.removeParameter(URLConstants.FRAGMENTATION_PARAMETER);
} else {
rootPageURL.setParameterValue(URLConstants.FRAGMENTATION_PARAMETER,
requestValue);
}
// Get the URLRewriter to use to encode session information in the
// URL and use it.
MarinerRequestContext requestContext = pageContext.getRequestContext();
URLRewriter sessionURLRewriter = pageContext.getSessionURLRewriter();
MarinerURL sessionURL
= sessionURLRewriter.mapToExternalURL(requestContext,
rootPageURL);
// perform any URL rewriting that may be required by an external plugin
PageURLRewriter urlRewriter = pageContext.getVolantisBean().
getLayoutURLRewriter();
MarinerURL externalURL =
urlRewriter.rewriteURL(pageContext.getRequestContext(),
sessionURL,
PageURLDetailsFactory.createPageURLDetails(
PageURLType.FRAGMENT));
String absoluteLink = externalURL.getExternalForm();
if (logger.isDebugEnabled()) {
logger.debug("URL after Rewriting is " + absoluteLink);
}
a.setInList(isInList);
a.setHref(absoluteLink);
a.setTagName("a");
// Calculate the style class for this link.
// We can either use the new link class defined on the source fragment
// or, if that is not present we should fall back to the old hardcoded
// "fraglinks" class.
// Note that we don't use the destination fragment link class, as this
// would mean that each fragment link on a page would appear in a
// different style - yuck!
String styleClass = source.getLinkClass();
if (styleClass == null) {
styleClass = "fraglinks";
}
// Get the styles associated with the fragment.
FormatStylingEngine formatStylingEngine =
formatRendererContext.getFormatStylingEngine();
Styles styles = formatStylingEngine.startStyleable(source, styleClass);
a.setStyles(styles);
if (pageContext.getPageTagId() != null) {
a.setId(pageContext.getPageTagId());
}
a.setName(fragmentName);
final OutputBuffer linkBuffer = getLinkBuffer(destination, toEnclosing);
a.setLinkText(linkBuffer);
VolantisProtocol protocol = pageContext.getProtocol();
try {
protocol.writeFragmentLink(a);
} catch (ProtocolException pe) {