001/*
002 * (C) Copyright 2006-2016 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 *     Alexandre Russel
018 *
019 */
020package org.nuxeo.ecm.platform.annotations.repository;
021
022import java.net.MalformedURLException;
023import java.net.URI;
024import java.net.URISyntaxException;
025import java.util.Optional;
026
027import org.nuxeo.ecm.core.api.CloseableCoreSession;
028import org.nuxeo.ecm.core.api.CoreInstance;
029import org.nuxeo.ecm.core.api.DocumentLocation;
030import org.nuxeo.ecm.core.api.DocumentModel;
031import org.nuxeo.ecm.core.api.DocumentRef;
032import org.nuxeo.ecm.core.api.NuxeoException;
033import org.nuxeo.ecm.platform.annotations.api.UriResolver;
034import org.nuxeo.ecm.platform.url.api.DocumentView;
035import org.nuxeo.ecm.platform.url.api.DocumentViewCodecManager;
036import org.nuxeo.ecm.platform.web.common.vh.VirtualHostHelper;
037import org.nuxeo.runtime.api.Framework;
038
039/**
040 * @author Alexandre Russel
041 */
042public class DefaultNuxeoUriResolver implements UriResolver {
043
044    private static final String NUXEO = VirtualHostHelper.getContextPathProperty() + "/";
045
046    private final URNDocumentViewTranslator translator = new URNDocumentViewTranslator();
047
048    private DocumentViewCodecManager viewCodecManager;
049
050    public DefaultNuxeoUriResolver() {
051        viewCodecManager = Framework.getService(DocumentViewCodecManager.class);
052    }
053
054    @Override
055    public URI getSearchURI(URI uri) {
056        DocumentView view = translator.getDocumentViewFromUri(uri);
057        return getGraphURIFromDocumentView(view);
058    }
059
060    @Override
061    public URI translateFromGraphURI(URI uri, String baseUrl) {
062        DocumentView view = translator.getDocumentViewFromUri(uri);
063        if (view == null || baseUrl == null) { // not a nuxeo document or
064            // already a urn
065            return uri;
066        }
067        String url = viewCodecManager.getUrlFromDocumentView(view, true, baseUrl);
068        URI u;
069        try {
070            u = new URI(url);
071        } catch (URISyntaxException e) {
072            throw new NuxeoException(e);
073        }
074        return u;
075    }
076
077    @Override
078    public URI translateToGraphURI(URI uri) {
079        if (uri.toString().startsWith("urn")) {
080            return uri;
081        }
082        DocumentView view = viewCodecManager.getDocumentViewFromUrl(uri.toString(), true, getBaseUrl(uri));
083        if (view == null) {// not a nuxeo uri
084            return uri;
085        }
086        return getGraphURIFromDocumentView(view);
087    }
088
089    protected URI getGraphURIFromDocumentView(DocumentView view) {
090        DocumentLocation docLoc = view.getDocumentLocation();
091        try (CloseableCoreSession session = CoreInstance.openCoreSession(docLoc.getServerName())) {
092            DocumentRef idRef = docLoc.getIdRef();
093            if (idRef == null) {
094                DocumentModel docModel = session.getDocument(docLoc.getDocRef());
095                idRef = docModel.getRef();
096            }
097            return translator.getUriFromDocumentView(docLoc.getServerName(), idRef);
098        }
099    }
100
101    @Override
102    public String getBaseUrl(URI uri) {
103        String url;
104        try {
105            url = uri.toURL().toString();
106        } catch (MalformedURLException e) {
107            throw new NuxeoException(e);
108        }
109        return url.substring(0, url.lastIndexOf(NUXEO) + NUXEO.length());
110    }
111
112    public DocumentRef getDocumentRef(URI uri) {
113        return retrieveDocumentLocation(uri).map(DocumentLocation::getDocRef).orElse(null);
114    }
115
116    public DocumentLocation getDocumentLocation(URI uri) {
117        return retrieveDocumentLocation(uri).orElse(null);
118    }
119
120    private Optional<DocumentLocation> retrieveDocumentLocation(URI uri) {
121        Optional<DocumentView> view;
122        if (translator.isNuxeoUrn(uri)) {
123            view = Optional.of(translator.getDocumentViewFromUri(uri));
124        } else {
125            view = Optional.ofNullable(viewCodecManager.getDocumentViewFromUrl(uri.toString(), true, getBaseUrl(uri)));
126        }
127        return view.map(DocumentView::getDocumentLocation);
128    }
129
130    public URI getUri(DocumentView view, String baseUrl) throws URISyntaxException {
131        return new URI(viewCodecManager.getUrlFromDocumentView(view, true, baseUrl));
132    }
133
134}