001: /*
002: * File : $Source: /usr/local/cvs/opencms/src/org/opencms/file/types/A_CmsResourceTypeFolderBase.java,v $
003: * Date : $Date: 2008-02-27 12:05:45 $
004: * Version: $Revision: 1.21 $
005: *
006: * This library is part of OpenCms -
007: * the Open Source Content Management System
008: *
009: * Copyright (c) 2002 - 2008 Alkacon Software GmbH (http://www.alkacon.com)
010: *
011: * This library is free software; you can redistribute it and/or
012: * modify it under the terms of the GNU Lesser General Public
013: * License as published by the Free Software Foundation; either
014: * version 2.1 of the License, or (at your option) any later version.
015: *
016: * This library is distributed in the hope that it will be useful,
017: * but WITHOUT ANY WARRANTY; without even the implied warranty of
018: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: * Lesser General Public License for more details.
020: *
021: * For further information about Alkacon Software GmbH, please see the
022: * company website: http://www.alkacon.com
023: *
024: * For further information about OpenCms, please see the
025: * project website: http://www.opencms.org
026: *
027: * You should have received a copy of the GNU Lesser General Public
028: * License along with this library; if not, write to the Free Software
029: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
030: */
031:
032: package org.opencms.file.types;
033:
034: import org.opencms.db.CmsSecurityManager;
035: import org.opencms.file.CmsDataNotImplementedException;
036: import org.opencms.file.CmsObject;
037: import org.opencms.file.CmsResource;
038: import org.opencms.file.CmsResourceFilter;
039: import org.opencms.file.CmsVfsException;
040: import org.opencms.lock.CmsLockType;
041: import org.opencms.main.CmsException;
042: import org.opencms.main.CmsIllegalArgumentException;
043: import org.opencms.main.OpenCms;
044: import org.opencms.util.CmsStringUtil;
045:
046: import java.util.List;
047:
048: /**
049: * Resource type descriptor for the type "folder".<p>
050: *
051: * @author Alexander Kandzior
052: *
053: * @version $Revision: 1.21 $
054: *
055: * @since 6.0.0
056: */
057: public abstract class A_CmsResourceTypeFolderBase extends
058: A_CmsResourceType {
059:
060: /**
061: * Default constructor, used to initialize member variables.<p>
062: */
063: public A_CmsResourceTypeFolderBase() {
064:
065: super ();
066: }
067:
068: /**
069: * @see org.opencms.file.types.I_CmsResourceType#chtype(org.opencms.file.CmsObject, CmsSecurityManager, CmsResource, int)
070: */
071: public void chtype(CmsObject cms,
072: CmsSecurityManager securityManager, CmsResource filename,
073: int newType) throws CmsException,
074: CmsDataNotImplementedException {
075:
076: if (!OpenCms.getResourceManager().getResourceType(newType)
077: .isFolder()) {
078: // it is not possible to change the type of a folder to a file type
079: throw new CmsDataNotImplementedException(Messages.get()
080: .container(Messages.ERR_CHTYPE_FOLDER_1,
081: cms.getSitePath(filename)));
082: }
083: super .chtype(cms, securityManager, filename, newType);
084: }
085:
086: /**
087: * @see org.opencms.file.types.I_CmsResourceType#copyResource(org.opencms.file.CmsObject, CmsSecurityManager, CmsResource, java.lang.String, CmsResource.CmsResourceCopyMode)
088: */
089: public void copyResource(CmsObject cms,
090: CmsSecurityManager securityManager, CmsResource source,
091: String destination,
092: CmsResource.CmsResourceCopyMode siblingMode)
093: throws CmsIllegalArgumentException, CmsException {
094:
095: // first validate the destination name
096: destination = validateFoldername(destination);
097:
098: // collect all resources in the folder (but exclude deleted ones)
099: List resources = securityManager.readChildResources(cms
100: .getRequestContext(), source,
101: CmsResourceFilter.IGNORE_EXPIRATION, true, true);
102:
103: // handle the folder itself
104: super .copyResource(cms, securityManager, source, destination,
105: siblingMode);
106:
107: // now walk through all sub-resources in the folder
108: for (int i = 0; i < resources.size(); i++) {
109: CmsResource childResource = (CmsResource) resources.get(i);
110: String childDestination = destination.concat(childResource
111: .getName());
112: // handle child resources
113: getResourceType(childResource).copyResource(cms,
114: securityManager, childResource, childDestination,
115: siblingMode);
116: }
117: }
118:
119: /**
120: * @see org.opencms.file.types.I_CmsResourceType#createResource(org.opencms.file.CmsObject, CmsSecurityManager, java.lang.String, byte[], List)
121: */
122: public CmsResource createResource(CmsObject cms,
123: CmsSecurityManager securityManager, String resourcename,
124: byte[] content, List properties) throws CmsException {
125:
126: resourcename = validateFoldername(resourcename);
127: return super .createResource(cms, securityManager, resourcename,
128: content, properties);
129: }
130:
131: /**
132: * @see org.opencms.file.types.I_CmsResourceType#getLoaderId()
133: */
134: public int getLoaderId() {
135:
136: // folders have no loader
137: return -1;
138: }
139:
140: /**
141: * @see org.opencms.file.types.A_CmsResourceType#isFolder()
142: */
143: public boolean isFolder() {
144:
145: return true;
146: }
147:
148: /**
149: * @see org.opencms.file.types.I_CmsResourceType#moveResource(org.opencms.file.CmsObject, org.opencms.db.CmsSecurityManager, org.opencms.file.CmsResource, java.lang.String)
150: */
151: public void moveResource(CmsObject cms,
152: CmsSecurityManager securityManager, CmsResource resource,
153: String destination) throws CmsException,
154: CmsIllegalArgumentException {
155:
156: String dest = cms.getRequestContext().addSiteRoot(destination);
157: if (!CmsResource.isFolder(dest)) {
158: // ensure folder name end's with a / (required for the following comparison)
159: dest = dest.concat("/");
160: }
161: if (resource.getRootPath().equals(dest)) {
162: // move to target with same name is not allowed
163: throw new CmsVfsException(
164: org.opencms.file.Messages
165: .get()
166: .container(
167: org.opencms.file.Messages.ERR_MOVE_SAME_NAME_1,
168: destination));
169: }
170: if (dest.startsWith(resource.getRootPath())) {
171: // move of folder inside itself is not allowed
172: throw new CmsVfsException(
173: org.opencms.file.Messages
174: .get()
175: .container(
176: org.opencms.file.Messages.ERR_MOVE_SAME_FOLDER_2,
177: cms.getSitePath(resource),
178: destination));
179: }
180:
181: // first validate the destination name
182: dest = validateFoldername(dest);
183:
184: securityManager.moveResource(cms.getRequestContext(), resource,
185: dest);
186: }
187:
188: /**
189: * @see org.opencms.file.types.I_CmsResourceType#replaceResource(org.opencms.file.CmsObject, CmsSecurityManager, CmsResource, int, byte[], List)
190: */
191: public void replaceResource(CmsObject cms,
192: CmsSecurityManager securityManager, CmsResource resource,
193: int type, byte[] content, List properties)
194: throws CmsException, CmsDataNotImplementedException {
195:
196: if (type != getTypeId()) {
197: // it is not possible to replace a folder with a different type
198: throw new CmsDataNotImplementedException(Messages.get()
199: .container(Messages.ERR_REPLACE_RESOURCE_FOLDER_1,
200: cms.getSitePath(resource)));
201: }
202: // properties of a folder can be replaced, content is ignored
203: super .replaceResource(cms, securityManager, resource,
204: getTypeId(), null, properties);
205: }
206:
207: /**
208: * @see org.opencms.file.types.I_CmsResourceType#restoreResourceBackup(org.opencms.file.CmsObject, CmsSecurityManager, CmsResource, int)
209: *
210: * @deprecated Use {@link #restoreResource(CmsObject,CmsSecurityManager,CmsResource,int)} instead
211: */
212: public void restoreResourceBackup(CmsObject cms,
213: CmsSecurityManager securityManager,
214: CmsResource resourename, int version) throws CmsException {
215:
216: restoreResource(cms, securityManager, resourename, version);
217: }
218:
219: /**
220: * @see org.opencms.file.types.I_CmsResourceType#setDateExpired(org.opencms.file.CmsObject, CmsSecurityManager, CmsResource, long, boolean)
221: */
222: public void setDateExpired(CmsObject cms,
223: CmsSecurityManager securityManager, CmsResource resource,
224: long dateLastModified, boolean recursive)
225: throws CmsException {
226:
227: // handle the folder itself
228: super .setDateExpired(cms, securityManager, resource,
229: dateLastModified, recursive);
230:
231: if (recursive) {
232: // collect all resources in the folder (but exclude deleted ones)
233: List resources = securityManager.readChildResources(cms
234: .getRequestContext(), resource,
235: CmsResourceFilter.IGNORE_EXPIRATION, true, true);
236:
237: // now walk through all sub-resources in the folder
238: for (int i = 0; i < resources.size(); i++) {
239: CmsResource childResource = (CmsResource) resources
240: .get(i);
241: // handle child resources
242: getResourceType(childResource).setDateExpired(cms,
243: securityManager, childResource,
244: dateLastModified, recursive);
245: }
246: }
247: }
248:
249: /**
250: * @see org.opencms.file.types.I_CmsResourceType#setDateLastModified(org.opencms.file.CmsObject, CmsSecurityManager, CmsResource, long, boolean)
251: */
252: public void setDateLastModified(CmsObject cms,
253: CmsSecurityManager securityManager, CmsResource resource,
254: long dateLastModified, boolean recursive)
255: throws CmsException {
256:
257: // handle the folder itself
258: super .setDateLastModified(cms, securityManager, resource,
259: dateLastModified, recursive);
260:
261: if (recursive) {
262: // collect all resources in the folder (but exclude deleted ones)
263: List resources = securityManager.readChildResources(cms
264: .getRequestContext(), resource,
265: CmsResourceFilter.IGNORE_EXPIRATION, true, true);
266:
267: // now walk through all sub-resources in the folder
268: for (int i = 0; i < resources.size(); i++) {
269: CmsResource childResource = (CmsResource) resources
270: .get(i);
271: // handle child resources
272: getResourceType(childResource).setDateLastModified(cms,
273: securityManager, childResource,
274: dateLastModified, recursive);
275: }
276: }
277: }
278:
279: /**
280: * @see org.opencms.file.types.I_CmsResourceType#setDateReleased(org.opencms.file.CmsObject, CmsSecurityManager, CmsResource, long, boolean)
281: */
282: public void setDateReleased(CmsObject cms,
283: CmsSecurityManager securityManager, CmsResource resource,
284: long dateLastModified, boolean recursive)
285: throws CmsException {
286:
287: // handle the folder itself
288: super .setDateReleased(cms, securityManager, resource,
289: dateLastModified, recursive);
290:
291: if (recursive) {
292: // collect all resources in the folder (but exclude deleted ones)
293: List resources = securityManager.readChildResources(cms
294: .getRequestContext(), resource,
295: CmsResourceFilter.IGNORE_EXPIRATION, true, true);
296:
297: // now walk through all sub-resources in the folder
298: for (int i = 0; i < resources.size(); i++) {
299: CmsResource childResource = (CmsResource) resources
300: .get(i);
301: // handle child resources
302: getResourceType(childResource).setDateReleased(cms,
303: securityManager, childResource,
304: dateLastModified, recursive);
305: }
306: }
307: }
308:
309: /**
310: * @see org.opencms.file.types.A_CmsResourceType#undelete(org.opencms.file.CmsObject, org.opencms.db.CmsSecurityManager, org.opencms.file.CmsResource, boolean)
311: */
312: public void undelete(CmsObject cms,
313: CmsSecurityManager securityManager, CmsResource resource,
314: boolean recursive) throws CmsException {
315:
316: // handle the folder itself
317: super .undelete(cms, securityManager, resource, recursive);
318:
319: if (recursive) {
320: // collect all resources in the folder (but exclude deleted ones)
321: List resources = securityManager.readChildResources(cms
322: .getRequestContext(), resource,
323: CmsResourceFilter.ALL, true, true);
324:
325: // now walk through all sub-resources in the folder
326: for (int i = 0; i < resources.size(); i++) {
327: CmsResource childResource = (CmsResource) resources
328: .get(i);
329: // handle child resources
330: getResourceType(childResource).undelete(cms,
331: securityManager, childResource, recursive);
332: }
333: }
334: }
335:
336: /**
337: * @see org.opencms.file.types.I_CmsResourceType#undoChanges(org.opencms.file.CmsObject, CmsSecurityManager, CmsResource, CmsResource.CmsResourceUndoMode)
338: */
339: public void undoChanges(CmsObject cms,
340: CmsSecurityManager securityManager, CmsResource resource,
341: CmsResource.CmsResourceUndoMode mode) throws CmsException {
342:
343: boolean recursive = mode.isRecursive();
344: if (mode == CmsResource.UNDO_MOVE_CONTENT) {
345: // undo move only?
346: String originalPath = securityManager.resourceOriginalPath(
347: cms.getRequestContext(), resource);
348: if (originalPath.equals(resource.getRootPath())) {
349: // resource not moved
350: recursive = false;
351: }
352: }
353:
354: List resources = null;
355: if (recursive) { // recursive?
356: // collect all resources in the folder (including deleted ones)
357: resources = securityManager.readChildResources(cms
358: .getRequestContext(), resource,
359: CmsResourceFilter.ALL, true, true);
360: }
361:
362: // handle the folder itself, undo move op
363: super .undoChanges(cms, securityManager, resource, mode);
364:
365: // the folder may have been moved back to its original position
366: CmsResource undoneResource2 = securityManager.readResource(cms
367: .getRequestContext(), resource.getStructureId(),
368: CmsResourceFilter.ALL);
369: boolean isMoved = !undoneResource2.getRootPath().equals(
370: resource.getRootPath());
371:
372: if (recursive && (resources != null)) { // recursive?
373: // now walk through all sub-resources in the folder, and undo first
374: for (int i = 0; i < resources.size(); i++) {
375: CmsResource childResource = (CmsResource) resources
376: .get(i);
377: I_CmsResourceType type = getResourceType(childResource);
378: if (isMoved) {
379: securityManager.lockResource(cms
380: .getRequestContext(), childResource,
381: CmsLockType.EXCLUSIVE);
382: }
383: if (childResource.isFolder()) {
384: // recurse into this method for subfolders
385: type.undoChanges(cms, securityManager,
386: childResource, mode);
387: } else if (!childResource.getState().isNew()) {
388: // undo changes for changed files
389: securityManager.undoChanges(
390: cms.getRequestContext(), childResource,
391: mode);
392: } else {
393: // undo move for new files? move with the folder
394: if (mode.isUndoMove()) {
395: String newPath = cms
396: .getRequestContext()
397: .removeSiteRoot(
398: securityManager
399: .readResource(
400: cms
401: .getRequestContext(),
402: resource
403: .getStructureId(),
404: CmsResourceFilter.ALL)
405: .getRootPath()
406: + childResource
407: .getName());
408: type.moveResource(cms, securityManager,
409: childResource, newPath);
410: }
411: }
412: }
413:
414: // now iterate again all sub-resources in the folder, and actualize the relations
415: for (int i = 0; i < resources.size(); i++) {
416: CmsResource childResource = (CmsResource) resources
417: .get(i);
418: updateRelationForUndo(cms, securityManager,
419: childResource);
420: }
421: }
422: }
423:
424: /**
425: * Checks if there are at least one character in the folder name,
426: * also ensures that it starts and ends with a '/'.<p>
427: *
428: * @param resourcename folder name to check (complete path)
429: *
430: * @return the validated folder name
431: *
432: * @throws CmsIllegalArgumentException if the folder name is empty or <code>null</code>
433: */
434: private String validateFoldername(String resourcename)
435: throws CmsIllegalArgumentException {
436:
437: if (CmsStringUtil.isEmpty(resourcename)) {
438: throw new CmsIllegalArgumentException(
439: org.opencms.db.Messages
440: .get()
441: .container(
442: org.opencms.db.Messages.ERR_BAD_RESOURCENAME_1,
443: resourcename));
444: }
445: if (!CmsResource.isFolder(resourcename)) {
446: resourcename = resourcename.concat("/");
447: }
448: if (resourcename.charAt(0) != '/') {
449: resourcename = "/".concat(resourcename);
450: }
451: return resourcename;
452: }
453: }
|