001/*
002 * Licensed to DuraSpace under one or more contributor license agreements.
003 * See the NOTICE file distributed with this work for additional information
004 * regarding copyright ownership.
005 *
006 * DuraSpace licenses this file to you under the Apache License,
007 * Version 2.0 (the "License"); you may not use this file except in
008 * compliance with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.fcrepo.http.commons.api.rdf;
019
020import static org.apache.commons.lang3.StringUtils.EMPTY;
021import static org.apache.commons.lang3.StringUtils.replaceOnce;
022import static org.fcrepo.kernel.api.FedoraTypes.FCR_ACL;
023import static org.fcrepo.kernel.api.FedoraTypes.FCR_METADATA;
024import static org.fcrepo.kernel.api.FedoraTypes.FCR_VERSIONS;
025import static org.slf4j.LoggerFactory.getLogger;
026import static org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext;
027
028import java.util.HashMap;
029import java.util.List;
030import java.util.Map;
031import java.util.regex.Pattern;
032import javax.ws.rs.core.UriBuilder;
033
034import com.google.common.base.Converter;
035import org.apache.jena.rdf.model.Resource;
036import org.apache.jena.rdf.model.ResourceFactory;
037import org.fcrepo.kernel.api.Transaction;
038import org.fcrepo.kernel.api.exception.RepositoryRuntimeException;
039import org.fcrepo.kernel.api.identifiers.IdentifierConverter;
040import org.fcrepo.kernel.api.models.FedoraResource;
041import org.glassfish.jersey.uri.UriTemplate;
042import org.slf4j.Logger;
043import org.springframework.context.ApplicationContext;
044
045/**
046 * Convert between Jena Resources and JCR Nodes using a JAX-RS UriBuilder to mediate the
047 * URI translation.
048 *
049 * @author cabeer
050 * @since 10/5/14
051 */
052@Deprecated
053public class HttpResourceConverter extends IdentifierConverter<Resource,FedoraResource> {
054
055    private static final Logger LOGGER = getLogger(HttpResourceConverter.class);
056
057    // Regex pattern which decomposes a http resource uri into components
058    // The first group determines if it is an fcr:metadata non-rdf source.
059    // The second group determines if the path is for a memento or timemap.
060    // The third group allows for a memento identifier.
061    // The fourth group for allows ACL.
062    // The fifth group allows for any hashed suffixes.
063    private final static Pattern FORWARD_COMPONENT_PATTERN = Pattern.compile(
064            ".*?(/" + FCR_METADATA + ")?(/" + FCR_VERSIONS + "(/\\d{14})?)?(/" + FCR_ACL + ")?(\\#\\S+)?$");
065
066    protected List<Converter<String, String>> translationChain;
067
068    private final Transaction transaction;
069    private final UriBuilder uriBuilder;
070
071    protected Converter<String, String> forward = identity();
072    protected Converter<String, String> reverse = identity();
073
074    private final UriTemplate uriTemplate;
075
076    /**
077     * Create a new identifier converter within the given transaction with the given URI template
078     * @param transaction the transaction
079     * @param uriBuilder the uri builder
080     */
081    public HttpResourceConverter(final Transaction transaction,
082                                 final UriBuilder uriBuilder) {
083
084        this.transaction = transaction;
085        this.uriBuilder = uriBuilder;
086        this.uriTemplate = new UriTemplate(uriBuilder.toTemplate());
087    }
088
089    private UriBuilder uriBuilder() {
090        return UriBuilder.fromUri(uriBuilder.toTemplate());
091    }
092
093    @Override
094    protected FedoraResource doForward(final Resource resource) {
095        //@TODO Implement this
096        return null;
097    }
098
099    @Override
100    protected Resource doBackward(final FedoraResource resource) {
101        return ResourceFactory.createResource(resource.getId());
102    }
103
104    @Override
105    public boolean inDomain(final Resource resource) {
106        //@TODO Implement this
107        return false;
108    }
109
110    @Override
111    public Resource toDomain(final String path) {
112        //@TODO Implement this
113        return null;
114    }
115
116    @Override
117    public String asString(final Resource resource) {
118        //@TODO Implement this
119        return null;
120    }
121
122    protected ApplicationContext getApplicationContext() {
123        return getCurrentWebApplicationContext();
124    }
125
126    /**
127     * Translate the current transaction into the identifier
128     */
129    static class TransactionIdentifierConverter extends Converter<String, String> {
130        public static final String TX_PREFIX = "tx:";
131
132        private final Transaction transaction;
133
134        public TransactionIdentifierConverter(final Transaction transaction) {
135            this.transaction = transaction;
136        }
137
138        @Override
139        protected String doForward(final String path) {
140
141            if (path.contains(TX_PREFIX) && !path.contains(txSegment())) {
142                throw new RepositoryRuntimeException("Path " + path
143                        + " is not in current transaction " +  transaction.getId());
144            }
145
146            return replaceOnce(path, txSegment(), EMPTY);
147        }
148
149        @Override
150        protected String doBackward(final String path) {
151            return txSegment() + path;
152        }
153
154        private String txSegment() {
155            return transaction.isShortLived() ? EMPTY : "/" + TX_PREFIX + transaction.getId();
156        }
157    }
158
159    private boolean isRootWithoutTrailingSlash(final Resource resource) {
160        final Map<String, String> values = new HashMap<>();
161
162        return uriTemplate.match(resource.getURI() + "/", values) && values.containsKey("path") &&
163            values.get("path").isEmpty();
164    }
165}