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