package org.madore.damlengine; import java.util.regex.Pattern; import java.util.regex.Matcher; import org.w3c.dom.*; public class TodoWrefAttr extends TodoAttr { public static class Factory extends TodoAttr.Factory { @Override public TodoWrefAttr newItem(Attr attr, Element owner, Context ctx, TodoItem caller) { return new TodoWrefAttr(attr, owner, ctx, caller); } } public TodoWrefAttr(Attr attr, Element owner, Context ctx, TodoItem caller) { super(attr, owner, ctx, caller); } @Override public void handle() { final String wrefStr = attr.getValue(); final Matcher wrefMatcher = Pattern.compile("^\\#d\\.(\\d{4})-(\\d{2})-(\\d{2})\\.(\\d{4})(|\\..*)$").matcher(wrefStr); if ( ! wrefMatcher.matches() ) throw new IllegalArgumentException("wref attribute must be of the form #d.YYYY-MM-DD.NNNN[.xxx]"); final String wrefYearStr = wrefMatcher.group(1); final String wrefMonthStr = wrefMatcher.group(2); final String wrefDayStr = wrefMatcher.group(3); final String wrefNumberStr = wrefMatcher.group(4); final int wrefNumber = Integer.parseInt(wrefNumberStr); final String wrefSupplementStr = wrefMatcher.group(5); String wrefCat; if ( this.owner.hasAttributeNS(DamlEngine.DAML_NS, "wrefcat") ) { wrefCat = this.owner.getAttributeNS(DamlEngine.DAML_NS, "wrefcat"); this.owner.removeAttributeNS(DamlEngine.DAML_NS, "wrefcat"); } else { wrefCat = null; } final String baseDir = (ctx.gc.uriToTop==null)?"":(ctx.gc.uriToTop+"weblog/"); final WeblogSummary wsum = WeblogSummary.getSummary(ctx.dc); final WeblogSummary.EntrySummary esum; // Get entry for target link from weblog summary if ( wsum != null && wsum.entries != null ) esum = wsum.entries.get(wrefNumber); else esum = null; // Check consistency if summary was available if ( esum != null ) { if ( ! ((wrefYearStr+"-"+wrefMonthStr+"-"+wrefDayStr) .equals(esum.date)) ) throw new IllegalArgumentException("date mismatch for reference to entry "+wrefNumberStr); if ( wrefCat != null && ! wrefCat.equals("@month") && ! wrefCat.equals("@single") ) { if ( esum.catSet == null || ! esum.catSet.contains(wrefCat) ) throw new IllegalArgumentException("reference to entry "+wrefNumberStr+" in wrong category "+wrefCat); } } // Prepare link object final WeblogLink lk; if ( esum != null && esum.specialName != null ) lk = new WeblogLink(wrefYearStr, wrefMonthStr, wrefDayStr, wrefNumberStr, wrefSupplementStr, esum.specialName); else lk = new WeblogLink(wrefYearStr, wrefMonthStr, wrefDayStr, wrefNumberStr, wrefSupplementStr); // Decide whether link target is on this page final boolean onThisPage; if ( esum != null && esum.hasCut && ! lk.supplementStr.equals("") ) { // Linking to a _fragment_ of an entry that has a cut-here element. if ( ctx.wsc != null && ctx.wsc.sel != null && ctx.wsc instanceof Context.WeblogSingleSelectionContext && ((Context.WeblogSingleSelectionContext)ctx.wsc).number == wrefNumber ) onThisPage = true; else onThisPage = false; } else { if ( ctx.wsc != null && ctx.wsc.sel != null && ctx.wsc.sel.contains(wrefNumber) ) onThisPage = true; else onThisPage = false; } // Choose file portion of link target if ( onThisPage ) lk.setTypeRelative(); else if ( wrefCat == null ) lk.setTypeStandard(); else if ( wrefCat.equals("@month") ) lk.setTypeMonth(); else if ( wrefCat.equals("@single") ) lk.setTypeSingle(); else lk.setTypeCat(wrefCat); // Construct full link target String target = lk.getTarget(baseDir); // Class and title attributes if ( ! this.owner.hasAttributeNS(null, "class") ) this.owner.setAttributeNS(null, "class", "weblog-internal-link"); if ( wrefSupplementStr.equals("") && ! this.owner.hasAttributeNS(null, "title") && esum != null && esum.title != null ) this.owner.setAttributeNS(null, "title", esum.title); // Replace this attribute by computed target this.owner.removeAttributeNode(this.attr); this.owner.setAttributeNS(null, "href", target); } }