001/*
002 * (C) Copyright 2009 Nuxeo SA (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 *     Thomas Roger
016 */
017
018package org.nuxeo.ecm.webapp.note;
019
020import static org.jboss.seam.ScopeType.CONVERSATION;
021
022import java.io.Serializable;
023import java.util.regex.Matcher;
024import java.util.regex.Pattern;
025
026import org.jboss.seam.annotations.In;
027import org.jboss.seam.annotations.Name;
028import org.jboss.seam.annotations.Scope;
029import org.nuxeo.ecm.core.api.CoreSession;
030import org.nuxeo.ecm.core.api.DocumentModel;
031import org.nuxeo.ecm.core.api.IdRef;
032import org.nuxeo.ecm.core.api.UnrestrictedSessionRunner;
033import org.nuxeo.ecm.platform.ui.web.api.NavigationContext;
034
035/**
036 * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a>
037 */
038@Scope(CONVERSATION)
039@Name("noteActions")
040public class NoteActions implements Serializable {
041
042    private static final long serialVersionUID = 1L;
043
044    protected static final Pattern PATTERN_TO_CHECK = Pattern.compile("(.*<img.*/files:files/.*/>.*)+", Pattern.DOTALL);
045
046    protected static final String PATTERN_TO_REPLACE = "(<img.*?)%s(/files:files/.*?/>)";
047
048    @In(create = true, required = false)
049    protected transient CoreSession documentManager;
050
051    @In(create = true, required = false)
052    protected transient NavigationContext navigationContext;
053
054    private static class LiveDocumentRefFinder extends UnrestrictedSessionRunner {
055
056        private String liveDocumentRef;
057
058        private final DocumentModel proxy;
059
060        public LiveDocumentRefFinder(DocumentModel proxy) {
061            super(proxy.getRepositoryName());
062            this.proxy = proxy;
063        }
064
065        @Override
066        public void run() {
067            liveDocumentRef = proxy.getRef().toString();
068            if (proxy.getSourceId() != null) {
069                liveDocumentRef = proxy.getSourceId();
070                DocumentModel version = session.getDocument(new IdRef(proxy.getSourceId()));
071                if (version.getSourceId() != null) {
072                    liveDocumentRef = version.getSourceId();
073                }
074            }
075        }
076
077        public String getLiveDocumentRef() {
078            if (liveDocumentRef == null) {
079                runUnrestricted();
080            }
081            return liveDocumentRef;
082        }
083
084    }
085
086    /**
087     * Translate the image links referencing attached files to use the docId of the current proxy or version. Do not
088     * translate anything if we are on a live document.
089     *
090     * @param note the note content
091     * @return the translated note content
092     */
093    public String translateImageLinks(String note) {
094        DocumentModel currentDocument = navigationContext.getCurrentDocument();
095        if (!(currentDocument.isProxy() || currentDocument.isVersion())) {
096            return note;
097        }
098
099        if (!hasImageLinksToTranslate(note)) {
100            return note;
101        }
102
103        String docIdToReplace = null;
104        if (currentDocument.isVersion()) {
105            docIdToReplace = currentDocument.getSourceId();
106        } else if (currentDocument.isProxy()) {
107            docIdToReplace = new LiveDocumentRefFinder(currentDocument).getLiveDocumentRef();
108        }
109
110        return translateImageLinks(note, docIdToReplace, currentDocument.getId());
111    }
112
113    protected boolean hasImageLinksToTranslate(String note) {
114        Matcher matcher = PATTERN_TO_CHECK.matcher(note);
115        return matcher.matches();
116    }
117
118    protected String translateImageLinks(String note, String fromDocRef, String toDocRef) {
119        String patternToReplace = String.format(PATTERN_TO_REPLACE, fromDocRef);
120        Pattern pattern = Pattern.compile(patternToReplace);
121        Matcher matcher = pattern.matcher(note);
122        String replacement = "$1" + toDocRef + "$2";
123        return matcher.replaceAll(replacement);
124    }
125
126}