DaisyLinkTransformer.java :  » Content-Management-System » daisy » org » outerj » daisy » frontend » Java Open Source

Java Open Source » Content Management System » daisy 
daisy » org » outerj » daisy » frontend » DaisyLinkTransformer.java
/*
 * Copyright 2004 Outerthought bvba and Schaubroeck nv
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.outerj.daisy.frontend;

import org.apache.cocoon.transformation.AbstractTransformer;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.components.flow.FlowHelper;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.commons.jxpath.JXPathContext;
import org.xml.sax.SAXException;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.AttributesImpl;
import org.outerj.daisy.frontend.components.siteconf.SiteConf;
import org.outerj.daisy.frontend.util.DaisyLinkUtil;
import org.outerj.daisy.util.Constants;
import org.outerj.daisy.repository.VariantKey;

import java.util.Map;
import java.util.regex.Matcher;
import java.io.IOException;

public class DaisyLinkTransformer extends AbstractTransformer {
    private String mountPoint;
    private SiteConf siteConf;
    private VariantKey documentKey;

    private static final String LT_NAMESPACE = "http://outerx.org/daisy/1.0#linktransformer";
    private static final String PUBLISHER_NAMESPACE = "http://outerx.org/daisy/1.0#publisher";

    public void setup(SourceResolver sourceResolver, Map objectModel, String s, Parameters parameters) throws ProcessingException, SAXException, IOException {
        Request request = ObjectModelHelper.getRequest(objectModel);
        FrontEndContext frontEndContext = FrontEndContext.get(request);
        siteConf = frontEndContext.getSiteConf();
        mountPoint = frontEndContext.getMountPoint();

        Object flowContext = FlowHelper.getContextObject(objectModel);
        JXPathContext jxpc = JXPathContext.newContext(flowContext);
        documentKey = (VariantKey)jxpc.getValue("/documentKey");
        if (documentKey == null)
            throw new ProcessingException("Unexpected error in DaisyLinkTransformer: documentKey is missing in flow context.");
    }

    public void recycle() {
        super.recycle();
        this.documentKey = null;
    }

    public void startElement(String namespaceURI, String localName, String qName, Attributes attributes) throws SAXException {
        String linkAttrName = null;
        if (namespaceURI.equals(Constants.DAISY_NAMESPACE) && localName.equals("link")) {
            linkAttrName = "target";
        } else if (localName.equals("a") && namespaceURI.equals("")) {
            linkAttrName = "href";
        } else if (localName.equals("img") && namespaceURI.equals("")) {
            linkAttrName = "src";
        } else if (localName.equals("span") && namespaceURI.equals("") && "crossreference".equals(attributes.getValue("class"))) {
            // This assumes cross references have been handled by the CrossRefParserTransformer.
            linkAttrName = "crossRefTarget";
        }

        if (linkAttrName != null) {
            // link translation can be disabled for particular links using an lt:ignore='true' attribute
            String ignoreAttr = attributes.getValue(LT_NAMESPACE, "ignore");
            if ("true".equals(ignoreAttr)) {
                // remove lt:ignore attribute
                attributes = copyAttributesExceptHrefAndOwn(attributes, null);
            } else {
                attributes = translateLink(attributes, linkAttrName);
            }
        }

        super.startElement(namespaceURI, localName, qName, attributes);
    }

    Attributes translateLink(Attributes attributes, String linkAttrName) {
        String href = attributes.getValue(linkAttrName);
        if (href != null) {
            Matcher matcher = Constants.DAISY_LINK_PATTERN.matcher(href);
            if (matcher.matches()) {
                String navigationPath = attributes.getValue(PUBLISHER_NAMESPACE, "navigationPath");

                String documentId = matcher.group(1);
                String version = matcher.group(4);

                String partLink = attributes.getValue(LT_NAMESPACE, "partLink");
                String fileName = attributes.getValue(LT_NAMESPACE, "fileName");
                fileName = fileName != null && fileName.length() != 0 ? "/" + fileName : "";

                StringBuilder path = new StringBuilder(300);
                path.append(mountPoint).append('/').append(siteConf.getName());
                if (navigationPath != null)
                    path.append(navigationPath);
                else
                    path.append('/').append(documentId);

                if (partLink != null) {
                    if (version == null)
                        version = "default";
                    path.append("/version/").append(version).append("/part/").append(partLink).append("/data").append(fileName);
                } else if (version != null) {
                    path.append("/version/").append(version);
                } else {
                    path.append(".html");
                }

                path.append(DaisyLinkUtil.getBranchLangQueryString(matcher, siteConf, documentKey.getBranchId(), documentKey.getLanguageId()));

                String fragmentIdentifier = matcher.group(7);
                if (fragmentIdentifier != null && !fragmentIdentifier.startsWith("#dsy")) {
                    fragmentIdentifier = "#dsy" + documentId + "_" + fragmentIdentifier.substring(1);
                    path.append(fragmentIdentifier);
                }

                AttributesImpl newAttributes = copyAttributesExceptHrefAndOwn(attributes, linkAttrName);
                newAttributes.addAttribute("", linkAttrName, linkAttrName, "CDATA", path.toString());
                attributes = newAttributes;
            } else if (href.startsWith("#") && !href.startsWith("#dsy")) {
                String newHref = "#dsy" + documentKey.getDocumentId() + "_" + href.substring(1);
                AttributesImpl newAttributes = new AttributesImpl(attributes);
                newAttributes.setAttribute(newAttributes.getIndex("", linkAttrName), "", linkAttrName, linkAttrName, "CDATA", newHref);
                attributes = newAttributes;
            }
        }
        return attributes;
    }

    private AttributesImpl copyAttributesExceptHrefAndOwn(Attributes attrs, String linkAttrName) {
        AttributesImpl newAttrs = new AttributesImpl();
        for (int i = 0; i < attrs.getLength(); i++) {
            if (!attrs.getURI(i).equals(LT_NAMESPACE) && !attrs.getURI(i).equals(PUBLISHER_NAMESPACE)
                && (linkAttrName == null || !(attrs.getLocalName(i).equals(linkAttrName) && attrs.getURI(i).equals("")))) {
                newAttrs.addAttribute(attrs.getURI(i), attrs.getLocalName(i), attrs.getQName(i), attrs.getType(i), attrs.getValue(i));
            }
        }
        return newAttrs;
    }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.