001/*
002 * (C) Copyright 2007 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 *
019 * $Id: DocumentLinkTagHandler.java 28610 2008-01-09 17:13:52Z sfermigier $
020 */
021
022package org.nuxeo.ecm.platform.ui.web.tag.handler;
023
024import javax.el.ELContext;
025import javax.el.ExpressionFactory;
026import javax.el.MethodExpression;
027import javax.faces.application.Application;
028import javax.faces.component.ActionSource2;
029import javax.faces.component.UIComponent;
030import javax.faces.context.FacesContext;
031import javax.faces.view.facelets.ComponentConfig;
032import javax.faces.view.facelets.FaceletContext;
033import javax.faces.view.facelets.MetaRuleset;
034import javax.faces.view.facelets.TagAttribute;
035
036import org.apache.commons.logging.Log;
037import org.apache.commons.logging.LogFactory;
038import org.nuxeo.ecm.core.api.DocumentModel;
039
040/**
041 * Component tag handler that wires a document link tag to a command link tag.
042 * <p>
043 * Useful when redirecting to a document using a post.
044 *
045 * @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a>
046 */
047public class DocumentLinkTagHandler extends GenericHtmlComponentHandler {
048
049    private static final Log log = LogFactory.getLog(DocumentLinkTagHandler.class);
050
051    private final TagAttribute document;
052
053    private final TagAttribute view;
054
055    public DocumentLinkTagHandler(ComponentConfig config) {
056        super(config);
057        document = getRequiredAttribute("document");
058        view = getAttribute("view");
059    }
060
061    @Override
062    @SuppressWarnings("rawtypes")
063    protected MetaRuleset createMetaRuleset(Class type) {
064        // expected created tag is an html command link
065        MetaRuleset mr = super.createMetaRuleset(type);
066        // alias title
067        mr.alias("title", "value");
068        mr.ignore("document");
069        mr.ignore("action");
070        mr.ignore("view");
071        return mr;
072    }
073
074    /**
075     * Sets action after component has been created.
076     */
077    @Override
078    public void onComponentCreated(FaceletContext ctx, UIComponent c, UIComponent parent) {
079        if (c instanceof ActionSource2) {
080            ActionSource2 command = (ActionSource2) c;
081            String docValue = getDocumentValue();
082            String viewId = getViewValue();
083            String actionValue;
084            if (viewId == null) {
085                actionValue = "#{navigationContext.navigateToDocument(" + docValue + ")}";
086            } else {
087                actionValue = "#{navigationContext.navigateToDocumentWithView(" + docValue + ", " + viewId + ")}";
088            }
089            FacesContext facesContext = ctx.getFacesContext();
090            Application app = facesContext.getApplication();
091            ExpressionFactory ef = app.getExpressionFactory();
092            ELContext context = facesContext.getELContext();
093            MethodExpression action = ef.createMethodExpression(context, actionValue, String.class, new Class[] {
094                    DocumentModel.class, String.class });
095            command.setActionExpression(action);
096        }
097    }
098
099    private String getDocumentValue() {
100        String docValue = document.getValue();
101        docValue = docValue.trim();
102        if (!((docValue.startsWith("${") || docValue.startsWith("#{")) && docValue.endsWith("}"))) {
103            log.error("Invalid value for document " + docValue);
104        }
105        docValue = docValue.substring(2, docValue.length() - 1);
106        return docValue;
107    }
108
109    private String getViewValue() {
110        String viewName = null;
111        if (view != null) {
112            viewName = view.getValue();
113            if (viewName != null) {
114                viewName = viewName.trim();
115                if ((viewName.startsWith("${") || viewName.startsWith("#{")) && viewName.endsWith("}")) {
116                    viewName = viewName.substring(2, viewName.length() - 1);
117                } else {
118                    viewName = '\"' + viewName + '\"';
119                }
120            }
121        }
122        return viewName;
123    }
124
125}