org.nuxeo.ecm.platform.ui.web.component.document.RestDocumentLink.java Source code

Java tutorial

Introduction

Here is the source code for org.nuxeo.ecm.platform.ui.web.component.document.RestDocumentLink.java

Source

/*
 * (C) Copyright 2006-2007 Nuxeo SA (http://nuxeo.com/) and others.
 *
 * 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.
 *
 * Contributors:
 *     <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a>
 *
 * $Id: RestDocumentLink.java 25089 2007-09-18 17:41:58Z ogrisel $
 */

package org.nuxeo.ecm.platform.ui.web.component.document;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.el.ELException;
import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.component.ContextCallback;
import javax.faces.component.UIComponent;
import javax.faces.component.UIParameter;
import javax.faces.component.html.HtmlOutputLink;
import javax.faces.context.FacesContext;
import javax.faces.event.FacesEvent;

import org.apache.commons.lang.StringUtils;
import org.nuxeo.ecm.core.api.DocumentLocation;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.DocumentRef;
import org.nuxeo.ecm.core.api.IdRef;
import org.nuxeo.ecm.core.api.impl.DocumentLocationImpl;
import org.nuxeo.ecm.platform.ui.web.api.WebActions;
import org.nuxeo.ecm.platform.ui.web.component.VariableManager;
import org.nuxeo.ecm.platform.ui.web.tag.fn.DocumentModelFunctions;
import org.nuxeo.ecm.platform.ui.web.util.BaseURL;

import com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.Param;

/**
 * Component that gives generates a Restful link given a document.
 *
 * @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a>
 */
public class RestDocumentLink extends HtmlOutputLink {

    public static final String COMPONENT_TYPE = RestDocumentLink.class.getName();

    public static final String COMPONENT_FAMILY = RestDocumentLink.class.getName();

    public static final String DEFAULT_VIEW_ID = "view_documents";

    protected static final Param[] EMPTY_PARAMS = new Param[0];

    protected DocumentModel document;

    /**
     * @since 5.7
     */
    protected String repositoryName;

    protected DocumentRef documentIdRef;

    /**
     * @since 7.4
     */
    protected DocumentRef documentPathRef;

    protected String view;

    protected String tab;

    protected String subTab;

    /**
     * @since 5.4.2
     */
    protected String tabs;

    protected Boolean addTabInfo;

    protected String pattern;

    protected Boolean newConversation;

    /**
     * @since 7.3
     */
    protected String baseURL;

    /**
     * @since 5.7
     */
    protected String var;

    /**
     * @since 5.7
     */
    protected Boolean resolveOnly;

    @Override
    public String getFamily() {
        return COMPONENT_FAMILY;
    }

