libreccm-legacy/ccm-docrepo/src/com/arsdigita/docrepo/Folder.java

363 lines
11 KiB
Java

/*
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.docrepo;
import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.domain.DomainCollection;
import com.arsdigita.persistence.DataObject;
import com.arsdigita.persistence.DataQuery;
import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.Session;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.persistence.DataAssociation;
import com.arsdigita.persistence.metadata.ObjectType;
import java.math.BigDecimal;
import java.util.StringTokenizer;
/**
* Represents a Folder in the document repository application.
*
* @author Stefan Deusch (stefan@arsdigita.com)
* @author Ron Henderson (ron@arsdigita.com)
* @version $Id: Folder.java pboy $
*/
public class Folder extends ResourceImpl {
public static final String BASE_DATA_OBJECT_TYPE =
"com.arsdigita.docrepo.Folder";
/**
* Constructor.
*/
public Folder() {
this(BASE_DATA_OBJECT_TYPE);
}
/**
* Creates a new folder object.
*/
public Folder(DataObject dataObject) {
super(dataObject);
}
/**
* Creates a new folder by retrieving it based on ID.
*
* @param id - the BigDecimal ID
*/
public Folder(BigDecimal id) throws DataObjectNotFoundException {
this(new OID(BASE_DATA_OBJECT_TYPE, id));
}
/**
* Creates a new folder by retrieving it based on OID.
*
* @param oid - the Object oID
*/
public Folder(OID oid) throws DataObjectNotFoundException {
super(oid);
}
public Folder(String objectTypeString) {
super(objectTypeString);
}
/**
* Constructor. The contained <code>DataObject</code> is
* initialized with a new <code>DataObject</code> with an
* <code>ObjectType</code> specified by <i>type</i>.
*
* @param type The <code>ObjectType</code> of the contained
* <code>DataObject</code>.
*
* @see com.arsdigita.domain.DomainObject#DomainObject(ObjectType)
* @see com.arsdigita.persistence.DataObject
* @see com.arsdigita.persistence.metadata.ObjectType
*/
protected Folder(ObjectType type) {
super(type);
}
/**
* Creates a named folder with a description.
*
* @param name the name of the folder
* @param description the description of the folder contents (may
* be null)
*/
public Folder(String name, String description) {
super(BASE_DATA_OBJECT_TYPE, name, description);
}
/**
* Creates a sub folder inside a given parent folder.
*
* @param name the name of the folder
* @param description the description of the folder contents (may
* be null)
*/
public Folder(String name, String description, Folder parent) {
super(BASE_DATA_OBJECT_TYPE);
if (parent.hasResource(name)) {
throw new ResourceExistsException("A resource named " +
name +
" exists in the parent folder " +
parent.getName());
}
setParent(parent);
setName(name);
setDescription(description);
}
@Override
protected void beforeSave() {
if (s_log.isDebugEnabled()) {
s_log.debug("folder before save");
}
set(Repository.IS_FOLDER, Boolean.TRUE);
super.beforeSave();
}
@Override
protected String getBaseDataObjectType() {
return BASE_DATA_OBJECT_TYPE;
}
@Override
public void setParent(Resource parent) {
if (parent instanceof Folder) {
final String parentPath = parent.getPath();
final String path = getPath();
if (s_log.isDebugEnabled()) {
s_log.debug("folder set parent Parent path: " +
parentPath +
" folder path: " +
path);
}
if (path != null && parentPath.startsWith(path)) {
throw new ResourceException(
"The parent is a child of this folder. "
+ "Parent path: " + parentPath
+ " folder path: " + path);
}
}
super.setParent(parent);
}
/**
* Retrieves the named sub folder by searching from the current folder
* along the given path. Returns the child folder or throws a
* DataObjectNotFoundException if the subfolder does not exist.
*
* @return child folder if and only if it exists as a sub folder
* with the correct path
*/
public Folder retrieveFolder(String path) throws DataObjectNotFoundException,
InvalidNameException {
return new Folder(getResourceID(path));
}
/**
*
* @param path
* @return
* @throws DataObjectNotFoundException
* @throws InvalidNameException
*/
public File retrieveFile(String path) throws DataObjectNotFoundException,
InvalidNameException {
return new File(getResourceID(path));
}
/**
*
* @param name
* @return
*/
public boolean hasResource(String name) {
DataAssociation da = (DataAssociation) get("immediateChildren");
DomainCollection resources = new DomainCollection(da);
resources.addEqualsFilter(Repository.NAME, name);
try {
return resources.next();
} finally {
resources.close();
}
}
/**
* Creates the sub folder named by path, including any necessary
* but nonexistent parent folders.
*/
public Folder createFolders(final String path)
throws InvalidNameException,
ResourceExistsException
{
int pec;
if ( (pec = isValidPath(path)) != 0 ) {
throw new InvalidNameException(pec);
}
// Build up the array of sub folders to search for. First we
// just extract the set of path elements from the path
// string. If the path is "a/b/c", this will produce:
//
// name[0] = a
// name[1] = b
// name[2] = c
StringTokenizer st = new StringTokenizer(path,SEPARATOR);
int pathElementCount = st.countTokens();
String name[] = new String[pathElementCount];
for (int i = 0; i < pathElementCount; i++) {
name[i] = st.nextToken();
}
// Build the array of sub paths. If the original path is
// "a/b/c", this will produce:
//
// subPath[0] = /a
// subPath[1] = /a/b
// subPath[2] = /a/b/c
String subPath[] = new String[pathElementCount];
for (int i = 0; i < pathElementCount; i++) {
StringBuilder buf = new StringBuilder();
for (int j = 0; j <= i; j++) {
buf.append(SEPARATOR);
buf.append(name[j]);
}
subPath[i] = buf.toString();
}
// Now we check for the existence of each Folder starting from
// the end until we find one that exists.
Folder folder[] = new Folder[pathElementCount];
int lastPathElementIndex = pathElementCount - 1;
int retrievedFolderIndex = -1;
for (retrievedFolderIndex = lastPathElementIndex;
retrievedFolderIndex >= 0;
retrievedFolderIndex--) {
try {
folder[retrievedFolderIndex] =
retrieveFolder(subPath[retrievedFolderIndex].substring(1));
break;
} catch (DataObjectNotFoundException ex) {
// continue retrieving
}
}
// Verify that we did NOT retrieve the first folder.
if (retrievedFolderIndex == lastPathElementIndex) {
throw new ResourceExistsException
("createFolders: folder exists:" + path);
}
// We now loop back and create each parent folder.
Folder parent = (retrievedFolderIndex < 0) ?
this : folder[retrievedFolderIndex];
for (int i = retrievedFolderIndex + 1; i < pathElementCount; i++) {
folder[i] = new Folder(name[i], null, parent);
folder[i].save();
parent = folder[i];
}
return folder[lastPathElementIndex];
}
/**
*
* @return
*/
public boolean isFolder() {
return true;
}
/**
*
* @return
*/
public boolean isFile() {
return false;
}
/**
* Returns the display name for a folder, which is equivalent to
* calling getName().
*/
@Override
public String getDisplayName() {
return getName();
}
/**
* Copy this folder to a new location. Recursively copies all
* children from the original resource location to the new
* resource location.
*/
public Resource copyTo(String name, Resource parent) {
Folder dest = new Folder();
copy(this,dest);
dest.setName(name);
dest.setParent(parent);
dest.save();
Session session = SessionManager.getSession();
DataQuery query = session.retrieveQuery
("com.arsdigita.docrepo.getDirectChildren");
// with byline Version BASE_DATA_OBJECT_TYPE =
// "com.arsdigita.docs.ResourceImpl"
// so all retrieveQueries might have be to corrected.
// ("com.arsdigita.docs.getDirectChildren");
// remove comment after intensive testing!
query.setParameter("parentID", getID());
while (query.next()) {
OID oid = new OID(ResourceImpl.BASE_DATA_OBJECT_TYPE,
query.get("id"));
try {
ResourceImpl orig = (ResourceImpl)
DomainObjectFactory.newInstance(oid);
orig.copyTo(dest);
} catch (DataObjectNotFoundException ex) {
throw new ResourceException(ex);
}
}
return dest;
}
}