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.platform.ui.web.util;
021
022import java.io.UnsupportedEncodingException;
023import java.net.URLDecoder;
024import java.net.URLEncoder;
025
026import org.apache.commons.logging.Log;
027import org.apache.commons.logging.LogFactory;
028import org.nuxeo.ecm.core.api.DocumentLocation;
029import org.nuxeo.ecm.core.api.DocumentRef;
030import org.nuxeo.ecm.core.api.IdRef;
031import org.nuxeo.ecm.core.api.PathRef;
032import org.nuxeo.ecm.core.api.impl.DocumentLocationImpl;
033import org.nuxeo.ecm.platform.util.RepositoryLocation;
034
035/**
036 * Utility class that externalize means to access a document by using an URL.
037 *
038 * @author DM
039 * @deprecated see the url service with codecs registered through extension points
040 */
041@Deprecated
042public final class DocumentLocator {
043
044    public static final String URL_PREFIX = "getDocument.faces?";
045
046    public static final String PARAM_NAME = "docRef";
047
048    public static final String CHAR_ENCODING = "UTF-8";
049
050    @SuppressWarnings("unused")
051    private static final Log log = LogFactory.getLog(DocumentLocator.class);
052
053    private DocumentLocator() {
054    }
055
056    public static String getDocumentUrl(RepositoryLocation serverLocation, DocumentRef docRef) {
057        if (serverLocation == null) {
058            String nullRepoName = null;
059            return getDocumentUrl(nullRepoName, docRef);
060        }
061        return getDocumentUrl(serverLocation.getName(), docRef);
062    }
063
064    /**
065     * Returns something like getDocument.faces?docRef=ServerLocationName/DocRef.
066     */
067    public static String getDocumentUrl(String serverLocationName, DocumentRef docRef) {
068
069        if (null == docRef) {
070            throw new IllegalArgumentException("null docRef");
071        }
072
073        final StringBuilder urlBuf = new StringBuilder();
074        urlBuf.append(URL_PREFIX);
075        urlBuf.append(PARAM_NAME);
076        urlBuf.append('=');
077        if (serverLocationName != null) {
078            // urlBuf.append(encode(serverLocation.getUri()));
079            // XXX : Uses server name instead of URI
080            // decoding tests fails otherwise
081            urlBuf.append(encode(serverLocationName));
082        }
083        urlBuf.append('/');
084        urlBuf.append(docRef.type());
085        urlBuf.append(':');
086        urlBuf.append(encode(docRef.reference().toString()));
087
088        return urlBuf.toString();
089    }
090
091    /**
092     * Encodes the given string to be safely used in an URL.
093     */
094    private static String encode(String txt) {
095        String safetxt;
096        try {
097            safetxt = URLEncoder.encode(txt, CHAR_ENCODING);
098        } catch (UnsupportedEncodingException e) {
099            log.error(e, e);
100            return null;
101        }
102        return safetxt;
103    }
104
105    private static String decode(String txt) {
106        final String decoded;
107        try {
108            decoded = URLDecoder.decode(txt, CHAR_ENCODING);
109        } catch (UnsupportedEncodingException e) {
110            log.error(e, e);
111            return null;
112        }
113        return decoded;
114    }
115
116    /**
117     * Returns something like http://server:port/nuxeo/getDocument.xhtml?docRef=ServerLocationName/DocRef.
118     */
119    public static String getFullDocumentUrl(RepositoryLocation serverLocation, DocumentRef docRef) {
120        String baseUrl = BaseURL.getBaseURL();
121        String docUrl = getDocumentUrl(serverLocation, docRef);
122        if (baseUrl != null) {
123            return baseUrl + docUrl;
124        }
125        return docUrl;
126    }
127
128    /**
129     * Returns something like http://server:port/nuxeo/getDocument.xhtml?docRef=ServerLocationName/DocRef.
130     */
131    public static String getFullDocumentUrl(String serverLocation, DocumentRef docRef) {
132        String baseUrl = BaseURL.getBaseURL();
133        String docUrl = getDocumentUrl(serverLocation, docRef);
134        if (baseUrl != null) {
135            return baseUrl + docUrl;
136        }
137        return docUrl;
138    }
139
140    /**
141     * @param docUriRef in format <ServerLocationName>/<DocRefType>:<doc reference>
142     */
143    public static DocumentLocation parseDocRef(String docUriRef) throws BadDocumentUriException {
144        final int pos = docUriRef.indexOf('/');
145        if (pos == -1) {
146            throw new BadDocumentUriException("/ delimiter not found");
147        }
148        String serverLocation = docUriRef.substring(0, pos);
149        serverLocation = decode(serverLocation);
150
151        final String serverLocationName = serverLocation;
152
153        int pos2 = docUriRef.indexOf(':', pos + 1);
154        if (pos2 == -1) {
155            throw new BadDocumentUriException(": delimiter not found");
156        }
157        final String refTypeStr = docUriRef.substring(pos + 1, pos2);
158        final int refType;
159        try {
160            refType = Integer.parseInt(refTypeStr);
161        } catch (NumberFormatException e) {
162            throw new BadDocumentUriException("bad refType (not a number) " + refTypeStr);
163        }
164
165        String reference = docUriRef.substring(pos2 + 1);
166        reference = decode(reference);
167
168        final DocumentRef docRef;
169        if (refType == DocumentRef.ID) {
170            docRef = new IdRef(reference);
171        } else if (DocumentRef.PATH == refType) {
172            docRef = new PathRef(reference);
173        } else {
174            throw new BadDocumentUriException("bad refType " + refType);
175        }
176
177        return new DocumentLocationImpl(serverLocationName, docRef);
178    }
179
180}