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_CONTAINER; 021import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_RESOURCE; 022import static org.fcrepo.kernel.modeshape.ContainerImpl.hasMixin; 023import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.getContainingNode; 024import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.touch; 025import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.touchLdpMembershipResource; 026import static org.modeshape.jcr.api.JcrConstants.JCR_CONTENT; 027import static org.modeshape.jcr.api.JcrConstants.NT_FOLDER; 028import static org.slf4j.LoggerFactory.getLogger; 029 030import javax.jcr.Node; 031import javax.jcr.RepositoryException; 032 033import org.fcrepo.kernel.api.FedoraSession; 034import org.fcrepo.kernel.api.exception.RepositoryRuntimeException; 035import org.fcrepo.kernel.api.exception.ResourceTypeException; 036import org.fcrepo.kernel.api.models.Container; 037import org.fcrepo.kernel.api.services.ContainerService; 038import org.fcrepo.kernel.modeshape.ContainerImpl; 039 040import org.slf4j.Logger; 041import org.springframework.stereotype.Component; 042 043/** 044 * Service for creating and retrieving {@link org.fcrepo.kernel.api.models.Container} without using the JCR API. 045 * 046 * @author cbeer 047 * @author ajs6f 048 * @since Feb 11, 2013 049 */ 050@Component 051public class ContainerServiceImpl extends AbstractService implements ContainerService { 052 053 private static final Logger LOGGER = getLogger(ContainerServiceImpl.class); 054 055 /** 056 * @param path the path 057 * @param session the session 058 * @return A {@link org.fcrepo.kernel.api.models.Container} with the proffered PID 059 */ 060 @Override 061 public Container findOrCreate(final FedoraSession session, final String path) { 062 LOGGER.trace("Executing findOrCreateObject() with path: {}", path); 063 064 try { 065 final Node node = findOrCreateNode(session, path, NT_FOLDER); 066 067 if (node.isNew()) { 068 initializeNewObjectProperties(node); 069 070 getContainingNode(node).ifPresent(parent -> { 071 touch(parent); 072 touchLdpMembershipResource(node); 073 }); 074 } 075 076 if (node.isNew()) { 077 touch(node); 078 } 079 080 return new ContainerImpl(node); 081 } catch (final RepositoryException e) { 082 throw new RepositoryRuntimeException(e); 083 } 084 } 085 086 /** 087 * Retrieve a {@link org.fcrepo.kernel.api.models.Container} instance by pid and dsid 088 * 089 * @param path the path 090 * @param session the session 091 * @return A {@link org.fcrepo.kernel.api.models.Container} with the proffered PID 092 */ 093 @Override 094 public Container find(final FedoraSession session, final String path) { 095 final Node node = findNode(session, path); 096 097 return cast(node); 098 } 099 100 private static void initializeNewObjectProperties(final Node node) { 101 try { 102 LOGGER.debug("Setting object properties on node {}...", node.getPath()); 103 104 if (node.canAddMixin(FEDORA_RESOURCE)) { 105 node.addMixin(FEDORA_RESOURCE); 106 } 107 108 if (node.canAddMixin(FEDORA_CONTAINER)) { 109 node.addMixin(FEDORA_CONTAINER); 110 } 111 112 } catch (final RepositoryException e) { 113 LOGGER.warn("Could not decorate {} with {} properties: {} ", 114 JCR_CONTENT, FEDORA_CONTAINER, e); 115 } 116 } 117 118 private Container cast(final Node node) { 119 assertIsType(node); 120 return new ContainerImpl(node); 121 } 122 123 private static void assertIsType(final Node node) { 124 if (!hasMixin(node)) { 125 throw new ResourceTypeException(node + " can not be used as a object"); 126 } 127 } 128 129}