1 16 package org.outerj.daisy.frontend; 17 18 import org.apache.cocoon.transformation.AbstractTransformer; 19 import org.apache.cocoon.environment.SourceResolver; 20 import org.apache.cocoon.environment.Request; 21 import org.apache.cocoon.environment.ObjectModelHelper; 22 import org.apache.cocoon.ProcessingException; 23 import org.apache.cocoon.components.flow.FlowHelper; 24 import org.apache.avalon.framework.parameters.Parameters; 25 import org.apache.commons.jxpath.JXPathContext; 26 import org.xml.sax.SAXException ; 27 import org.xml.sax.Attributes ; 28 import org.xml.sax.helpers.AttributesImpl ; 29 import org.outerj.daisy.frontend.components.siteconf.SiteConf; 30 import org.outerj.daisy.frontend.util.DaisyLinkUtil; 31 import org.outerj.daisy.util.Constants; 32 import org.outerj.daisy.repository.VariantKey; 33 34 import java.util.Map ; 35 import java.util.regex.Matcher ; 36 import java.io.IOException ; 37 38 public class DaisyLinkTransformer extends AbstractTransformer { 39 private String mountPoint; 40 private SiteConf siteConf; 41 private VariantKey documentKey; 42 43 private static final String LT_NAMESPACE = "http://outerx.org/daisy/1.0#linktransformer"; 44 private static final String PUBLISHER_NAMESPACE = "http://outerx.org/daisy/1.0#publisher"; 45 46 public void setup(SourceResolver sourceResolver, Map objectModel, String s, Parameters parameters) throws ProcessingException, SAXException , IOException { 47 Request request = ObjectModelHelper.getRequest(objectModel); 48 siteConf = WikiHelper.getSiteConf(request); 49 mountPoint = WikiHelper.getMountPoint(request); 50 51 Object flowContext = FlowHelper.getContextObject(objectModel); 52 JXPathContext jxpc = JXPathContext.newContext(flowContext); 53 documentKey = (VariantKey)jxpc.getValue("/documentKey"); 54 if (documentKey == null) 55 throw new ProcessingException("Unexpected error in DaisyLinkTransformer: documentKey is missing in flow context."); 56 } 57 58 public void recycle() { 59 super.recycle(); 60 this.documentKey = null; 61 } 62 63 public void startElement(String namespaceURI, String localName, String qName, Attributes attributes) throws SAXException { 64 if (namespaceURI.equals(Constants.DAISY_NAMESPACE) && localName.equals("link")) { 65 attributes = translateLink(attributes, "target"); 66 } else if (localName.equals("a") && namespaceURI.equals("")) { 67 attributes = translateLink(attributes, "href"); 68 } else if (localName.equals("img") && namespaceURI.equals("")) { 69 attributes = translateLink(attributes, "src"); 70 } else if (localName.equals("span") && namespaceURI.equals("") && "crossreference".equals(attributes.getValue("class"))) { 71 attributes = translateLink(attributes, "crossRefTarget"); 73 } 74 75 super.startElement(namespaceURI, localName, qName, attributes); 76 } 77 78 Attributes translateLink(Attributes attributes, String linkAttrName) { 79 String href = attributes.getValue(linkAttrName); 80 if (href != null) { 81 Matcher matcher = Constants.DAISY_LINK_PATTERN.matcher(href); 82 if (matcher.matches()) { 83 String navigationPath = attributes.getValue(PUBLISHER_NAMESPACE, "navigationPath"); 84 85 String documentId = matcher.group(1); 86 String version = matcher.group(7); 87 88 String partLink = attributes.getValue(LT_NAMESPACE, "partLink"); 89 String fileName = attributes.getValue(LT_NAMESPACE, "fileName"); 90 fileName = fileName != null && fileName.length() != 0 ? "/" + fileName : ""; 91 92 StringBuffer path = new StringBuffer (300); 93 path.append(mountPoint).append('/').append(siteConf.getName()); 94 if (navigationPath != null) 95 path.append(navigationPath); 96 else 97 path.append('/').append(documentId); 98 99 if (partLink != null) { 100 if (version == null) 101 version = "default"; 102 path.append("/version/").append(version).append("/part/").append(partLink).append("/data").append(fileName); 103 } else if (version != null) { 104 path.append("/version/").append(version); 105 } else { 106 path.append(".html"); 107 } 108 109 path.append(DaisyLinkUtil.getBranchLangQueryString(matcher, siteConf, documentKey.getBranchId(), documentKey.getLanguageId())); 110 111 String fragmentIdentifier = matcher.group(8); 112 if (fragmentIdentifier != null && !fragmentIdentifier.startsWith("#dsy")) { 113 fragmentIdentifier = "#dsy" + documentId + "_" + fragmentIdentifier.substring(1); 114 path.append(fragmentIdentifier); 115 } 116 117 AttributesImpl newAttributes = copyAttributesExceptHrefAndOwn(attributes, linkAttrName); 118 newAttributes.addAttribute("", linkAttrName, linkAttrName, "CDATA", path.toString()); 119 attributes = newAttributes; 120 } else if (href.startsWith("#") && !href.startsWith("#dsy")) { 121 String newHref = "#dsy" + documentKey.getDocumentId() + "_" + href.substring(1); 122 AttributesImpl newAttributes = new AttributesImpl (attributes); 123 newAttributes.setAttribute(newAttributes.getIndex("", linkAttrName), "", linkAttrName, linkAttrName, "CDATA", newHref); 124 attributes = newAttributes; 125 } 126 } 127 return attributes; 128 } 129 130 private AttributesImpl copyAttributesExceptHrefAndOwn(Attributes attrs, String linkAttrName) { 131 AttributesImpl newAttrs = new AttributesImpl (); 132 for (int i = 0; i < attrs.getLength(); i++) { 133 if (!attrs.getURI(i).equals(LT_NAMESPACE) && !attrs.getURI(i).equals(PUBLISHER_NAMESPACE) 134 && !(attrs.getLocalName(i).equals(linkAttrName) && attrs.getURI(i).equals(""))) { 135 newAttrs.addAttribute(attrs.getURI(i), attrs.getLocalName(i), attrs.getQName(i), attrs.getType(i), attrs.getValue(i)); 136 } 137 } 138 return newAttrs; 139 } 140 141 } 142 | Popular Tags |