    /**
     * Override to build the URL thanks to other tag attributes information.
     * <p>
     * The document view service is queried to build it, and the tag attribute named "value" is ignored.
     */
    @Override
    public Object getValue() {
        DocumentModel doc = getDocument();
        DocumentRef documentIdRef = getDocumentIdRef();
        DocumentRef documentPathRef = getDocumentPathRef();
        String repoName = getRepositoryName();
        if (doc == null && repoName == null
                || (documentIdRef != null || documentPathRef != null) && repoName == null) {
            return null;
        }

        String viewId = getView();

        Map<String, String> params = new LinkedHashMap<String, String>();
        String tabValue = getTab();
        String subTabValue = getSubTab();
        String tabValues = getTabs();
        if (tabValues == null) {
            tabValues = "";
        }
        if (tabValue != null && !tabValue.isEmpty()) {
            if (!tabValues.isEmpty()) {
                tabValues += ",";
            }
            tabValues += ":" + tabValue;
            // params.put("tabId", tabValue); // BBB
            if (subTabValue != null) {
                tabValues += ":" + subTabValue;
                // params.put("subTabId", subTabValue); // BBB
            }
        } else {
            if (Boolean.TRUE.equals(getAddTabInfo())) {
                // reset tab info, resetting the tab will reset the sub tab
                if (!tabValues.isEmpty()) {
                    tabValues += ",";
                }
                tabValues += ":" + WebActions.NULL_TAB_ID;
                // params.put("tabId", WebActions.NULL_TAB_ID); // BBB
            }
        }
        if (!tabValues.isEmpty()) {
            params.put("tabIds", tabValues);
        }

        // add parameters from f:param sub tags
        Param[] paramTags = getParamList();
        for (Param param : paramTags) {
            String pn = param.name;
            if (pn != null && pn.length() != 0) {
                String pv = param.value;
                if (pv != null && pv.length() != 0) {
                    params.put(pn, pv);
                }
            }
        }

        String pattern = getPattern();
        String baseURL = getBaseURL();
        if (StringUtils.isEmpty(baseURL)) {
            baseURL = BaseURL.getBaseURL();
        }

        // new conversation variable handled by renderer
        boolean useNewConversation = true;
        if (doc != null) {
            return DocumentModelFunctions.documentUrl(pattern, doc, viewId, params, useNewConversation, baseURL);
        } else if (documentIdRef != null) {
            DocumentLocation docLoc = new DocumentLocationImpl(repoName, documentIdRef);
            return DocumentModelFunctions.documentUrl(pattern, docLoc, viewId, params, useNewConversation, baseURL);
        } else if (documentPathRef != null) {
            DocumentLocation docLoc = new DocumentLocationImpl(repoName, documentPathRef);
            return DocumentModelFunctions.documentUrl(pattern, docLoc, viewId, params, useNewConversation, baseURL);
        } else {
            return DocumentModelFunctions.repositoryUrl(pattern, repoName, viewId, params, useNewConversation,
                    baseURL);
        }
    }

    protected Param[] getParamList() {
        if (getChildCount() > 0) {
            ArrayList<Param> parameterList = new ArrayList<Param>();
            for (UIComponent kid : getChildren()) {
                if (kid instanceof UIParameter) {
                    UIParameter uiParam = (UIParameter) kid;
                    Object value = uiParam.getValue();
                    Param param = new Param(uiParam.getName(), (value == null ? null : value.toString()));
                    parameterList.add(param);
                }
            }
            return parameterList.toArray(new Param[parameterList.size()]);
        } else {
            return EMPTY_PARAMS;
        }

    }

    // setters and getters for tag attributes

    public String getPattern() {
        if (pattern != null) {
            return pattern;
        }
        ValueExpression ve = getValueExpression("pattern");
        if (ve != null) {
            try {
                return (String) ve.getValue(getFacesContext().getELContext());
            } catch (ELException e) {
                throw new FacesException(e);
            }
        } else {
            return null;
        }
    }

    public void setPattern(String codec) {
        pattern = codec;
    }

    public DocumentModel getDocument() {
        if (document != null) {
            return document;
        }
        ValueExpression ve = getValueExpression("document");
        if (ve != null) {
            try {
                return (DocumentModel) ve.getValue(getFacesContext().getELContext());
            } catch (ELException e) {
                throw new FacesException(e);
            }
        } else {
            return null;
        }
    }

    public void setDocument(DocumentModel document) {
        this.document = document;
    }

    public String getRepositoryName() {
        if (repositoryName != null) {
            return repositoryName;
        }
        ValueExpression ve = getValueExpression("repositoryName");
        if (ve != null) {
            try {
                return (String) ve.getValue(getFacesContext().getELContext());
            } catch (ELException e) {
                throw new FacesException(e);
            }
        } else {
            return null;
        }
    }

    public void setRepositoryName(String repositoryName) {
        this.repositoryName = repositoryName;
    }

    public DocumentRef getDocumentIdRef() {
        if (documentIdRef != null) {
            return documentIdRef;
        }
        ValueExpression ve = getValueExpression("documentId");
        if (ve != null) {
            try {
                String id = (String) ve.getValue(getFacesContext().getELContext());
                if (id != null) {
                    return new IdRef(id);
                } else {
                    return null;
                }
            } catch (ELException e) {
                throw new FacesException(e);
            }
        } else {
            return null;
        }
    }

