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.kernel.modeshape.services; 019 020import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_RESOURCE; 021import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_TIME_MAP; 022import static org.fcrepo.kernel.api.FedoraTypes.MEMENTO_ORIGINAL; 023import static org.fcrepo.kernel.api.RdfLexicon.LDPCV_TIME_MAP; 024import static org.modeshape.jcr.api.JcrConstants.NT_FOLDER; 025import static org.slf4j.LoggerFactory.getLogger; 026 027import javax.jcr.Node; 028import javax.jcr.RepositoryException; 029import org.fcrepo.kernel.api.FedoraSession; 030import org.fcrepo.kernel.api.exception.RepositoryRuntimeException; 031import org.fcrepo.kernel.api.exception.ResourceTypeException; 032import org.fcrepo.kernel.api.models.FedoraTimeMap; 033import org.fcrepo.kernel.api.services.TimeMapService; 034import org.fcrepo.kernel.modeshape.FedoraTimeMapImpl; 035import org.slf4j.Logger; 036import org.springframework.stereotype.Component; 037 038 039/** 040 * Service for creating and retrieving {@link org.fcrepo.kernel.api.models.FedoraTimeMap} without using the JCR API. 041 * 042 * @author bbpennel 043 */ 044@Component 045public class TimeMapServiceImpl extends AbstractService implements TimeMapService { 046 047 private static final Logger LOGGER = getLogger(TimeMapServiceImpl.class); 048 049 @Override 050 public FedoraTimeMap find(final FedoraSession session, final String path) { 051 final String ldpcvPath = getLdpcvPath(path); 052 053 return cast(findNode(session, ldpcvPath)); 054 } 055 056 @Override 057 public FedoraTimeMap findOrCreate(final FedoraSession session, final String path) { 058 try { 059 // Add fedora:timemap to path if not present 060 final String ldpcvPath = getLdpcvPath(path); 061 062 final Node node = findOrCreateNode(session, ldpcvPath, NT_FOLDER); 063 064 if (node.isNew()) { 065 LOGGER.debug("Created TimeMap LDPCv {}", node.getPath()); 066 067 // add mixin type fedora:Resource 068 if (node.canAddMixin(FEDORA_RESOURCE)) { 069 node.addMixin(FEDORA_RESOURCE); 070 } 071 072 // add mixin type fedora:TimeMap 073 if (node.canAddMixin(FEDORA_TIME_MAP)) { 074 node.addMixin(FEDORA_TIME_MAP); 075 } 076 077 // Set reference from timegate/map to original resource 078 node.setProperty(MEMENTO_ORIGINAL, node.getParent()); 079 } 080 081 return new FedoraTimeMapImpl(node); 082 } catch (final RepositoryException e) { 083 throw new RepositoryRuntimeException(e); 084 } 085 } 086 087 @Override 088 public boolean exists(final FedoraSession session, final String path) { 089 final String ldpcvPath = getLdpcvPath(path); 090 return super.exists(session, ldpcvPath); 091 } 092 093 private static final String getLdpcvPath(final String path) { 094 if (path.endsWith("/" + LDPCV_TIME_MAP)) { 095 return path; 096 } else { 097 return path.replaceFirst("/*$", "") + "/" + LDPCV_TIME_MAP; 098 } 099 } 100 101 private FedoraTimeMap cast(final Node node) { 102 assertIsType(node); 103 return new FedoraTimeMapImpl(node); 104 } 105 106 private static void assertIsType(final Node node) { 107 if (!FedoraTimeMapImpl.hasMixin(node)) { 108 throw new ResourceTypeException(node + " can not be used as a timemap"); 109 } 110 } 111}