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_TOMBSTONE; 021import static org.fcrepo.kernel.modeshape.FedoraSessionImpl.getJcrSession; 022import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.getJcrNode; 023import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.touchLdpMembershipResource; 024import static org.fcrepo.kernel.modeshape.utils.NamespaceTools.validatePath; 025import static org.slf4j.LoggerFactory.getLogger; 026 027import javax.jcr.Node; 028import javax.jcr.RepositoryException; 029import javax.jcr.Session; 030 031import org.fcrepo.kernel.api.FedoraSession; 032import org.fcrepo.kernel.api.exception.InvalidResourceIdentifierException; 033import org.fcrepo.kernel.api.exception.RepositoryRuntimeException; 034import org.fcrepo.kernel.api.models.FedoraResource; 035import org.fcrepo.kernel.api.services.NodeService; 036import org.fcrepo.kernel.modeshape.FedoraResourceImpl; 037import org.slf4j.Logger; 038import org.springframework.stereotype.Component; 039 040/** 041 * Service for managing access to Fedora 'nodes' (either datastreams or objects, we don't care.) 042 * 043 * @author Chris Beer 044 * @author ajs6f 045 * @since May 9, 2013 046 */ 047@Component 048public class NodeServiceImpl extends AbstractService implements NodeService { 049 050 private static final Logger LOGGER = getLogger(NodeServiceImpl.class); 051 052 /* (non-Javadoc) 053 * @see org.fcrepo.kernel.api.services.Service#exists(javax.jcr.Session, java.lang.String) 054 */ 055 @Override 056 public boolean exists(final FedoraSession session, final String path) { 057 final Session jcrSession = getJcrSession(session); 058 final String encodedPath = encodePath(path, session); 059 try { 060 validatePath(jcrSession, encodedPath); 061 return jcrSession.nodeExists(encodedPath); 062 } catch (final IllegalArgumentException e) { 063 throw new InvalidResourceIdentifierException("Illegal path: " + path); 064 } catch (final RepositoryException e) { 065 throw new RepositoryRuntimeException(e); 066 } 067 } 068 069 /** 070 * Retrieve an existing Fedora resource at the given path 071 * 072 * @param session a JCR session 073 * @param path a JCR path 074 * @return Fedora resource at the given path 075 */ 076 @Override 077 public FedoraResource find(final FedoraSession session, final String path) { 078 final Session jcrSession = getJcrSession(session); 079 try { 080 return new FedoraResourceImpl(jcrSession.getNode(encodePath(path, session))); 081 } catch (final RepositoryException e) { 082 throw new RepositoryRuntimeException(e); 083 } 084 } 085 086 /** 087 * Copy an existing object from the source path to the destination path 088 * 089 * @param session a JCR session 090 * @param source the source path 091 * @param destination the destination path 092 */ 093 @Override 094 public void copyObject(final FedoraSession session, final String source, final String destination) { 095 final Session jcrSession = getJcrSession(session); 096 try { 097 jcrSession.getWorkspace().copy(encodePath(source, session), encodePath(destination, session)); 098 touchLdpMembershipResource(getJcrNode(find(session, encodePath(destination, session)))); 099 } catch (final RepositoryException e) { 100 throw new RepositoryRuntimeException(e); 101 } 102 } 103 104 /** 105 * Move an existing object from the source path to the destination path 106 * 107 * @param session the session 108 * @param source the source path 109 * @param destination the destination path 110 */ 111 @Override 112 public void moveObject(final FedoraSession session, final String source, final String destination) { 113 final Session jcrSession = getJcrSession(session); 114 try { 115 final FedoraResource srcResource = find(session, encodePath(source, session)); 116 final Node sourceNode = getJcrNode(srcResource); 117 final String name = sourceNode.getName(); 118 final Node parent = sourceNode.getDepth() > 0 ? sourceNode.getParent() : null; 119 120 jcrSession.getWorkspace().move(source, encodePath(destination, session)); 121 122 if (parent != null) { 123 createTombstone(parent, encodePath(name, session)); 124 } 125 126 touchLdpMembershipResource(getJcrNode(find(session, encodePath(source, session)))); 127 touchLdpMembershipResource(getJcrNode(find(session, encodePath(destination, session)))); 128 129 } catch (final RepositoryException e) { 130 throw new RepositoryRuntimeException(e); 131 } 132 } 133 134 private static void createTombstone(final Node parent, final String path) throws RepositoryException { 135 final FedoraResourceImpl fedoraResource = new FedoraResourceImpl(parent); 136 final Node n = fedoraResource.findOrCreateChild(parent, path, FEDORA_TOMBSTONE); 137 LOGGER.info("Created tombstone at {} ", n.getPath()); 138 } 139 140 /** 141 * @param session the session 142 * @param path the path 143 */ 144 @Override 145 public FedoraResource findOrCreate(final FedoraSession session, final String path) { 146 throw new RepositoryRuntimeException("unimplemented"); 147 } 148}