    public void setDocumentIdRef(DocumentRef documentIdRef) {
        this.documentIdRef = documentIdRef;
    }

    public DocumentRef getDocumentPathRef() {
        if (documentPathRef != null) {
            return documentPathRef;
        }
        ValueExpression ve = getValueExpression("documentPath");
        if (ve != null) {
            try {
                String id = (String) ve.getValue(getFacesContext().getELContext());
                if (id != null) {
                    return new IdRef(id);
                } else {
                    return null;
                }
            } catch (ELException e) {
                throw new FacesException(e);
            }
        } else {
            return null;
        }
    }

    public void setDocumentPathRef(DocumentRef documentPathRef) {
        this.documentPathRef = documentPathRef;
    }

    /**
     * Returns true if URL must link to a page in a new conversation.
     * <p>
     * Defaults to false.
     */
    public Boolean getNewConversation() {
        if (newConversation != null) {
            return newConversation;
        }
        ValueExpression ve = getValueExpression("newConversation");
        if (ve != null) {
            try {
                return Boolean.valueOf(!Boolean.FALSE.equals(ve.getValue(getFacesContext().getELContext())));
            } catch (ELException e) {
                throw new FacesException(e);
            }
        } else {
            // default value
            return Boolean.FALSE;
        }
    }

    public void setNewConversation(Boolean newConversation) {
        this.newConversation = newConversation;
    }

    public String getSubTab() {
        if (subTab != null) {
            return subTab;
        }
        ValueExpression ve = getValueExpression("subTab");
        if (ve != null) {
            try {
                return (String) ve.getValue(getFacesContext().getELContext());
            } catch (ELException e) {
                throw new FacesException(e);
            }
        } else {
            return null;
        }
    }

    public void setSubTab(String subTab) {
        this.subTab = subTab;
    }

    public String getTab() {
        if (tab != null) {
            return tab;
        }
        ValueExpression ve = getValueExpression("tab");
        if (ve != null) {
            try {
                return (String) ve.getValue(getFacesContext().getELContext());
            } catch (ELException e) {
                throw new FacesException(e);
            }
        } else {
            return null;
        }
    }

    public void setTab(String tab) {
        this.tab = tab;
    }

    /**
     * @since 7.3
     */
    public String getBaseURL() {
        if (baseURL != null) {
            return baseURL;
        }
        ValueExpression ve = getValueExpression("baseURL");
        if (ve != null) {
            try {
                return (String) ve.getValue(getFacesContext().getELContext());
            } catch (ELException e) {
                throw new FacesException(e);
            }
        } else {
            return null;
        }
    }

    /**
     * @since 7.3
     */
    public void setBaseURL(String baseURL) {
        this.baseURL = baseURL;
    }

    public String getView() {
        if (view != null) {
            return view;
        }
        ValueExpression ve = getValueExpression("view");
        if (ve != null) {
            try {
                return (String) ve.getValue(getFacesContext().getELContext());
            } catch (ELException e) {
                throw new FacesException(e);
            }
        } else {
            return null;
        }
    }

    public void setView(String view) {
        this.view = view;
    }

    public Boolean getAddTabInfo() {
        if (addTabInfo != null) {
            return addTabInfo;
        }
        ValueExpression ve = getValueExpression("addTabInfo");
        if (ve != null) {
            try {
                return Boolean.valueOf(!Boolean.FALSE.equals(ve.getValue(getFacesContext().getELContext())));
            } catch (ELException e) {
                throw new FacesException(e);
            }
        } else {
            // default value
            return Boolean.TRUE;
        }
    }

    public void setAddTabInfo(Boolean addTabInfo) {
        this.addTabInfo = addTabInfo;
    }

    public String getTabs() {
        if (tabs != null) {
            return tabs;
        }
        ValueExpression ve = getValueExpression("tabs");
        if (ve != null) {
            try {
                return (String) ve.getValue(getFacesContext().getELContext());
            } catch (ELException e) {
                throw new FacesException(e);
            }
        } else {
            return null;
        }
    }

