001/* 002 * Copyright 2010 Anyware Services 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 */ 016package org.ametys.plugins.explorer.resources.jcr; 017 018import java.util.List; 019 020import javax.jcr.Node; 021import javax.jcr.Property; 022import javax.jcr.RepositoryException; 023 024import org.ametys.plugins.explorer.ExplorerNode; 025import org.ametys.plugins.explorer.resources.ModifiableResourceCollection; 026import org.ametys.plugins.explorer.resources.Resource; 027import org.ametys.plugins.repository.AmetysObject; 028import org.ametys.plugins.repository.AmetysObjectIterable; 029import org.ametys.plugins.repository.AmetysRepositoryException; 030import org.ametys.plugins.repository.CopiableAmetysObject; 031import org.ametys.plugins.repository.ModifiableTraversableAmetysObject; 032import org.ametys.plugins.repository.UnknownAmetysObjectException; 033import org.ametys.plugins.repository.data.ametysobject.ModifiableModelLessDataAwareAmetysObject; 034import org.ametys.plugins.repository.data.holder.ModifiableModelLessDataHolder; 035import org.ametys.plugins.repository.data.holder.impl.DefaultModifiableModelLessDataHolder; 036import org.ametys.plugins.repository.data.repositorydata.ModifiableRepositoryData; 037import org.ametys.plugins.repository.data.repositorydata.impl.JCRRepositoryData; 038import org.ametys.plugins.repository.jcr.DefaultTraversableAmetysObject; 039import org.ametys.plugins.repository.jcr.JCRTraversableAmetysObject; 040import org.ametys.plugins.repository.jcr.NameHelper; 041import org.ametys.plugins.repository.jcr.NameHelper.NameComputationMode; 042import org.ametys.plugins.repository.jcr.NodeHelper; 043import org.ametys.plugins.repository.jcr.NodeTypeHelper; 044import org.ametys.plugins.repository.trash.TrashElement; 045import org.ametys.plugins.repository.trash.TrashableAmetysObject; 046import org.ametys.plugins.repository.trash.UnknownParentException; 047 048/** 049 * {@link ExplorerNode} representing a collection of resources. 050 * @param <F> the actual type of factory. 051 */ 052public class JCRResourcesCollection<F extends JCRResourcesCollectionFactory> extends DefaultTraversableAmetysObject<F> implements ModifiableResourceCollection, CopiableAmetysObject, ModifiableModelLessDataAwareAmetysObject, TrashableAmetysObject 053{ 054 /** application id for resources collections. */ 055 public static final String APPLICATION_ID = "Ametys.plugins.explorer.applications.resources.Resources"; 056 057 /** Constants for description metadata */ 058 protected static final String DATA_DESCRIPTION = "description"; 059 060 /** 061 * Constructor 062 * @param node The jcr node 063 * @param parentPath The parent path 064 * @param factory The factory 065 */ 066 public JCRResourcesCollection(Node node, String parentPath, F factory) 067 { 068 super(node, parentPath, factory); 069 } 070 071 @Override 072 public String getIconCls() 073 { 074 return "ametysicon-folder249"; 075 } 076 077 @Override 078 public String getApplicationId() 079 { 080 return APPLICATION_ID; 081 } 082 083 @Override 084 public String getCollectionType() 085 { 086 return JCRResourcesCollectionFactory.RESOURCESCOLLECTION_NODETYPE; 087 } 088 089 @Override 090 public String getResourceType() 091 { 092 return JCRResourceFactory.RESOURCES_NODETYPE; 093 } 094 095 @Override 096 public String getResourcePath() throws AmetysRepositoryException 097 { 098 return getExplorerPath(); 099 } 100 101 @Override 102 public String getExplorerPath() 103 { 104 AmetysObject parent = getParent(); 105 106 if (parent instanceof ExplorerNode) 107 { 108 return ((ExplorerNode) parent).getExplorerPath() + "/" + getName(); 109 } 110 else 111 { 112 return ""; 113 } 114 } 115 116 public boolean hasChildResources() throws AmetysRepositoryException 117 { 118 AmetysObjectIterable<AmetysObject> children = getChildren(); 119 for (AmetysObject child : children) 120 { 121 if (child instanceof Resource) 122 { 123 return true; 124 } 125 } 126 127 return false; 128 } 129 130 public boolean hasChildExplorerNodes() throws AmetysRepositoryException 131 { 132 AmetysObjectIterable<AmetysObject> children = getChildren(); 133 for (AmetysObject child : children) 134 { 135 if (child instanceof ExplorerNode) 136 { 137 return true; 138 } 139 } 140 141 return false; 142 } 143 144 @Override 145 public AmetysObject copyTo(ModifiableTraversableAmetysObject parent, String name) throws AmetysRepositoryException 146 { 147 try 148 { 149 String nodeTypeName = NodeTypeHelper.getNodeTypeName(getNode()); 150 151 JCRResourcesCollection copiedCollection = parent.createChild(name, nodeTypeName); 152 parent.saveChanges(); 153 154 for (AmetysObject object : getChildren()) 155 { 156 if (object instanceof CopiableAmetysObject) 157 { 158 ((CopiableAmetysObject) object).copyTo(copiedCollection, object.getName()); 159 } 160 } 161 162 return copiedCollection; 163 } 164 catch (RepositoryException e) 165 { 166 throw new AmetysRepositoryException("Error copying the collection " + getId() + " into " + parent.getId(), e); 167 } 168 } 169 170 @Override 171 public AmetysObject copyTo(ModifiableTraversableAmetysObject parent, String name, List<String> restrictTo) throws AmetysRepositoryException 172 { 173 return copyTo(parent, name); 174 } 175 176 @Override 177 public String getDescription() 178 { 179 return getValue(DATA_DESCRIPTION, null); 180 } 181 182 @Override 183 public void setDescription(String description) 184 { 185 setValue(DATA_DESCRIPTION, description); 186 } 187 188 public ModifiableModelLessDataHolder getDataHolder() 189 { 190 ModifiableRepositoryData repositoryData = new JCRRepositoryData(getNode()); 191 return new DefaultModifiableModelLessDataHolder(_getFactory().getDataTypesExtensionPoint(), repositoryData); 192 } 193 194 public TrashElement moveToTrash() 195 { 196 TrashElement trashElement = _getFactory()._getTrashElementDAO().createTrashElement(this, getName()); 197 // Clone the ametys object from the original session to trash session 198 Node storedNode = NodeHelper.cloneNode(getNode(), trashElement.getNode()); 199 200 try 201 { 202 storedNode.setProperty("ametys-internal:path", this.getParentPath()); 203 } 204 catch (RepositoryException e) 205 { 206 throw new AmetysRepositoryException("failed to store the content path", e); 207 } 208 209 // Remove the node from the original session 210 remove(); 211 212 return trashElement; 213 } 214 215 public JCRResourcesCollection restoreFromTrash() throws UnknownParentException 216 { 217 try 218 { 219 Property property = getNode().getProperty("ametys-internal:path"); 220 String parentPath = property.getValue().getString(); 221 property.remove(); 222 JCRTraversableAmetysObject parent; 223 try 224 { 225 parent = _getFactory()._getResolver().resolveByPath(parentPath); 226 } 227 catch (UnknownAmetysObjectException e) 228 { 229 throw new UnknownParentException("No parent available at path " + parentPath, e); 230 } 231 232 // Get the node name, can be adjust if another content has already the same node name 233 String nodeName = NameHelper.getUniqueAmetysObjectName(parent, getName(), NameComputationMode.USER_FRIENDLY, true); 234 235 // Clone the ametys object from the trash session to default session 236 NodeHelper.cloneNode(getNode(), parent.getNode(), nodeName); 237 238 // Remove the node from the trash session 239 remove(); 240 241 return parent.getChild(nodeName); 242 } 243 catch (RepositoryException e) 244 { 245 throw new AmetysRepositoryException("failed to store the content path", e); 246 } 247 } 248}