001/*
002 * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 *
017 * $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $
018 */
019
020package org.nuxeo.ecm.webapp.helpers;
021
022import static org.jboss.seam.ScopeType.CONVERSATION;
023
024import java.io.IOException;
025import java.io.Serializable;
026
027import javax.faces.context.FacesContext;
028import javax.servlet.http.HttpServletResponse;
029
030import org.apache.commons.logging.Log;
031import org.apache.commons.logging.LogFactory;
032import org.jboss.seam.annotations.In;
033import org.jboss.seam.annotations.Name;
034import org.jboss.seam.annotations.web.RequestParameter;
035import org.jboss.seam.annotations.Scope;
036import org.jboss.seam.core.ConversationEntry;
037import org.jboss.seam.core.Manager;
038import org.nuxeo.ecm.core.api.Blob;
039import org.nuxeo.ecm.core.api.CoreSession;
040import org.nuxeo.ecm.core.api.DocumentModel;
041import org.nuxeo.ecm.core.api.DocumentNotFoundException;
042import org.nuxeo.ecm.core.api.DocumentRef;
043import org.nuxeo.ecm.core.api.IdRef;
044import org.nuxeo.ecm.core.api.PropertyException;
045import org.nuxeo.ecm.platform.ui.web.api.NavigationContext;
046
047@Name("logoHelper")
048@Scope(CONVERSATION)
049public class LogoHelper implements Serializable {
050
051    private static final long serialVersionUID = 876540986876L;
052
053    private static final String PAGE_NAME = "/showLogo.faces";
054
055    private static final String DEFAULT_LOGO = "/img/default_logo.gif";
056
057    private static final Log log = LogFactory.getLog(LogoHelper.class);
058
059    @In(value = "org.jboss.seam.core.manager")
060    public transient Manager conversationManager;
061
062    @In(create = true, required = false)
063    transient NavigationContext navigationContext;
064
065    @In(create = true, required = false)
066    transient CoreSession documentManager;
067
068    private String lastLogoHolderKey = "";
069
070    private DocumentModel lastLogoHolder;
071
072    private String lastURL = "";
073
074    private String lastMainConversation = "";
075
076    public String getLogoURL() {
077        if (navigationContext == null || navigationContext.getCurrentServerLocation() == null) {
078            lastLogoHolderKey = "";
079            lastURL = "";
080            return DEFAULT_LOGO;
081        }
082
083        DocumentModel ws = navigationContext.getCurrentWorkspace();
084
085        return getLogoURL(ws);
086    }
087
088    public String getDefaultLogoURL() {
089        return DEFAULT_LOGO;
090    }
091
092    public String getLogoURLFromDocRef(String docRef) {
093        if (documentManager == null) {
094            return DEFAULT_LOGO;
095        }
096        DocumentRef ref = new IdRef(docRef);
097        try {
098            DocumentModel doc = documentManager.getDocument(ref);
099            return getLogoURL(doc);
100        } catch (DocumentNotFoundException e) {
101            log.error(e, e);
102            return DEFAULT_LOGO;
103        }
104    }
105
106    public String getLogoURL(DocumentModel doc) {
107        if (doc == null) {
108            return DEFAULT_LOGO;
109        }
110
111        String key = doc.getCacheKey();
112        if (key.equals(lastLogoHolderKey)) {
113            return lastURL;
114        }
115
116        Blob blob = getBlob(doc);
117        if (blob == null) {
118            return DEFAULT_LOGO;
119        }
120        lastURL = PAGE_NAME + "?key=" + key + "&docRef=" + doc.getRef().toString() + '&'
121                + getConversationPropagationSuffix();
122        lastLogoHolderKey = doc.getCacheKey();
123        lastLogoHolder = doc;
124
125        return lastURL;
126    }
127
128    private static Blob getBlob(DocumentModel doc) {
129        if (doc == null) {
130            return null;
131        }
132        if (doc.hasSchema("file")) {
133            try {
134                return (Blob) doc.getProperty("file", "content");
135            } catch (PropertyException e) {
136                return null;
137            }
138        } else {
139            return null;
140        }
141    }
142
143    @RequestParameter
144    String key;
145
146    @RequestParameter
147    String docRef;
148
149    public String getLogo() {
150        Blob imgBlob = null;
151
152        // returns cached blob
153        if (key != null && key.equals(lastLogoHolderKey)) {
154            imgBlob = getBlob(lastLogoHolder);
155        }
156
157        // recompute blob
158        if (imgBlob == null) {
159            DocumentModel ob = navigationContext.getCurrentWorkspace();
160            if (ob == null || !ob.getRef().toString().equals(docRef)) {
161                DocumentRef ref = new IdRef(docRef);
162                try {
163                    ob = documentManager.getDocument(ref);
164                } catch (DocumentNotFoundException e) {
165                    log.error(e, e);
166                }
167            }
168            imgBlob = getBlob(ob);
169        }
170
171        FacesContext context = FacesContext.getCurrentInstance();
172        HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
173        try {
174            if (imgBlob == null
175                    || (imgBlob.getMimeType() != null && !imgBlob.getMimeType().toLowerCase().startsWith("image"))) {
176                response.setContentType("image/gif");
177                response.sendRedirect(context.getExternalContext().getRequestContextPath() + DEFAULT_LOGO);
178                return null;
179            } else {
180                response.addHeader("Cache-Control", "max-age=600");
181                response.addHeader("Cache-Control", "public");
182                response.setContentType(imgBlob.getMimeType());
183                response.getOutputStream().write(imgBlob.getByteArray());
184                response.getOutputStream().close();
185                response.flushBuffer();
186                context.responseComplete();
187            }
188
189        } catch (IOException e) {
190            log.error("error while sending logo: ", e);
191        }
192
193        return null;
194    }
195
196    private String getLastOrMainConversationId(String cId) {
197        if (!cId.startsWith("0NX")) {
198            cId = lastMainConversation;
199        }
200
201        if (lastMainConversation == null || lastMainConversation.equals("")) {
202            cId = "0NXMAIN";
203        }
204        return cId;
205    }
206
207    private String getConversationPropagationSuffix() {
208        String suffix = "";
209
210        if (!conversationManager.getCurrentConversationEntry().isNested()) {
211            String cId = conversationManager.getCurrentConversationId();
212            // tmp hack to handle the case when the logo is rendered
213            // just after the page existed the conversation
214            cId = getLastOrMainConversationId(cId);
215            suffix += conversationManager.getConversationIdParameter() + '=' + cId;
216            /**
217             * if (conversationManager.isLongRunningConversation()) { suffix += '&' +
218             * conversationManager.getConversationIsLongRunningParameter() + "true"; lastMainConversation = cId; }
219             **/
220        } else {
221            ConversationEntry conv = conversationManager.getCurrentConversationEntry();
222            String convId = conv.getConversationIdStack().get(0);
223            convId = getLastOrMainConversationId(convId);
224            suffix += conversationManager.getConversationIdParameter() + '=' + convId;
225            /**
226             * suffix += '&' + conversationManager.getConversationIsLongRunningParameter() + "true";
227             * lastMainConversation = convId;
228             **/
229        }
230
231        return suffix;
232    }
233
234}