    public void setTabs(String tabs) {
        this.tabs = tabs;
    }

    public Boolean getResolveOnly() {
        if (resolveOnly != null) {
            return resolveOnly;
        }
        ValueExpression ve = getValueExpression("resolveOnly");
        if (ve != null) {
            try {
                return Boolean.valueOf(!Boolean.FALSE.equals(ve.getValue(getFacesContext().getELContext())));
            } catch (ELException e) {
                throw new FacesException(e);
            }
        } else {
            // default value
            return Boolean.FALSE;
        }
    }

    public void setResolveOnly(Boolean resolveOnly) {
        this.resolveOnly = resolveOnly;
    }

    public String getVar() {
        if (var != null) {
            return var;
        }
        ValueExpression ve = getValueExpression("var");
        if (ve != null) {
            try {
                return (String) ve.getValue(getFacesContext().getELContext());
            } catch (ELException e) {
                throw new FacesException(e);
            }
        } else {
            return null;
        }
    }

    public void setVar(String var) {
        this.var = var;
    }

    // "resolveOnly" attribute management: expose value instead of rendering
    // the tag

    /**
     * Saves the current value exposed as param to the request, and put new variable value instead.
     * <p>
     * Returns the original value exposed to the request.
     *
     * @since 5.7
     */
    protected Object beforeRender() {
        String var = getVar();
        Object orig = VariableManager.saveRequestMapVarValue(var);
        if (Boolean.TRUE.equals(getResolveOnly())) {
            VariableManager.putVariableToRequestParam(var, getValue());
        }
        return orig;
    }

    /**
     * Restored the original value exposed as param to the request, and remove current variable value.
     *
     * @since 5.7
     */
    protected void afterRender(Object origVarValue) {
        String var = getVar();
        VariableManager.restoreRequestMapVarValue(var, origVarValue);
    }

    /**
     * @since 5.7
     */
    @Override
    public boolean invokeOnComponent(FacesContext context, String clientId, ContextCallback callback)
            throws FacesException {
        Object varValue = beforeRender();
        try {
            return super.invokeOnComponent(context, clientId, callback);
        } finally {
            afterRender(varValue);
        }
    }

    /**
     * @since 5.7
     */
    @Override
    public void broadcast(FacesEvent event) {
        Object varValue = beforeRender();
        try {
            super.broadcast(event);
        } finally {
            afterRender(varValue);
        }
    }

    /**
     * @since 5.7
     */
    @Override
    public void encodeBegin(FacesContext context) throws IOException {
        if (!Boolean.TRUE.equals(getResolveOnly())) {
            super.encodeBegin(context);
        }
    }

    @Override
    public void encodeChildren(FacesContext context) throws IOException {
        Object varValue = beforeRender();
        try {
            super.encodeChildren(context);
        } finally {
            afterRender(varValue);
        }
    }

    /**
     * @since 5.7
     */
    @Override
    public void encodeEnd(FacesContext context) throws IOException {
        if (!Boolean.TRUE.equals(getResolveOnly())) {
            super.encodeEnd(context);
        }
    }

    // state holder

    @Override
    public Object saveState(FacesContext context) {
        return new Object[] { super.saveState(context), document, documentIdRef, view, tab, subTab, tabs,
                addTabInfo, pattern, newConversation, baseURL, var, resolveOnly };
    }

    @Override
    public void restoreState(FacesContext context, Object state) {
        Object[] values = (Object[]) state;
        super.restoreState(context, values[0]);
        document = (DocumentModel) values[1];
        documentIdRef = (DocumentRef) values[2];
        view = (String) values[3];
        tab = (String) values[4];
        subTab = (String) values[5];
        tabs = (String) values[6];
        addTabInfo = (Boolean) values[7];
        pattern = (String) values[8];
        newConversation = (Boolean) values[9];
        baseURL = (String) values[10];
        var = (String) values[11];
        resolveOnly = (Boolean) values[12];
    }

}