[FEATURE]

- adds implementation for the ObjectImporter
- changes name for the im-/exporter business from exchange to portation
  (the package name)
- adds implemtation of ObjectImporter for the File in DocRepo
- adds build dependancy for DocRepo
- removes non-compilable stuff of DocRepo
  (necessary so the tests in docrepo can be compiled before running)
- adds testclass for the FileExporter and FileImporter (last not functioning yet)

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3810 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
tosmers 2016-01-20 19:08:33 +00:00
parent 54f8c657f7
commit 1afb8348ed
38 changed files with 573 additions and 4647 deletions

View File

@ -1,147 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.exchange.exporter.docrepo;
import org.hibernate.validator.constraints.NotEmpty;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.Objects;
/**
* Entity class for a blob object in the doc-repository. Instances of this class
* will be persisted into the database.
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 01/10/2015
*/
@Entity
@Table(schema = "CCM_DOCREPO", name = "BLOB_OBJECTS")
public class BlobObject implements Serializable {
private static final long serialVersionUID = -7468014879548796218L;
/**
* The ID/primary key for the {@code BlobObject}. Please note that it is not
* necessary to define an additional ID on classes which extend this class.
*/
@Id
@Column(name = "BLOB_OBJECT_ID")
@GeneratedValue(strategy = GenerationType.AUTO)
private long blobObjectId;
/**
* The Content of the {@code BlobObject}.
*/
@Column(name = "CONTENT")
@Lob
@NotEmpty
private byte[] content;
/**
* The {@link Resource} the {@code BlobObject} was assigned to.
*/
@OneToOne(mappedBy = "content")
@NotEmpty
private Resource resource;
/**
* Constructor.
*/
public BlobObject() {}
//> Begin GETTER & SETTER
public long getBlobObjectId() {
return blobObjectId;
}
public void setBlobObjectId(long blobObjectId) {
this.blobObjectId = blobObjectId;
}
public byte[] getContent() {
return content;
}
public void setContent(byte[] content) {
this.content = content;
}
public Resource getResource() {
return resource;
}
public void setResource(Resource resource) {
this.resource = resource;
}
//< End GETTER & SETTER
@Override
public int hashCode() {
int hash = 5;
hash = 61 * hash + (int) (blobObjectId ^ (blobObjectId >>> 32));
hash = 61 * hash + Objects.hashCode(content);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof BlobObject)) {
return false;
}
final BlobObject other = (BlobObject) obj;
if (!other.canEqual(this)) {
return false;
}
return blobObjectId == other.getBlobObjectId() &&
Objects.equals(content, other.getContent());
}
public boolean canEqual(final Object obj) {
return obj instanceof BlobObject;
}
@Override
public String toString() {
return String.format("%s{ "
+ "blobObjectId = %d, "
+ "content = %s, "
+ " }",
super.toString(),
blobObjectId,
content.toString());
}
}

View File

@ -1,44 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.exchange.exporter.docrepo;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* Entity class for a file in the doc-repository. Instances will be persisted
* into the database. Instance variables are inherited from {@link Resource}.
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 01/10/2015
*/
@Entity
@Table(schema = "CCM_DOCREPO", name = "FILES")
public class File extends Resource {
private static final long serialVersionUID = -504220783419811504L;
/**
* Constructor calls the super-class-constructor of {@link Resource}.
*/
public File() {
super();
}
}

View File

@ -1,62 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.exchange.exporter.docrepo;
import javax.persistence.Entity;
import javax.persistence.OneToOne;
import javax.persistence.Table;
/**
* Entity class of a folder in the doc-repository. Instances will be persisted
* into the database. Instance variables are inherited from {@link Resource}.
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 01/10/2015
*/
@Entity
@Table(schema = "CCM_DOCREPO", name = "FOLDERS")
public class Folder extends Resource {
private static final long serialVersionUID = 1561466556458872622L;
/**
* The {@link Repository} this {@code Folder} is assigned to as root.
*/
@OneToOne(mappedBy = "rootFolder")
private Repository repository;
/**
* Constructor calls the super-class-constructor of {@link Resource}.
*/
public Folder() {
super();
}
//> Begin GETTER & SETTER
public Repository getRepository() {
return repository;
}
public void setRepository(Repository repository) {
this.repository = repository;
}
//< End GETTER & SETTER
}

View File

@ -1,46 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.exchange.exporter.docrepo;
import org.libreccm.portal.Portlet;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* Entity class for a portlet of recent updated documents in the doc-repository.
* Instances will be persisted into the database. Instance variables are inherited
* form {@link Portlet}.
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 01/10/2015
*/
@Entity
@Table(schema = "CCM_DOCREPO", name = "REC_UPD_DOCS_PORTLETS")
public class RecUpdDocsPortlet extends Portlet {
private static final long serialVersionUID = -4091024367070127101L;
/**
* Constructor calls the super-class-constructor of {@link Portlet}.
*/
public RecUpdDocsPortlet() {
super();
}
}

View File

@ -1,126 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.exchange.exporter.docrepo;
import org.hibernate.validator.constraints.NotBlank;
import org.libreccm.security.User;
import org.libreccm.web.CcmApplication;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import java.util.List;
/**
* Entity class of a repository for documents. Instances will be persisted into
* the database. Instance variables are inherited from {@link CcmApplication}.
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 01/10/2015
*/
@Entity
@Table(schema = "CCM_DOCREPO", name = "REPOSITORIES")
@NamedQueries({
@NamedQuery(name = "DocRepo.findRepositoriesForOwner",
query = "SELECT r FROM Repository r WHERE r.owner = :owner")
})
public class Repository extends CcmApplication {
private static final long serialVersionUID = 6673243021462798036L;
/**
* Name des {@code Repository}s.
*/
@Column(name = "NAME", length = 512, unique = true, nullable = false)
@NotBlank
private String name;
/**
* The root of the {@code Repository}.
*/
@OneToOne
@JoinColumn(name = "ROOT_FOLDER_ID", unique = true, nullable = false)
@NotBlank
private Folder rootFolder;
/**
* The owner of the {@code Repository}.
*/
@OneToOne
@JoinColumn(name = "OWNER_ID", nullable = false)
@NotBlank
private User owner;
/**
* All {@link Resource}s contained in this {@code Repository}.
*/
@OneToMany(mappedBy = "repository")
private List<Resource> resources;
/**
* Constructor calls the super-class-constructor of {@link CcmApplication}.
*/
public Repository() {
super();
}
//> Begin GETTER & SETTER
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Folder getRootFolder() {
return rootFolder;
}
public void setRootFolder(Folder root_folder) {
this.rootFolder = root_folder;
}
public User getOwner() {
return owner;
}
public void setOwner(User owner) {
this.owner = owner;
}
public List<Resource> getResources() {
return resources;
}
public void setResources(List<Resource> resources) {
this.resources = resources;
}
//< End GETTER & SETTER
}

View File

@ -1,95 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.exchange.exporter.docrepo;
import org.libreccm.auditing.AbstractAuditedEntityRepository;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.security.PermissionChecker;
import org.libreccm.security.User;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.util.List;
import java.util.stream.Collectors;
/**
* Repository class for retrieving, storing and deleting {@code Repository}s.
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 25/11/2015
*/
@RequestScoped
public class RepositoryRepository extends
AbstractAuditedEntityRepository<Long, Repository> {
@Inject
private EntityManager entityManager;
@Override
public Long getEntityId(Repository entity) {
return entity.getObjectId();
}
@Override
public Class<Repository> getEntityClass() {
return Repository.class;
}
@Override
public boolean isNew(Repository entity) {
if (entity == null) {
throw new IllegalArgumentException("Entity to save can't be null.");
}
return entity.getObjectId() == 0;
}
/**
* Checks if the current subject has permissions grating him the
* privilege to read the requested {@link Repository}(s) and removes the
* ones he is not allowed to access.
*
* @param repositories The requested {@link Resource}s, found in the database
* @return A list of {@link Resource}s the subject is allowed to access
*/
private List<Repository> permissionFilter(List<Repository> repositories) {
final CdiUtil cdiUtil = new CdiUtil();
final PermissionChecker permissionChecker = cdiUtil.findBean(
PermissionChecker.class);
return repositories.stream().filter(repository -> permissionChecker
.isPermitted("read", repository)).collect(Collectors.toList());
}
/**
* Retrieve all {@link Repository}s a given {@link User} ownes.
*
* @param owner The owner of the {@link Repository}s
*
* @return The {@link Repository}s owned by the given {@link User}
*/
public List<Repository> findForOwner(User owner) {
final TypedQuery<Repository> query = entityManager.createNamedQuery(
"DocRepo.findRepositoriesForOwner", Repository.class);
query.setParameter("owner", owner);
return permissionFilter(query.getResultList());
}
}

View File

@ -1,324 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.exchange.exporter.docrepo;
import org.hibernate.validator.constraints.NotBlank;
import org.libreccm.core.CcmObject;
import org.libreccm.security.User;
import javax.activation.MimeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import java.util.Date;
import java.util.List;
/**
* Abstract entity class of a resource. Instances will be persisted into the
* database through the inheriting subclasses.
*
* The inheriting subclasses and therefore resources are: {@link File},
* {@link Folder}
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 01/10/2015
*/
@Entity(name = "DocRepoResource")
@Table(schema = "CCM_DOCREPO", name = "RESOURCES")
@NamedQueries({
@NamedQuery(name = "DocRepo.findResourceByPath",
query = "SELECT r FROM DocRepoResource r WHERE " +
"r.path = :pathName"),
@NamedQuery(name = "DocRepo.findResourcesByName",
query = "SELECT r FROM DocRepoResource r WHERE " +
"r.name = :name"),
@NamedQuery(name = "DocRepo.findCreatedResourcesFromUser",
query = "SELECT r FROM DocRepoResource r WHERE " +
"r.creationUser = :user"),
@NamedQuery(name = "DocRepo.findModifiedResourcesFromUser",
query = "SELECT r FROM DocRepoResource r WHERE " +
"r.lastModifiedUser = :user")})
public abstract class Resource extends CcmObject {
private static final long serialVersionUID = -910317798106611214L;
/**
* Name of the {@code Resource}.
*/
@Column(name = "NAME", length = 512, unique = true, nullable = false)
@NotBlank
private String name;
/**
* Description of the {@code Resource}.
*/
@Column(name = "DESCRIPTION")
private String description;
/**
* Flag, wheather the {@code Resource} is a {@link Folder} or not.
*/
@Column(name = "IS_FOLDER")
@NotBlank
private boolean isFolder;
/**
* Path to the {@code Resource}.
*/
@Column(name = "PATH", unique = true)
@NotBlank
private String path;
/**
* Mime-type of the {@code Resource}.
*/
@Column(name = "MIME_TYPE")
private MimeType mimeType;
/**
* Size of the {@code Resource}.
*/
@Column(name = "SIZE")
private long size;
/**
* Content of the {@code Resource} as a {@link BlobObject}.
*/
@OneToOne
@JoinColumn(name = "CONTENT_ID")
private BlobObject content;
/**
* Creation date of the {@code Resource}.
*/
@Column(name = "CREATION_DATE")
@NotBlank
@Temporal(TemporalType.TIMESTAMP)
private Date creationDate;
/**
* Date of the latest modification of the {@code Resource}.
*/
@Column(name = "LAST_MODIFIED_DATE")
@NotBlank
@Temporal(TemporalType.TIMESTAMP)
private Date lastModifiedDate;
/**
* Creation ip of the {@code Resource}.
*/
@Column(name = "CREATION_IP")
private String creationIp;
/**
* Ip of the latest modification of the {@code Resource}.
*/
@Column(name = "LAST_MODIFIED_IP")
private String lastModifiedIp;
/**
* The {@link User}, who created the {@code Resource}.
*/
@ManyToOne
@JoinColumn(name = "CREATION_USER_ID")
private User creationUser;
/**
* The {@link User}, who last modified the {@code Resource}.
*/
@ManyToOne
@JoinColumn(name = "LAST_MODIFIED_USER_ID")
private User lastModifiedUser;
/**
* The parent-{@code Resource} of the {@code Resource}.
*/
@ManyToOne
@JoinColumn(name = "PARENT_ID")
private Resource parent;
/**
* The child-{@code Resource}s of the {@code Resource}.
*/
@OneToMany(mappedBy = "parent")
private List<Resource> immediateChildren;
/**
* The {@link Repository} containing this {@code Resource}.
*/
@ManyToOne
@JoinColumn(name = "REPOSITORY_ID")
private Repository repository;
/**
* Constructor calls the super-class-constructor of {@link CcmObject}.
*/
public Resource() {
super();
}
//> Begin GETTER & SETTER
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public boolean isFolder() {
return isFolder;
}
public void setIsFolder(boolean isFolder) {
this.isFolder = isFolder;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public MimeType getMimeType() {
return mimeType;
}
public void setMimeType(MimeType mimeType) {
this.mimeType = mimeType;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public BlobObject getContent() {
return content;
}
public void setContent(BlobObject content) {
this.content = content;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public Date getLastModifiedDate() {
return lastModifiedDate;
}
public void setLastModifiedDate(Date lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}
public String getCreationIp() {
return creationIp;
}
public void setCreationIp(String creationIp) {
this.creationIp = creationIp;
}
public String getLastModifiedIp() {
return lastModifiedIp;
}
public void setLastModifiedIp(String lastModifiedIp) {
this.lastModifiedIp = lastModifiedIp;
}
public User getCreationUser() {
return creationUser;
}
public void setCreationUser(User creationUser) {
this.creationUser = creationUser;
}
public User getLastModifiedUser() {
return lastModifiedUser;
}
public void setLastModifiedUser(User lastModifiedUser) {
this.lastModifiedUser = lastModifiedUser;
}
public Resource getParent() {
return parent;
}
public void setParent(Resource parent) {
this.parent = parent;
}
public List<Resource> getImmediateChildren() {
return immediateChildren;
}
public void setImmediateChildren(List<Resource> immediateChildren) {
this.immediateChildren = immediateChildren;
}
public Repository getRepository() {
return repository;
}
public void setRepository(Repository repository) {
this.repository = repository;
}
//< End GETTER & SETTER
public boolean isRoot() {
return isFolder() && getParent() == null;
}
public boolean isFile() {
return !isFolder();
}
}

View File

@ -1,108 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.exchange.exporter.docrepo;
import org.apache.log4j.Logger;
import org.apache.oro.text.perl.Perl5Util;
import javax.activation.MimetypesFileTypeMap;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
/**
* Manager class for complex operations on {@code Resource}-objects.
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 01/10/2015
*/
@RequestScoped
public class ResourceManager {
private static final Logger log = Logger.getLogger(ResourceManager.class);
@Inject
private ResourceRepository resourceRepository;
/**
* Copies a given {@link Resource} to a given {@link Folder}.
*
* @param original The {@link Resource} to be copied
* @param folder The {@link Folder} to copy to
*/
public void copyToFolder(Resource original, Folder folder) {
Resource copy = original.isFolder() ? new Folder() : new File();
copy.setName(original.getName());
copy.setDescription(original.getDescription());
copy.setIsFolder(original.isFolder());
copy.setPath(String.format("%s/%s", folder.getPath(), copy.getName()));
copy.setMimeType(original.getMimeType());
copy.setSize(original.getSize());
copy.setContent(original.getContent());
copy.setParent(folder);
copy.setImmediateChildren(original.getImmediateChildren());
resourceRepository.save(copy);
}
/**
* Determines weather the given name is a valid new name for the also
* given {@link Resource}.
*
* Verifies that the string only contains valid characters for
* {@link Resource} names. The following name patterns are allowed:
*
* [a-z][A-Z][0-9][-., ]
*
* In addition, names cannot begin with ".", i.e. we do NOT support file
* names like ".profile" at the moment. The current implementation does
* not allow international characters for resource names.
*
* @param name The resource name for validation
* @param resource The resource for which the new name needs to be validated
*
* @return true for a system-valid resource name, otherwise false
*/
public boolean isValidNewResourceName(String name, Resource resource) {
Perl5Util perl5Util = new Perl5Util();
final String INVALID_START_PATTERN = "/^[.]+/";
final String INVALID_NAME_PATTERN = "/[^a-zA-Z0-9\\_\\.\\-\\ ]+/";
final String EXTENSION_PATTERN = "/^([^\\.].*)(\\.\\w+)$/";
// adds an extension if non-existent
if (!perl5Util.match(EXTENSION_PATTERN, name)) {
if (perl5Util.match(EXTENSION_PATTERN, resource.getName())) {
name += perl5Util.group(2);
}
}
// checks pattern of the name
boolean validName = !(perl5Util.match(INVALID_START_PATTERN, name) ||
perl5Util.match(INVALID_NAME_PATTERN, name));
// checks duplication of the name; database access (mind performance)
validName &= resourceRepository.findByName(name).isEmpty();
// checks that the name corresponds to a compatible MIME type
validName &= new MimetypesFileTypeMap().getContentType(name).equals
(resource.getMimeType().toString());
return validName;
}
}

View File

@ -1,156 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.exchange.exporter.docrepo;
import org.libreccm.auditing.AbstractAuditedEntityRepository;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.security.PermissionChecker;
import org.libreccm.security.User;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* Repository class for retrieving, storing and deleting {@code Resource}s.
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 01/10/2015
*/
@RequestScoped
public class ResourceRepository extends AbstractAuditedEntityRepository<Long, Resource> {
@Inject
private EntityManager entityManager;
@Override
public Long getEntityId(Resource entity) {
return entity.getObjectId();
}
@Override
public Class<Resource> getEntityClass() {
return Resource.class;
}
@Override
public boolean isNew(Resource entity) {
if (entity == null) {
throw new IllegalArgumentException("Entity to save can't be null.");
}
return entity.getObjectId() == 0;
}
/**
* Checks if the current subject has permissions grating him the
* privilege to read the requested {@link Resource}(s) and removes the
* ones he is not allowed to access.
*
* @param resources The requested {@link Resource}s, found in the database
* @return A list of {@link Resource}s the subject is allowed to access
*/
private List<Resource> permissionFilter(List<Resource> resources) {
final CdiUtil cdiUtil = new CdiUtil();
final PermissionChecker permissionChecker = cdiUtil.findBean(
PermissionChecker.class);
return resources.stream().filter(resource -> permissionChecker
.isPermitted("read", resource)).collect(Collectors.toList());
}
/**
* Checks if the current subject has permissions grating him the
* privilege to read the one requested {@link Resource} and removes it if
* he is not allowed to access.
*
* @param resource The requested {@link Resource}, found in the database
* @return A list of at most one {@link Resource} the subject is allowed to
* access
*/
private Resource permissionFilter(Resource resource) {
return permissionFilter(Arrays.asList(resource)).get(0);
}
/**
* Retrieve a {@code Resource} by its {@code path}.
*
* @param pathName The {@code path} to the {@code Resource}.
*
* @return The {@code Resource} identified by the given {@code path}, if there is
* such a {@code Resource}, {@code null} if not.
*/
public Resource findByPathName(final String pathName) {
final TypedQuery<Resource> query = entityManager.createNamedQuery(
"DocRepo.findResourceByPath", Resource.class);
query.setParameter("pathName", pathName);
return permissionFilter(query.getSingleResult());
}
/**
* Retrieve the {@code Resource}s, a given {@link User} created.
*
* @param creator The {@link User}, who created the {@code Resource}s.
*
* @return The {@code Resource}s, created by the given {@link User}, if there
* are such {@code Resource}s, {@code EmptyList} if not.
*/
public List<Resource> findForCreator(final User creator) {
final TypedQuery<Resource> query = entityManager.createNamedQuery(
"DocRepo.findCreatedResourcesFromUser", Resource.class);
query.setParameter("user", creator);
return permissionFilter(query.getResultList());
}
/**
* Retrieve the {@code Resource}s, a given {@link User} last modified.
*
* @param modifier The {@link User}, who last modified the {@code Resource}s.
*
* @return The {@code Resource}s, last modified by the given {@link User}, if
* there are such {@code Resource}s, {@code EmptyList} if not.
*/
public List<Resource> findForModifier(final User modifier) {
final TypedQuery<Resource> query = entityManager.createNamedQuery(
"DocRepo.findModifiedResourcesFromUser", Resource.class);
query.setParameter("user", modifier);
return permissionFilter(query.getResultList());
}
/**
* Retrieve all {@link Resource}s with the given name.
*
* @param name The name for the searched {@link Resource}
* @return The {@link Resource}s with the given name, if there aren't
* any an {@code EmptyList}
*/
public List<Resource> findByName(final String name) {
final TypedQuery<Resource> query = entityManager.createNamedQuery(
"DocRepo.findResourcesByName", Resource.class);
query.setParameter("name", name);
return permissionFilter(query.getResultList());
}
}

View File

@ -16,13 +16,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA * MA 02110-1301 USA
*/ */
package org.libreccm.exchange.exporter; package org.libreccm.portation.exporter;
import com.opencsv.CSVWriter; import com.opencsv.CSVWriter;
import org.apache.commons.lang.NullArgumentException;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.libreccm.security.User; import org.libreccm.security.User;
import java.io.FileNotFoundException;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
@ -31,7 +31,8 @@ import java.util.stream.Collectors;
/** /**
* Main class for exporting database objects as .csv-textfiles. Subclasses * Main class for exporting database objects as .csv-textfiles. Subclasses
* are required to implement the method {@code asList} matching their own * are required to implement the methods {@code getClassName}, {@code
* getAttributeNames} and {@code reduceToStrings} matching their own
* needs. This is necessary, because every object class stored in the * needs. This is necessary, because every object class stored in the
* database has its own parameters which refer sometimes to other object * database has its own parameters which refer sometimes to other object
* classes. But these other object classes do not need to be exported in * classes. But these other object classes do not need to be exported in
@ -44,7 +45,7 @@ public abstract class ObjectExporter<T> {
private static final Logger log = Logger.getLogger(ObjectExporter.class); private static final Logger log = Logger.getLogger(ObjectExporter.class);
private String filename = "ccm_ng-defaultExportFilename.csv"; private String filename = null;
private char separator = ','; private char separator = ',';
//> Begin GETTER & SETTER //> Begin GETTER & SETTER
@ -77,27 +78,30 @@ public abstract class ObjectExporter<T> {
* {@link User}s, as a .csv-textfile with the specified {@code filename}. * {@link User}s, as a .csv-textfile with the specified {@code filename}.
* *
* @param exportObjects List of objects of type {@code T} to be exported * @param exportObjects List of objects of type {@code T} to be exported
* @throws FileNotFoundException
*/ */
public void export(List<T> exportObjects) throws NullArgumentException { public void exportToCSV(List<T> exportObjects) throws
CSVWriter csvWriter = null; FileNotFoundException {
if (filename == null) {
throw new NullArgumentException(filename);
}
try { try {
csvWriter = new CSVWriter(new FileWriter(filename), CSVWriter csvWriter = new CSVWriter(new FileWriter(filename),
separator); separator);
csvWriter.writeAll(asList(exportObjects)); csvWriter.writeAll(asList(exportObjects));
csvWriter.close(); csvWriter.close();
log.info(String.format("The given objects have been successfully " +
"exported into " +
"the file %s.", filename));
} catch (IOException e) { } catch (IOException e) {
//Todo: what to do log.error(String.format("A FileWriter with the name %s has not " +
e.printStackTrace(); "been able to be created.", filename));
// Todo: throw Exception to modify in ui
throw new FileNotFoundException();
} }
} }
/** /**
* Abstract method to force extending subclasses to implement this * Transforms the list of export objects into a list of {@link String}s
* method, so the needed list for the export is matching their special * by calling the overriding methods declared as abstract in this class.
* needs.
* *
* @param exportObjects List of objects of type {@code T} to be exported * @param exportObjects List of objects of type {@code T} to be exported
* @return A list of strings containing all database information of the * @return A list of strings containing all database information of the
@ -123,8 +127,8 @@ public abstract class ObjectExporter<T> {
protected abstract String[] getClassName(); protected abstract String[] getClassName();
/** /**
* Abstract method to get the class header for the secfirstond line in the * Abstract method to get the class header for the first and second line in
* .csv-textfile. * the .csv-textfile.
* *
* @return A list of strings representing the object attributes * @return A list of strings representing the object attributes
*/ */

View File

@ -0,0 +1,148 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.portation.importer;
import com.opencsv.CSVReader;
import org.apache.log4j.Logger;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
/**
* Main class for importing .csv-textfiles by extracting all their information
* and storing them in new instances of existing database objects. Its
* important, to pay attention to the right order of the information in the
* .csv-textfile to correctly match information with the attributes of the
* database objects. The UUID is being used for reconnecting the referenced
* id's of other objects types with there actual object instance.
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 07/01/2016
*/
public abstract class ObjectImporter<T> {
private static final Logger log = Logger.getLogger(ObjectImporter.class);
private String filename = null;
private char separator = ',';
//> Begin GETTER & SETTER
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public char getSeparator() {
return separator;
}
public void setSeparator(char separator) {
this.separator = separator;
}
//< End GETTER & SETTER
/**
* Empty constructor.
*/
public ObjectImporter() {}
/**
* Imports object information as {@link String} from a .csv-textfile as new
* objects of type {@code T} into the database.
*
* @throws FileNotFoundException
*/
public List<T> importFromCSV() throws FileNotFoundException {
try {
CSVReader csvReader = new CSVReader(new FileReader(filename),
separator);
List<String[]> importList = csvReader.readAll();
if (importList.size() < 3) {
log.error("The given file does not contain any importable " +
"data.");
return null;
}
log.info(String.format("All objects imported from the file %s " +
"have been successfully imported into this systems " +
"database.", filename));
return fromList(importList);
} catch (IOException e) {
log.error(String.format("Either a FileReader with the name %s has " +
"not been able to be created or the file could not be " +
"read.", filename));
// Todo: throw Exception to modify in ui
throw new FileNotFoundException();
}
}
/**
* Transforms the list of {@link String}s into a list of import objects
* by calling the overriding methods declared as abstract in this class.
*
* @param importList List of {@link String}s being imported
* @return A list of objects of type {@code T} containing all the
* information imported from the .csv-textfile.
*/
private List<T> fromList(List<String[]> importList) {
// removes class name and attribute names
importList.remove(0);
if (checkAttributeNames(importList.remove(0))) {
log.error("The attributes in the import file does not match " +
"the attributes of this system");
return null;
}
return importList.stream().map(this::expandFromStrings).collect
(Collectors.toList());
}
/**
* Abstract method to check if the names of the attributes read from the
* .csv-textfile correctly correspond to the attributes of this systems
* database object of type {@code T}.
*
* @param attributeNames List of names hopefully representing the right
* attribute names
* @return true on success, false otherwise
*/
protected abstract boolean checkAttributeNames(String[] attributeNames);
/**
* Abstact method to create a new object of type {@code T} with the imported
* attributes given as parameter and storing that object into the
* systems database.
*
* @param importStrings The attributes belonging to the new database object
* @return The new database object, already inserted into the database
*/
protected abstract T expandFromStrings(String[] importStrings);
}

View File

@ -110,6 +110,11 @@
<artifactId>h2</artifactId> <artifactId>h2</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.13</version>
</dependency>
</dependencies> </dependencies>
@ -122,8 +127,8 @@
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version> <version>3.3</version>
<configuration> <configuration>
<source>1.7</source> <source>1.8</source>
<target>1.7</target> <target>1.8</target>
<optimize>true</optimize> <optimize>true</optimize>
<debug>true</debug> <debug>true</debug>
<encoding>${project.build.sourceEncoding}</encoding> <encoding>${project.build.sourceEncoding}</encoding>

View File

@ -1,451 +0,0 @@
/*
* Copyright (C) 2003-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.ui;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Container;
import com.arsdigita.bebop.DimensionalNavbar;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Link;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.event.PrintEvent;
import com.arsdigita.bebop.event.PrintListener;
import com.arsdigita.bebop.parameters.IntegerParameter;
import com.arsdigita.docrepo.util.GlobalizationUtil;
import com.arsdigita.util.Assert;
import com.arsdigita.web.Web;
import com.arsdigita.xml.Element;
import org.libreccm.web.CcmApplication;
/**
* <p>BasePage class</p>
*
* @author <a href="mailto:jparsons@arsdigita.com">Jim Parsons</a>
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
*/
public class BasePage extends Page {
private final Container globalContainer;
private final Container headerContainer;
private final Container bodyContainer;
private final Container footerContainer;
private IntegerParameter selected = new IntegerParameter("m");
// Todo: add strings to package properties
public static final String DOC_GLOBAL_ELEMENT = "docs:global";
public static final String DOC_HEADER_ELEMENT = "docs:header";
public static final String DOC_BODY_ELEMENT = "docs:body";
public static final String DOC_FOOTER_ELEMENT = "docs:footer";
public static final String DOC_XML_NS = "http://www.redhat.com/docs/1.0";
// There are 2 views: user and admin. view determines which context
// bar and view link to show.
private String view;
private Link viewLink;
/**
* Default constructor.
*/
public BasePage() {
this(null);
}
/**
* Overloaded constructor.
*
* @param view A String that specifies which application view to
* show. Valid values: "user", "admin" and "null". If view is
* "null", there will be no right-hand navigation link. Note -
* We've decided not to have the right-hand navigation link at
* all. Instead, you should create tabs. So, once the
* applications are migrated, view will always be null and we can
* remove view altogether.
*/
public BasePage(String view) {
super(new Label(), new SimpleContainer());
setClassAttr("DOCS");
m_panel = new Panel();
addGlobalStateParam(selected);
globalContainer = new SimpleContainer(DOC_GLOBAL_ELEMENT, DOC_XML_NS);
headerContainer = new SimpleContainer(DOC_HEADER_ELEMENT, DOC_XML_NS);
bodyContainer = new SimpleContainer(DOC_BODY_ELEMENT, DOC_XML_NS);
footerContainer = new SimpleContainer(DOC_FOOTER_ELEMENT, DOC_XML_NS);
super.add(globalContainer);
super.add(headerContainer);
super.add(bodyContainer);
super.add(footerContainer);
this.view = view;
}
/**
* Getter for the global container.
*
* @return The global container.
*/
public Container getGlobal() {
return globalContainer;
}
/**
* Getter for the header container.
*
* @return The header container.
*/
public Container getHeader() {
return headerContainer;
}
/**
* Getter for the body container.
*
* @return The body container.
*/
public Container getBody() {
return bodyContainer;
}
/**
* Getter for the footer container.
*
* @return The footer container.
*/
public Container getFooter() {
return footerContainer;
}
/**
* Locks the page and all its components against further modifications.
*
* <p>Locking a page helps in finding mistakes that result from modifying a
* page's structure.</P>
*/
@Override
public void lock() {
buildPage();
super.lock();
}
/**
* Builds the page.
*
* Only the PortalPage.lock() should invoke this method, though users
* of this class may sometimes want to <em>override</em> this method.
*
* Todo: resolvable or deletable?
* Context Bar temporarily deactivated until the functionality to create
* multiple repositories (table docs_mounted) is restored. Because
* currently there is only one repository mounted there is no relevant
* context
*/
protected final void buildPage() {
buildTitle();
//buildContextBar();
buildGlobal(getGlobal());
buildHeader(getHeader());
buildBody(getBody());
buildFooter(getFooter());
}
/**
* Builds the title.
*/
protected void buildTitle() {
/**
* Internal class.
*/
class ApplicationAdminLabelPrinter implements PrintListener {
public void prepare(PrintEvent e) {
Label targetLabel = (Label)e.getTarget();
CcmApplication application = Web.getWebContext().getApplication();
Assert.exists(application, CcmApplication.class);
targetLabel.setLabel(application.getTitle() + " Administration");
}
}
if (view != null && view.equals("admin")) {
setTitle(new Label(new ApplicationAdminLabelPrinter()));
} else {
setTitle(new Label(new CurrentApplicationLabelPrinter()));
}
}
/**
* Builds the context bar.
*
* Todo: unused method.. delete?
*/
protected void buildContextBar() {
DimensionalNavbar navbar = new DimensionalNavbar();
navbar.setClassAttr("portalNavbar");
navbar.add(new Link(new ParentApplicationLinkPrinter()));
navbar.add(new Link(new CurrentApplicationLinkPrinter()));
getHeader().add(navbar);
}
/**
* Builds by default the global container in the base page.
*
* @param global The global container.
*/
protected void buildGlobal(Container global) {
Link link = new Link(new Label(GlobalizationUtil.globalize("ui.workspace.sign_out")), "/register/logout");
link.setClassAttr("signoutLink");
getGlobal().add(link);
}
/**
* Builds by default the header container in the base page.
*
* @param header The header container.
*/
protected void buildHeader(Container header) {
if (view != null) {
if (view.equals("user")) {
viewLink = new Link(new Label(GlobalizationUtil.globalize("ui.view.admin")), "./admin/index.jsp") {
public boolean isVisible(PageState ps) {
return userIsAdmin(ps);
}};
} else if (view.equals("admin")) {
viewLink = new Link( new Label(GlobalizationUtil.globalize("ui.view.user")), "../index.jsp");
}
}
if (viewLink != null) {
viewLink.setClassAttr("portalControl");
header.add(viewLink);
}
}
/**
* Builds the body container in the base page. By default
* nothing.
*
* @param body The body container.
*/
protected void buildBody(Container body) {}
/**
* Builds the footer container in the base page. By default
* nothing.
*
* @param footer The body container.
*/
protected void buildFooter(Container footer) {}
/**
* Represents a panel as a simple container.
*/
private class Panel extends SimpleContainer {
@Override
public void generateXML(PageState ps, Element p) {
Component selected = getSelected(ps);
if (selected == null) {
super.generateXML(ps, p);
} else {
SimpleContainer fakeBody = new SimpleContainer(DOC_BODY_ELEMENT, DOC_XML_NS);
fakeBody.add(selected);
Element parent = generateParent(p);
headerContainer.generateXML(ps, parent);
footerContainer.generateXML(ps, parent);
fakeBody.generateXML(ps, parent);
}
}
}
/**
* Gets the selected component by the given page state.
*
* @param ps The given page state.
* @return The slected component.
*/
private Component getSelected(PageState ps) {
Integer stateIndex = (Integer) ps.getValue(selected);
Component c = null;
if (stateIndex != null) {
c = getComponent(stateIndex);
}
return c;
}
/**
* Sets the selected component by a given page state and component.
*
* @param ps The page state.
* @param c The component being selected.
*/
private void setSelected(PageState ps, Component c) {
if (c == null) {
ps.setValue(selected, null);
} else {
ps.setValue(selected, stateIndex(c));
}
}
/**
* Makes the given component the only visible component between
* the header and footer of this page.
*
* @param ps The page state.
* @param c The given component.
*/
public void goModal(PageState ps, Component c) {
Component oldc = getSelected(ps);
if (oldc != null) {
oldc.setVisible(ps, false);
}
c.setVisible(ps, true);
setSelected(ps, c);
}
/**
* Clears the currently selected modal component if it has been set.
*
* @param ps The page state to be cleared.
*/
public void goUnmodal(PageState ps) {
Component oldc = getSelected(ps);
if (oldc != null) {
oldc.setVisible(ps, false);
}
setSelected(ps, null);
}
/**
* Checks on the permission level, weather the user is admin by the
* given page state.
*
* @param ps The given page state
* @return true if the user is admin, false otherwise.
*
* Todo: does not need param, can be changed
* Todo: Usage of Permission classes don't work
*/
private boolean userIsAdmin(PageState ps) {
// PermissionDescriptor permDescriptor =
// new PermissionDescriptor(PrivilegeDescriptor.ADMIN,
// Web.getWebContext().getApplication(),
// Kernel.getContext().getParty());
// return PermissionService.checkPermission(permDescriptor);
return false;
}
/**
* Adds a component to the body.
*
* @param pc the component to be added
*/
@Override
public void add(Component pc) {
Assert.isUnlocked(this);
bodyContainer.add(pc);
}
/**
* Class.
*/
protected class CurrentApplicationLinkPrinter implements PrintListener {
public CurrentApplicationLinkPrinter() {
// Empty
}
public void prepare(PrintEvent e) {
Link link = (Link) e.getTarget();
//PageState pageState = e.getPageState();
CcmApplication app = Web.getWebContext().getApplication();
Assert.exists(app, CcmApplication.class);
link.setChild(new Label(app.getTitle().toString()));
link.setTarget(app.getPrimaryUrl());
}
}
/**
* Class.
*/
protected class ParentApplicationLinkPrinter implements PrintListener {
public ParentApplicationLinkPrinter() {
// Empty
}
public void prepare(PrintEvent e) {
Link link = (Link) e.getTarget();
//PageState pageState = e.getPageState();
CcmApplication app = Web.getWebContext().getApplication();
Assert.exists(app, CcmApplication.class);
CcmApplication parent = (CcmApplication) app.getParent();
if (parent != null ) {
link.setChild(new Label(parent.getTitle().toString()));
link.setTarget(parent.getPrimaryUrl());
} else {
link.setChild(new Label("/"));
link.setTarget(com.arsdigita.web.URL.root().toString());
}
}
}
/**
* Class.
*/
protected class CurrentApplicationLabelPrinter implements PrintListener {
public CurrentApplicationLabelPrinter() {
// Empty
}
public void prepare(PrintEvent e) {
Label label = (Label) e.getTarget();
//PageState pageState = e.getPageState();
CcmApplication app = Web.getWebContext().getApplication();
Assert.exists(app, CcmApplication.class);
label.setLabel(app.getTitle().toString());
}
}
}

View File

@ -1,469 +0,0 @@
/*
* 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.ui;
import com.arsdigita.bebop.ActionLink;
import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Container;
import com.arsdigita.bebop.GridPanel;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Link;
import com.arsdigita.bebop.List;
import com.arsdigita.bebop.ModalContainer;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.RequestLocal;
import com.arsdigita.bebop.SegmentedPanel;
import com.arsdigita.bebop.SimpleComponent;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.Tree;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.event.ChangeEvent;
import com.arsdigita.bebop.event.ChangeListener;
import com.arsdigita.bebop.event.RequestEvent;
import com.arsdigita.bebop.event.RequestListener;
import com.arsdigita.bebop.list.ListCellRenderer;
import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.xml.Element;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.docrepo.File;
import org.libreccm.docrepo.Resource;
import org.libreccm.docrepo.ResourceRepository;
import java.math.BigDecimal;
import java.util.ArrayList;
/**
* User Interface component of the Document Repository application which
* which serves as entry-point and navigation tool of the repositories
* that a user has subscribed too.
* The tree of all subscribed repositories is on the left side, the full
* listing of the currently selected directory is on the right side.
*
* @author <a href="mailto:StefanDeusch@computer.org">Stefan Deusch</a>
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
*/
public class BrowsePane extends ModalContainer implements Constants, ChangeListener, RequestListener {
//private static final Logger log = Logger.getLogger(BrowsePane.class);
private Component m_folderContent;
private Component m_destinationFolderPanel;
private Component m_newFileForm;
private Component m_newFolderForm;
private Component m_errorMsgPanel;
private DestinationFolderForm m_destinationFolderForm;
private ErrorMessageLabel m_errorMsgLabel;
private Container m_segmentPanelBrowseContainer;
private Tree m_tree;
private BigDecimalParameter m_rootFolderIdParam = new BigDecimalParameter(ROOTFOLDER_ID_PARAM_NAME);
private BigDecimalParameter m_selFolderIdParam = new BigDecimalParameter(SEL_FOLDER_ID_PARAM_NAME);
private BigDecimalParameter m_fileIdParam = new BigDecimalParameter(FILE_ID_PARAM_NAME);
private StringParameter m_rootAddDocParam= new StringParameter(ROOT_ADD_DOC_PARAM_NAME);
/**
* Default constructor.
*/
public BrowsePane() {
m_segmentPanelBrowseContainer = new BoxPanel();
m_segmentPanelBrowseContainer.setClassAttr("sidebarNavPanel");
BoxPanel leftSide = new BoxPanel();
leftSide.setClassAttr("navbar");
m_tree = new SuperTree(new RepositoriesSuperTreeModel());
m_tree.addChangeListener(this);
leftSide.add(m_tree);
m_segmentPanelBrowseContainer.add(leftSide);
// Create all panels on the right side.
SegmentedPanel rightSide = new SegmentedPanel();
rightSide.setClassAttr("segmentPanel");
m_folderContent = makeContentPanel(rightSide);
m_segmentPanelBrowseContainer.add(rightSide);
// Add all forms and panels to the container
m_newFileForm = makeFileUploadForm();
m_segmentPanelBrowseContainer.add(m_newFileForm);
m_newFolderForm = makeFolderCreateForm();
m_segmentPanelBrowseContainer.add(m_newFolderForm);
m_destinationFolderPanel = makeExpandFolderPanel();
m_segmentPanelBrowseContainer.add(m_destinationFolderPanel);
m_errorMsgPanel = makeErrorMsgPanel();
m_segmentPanelBrowseContainer.add(m_errorMsgPanel);
}
/**
* Register the page the fist time.
*
* @param page The page to be registered.
*/
@Override
public void register(Page page) {
page.addGlobalStateParam(m_rootFolderIdParam);
page.addGlobalStateParam(m_selFolderIdParam);
page.addGlobalStateParam(m_rootAddDocParam);
page.addGlobalStateParam(m_fileIdParam);
page.addRequestListener(this);
super.register(page);
}
/**
* Checks if a folder is selected in the page state and consequently
* hides or shows the Folder Contents or the Folder Action panels.
*
* @param event The request event.
*/
public void pageRequested(RequestEvent event) {
PageState state = event.getPageState();
Long fileId = ((BigDecimal) state.getValue(m_fileIdParam)).longValue();
boolean display = false;
String key = (String) m_tree.getSelectedKey(state);
// start out with root folder selected and open
if (key == null) {
key = Utils.getRootFolder(state).getID().toString();
m_tree.setSelectedKey(state, key);
display = true;
}
// need this only when coming from 1-file page
if (fileId != null) {
final CdiUtil cdiUtil = new CdiUtil();
final ResourceRepository resourceRepository = cdiUtil.findBean(
ResourceRepository.class);
final File file = (File) resourceRepository.findById(fileId);
Resource parent = file.getParent();
key = Long.toString(parent.getObjectId());
while (!parent.isRoot()) {
parent = parent.getParent();
String nextKey = Long.toString(parent.getObjectId());
m_tree.expand(nextKey, state);
}
// to display this file's folder in the table
m_tree.setSelectedKey(state, key);
// now wipe out file param to avoid trouble elsewhere
state.setValue(m_fileIdParam, null);
}
// finally expand selected folder
m_tree.expand(key, state);
if (display) {
if( "t".equalsIgnoreCase(((String)state.getValue(m_rootAddDocParam)))) {
// Entry hook to display FileUpload Form for Root folder
displayFileUpload(state);
} else {
displayFolderContentPanel(state);
}
}
}
/**
* Helper method to communicate selected folder ID to sub components.
* Return only non-null after tree has been displayed at least once.
*
* @param state The page state.
*
* @return The folder id.
*/
public BigDecimal getFolderID(PageState state) {
return new BigDecimal((String) m_tree.getSelectedKey(state));
}
/**
* Implementation of the change listener, clicking on the folder
* loads the directory on the right side.
*
* @param event The change event. e.g. clicking.
*/
public void stateChanged(ChangeEvent event) {
PageState state = event.getPageState();
// Display folder on the right side corresponding to the key
displayFolderContentPanel(state);
}
/**
* Build a panel to display the Folder content of the selected Folder
* and add it as a segment to the passed Segmented Panel
*
* @param segmentPanel The segment panel.
*
* @return The segment panel with the added segment as a component.
*/
private Component makeContentPanel(SegmentedPanel segmentPanel) {
Label folder_info_header = new Label
(new GlobalizedMessage("ui.folder.content.header", BUNDLE_NAME));
folder_info_header.addPrintListener(
new FolderNamePrintListener(m_tree));
ActionLink newFileLink = new ActionLink(new Label(FOLDER_NEW_FILE_LINK));
newFileLink.setClassAttr("actionLink");
ActionLink newFolderLink =
new ActionLink(new Label(FOLDER_NEW_FOLDER_LINK));
newFolderLink.setClassAttr("actionLink");
newFileLink.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
displayFileUpload(e.getPageState());
}
});
newFolderLink.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
displayFolderCreate(e.getPageState());
}
});
GridPanel folderGrid = new GridPanel(1);
SimpleContainer pane = new SimpleContainer();
pane.add(newFileLink);
pane.add(new Label(" "));
pane.add(newFolderLink);
folderGrid.add(pane, GridPanel.RIGHT | GridPanel.BOTTOM);
folderGrid.add(new FolderContentsTableForm(this, m_tree),
GridPanel.LEFT | GridPanel.BOTTOM);
return segmentPanel.addSegment(folder_info_header,
folderGrid);
}
/**
* Builds the file upload form.
*
* @return A component with the build file upload form.
*/
private Component makeFileUploadForm() {
GridPanel gridPanel = new GridPanel(1);
Label fileUploadFormHeaderLabel = new Label(new GlobalizedMessage("ui.file.upload.header", BUNDLE_NAME));
fileUploadFormHeaderLabel.addPrintListener(new FolderNamePrintListener(m_tree));
gridPanel.add(fileUploadFormHeaderLabel);
gridPanel.add(new FileUploadForm(this, m_tree));
return gridPanel;
}
/**
* Builds the folder create form.
*
* @return A component with the build folder create form.
*/
private Component makeFolderCreateForm() {
GridPanel gridPanel = new GridPanel(1);
Label folderCreateFormHeaderLabel = new Label(new GlobalizedMessage("ui.folder.create.header", BUNDLE_NAME));
folderCreateFormHeaderLabel.addPrintListener(new FolderNamePrintListener(m_tree));
gridPanel.add(folderCreateFormHeaderLabel);
gridPanel.add(new FolderCreateForm(this, m_tree));
return gridPanel;
}
/**
* Builds the destination folders tree.
*
* @return A component with the destination folder tree.
*/
private Component makeExpandFolderPanel() {
GridPanel gridPanel = new GridPanel(1);
m_destinationFolderForm = new DestinationFolderForm(this);
gridPanel.add(DESTINATION_FOLDER_PANEL_HEADER);
gridPanel.add(m_destinationFolderForm);
return gridPanel;
}
/**
* Builds the panel to display error messages when copy/move failed.
*
* @return A component with the panel to display error messages.
*/
private Component makeErrorMsgPanel() {
ColumnPanel columnPanel = new ColumnPanel(1);
m_errorMsgLabel = new ErrorMessageLabel();
columnPanel.add(m_errorMsgLabel);
ActionLink link = new ActionLink(ACTION_ERROR_CONTINUE);
link.setClassAttr("actionLink");
link.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
displayFolderContentPanel(e.getPageState());
}
});
columnPanel.add(link);
return columnPanel;
}
/**
* Display the file upload form.
*
* @param state The page state
*/
public void displayFileUpload(PageState state) {
m_newFileForm.setVisible(state, true);
}
/**
* Display the folder create form.
*
* @param state The page state
*/
public void displayFolderCreate(PageState state) {
m_newFolderForm.setVisible(state, true);
}
/**
* Display the folder content panel.
*
* @param state The page state
*/
public void displayFolderContentPanel(PageState state) {
m_segmentPanelBrowseContainer.setVisible(state, true);
}
/**
* Display the folder destination panel.
*
* @param state The page state
* @param resourceList A list of resources
* @param isMove Weather its moved or copied
*/
public void displayDestinationFolderPanel(PageState state,
Object[] resourceList,
boolean isMove) {
m_destinationFolderPanel.setVisible(state, true);
m_destinationFolderForm.setResourceList(state, resourceList);
if (isMove) {
m_destinationFolderForm.setMove(state);
} else {
m_destinationFolderForm.setCopy(state);
}
}
/**
* Display the error message panel.
*
* @param state The page state
* @param action The file operation
* @param list The list of messages
*/
public void displayErrorMsgPanel(PageState state,
String action,
ArrayList list) {
m_errorMsgLabel.setMessages(state, action, list);
m_errorMsgPanel.setVisible(state, true);
}
/**
* Error message panel that allows to set customized error
* messages without showing a tomcat stacktrace.
*/
private static class ErrorMessageLabel extends SimpleComponent implements Constants {
private RequestLocal m_msgs;
private RequestLocal m_action;
/**
* Constructor.
*/
public ErrorMessageLabel() {
m_msgs = new RequestLocal();
m_action = new RequestLocal();
}
/**
* Set list of file/folder that could not be delete/move/copy.
*
* @param state The page state
* @param action The file operation (action, move, copy)
* @param msgs The list of messages
*/
public void setMessages(PageState state,
String action,
ArrayList msgs) {
m_action.set(state, action);
m_msgs.set(state, msgs);
}
@Override
public void generateXML(PageState state, Element parent) {
Element element = parent.newChildElement("docs:error-label",
DOCS_XML_NS);
element.addAttribute("action", (String) m_action.get(state));
ArrayList list = (ArrayList) m_msgs.get(state);
if (list != null) {
for (Object aList : list) {
Element item = element.newChildElement("docs:item", DOCS_XML_NS);
item.addAttribute("name", ((String) aList));
}
}
}
}
/**
* Table Cell Renderer that provides clickable Links to follow
* directory links .
*
* Todo: inner private class never used..
*/
private static class DirLinkRenderer implements ListCellRenderer {
public Component getComponent(List list, PageState state,
Object value, String key,
int index, boolean isSelected) {
Link link = new Link((String)value,
"?" + SEL_FOLDER_ID_PARAM.getName() +
"=" + key);
return link;
}
}
}

View File

@ -1,35 +0,0 @@
/*
* Copyright (C) 2002-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.ui;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.globalization.GlobalizedMessage;
/**
* Customized Cancel button that takes you 1 level back in
* the browser history.
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
*/
public class CancelButton extends Submit {
public CancelButton(GlobalizedMessage label) {
super(label);
setOnClick("history.go(-1); return false;");
}
}

View File

@ -1,394 +0,0 @@
/*
* 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.ui;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.globalization.GlobalizedMessage;
/**
* Variously used constant objects used in Document Repository UI
*
* Todo: refactor this whole fucking class. Totally idiotic.
*
* @author <a href="mailto:StefanDeusch@computer.org">Stefan Deusch</a>
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
*/
public interface Constants {
// PDL vars
String FOLDER_ID = "folderID";
String IS_LOCKED = "isLocked";
String IS_MOUNTED = "isMounted";
String LAST_MODIFIED = "lastModified";
String MODIFYING_USER = "modifyingUser";
String MIME_TYPE_LABEL = "mimeTypeDescription";
String NAME = "name";
String ABS_PATH = "absPath";
String NUM_FILES = "numFiles";
String REPOSITORY_ID = "repositoryID";
String RESOURCE_ID = "resourceID";
String SIZE = "size";
String TYPE = "mimeType";
String IS_FOLDER = "isFolder";
// PDL queries
String GET_ALL_TREES = "com.arsdigita.docrepo.getAllTreesView";
String GET_REPOSITORIES = "com.arsdigita.docrepo.getRepositoriesView";
String GET_REPOSITORIES_ROOTS = "com.arsdigita.docrepo.getRepositoryRoots";
String GET_CHILDREN = "com.arsdigita.docrepo.getChildren";
// PDL associations
String FILES = "files";
String FOLDERS = "folders";
/**
* The XML namespace.
*/
String DOCS_XML_NS = "http://www.arsdigita.com/docs-ui/1.0";
/**
* Globalization resource
*/
String BUNDLE_NAME = "com.arsdigita.docrepo.DRResources";
/**
* Global state parameters.
*/
String ROOTFOLDER_ID_PARAM_NAME = "r_id";
BigDecimalParameter ROOTFOLDER_ID_PARAM = new BigDecimalParameter(ROOTFOLDER_ID_PARAM_NAME);
String SEL_FOLDER_ID_PARAM_NAME = "f_id";
BigDecimalParameter SEL_FOLDER_ID_PARAM = new BigDecimalParameter(SEL_FOLDER_ID_PARAM_NAME);
String FILE_ID_PARAM_NAME = "d_id";
BigDecimalParameter FILE_ID_PARAM = new BigDecimalParameter(FILE_ID_PARAM_NAME);
/**
* DM Index page title
*/
Label PAGE_TITLE_LABEL = new Label
(new GlobalizedMessage("ui.page.title", BUNDLE_NAME));
/**
* DM File Info Page
*/
Label FILE_INFO_LABEL = new Label
(new GlobalizedMessage("ui.fileinfo.title", BUNDLE_NAME));
// File Info Navigational Tabs
Label FILE_INFO_PROPERTIES_TITLE = new Label
(new GlobalizedMessage("ui.fileinfo.properties.title", BUNDLE_NAME));
Label FILE_INFO_HISTORY_TITLE = new Label
(new GlobalizedMessage("ui.fileinfo.history.title", BUNDLE_NAME));
Label FILE_INFO_COMMENTS_TITLE = new Label
(new GlobalizedMessage("ui.fileinfo.comments.title", BUNDLE_NAME));
Label FILE_INFO_LINKS_TITLE = new Label
(new GlobalizedMessage("ui.fileinfo.links.title", BUNDLE_NAME));
Label GO_BACK_LABEL = new Label
(new GlobalizedMessage("ui.fileinfo.goback.label", BUNDLE_NAME));
/**
* Navigational dimensional bar
*/
Label MY_WORKSPACE_LABEL = new Label
(new GlobalizedMessage("ui.workspace.title", BUNDLE_NAME));
Label SIGN_OUT_LABEL = new Label
(new GlobalizedMessage("ui.nav.signout", BUNDLE_NAME));
Label HELP_LABEL = new Label
(new GlobalizedMessage("ui.nav.help", BUNDLE_NAME));
/**
* Page navigational tabs
*/
Label WS_BROWSE_TITLE = new Label
(new GlobalizedMessage("ui.workspace.browse.title", BUNDLE_NAME));
Label WS_SEARCH_TITLE = new Label
(new GlobalizedMessage("ui.workspace.search.title", BUNDLE_NAME));
Label WS_REPOSITORIES_TITLE = new Label
(new GlobalizedMessage("ui.workspace.repositories.title", BUNDLE_NAME));
/**
* One Folder content
*/
Label FOLDER_INFORMATION_HEADER = new Label
(new GlobalizedMessage("ui.folder.content.header", BUNDLE_NAME));
/**
* Repositories
*/
Label REPOSITORIES_INFORMATION_HEADER = new Label
(new GlobalizedMessage("ui.repositories.content.header", BUNDLE_NAME));
GlobalizedMessage REPOSITORY_RECENTDOCS_EMPTY
= new GlobalizedMessage("ui.repositories.recentDocs.empty", BUNDLE_NAME);
/**
* File Uplaod Form
*/
Label FILE_UPLOAD_FORM_HEADER = new Label
(new GlobalizedMessage("ui.file.upload.header", BUNDLE_NAME));
/**
* Folder Create Form
*/
Label FOLDER_CREATE_FORM_HEADER = new Label
(new GlobalizedMessage("ui.folder.create.header", BUNDLE_NAME));
/**
* File Properties
*/
Label FILE_PROPERTIES_HEADER = new Label
(new GlobalizedMessage("ui.fileinfo.properties.header", BUNDLE_NAME));
/**
* File Edit Panel
*/
Label FILE_EDIT_HEADER = new Label
(new GlobalizedMessage("ui.fileinfo.edit.header", BUNDLE_NAME));
GlobalizedMessage FILE_EDIT_ACTION_DESCRIPTION =
new GlobalizedMessage("ui.fileinfo.edit.action.description", BUNDLE_NAME);
/**
* File Upload Panel
*/
Label FILE_UPLOAD_HEADER = new Label
(new GlobalizedMessage("ui.fileinfo.upload.header", BUNDLE_NAME));
GlobalizedMessage FILE_UPLOAD_INITIAL_TRANSACTION_DESCRIPTION =
new GlobalizedMessage("ui.fileinfo.upload.initialversion.description", BUNDLE_NAME);
/**
* File Download Panel
*/
Label FILE_DOWNLOAD_HEADER = new Label
(new GlobalizedMessage("ui.fileinfo.download.header", BUNDLE_NAME));
/**
* File-Send-to-Colleague Form
*/
Label FILE_SEND_COLLEAGUE_HEADER = new Label
(new GlobalizedMessage("ui.fileinfo.sendcolleague.header", BUNDLE_NAME));
/**
* File-Delete Form
*/
Label FILE_DELETE_HEADER = new Label
(new GlobalizedMessage("ui.fileinfo.delete.header", BUNDLE_NAME));
/**
* File Action Panel
*/
Label FILE_ACTION_HEADER = new Label
(new GlobalizedMessage("ui.fileinfo.actions.header", BUNDLE_NAME));
/**
* File Revision History Panel
*/
Label FILE_REVISION_HISTORY_HEADER = new Label
(new GlobalizedMessage("ui.fileinfo.history.header", BUNDLE_NAME));
/**
* File Feedback Panel
*/
Label FILE_FEEDBACK_HEADER = new Label
(new GlobalizedMessage("ui.fileinfo.feedback.header", BUNDLE_NAME));
/**
* Action Panel Constants
*/
Label DESTINATION_FOLDER_PANEL_HEADER = new Label(
new GlobalizedMessage("ui.folder.destination.list.header", BUNDLE_NAME));
Label FOLDER_EMPTY_LABEL = new Label(
new GlobalizedMessage("ui.folder.empty", BUNDLE_NAME));
GlobalizedMessage FOLDER_NEW_FOLDER_LINK =
new GlobalizedMessage("ui.action.newfolder", BUNDLE_NAME);
GlobalizedMessage FOLDER_NEW_FILE_LINK =
new GlobalizedMessage("ui.action.newfile", BUNDLE_NAME);
Label ACTION_CUT_LABEL = new Label(
new GlobalizedMessage("ui.action.edit.cut", BUNDLE_NAME));
Label ACTION_COPY_LABEL = new Label(
new GlobalizedMessage("ui.action.edit.copy", BUNDLE_NAME));
Label ACTION_DELETE_LABEL = new Label(
new GlobalizedMessage("ui.action.edit.delete", BUNDLE_NAME));
GlobalizedMessage ACTION_DELETE_CONFIRM =
new GlobalizedMessage("ui.action.confirm.delete", BUNDLE_NAME);
Label ACTION_ERROR_LABEL = new Label(
new GlobalizedMessage("ui.action.error", BUNDLE_NAME));
Label ACTION_ERROR_CONTINUE = new Label(
new GlobalizedMessage("ui.action.error.continue", BUNDLE_NAME));
String ACTION_CUT_VALUE = "resource-cut";
String ACTION_COPY_VALUE = "resource-copy";
String ACTION_DELETE_VALUE = "resource-delete";
GlobalizedMessage ACTION_DELETE_SUBMIT =
new GlobalizedMessage("ui.action.submit.delete", BUNDLE_NAME);
GlobalizedMessage ACTION_COPY_SUBMIT =
new GlobalizedMessage("ui.action.submit.copy", BUNDLE_NAME);
GlobalizedMessage ACTION_MOVE_SUBMIT =
new GlobalizedMessage("ui.action.submit.move", BUNDLE_NAME);
/**
* Portlet Panel Constants
*/
GlobalizedMessage ROOT_ADD_RESOURCE_LINK =
new GlobalizedMessage("ui.action.portlet.newresource", BUNDLE_NAME);
String ROOT_ADD_DOC_PARAM_NAME = "root_add_doc";
StringParameter ROOT_ADD_DOC_PARAM =
new StringParameter(ROOT_ADD_DOC_PARAM_NAME);
/**
* File Action Panel Constants
*/
GlobalizedMessage FILE_EDIT_LINK =
new GlobalizedMessage("ui.fileinfo.edit.link", BUNDLE_NAME);
GlobalizedMessage FILE_NEW_VERSION_LINK =
new GlobalizedMessage("ui.fileinfo.newversion.link", BUNDLE_NAME);
GlobalizedMessage FILE_DOWNLOAD_LINK =
new GlobalizedMessage("ui.fileinfo.download.link", BUNDLE_NAME);
GlobalizedMessage FILE_SEND_COLLEAGUE_LINK =
new GlobalizedMessage("ui.fileinfo.sendcolleague.link", BUNDLE_NAME);
GlobalizedMessage FILE_DELETE_LINK =
new GlobalizedMessage("ui.fileinfo.delete.link", BUNDLE_NAME);
/**
* Error messages
*/
GlobalizedMessage FOLDER_PARENTNOTFOUND_ERROR =
new GlobalizedMessage("ui.error.parentnotfound", BUNDLE_NAME);
GlobalizedMessage RESOURCE_EXISTS_ERROR =
new GlobalizedMessage("ui.error.resourceexists", BUNDLE_NAME);
GlobalizedMessage EMAIL_INVALID_ERROR =
new GlobalizedMessage("ui.email.formatinvalid", BUNDLE_NAME);
GlobalizedMessage DIFFERENT_MIMETYPE_ERROR =
new GlobalizedMessage("ui.error.mimetype", BUNDLE_NAME);
/**
* FILE DELETE link
*/
GlobalizedMessage FILE_DELETE_CONFIRM =
new GlobalizedMessage("ui.file.confirm.delete", BUNDLE_NAME);
// Labels for Files
GlobalizedMessage FILE_NAME =
new GlobalizedMessage("ui.file.name", BUNDLE_NAME);
GlobalizedMessage FILE_NAME_REQUIRED =
new GlobalizedMessage("ui.file.name.required", BUNDLE_NAME);
GlobalizedMessage FILE_UPLOAD_ADD_FILE =
new GlobalizedMessage("ui.file.upload", BUNDLE_NAME);
GlobalizedMessage FILE_SOURCE =
new GlobalizedMessage("ui.file.source", BUNDLE_NAME);
GlobalizedMessage FILE_DESCRIPTION =
new GlobalizedMessage("ui.file.description", BUNDLE_NAME);
GlobalizedMessage FILE_VERSION_DESCRIPTION =
new GlobalizedMessage("ui.file.version.description", BUNDLE_NAME);
GlobalizedMessage FILE_KEYWORDS =
new GlobalizedMessage("ui.file.keywords", BUNDLE_NAME);
GlobalizedMessage FILE_SAVE =
new GlobalizedMessage("ui.file.save", BUNDLE_NAME);
GlobalizedMessage FILE_SUBMIT =
new GlobalizedMessage("ui.file.submit", BUNDLE_NAME);
GlobalizedMessage CANCEL =
new GlobalizedMessage("ui.action.cancel", BUNDLE_NAME);
/**
* Folder parameters
*/
String FOLDER_NAME = "folder-name";
String FOLDER_DESCRIPTION = "folder-description";
Label FOLDER_NAME_LABEL = new Label(
new GlobalizedMessage("ui.folder.name", BUNDLE_NAME));
Label FOLDER_DESCRIPTION_LABEL = new Label(
new GlobalizedMessage("ui.folder.description", BUNDLE_NAME));
GlobalizedMessage FOLDER_SAVE =
new GlobalizedMessage("ui.folder.save", BUNDLE_NAME);
/**
* Repsitories Selection Form
*/
GlobalizedMessage REPOSITORIES_MOUNTED_SAVE =
new GlobalizedMessage("ui.repositories.mounted.save", BUNDLE_NAME);
/**
* Send to colleague form variables.
*/
Label SEND_FRIEND_FORM_EMAIL_SUBJECT = new Label(
new GlobalizedMessage("ui.send.friend.email.subject", BUNDLE_NAME));
Label SEND_FRIEND_FORM_EMAIL_LIST = new Label(
new GlobalizedMessage("ui.send.friend.email.list", BUNDLE_NAME));
Label SEND_FRIEND_FORM_DESCRIPTION = new Label(
new GlobalizedMessage("ui.send.friend.description", BUNDLE_NAME));
GlobalizedMessage SEND_FRIEND_FORM_SUBMIT =
new GlobalizedMessage("ui.send.friend.submit", BUNDLE_NAME);
}

View File

@ -1,347 +0,0 @@
/*
* 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.ui;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.RequestLocal;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.form.Hidden;
import com.arsdigita.bebop.form.RadioGroup;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.parameters.ArrayParameter;
import com.arsdigita.docrepo.util.GlobalizationUtil;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.web.Web;
import com.arsdigita.xml.Element;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.docrepo.Folder;
import org.libreccm.docrepo.Repository;
import org.libreccm.docrepo.Resource;
import org.libreccm.docrepo.ResourceManager;
import org.libreccm.docrepo.ResourceRepository;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
/**
* Intermediate form of the "Move-to" and "Copy-to" process.
* It shows the folder tree of the repositories expanded
* with checkboxes next to it.
*
* @author <a href="mailto:ddao@arsdigita.com">David Dao</a>
* @author <a href="mailto:stefan@arsdigita.com">Stefan Deusch</a>
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
*/
public class DestinationFolderForm extends Form implements FormInitListener,
FormProcessListener, Constants {
private static final Logger log = Logger.getLogger(
DestinationFolderForm.class);
private Hidden m_resourceList;
private ExpandedFolderTree m_radioGroup;
private Submit m_copySubmit;
private Submit m_moveSubmit;
private BrowsePane m_parent;
/**
* Constructor. Creates a destination folder form.
*
* @param parent The parent of the destination folder form
*/
public DestinationFolderForm(BrowsePane parent) {
super("Destination-Folder", new ColumnPanel(1));
m_parent = parent;
m_resourceList = new Hidden(new ArrayParameter("resourceList"));
add(m_resourceList);
m_radioGroup = new ExpandedFolderTree();
add(m_radioGroup);
m_copySubmit = new Submit(GlobalizationUtil.globalize(
"ui.action.submit.copy"));
add(m_copySubmit);
m_moveSubmit = new Submit(GlobalizationUtil.globalize(
"ui.action.submit.copy"));
add(m_moveSubmit);
addInitListener(this);
addProcessListener(this);
}
/**
* <p>Adds a DOM subtree representing this component under the given
* parent node. Uses the request values stored in <code>state</code>.</p>
*
* @param ps represents the current request
* @param elt the node under which the DOM subtree should be added
*/
@Override
public void generateXML(PageState ps, Element elt) {
doSubmit(ps);
super.generateXML(ps, elt);
}
/**
* Does a submit on a given page state.
*
* @param ps The page state
*/
private void doSubmit(PageState ps) {
Object[] list = (Object[]) m_resourceList.getValue(ps);
ArrayList l = new ArrayList();
for (int i = 0; i < list.length; i++) {
l.add(list[i]);
}
m_radioGroup.setSources(ps, l);
}
/**
* Sets a resource list with the given list of objects.
*
* @param state The page state
* @param list The list of objects
*/
public void setResourceList(PageState state, Object[] list) {
m_resourceList.setValue(state, list);
}
/**
* Sets the copy submit to the page state.
*
* @param state The page state
*/
public void setCopy(PageState state) {
state.setVisible(m_moveSubmit, false);
state.setVisible(m_copySubmit, true);
}
/**
* Sets the move submit to the page state.
*
* @param state The page state
*/
public void setMove(PageState state) {
state.setVisible(m_moveSubmit, true);
state.setVisible(m_copySubmit, false);
}
/**
* Initializes the destination folder form, when triggered by an event.
* Todo: fix usage of class Kernel
*
* @param event The section event to be triggered
*/
public void init(FormSectionEvent event) {
// if ( Kernel.getContext().getParty() == null ) {
// Util.redirectToLoginPage(event.getPageState());
// }
}
/**
* Processes the destination folder form after it has been triggered.
*
* @param event The section event to be triggered
*
* @throws FormProcessException
*/
public void process(FormSectionEvent event) throws FormProcessException {
PageState state = event.getPageState();
boolean isCopy = true;
boolean isError = false;
ArrayList errorList = new ArrayList();
if (m_moveSubmit.isSelected(state)) {
isCopy = false;
}
Long folderId = Long.valueOf((String) m_radioGroup.getValue(state));
if (folderId == null) {
throw new FormProcessException(GlobalizationUtil.globalize(
"ui.folder.choose_destination"));
}
final CdiUtil cdiUtil = new CdiUtil();
final ResourceRepository resourceRepository = cdiUtil.findBean(
ResourceRepository.class);
final ResourceManager resourceManager = cdiUtil.findBean(
ResourceManager.class);
final Folder folder = (Folder) resourceRepository.findById(folderId);
if (folder == null) {
isError = true;
log.error(GlobalizationUtil.globalize("db.notfound.folder",
Arrays.asList(folderId).toArray()));
}
String[] resourceStrings = (String[]) m_resourceList.getValue(state);
for (String resourceString : resourceStrings) {
Long resourceId = Long.valueOf(resourceString);
Resource resource = resourceRepository.findById(resourceId);
if (resource == null) {
errorList.add(resourceString);
log.debug(GlobalizationUtil.globalize("db.notfound.resource",
Arrays.asList(resourceId).toArray()));
continue;
}
// Knowledge, weather it's a folder or a file is not necessary
if (isCopy) {
resourceManager.copyToFolder(resource, folder);
} else {
resource.setParent(folder);
resourceRepository.save(resource);
}
}
if (isError) {
String action = isCopy ? "copy" : "move";
m_parent.displayErrorMsgPanel(state, action, errorList);
} else {
m_parent.displayFolderContentPanel(state);
}
}
/**
* Create an expanded tree of all repositories and folder for given user.
* Each folder has a checkbox to be selected as destination folder. The
* parent folder is not selectable. This class should not be use
* outside of document repository.
*/
private class ExpandedFolderTree extends RadioGroup {
// Exclusion list of folders.
private RequestLocal m_srcResources;
/**
* Constructor of inner private class.
*/
public ExpandedFolderTree() {
super("resourceID");
m_srcResources = new RequestLocal();
}
/**
* Sets sources to the exclusion list of folders.
*
* @param state The page state
* @param list A list of sources
*/
public void setSources(PageState state, ArrayList list) {
m_srcResources.set(state, list);
}
/**
* Generates xml for the destination folder form. Therefore retrieving
* a list of all folders in a certain repository for Copy and Move
* operations.
*
* Todo: what does this method?
* Todo: rewrite for ccm_ng
*
* @param state The page state
* @param parent The element
*/
@Override
public void generateXML(PageState state, Element parent) {
Element treeElement = parent.newChildElement("bebop:tree", BEBOP_XML_NS);
Long sourceFolderId = (m_parent.getFolderID(state)).longValue();
final CdiUtil cdiUtil = new CdiUtil();
final ResourceRepository resourceRepository = cdiUtil.findBean(
ResourceRepository.class);
final Folder sourceFolder = (Folder) resourceRepository.findById(
sourceFolderId);
if (sourceFolder != null) {
HashMap map = new HashMap();
map.put(new Long("-1"), treeElement);
Repository repository = (Repository) Web.
getWebContext().getApplication();
Folder rootFolder = repository.getRootFolder();
List<Resource> resources = rootFolder.getImmediateChildren();
for (Resource resource : resources) {
if (resource.isFolder()) {
Long parentId = resource.getParent().getObjectId();
Long resourceId = resource.getObjectId();
Element parentElement = (Element) map.get(parentId);
if (parentElement != null) {
boolean isSelectable = resource.equals(sourceFolder);
map.put(resourceId, createNode(state, parentElement,
isSelectable, (Folder) resource));
}
}
}
} else {
log.error(GlobalizationUtil.globalize("db.notfound.folder",
Arrays.asList(sourceFolderId).toArray()));
}
}
/**
* Creates a new element node with given folder.
*
* @param state The page state
* @param parent The elements parent
* @param makeSelectable If new element needs to be selectable
* @param folder The folder
*
* @return The new element node
*/
private Element createNode(PageState state, Element parent,
boolean makeSelectable, Folder folder) {
Element element = parent.newChildElement("bebop:t_node", BEBOP_XML_NS);
element.addAttribute("indentStart", "t");
element.addAttribute("indentClose", "t");
if (makeSelectable) {
element.addAttribute("resourceID", String.valueOf(
folder.getObjectId()));
element.addAttribute("radioGroup", "t");
element.addAttribute("radioGroupName", getName());
} else {
element.addAttribute("radioGroup", "f");
}
Label label = new Label(new GlobalizedMessage(folder.getName()));
label.generateXML(state, element);
return element;
}
}
}

View File

@ -1,64 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.docrepo.ui;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.RequestLocal;
import com.arsdigita.docrepo.util.GlobalizationUtil;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.docrepo.File;
import org.libreccm.docrepo.Resource;
import org.libreccm.docrepo.ResourceRepository;
import java.util.Arrays;
/**
* Same as the {@link RequestLocal} but overrides the
* {@code initialValue} uniquely for {@code DocRepo} classes.
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 02/12/2015
*/
public class DocRepoRequestLocal extends RequestLocal
implements Constants {
private static final Logger log = Logger.getLogger(
DocRepoRequestLocal.class);
@Override
protected File initialValue(PageState state) {
Long id = (Long) state.getValue(FILE_ID_PARAM);
final CdiUtil cdiUtil = new CdiUtil();
final ResourceRepository resourceRepository = cdiUtil.findBean(
ResourceRepository.class);
final Resource resource = resourceRepository.findById(id);
File file = resource != null && resource.isFile() ? (File) resource :
null;
if (file == null) {
log.error(GlobalizationUtil.globalize("db.notfound.file",
Arrays.asList(id).toArray()));
}
return file;
}
}

View File

@ -1,196 +0,0 @@
/*
* 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.ui;
import com.arsdigita.bebop.ActionLink;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Link;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.RequestLocal;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.event.PrintEvent;
import com.arsdigita.bebop.event.PrintListener;
import com.arsdigita.dispatcher.DispatcherHelper;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.web.Web;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.docrepo.File;
import org.libreccm.docrepo.ResourceRepository;
import java.io.IOException;
/**
* This component shows the meta data of a file with links to administrative
* actions on it.
*
* @author <a href="mailto:StefanDeusch@computer.org">Stefan Deusch</a>
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
*/
public class FileActionPane extends ColumnPanel implements Constants {
private static final Logger log = Logger.getLogger(FileActionPane.class);
private FileInfoPropertiesPane m_parent;
private RequestLocal m_fileData;
private Link m_download;
private ActionLink m_newVersion;
private ActionLink m_email;
private ActionLink m_delete;
/**
* Constructor. Initializes the action pane for the given info properties.
*
* @param parent The info property pane
*/
public FileActionPane(FileInfoPropertiesPane parent) {
super(1);
m_parent = parent;
m_fileData = new DocRepoRequestLocal();
m_newVersion = addActionLink(FILE_NEW_VERSION_LINK);
PrintListener printListener = new PrintListener() {
public void prepare(PrintEvent event) {
Link link = (Link) event.getTarget();
PageState state = event.getPageState();
File file = getFile(state);
link.setTarget(String.format("download/%s?%s=%d", file.getName(),
FILE_ID_PARAM.getName(), file.getObjectId()));
}
};
m_download = new Link(new Label(FILE_DOWNLOAD_LINK),
printListener);
m_download.setClassAttr("actionLink");
add(m_download);
m_email = addActionLink(FILE_SEND_COLLEAGUE_LINK);
m_delete = addActionLink(FILE_DELETE_LINK);
m_newVersion.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
m_parent.displayUploadForm(e.getPageState());
}
});
m_email.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
m_parent.displaySendColleagueForm(e.getPageState());
}
});
m_delete.addActionListener(new DeleteListener());
m_delete.setConfirmation(FILE_DELETE_CONFIRM);
}
/**
* Adds the action link to this file action pane.
*
* @param msg Label of the action link
*
* @return The action link
*/
private ActionLink addActionLink(GlobalizedMessage msg) {
ActionLink actionlink = new ActionLink(new Label(msg));
actionlink.setClassAttr("actionLink");
this.add(actionlink);
return actionlink;
}
/**
* Return file initialized in RequestLocal
*
* @param state The page state
*
* @return The initialized file
*/
private File getFile(PageState state) {
return (File) m_fileData.get(state);
}
/**
* Private inner class. DeleteListener of a file.
*/
private final class DeleteListener implements ActionListener {
/**
* Method get triggered, if the delete action has been perfomed.
*
* @param event The delete event
*/
public void actionPerformed(ActionEvent event) {
PageState state = event.getPageState();
final File file = getFile(state);
Long parentFolderId = file.getParent().getObjectId();
final CdiUtil cdiUtil = new CdiUtil();
final ResourceRepository resourceRepository = cdiUtil.findBean
(ResourceRepository.class);
// Todo: replace KernelExcursion
// KernelExcursion ex = new KernelExcursion() {
// protected void excurse() {
// setEffectiveParty(Kernel.getSystemParty());
// resourceRepository.delete(file);
// }
// };
// ex.run();
try {
String appURI = getRedirectURI(state);
DispatcherHelper.sendRedirect(state.getRequest(),
state.getResponse(), String.format("%s?%s=%d",
appURI, SEL_FOLDER_ID_PARAM.getName(),
parentFolderId));
} catch(IOException iox) {
log.error("Failed to send the url for the redirect.", iox);
}
}
/**
* Gets the redirecting uri through a given page state.
*
* @param state The page state
*
* @return The new uri
*/
private String getRedirectURI(PageState state) {
String appURI = state.getRequestURI();
log.debug(String.format("Original app URI: %s", appURI));
int idx = appURI.indexOf("/file/");
appURI = appURI.substring(0, idx);
final String servletPath = Web.getConfig().getDispatcherServletPath();
if (appURI.startsWith(servletPath)) {
appURI = appURI.substring(servletPath.length());
}
log.debug(String.format("New URI: %s", appURI));
return appURI;
}
}
}

View File

@ -1,200 +0,0 @@
/*
* 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.ui;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormValidationListener;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.form.TextArea;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.bebop.parameters.NotEmptyValidationListener;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.docrepo.util.GlobalizationUtil;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.docrepo.File;
import org.libreccm.docrepo.Resource;
import org.libreccm.docrepo.ResourceManager;
import org.libreccm.docrepo.ResourceRepository;
import java.util.Arrays;
/**
* This component allows to change the file name and the description of a
* file. It also serves to associate keywords to a file (knowledge object).
*
* @author <a href="mailto:StefanDeusch@computer.org">Stefan Deusch</a>
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
*/
public class FileEditForm extends Form implements FormValidationListener,
FormProcessListener, FormInitListener, Constants {
private static final Logger log = Logger.getLogger(FileEditForm.class);
// Todo: add strings to package properties
private final static String FILE_EDIT = "file-edit";
private final static String FILE_EDIT_FNAME = "file-edit-name";
private final static String FILE_EDIT_DESCRIPTION = "file-edit-description";
private StringParameter m_FileName;
private StringParameter m_FileDesc;
private FileInfoPropertiesPane m_parent;
/**
* Constructor. Initializes the file edit form in the info property pane.
*
* @param parent The file property pane
*/
public FileEditForm(FileInfoPropertiesPane parent) {
super(FILE_EDIT, new ColumnPanel(2));
m_parent = parent;
m_FileName = new StringParameter(FILE_EDIT_FNAME);
m_FileDesc = new StringParameter(FILE_EDIT_DESCRIPTION);
add(new Label(FILE_NAME_REQUIRED));
TextField fnameEntry = new TextField(m_FileName);
fnameEntry.addValidationListener(new NotEmptyValidationListener());
add(fnameEntry);
add(new Label(FILE_DESCRIPTION));
TextArea descArea = new TextArea(m_FileDesc);
descArea.setRows(10);
descArea.setCols(40);
add(descArea);
Submit submit = new Submit("file-edit-save");
submit.setButtonLabel(FILE_SAVE);
add(new Label());
SimpleContainer sc = new SimpleContainer();
sc.add(submit);
sc.add(new CancelButton(CANCEL));
add(sc);
addInitListener(this);
addProcessListener(this);
addValidationListener(this);
}
/**
* Initializer to pre-fill name and description after an event has been
* triggered.
*
* @param event The event
*/
public void init(FormSectionEvent event) {
PageState state = event.getPageState();
// Todo: exchange usage of Kernel class
// if (Kernel.getContext().getParty() == null) {
// Util.redirectToLoginPage(state);
// }
FormData data = event.getFormData();
Long fileId = (Long) state.getValue(FILE_ID_PARAM);
final CdiUtil cdiUtil = new CdiUtil();
final ResourceRepository resourceRepository = cdiUtil.findBean(
ResourceRepository.class);
final File file = (File) resourceRepository.findById(fileId);
if (file == null) {
log.error(GlobalizationUtil.globalize("db.notfound.file",
Arrays.asList(fileId).toArray()));
}
data.put(FILE_EDIT_FNAME, file.getName());
data.put(FILE_EDIT_DESCRIPTION, file.getDescription());
}
/**
* Tests if the new name already exists in the current folder when event
* has been triggered. Is been called before processed.
*
* @param event The event
*
* @throws FormProcessException
*/
public void validate(FormSectionEvent event) throws FormProcessException {
PageState state = event.getPageState();
FormData data = event.getFormData();
Long resourceId = (Long) state.getValue(FILE_ID_PARAM);
final CdiUtil cdiUtil = new CdiUtil();
final ResourceRepository resourceRepository = cdiUtil.findBean(
ResourceRepository.class);
final ResourceManager resourceManager = cdiUtil.findBean(
ResourceManager.class);
final Resource resource = resourceRepository.findById(resourceId);
final File file = resource.isFile() ? (File) resource : null;
if (resourceManager != null && file != null) {
String fname = (String) data.get(FILE_EDIT_FNAME);
if (!resourceManager.isValidNewResourceName(fname, file)) {
throw new FormProcessException(GlobalizationUtil.globalize(
"ui.file.name.invalid"));
}
}
}
/**
* Read form and update when event has been triggered.+
*
* @param event The event
*/
public void process(FormSectionEvent event) {
PageState state = event.getPageState();
FormData data = event.getFormData();
String fname = (String) data.get(FILE_EDIT_FNAME);
String fdesc = (String) data.get(FILE_EDIT_DESCRIPTION);
Long fileId = (Long) state.getValue(FILE_ID_PARAM);
final CdiUtil cdiUtil = new CdiUtil();
final ResourceRepository resourceRepository = cdiUtil.findBean(
ResourceRepository.class);
File file = (File) resourceRepository.findById(fileId);
if (file != null) {
file.setName(fname);
file.setDescription(fdesc);
resourceRepository.save(file);
} else {
log. error(String.format("Couldn't find file %d in the " +
"database.", fileId));
}
m_parent.displayPropertiesAndActions(state);
}
}

View File

@ -1,92 +0,0 @@
/*
* 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.ui;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.RequestLocal;
import com.arsdigita.bebop.SegmentedPanel;
import com.arsdigita.bebop.SimpleContainer;
import org.libreccm.docrepo.File;
import org.apache.log4j.Logger;
/**
* This component shows the version history of a document. It allows
* to download historical versions.
*
* @author <a href="mailto:StefanDeusch@computer.org">Stefan Deusch</a>
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
*/
public class FileInfoHistoryPane extends SimpleContainer implements Constants {
private static final Logger log = Logger.getLogger(
FileInfoHistoryPane.class);
private Component m_history;
// share file instance for all sub components
private RequestLocal requestLocal;
/**
* Constructor. Constructs the info-history pane for a file.
*/
public FileInfoHistoryPane() {
requestLocal = new DocRepoRequestLocal();
SegmentedPanel main = new SegmentedPanel();
main.setClassAttr("main");
m_history = makeHistoryPane(main);
add(main);
}
/**
* Creates a new history pane.
*
* @param panel The segment panel.
* @return The new segment panel with a created history pane.
*/
private Component makeHistoryPane(SegmentedPanel panel) {
return panel.addSegment(FILE_REVISION_HISTORY_HEADER,
new FileRevisionsTable(this));
}
/**
* Registers the given page.
*
* @param page The page.
*/
@Override
public void register(Page page) {
page.addGlobalStateParam(FILE_ID_PARAM);
super.register(page);
}
/**
* Returns a file.
*
* @param state The page state
* @return A file
*/
public File getFile(PageState state) {
return (File) requestLocal.get(state);
}
}

View File

@ -1,222 +0,0 @@
/*
* 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.ui;
import com.arsdigita.bebop.ActionLink;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SegmentedPanel;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import java.util.ArrayList;
/**
* This component shows all the properties of a file with links
* to administrative actions to change those.
*
* @author <a href="mailto:StefanDeusch@computer.org">Stefan Deusch</a>
*/
public class FileInfoPropertiesPane extends SimpleContainer implements
Constants {
private ArrayList m_componentList;
private Component m_properties;
private Component m_upload;
private Component m_sendColleague;
private Component m_edit;
private Component m_action;
private BasePage m_page;
/**
* Constructor. Creates different panes and adds them to a list of
* components.
*
* @param page The BasePage
*/
public FileInfoPropertiesPane(BasePage page) {
m_page = page;
SegmentedPanel main = new SegmentedPanel();
main.setClassAttr("main");
m_componentList = new ArrayList<>();
m_properties = makePropertiesPane(main);
m_componentList.add(m_properties);
m_edit = makeEditPane(main);
m_componentList.add(m_edit);
m_action = makeActionPane(main);
m_componentList.add(m_action);
m_upload = makeUploadPane(main);
m_componentList.add(m_upload);
m_sendColleague = makeSendColleaguePane(main);
m_componentList.add(m_sendColleague);
add(main);
}
/**
* Makes the properties pane
*
* @param main The main segment panel
*
* @return A component with the properties pane
*/
private Component makePropertiesPane(SegmentedPanel main) {
SimpleContainer container= new SimpleContainer();
container.add(new FilePropertiesPanel());
ActionLink link = new ActionLink(new Label(FILE_EDIT_LINK));
link.setClassAttr("actionLink");
link.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
PageState state = e.getPageState();
displayEditForm(state);
}
});
container.add(link);
return main.addSegment(FILE_PROPERTIES_HEADER, container);
}
/**
* Makes the edit pane
*
* @param main The main segment panel
*
* @return A component with the edit pane
*/
private Component makeEditPane(SegmentedPanel main) {
return main.addSegment(FILE_EDIT_HEADER,
new FileEditForm(this));
}
/**
* Makes the action pane
*
* @param main The main segment panel
*
* @return A component with the action pane
*/
private Component makeActionPane(SegmentedPanel main) {
return main.addSegment(FILE_ACTION_HEADER,
new FileActionPane(this));
}
/**
* Makes the upload pane
*
* @param main The main segment panel
*
* @return A component with the upload pane
*/
private Component makeUploadPane(SegmentedPanel main) {
return main.addSegment(FILE_UPLOAD_HEADER,
new VersionUploadForm(this));
}
/**
* Makes the send to colleagues pane
*
* @param main The main segment panel
*
* @return A component with the send to colleague pane
*/
private Component makeSendColleaguePane(SegmentedPanel main) {
return main.addSegment(FILE_SEND_COLLEAGUE_HEADER,
new FileSendColleagueForm(this));
}
/**
* Registers the page with the properties of a file
*
* @param p The page
*/
public void register(Page p) {
for (Object aM_componentList : m_componentList) {
p.setVisibleDefault((Component) aM_componentList, false);
}
p.setVisibleDefault( m_properties, true);
p.setVisibleDefault( m_action, true);
p.addGlobalStateParam(FILE_ID_PARAM);
super.register(p);
}
/**
* Visibility of components management methods
*
* @param state The page state
*/
private void hideAll(PageState state) {
for (Object aM_componentList : m_componentList) {
((Component) aM_componentList).setVisible(state, false);
}
}
/**
* Displays the properties and actions of a file
*
* @param state The page state
*/
public void displayPropertiesAndActions(PageState state) {
m_page.goUnmodal(state);
hideAll(state);
m_properties.setVisible(state, true);
m_action.setVisible(state, true);
}
/**
* Displays the edit form for the file
*
* @param state The page state
*/
public void displayEditForm(PageState state) {
m_page.goModal(state, m_edit);
}
/**
* Displays the upload form for a file
*
* @param state The page state
*/
public void displayUploadForm(PageState state) {
m_page.goModal(state, m_upload);
}
/**
* Displays the send to colleague form
*
* @param state The page state
*/
public void displaySendColleagueForm(PageState state) {
m_page.goModal(state, m_sendColleague);
}
}

View File

@ -1,157 +0,0 @@
/*
* 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.ui;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SimpleComponent;
import com.arsdigita.docrepo.util.GlobalizationUtil;
import com.arsdigita.web.ParameterMap;
import com.arsdigita.web.URL;
import com.arsdigita.xml.Element;
import org.apache.log4j.Logger;
import org.apache.shiro.authz.AuthorizationException;
import org.hibernate.envers.exception.NotAuditedException;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.docrepo.File;
import org.libreccm.docrepo.Resource;
import org.libreccm.docrepo.ResourceRepository;
import org.libreccm.security.PermissionChecker;
import org.libreccm.security.User;
import javax.activation.MimeType;
import javax.servlet.http.HttpServletRequest;
/**
* A simple custom bebop component that summarizes the properties of a
* file in tabular form.
*
* @author StefanDeusch@computer.org, ddao@arsdigita.com
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version $Id: FilePropertiesPanel.java pboy $
*/
public class FilePropertiesPanel extends SimpleComponent implements Constants {
private static final Logger log = Logger.getLogger(
FilePropertiesPanel.class);
/**
* Generates the XML for this container.
*
* @param state represents the current request
* @param parent the parent XML element
*/
@Override
public void generateXML(PageState state, Element parent) {
// Get file id.
Long resourceId = (Long) state.getValue(FILE_ID_PARAM);
Element element = parent.newChildElement("docs:file-info", DOCS_XML_NS);
File file = null;
final CdiUtil cdiUtil = new CdiUtil();
ResourceRepository resourceRepository = null;
final PermissionChecker permissionChecker;
try {
resourceRepository = cdiUtil.findBean(ResourceRepository.class);
Resource resource = resourceRepository.findById(resourceId);
file = resource.isFile() ? (File) resource : null;
permissionChecker = cdiUtil.findBean(PermissionChecker.class);
// checks if the subject has permissions granting the privilege to
// 'read' the file
permissionChecker.checkPermission("read", file);
} catch (AuthorizationException authEx) {
log.error(GlobalizationUtil.globalize("ui.file.failure.privilege.read"),
authEx);
}
Element nameElement = element.newChildElement("docs:name", DOCS_XML_NS);
nameElement.setText(file.getName());
Element descriptionElement = element.newChildElement("docs:description",
DOCS_XML_NS);
String description = file.getDescription();
if (description != null) {
descriptionElement.setText(description);
}
Element sizeElement = element.newChildElement("docs:size", DOCS_XML_NS);
sizeElement.setText(Utils.FileSize.formatFileSize(file.getSize(), state));
Element typeElement = element.newChildElement("docs:type", DOCS_XML_NS);
// Retrieve pretty name for a mime type.
MimeType mimeType = file.getMimeType();
typeElement.setText(mimeType.getBaseType());
Element lastModifiedElement = element.newChildElement(
"docs:last-modified", DOCS_XML_NS);
lastModifiedElement.setText(Utils.DateFormat.format(
file.getLastModifiedDate()));
Element revisionElement = element.newChildElement("docs:revision",
DOCS_XML_NS);
long numRevs = 0; // if there aren't any revisions 0 is accurate
if (resourceRepository != null) {
try {
numRevs = resourceRepository.retrieveRevisionNumbersOfEntity(
file, file.getObjectId()).size();
} catch (IllegalArgumentException |
NotAuditedException |
IllegalStateException ex) {
log.error(GlobalizationUtil.globalize("ui.file.failure" +
".retrieve.revisionNumber"), ex);
}
}
//deprecated: exchanged through the above
//TransactionCollection tc = file.getTransactions();
//long numRevs = tc.size();
revisionElement.setText(numRevs + "");
// Must allow for the possibility that not author is available.
Element authorElement = element.newChildElement("docs:author",
DOCS_XML_NS);
User author = file.getCreationUser();
if (author != null) {
authorElement.setText(author.getName());
} else {
authorElement.setText("Unknown");
}
Element uriElement = element.newChildElement("docs:uri", DOCS_XML_NS);
uriElement.setText(makeFileURL(file, state));
}
/**
* Makes an url for a given file.
*
* @param file The file
* @param state The page state
*
* @return The url to the file
*/
private static String makeFileURL(File file, PageState state) {
final HttpServletRequest req = state.getRequest();
final ParameterMap params = new ParameterMap();
params.setParameter(FILE_ID_PARAM.getName(), file.getObjectId());
return URL.here(req, "/download/" + file.getName(), params).toString();
}
}

View File

@ -1,201 +0,0 @@
/*
* 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.ui;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Link;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.event.TableActionEvent;
import com.arsdigita.bebop.event.TableActionListener;
import com.arsdigita.bebop.table.TableCellRenderer;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.table.TableModelBuilder;
import org.libreccm.docrepo.File;
import com.arsdigita.util.LockableImpl;
import org.apache.log4j.Logger;
/**
* This component lists all file revisions in tabular form.
* The right-most column has a button to download that particular
* version.
*
* @author <a href="mailto:StefanDeusch@computer.org">Stefan Deusch</a>
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
*/
public class FileRevisionsTable extends Table implements TableActionListener,
Constants {
private static Logger log = Logger.getLogger(FileRevisionsTable.class);
private FileInfoHistoryPane m_parent;
private static String[] s_tableHeaders =
{"", "Author", "Date", "Comments", ""};
/**
* Constructor. Creates a file revision table for a given file info
* history pane.
*
* @param parent The fileInfoHisoryPane
*/
public FileRevisionsTable(FileInfoHistoryPane parent) {
super(new FileRevisionsTableModelBuilder(parent), s_tableHeaders);
m_parent = parent;
setClassAttr("AlternateTable");
setWidth("100%");
setCellRenderers();
addTableActionListener(this);
}
public void cellSelected(TableActionEvent e) {
}
public void headSelected(TableActionEvent e) {
throw new UnsupportedOperationException();
}
private void setCellRenderers() {
getColumn(4).setCellRenderer(new LinkRenderer());
}
private final class LinkRenderer implements TableCellRenderer {
public Component getComponent(Table table, PageState state,
Object value, boolean isSelected,
Object key, int row, int column) {
if (value != null) {
File file = m_parent.getFile(state);
Link link = new Link("Download", "download/?" + FILE_ID_PARAM
.getName() + "=" + file.getObjectId() + "&trans_id=" + key);
link.setClassAttr("downloadLink");
return link;
} else {
return new Label();
}
}
}
private final class FileRevisionsTableModelBuilder extends LockableImpl
implements TableModelBuilder {
private FileInfoHistoryPane m_parent;
FileRevisionsTableModelBuilder(FileInfoHistoryPane parent) {
m_parent = parent;
}
public TableModel makeModel(Table t, PageState state) {
return new FileRevisionsTableModel(m_parent.getFile(state), state);
}
}
private final class FileRevisionsTableModel implements TableModel,
Constants {
private FileInfoHistoryPane m_parent;
private File m_file;
private PageState m_state;
private TransactionCollection m_tc;
private Transaction m_transaction;
private Transaction m_lastContentChange;
private int m_row;
private int m_last = 2;
FileRevisionsTableModel(File file, PageState state) {
m_file = file;
m_state = state;
m_tc = m_file.getRevision();
m_row = (int) m_tc.size() + 1;
m_last = m_row;
// separate collection from last content changes
}
public int getColumnCount() {
return 5;
}
public Object getElementAt(int columnIndex) {
switch (columnIndex) {
case 0:
return new BigDecimal(m_row);
case 1: {
com.arsdigita.kernel.User user = m_file.getLastModifiedUser();
if (null == user) {
return "Unknown";
} else {
return user.getPersonName().toString();
}
}
case 2:
if (m_row == 0)
return Utils.DateFormat.format(m_file.getCreationDate());
else
return Utils.DateFormat.format(m_file.getLastModifiedDate());
case 3: {
StringBuffer sb = new StringBuffer();
TagCollection tc = m_transaction.getTags();
int counter = 0;
while (tc.next()) {
counter++;
Tag t = tc.getTag();
sb.append(counter + ") " + t.getDescription() + " ");
}
return sb.toString();
}
case 4:
return "download";
default:
break;
}
return null;
}
public Object getKeyAt(int columnIndex) {
if (columnIndex == 4) {
if (m_row == m_last - 1) {
return "current";
} else {
return m_transaction.getID();
}
} else {
return m_file.getID() + "." + (m_row);
}
}
public boolean nextRow() {
m_row--;
if (m_tc.next()) {
m_transaction = m_tc.getTransaction();
return true;
} else {
m_tc.close();
return false;
}
}
}
}

View File

@ -1,240 +0,0 @@
/*
* 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.ui;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.RequestLocal;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.form.TextArea;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.bebop.parameters.NotEmptyValidationListener;
import com.arsdigita.docrepo.File;
import com.arsdigita.mail.Mail;
import com.arsdigita.util.StringUtils;
import org.apache.log4j.Logger;
import javax.mail.MessagingException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
//import com.arsdigita.bebop.FormProcessException;
/**
* This component allows the user to send the document to
* someone by e-mail. The document is enclosed as an attachment
* and send using the com.arsdigita.mail package services, this
* package is built ontop of javax.mail.
*
* @see com.arsdigita.mail
*
* @author <mailto href="StefanDeusch@computer.org">Stefan Deusch</a>
* @author <mailto href="ddao@arsdigita.com">David Dao</a>
* @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers</a>
*/
public class FileSendColleagueForm extends Form implements FormProcessListener,
FormInitListener, Constants {
private static final Logger log = Logger.getLogger(
FileSendColleagueForm.class);
private static final char EMAIL_SEPARATOR = ';';
private static final String EMAIL_LIST = "emailList";
private static final String EMAIL_SUBJECT = "subject";
private static final String DESCRIPTION = "description";
private RequestLocal m_fileData;
private TextField m_emailList;
private TextField m_subject;
private TextArea m_message;
private FileInfoPropertiesPane m_parent;
/**
* Constructor. Creates the necessary form.
*
* @param parent The fileInfoPropertiesPane
*/
public FileSendColleagueForm(FileInfoPropertiesPane parent) {
super("FileSendColleagueForm", new ColumnPanel(2));
m_parent = parent;
// initialize the file
m_fileData = new DocRepoRequestLocal();
add(SEND_FRIEND_FORM_EMAIL_SUBJECT);
m_subject = new TextField(EMAIL_SUBJECT);
m_subject.addValidationListener(new NotEmptyValidationListener());
add(m_subject);
add(SEND_FRIEND_FORM_EMAIL_LIST);
m_emailList = new TextField(EMAIL_LIST);
m_emailList.addValidationListener(new NotEmptyValidationListener());
add(m_emailList);
add(SEND_FRIEND_FORM_DESCRIPTION);
m_message = new TextArea(DESCRIPTION);
m_message.setRows(10);
m_message.setCols(40);
add(m_message);
SimpleContainer sc = new SimpleContainer();
sc.add(new Submit(SEND_FRIEND_FORM_SUBMIT));
CancelButton cancel = new CancelButton(CANCEL);
sc.add(cancel);
add(new Label()); // spacer
add(sc, ColumnPanel.LEFT);
addInitListener(this);
addProcessListener(this);
}
/**
* Returns a file as the request-specific value for the current state
*
* @param s The current page state
* @return A file
*/
private File getFile(PageState s) {
return (File) m_fileData.get(s);
}
/**
* Pre-fill the e-mail subject field with file name.
*
* @param e the FormSectionEvent
*/
public void init(FormSectionEvent e)
throws FormProcessException {
PageState state = e.getPageState();
// Todo: fix the Kernel Context
// if ( Kernel.getContext().getParty() == null ) {
// Util.redirectToLoginPage(state);
// return;
// }
FormData data = e.getFormData();
data.put(EMAIL_SUBJECT, getFile(state).getName());
}
/**
* No Form validation happens here, the email addresses are parsed
* and the file is e-mailed as attachment.
*
* @param e The FormSectionEvent
*/
public void process(FormSectionEvent e)
throws FormProcessException {
PageState state = e.getPageState();
// Todo: not used
//FormData data = e.getFormData();
//HttpServletRequest req = state.getRequest();
String emailRecpts = (String) m_emailList.getValue(state);
String recipient[] = StringUtils.split(emailRecpts, EMAIL_SEPARATOR);
String subject = (String) m_subject.getValue(state);
// message to go with the doc attachment
String message = (String) m_message.getValue(state);
// Sender e-mail address
String from = Utils.getUser(state).getPrimaryEmailAddress()
.getAddress();
File file = getFile(state);
String filename = file.getName();
String mimeType = file.getContentType();
byte[] attachment = getBytes(file);
for (String aRecipient : recipient) {
// TODO validate email of recipient for format
sendDocument(aRecipient, from, subject, message, filename,
mimeType, attachment);
}
m_parent.displayPropertiesAndActions(state);
}
/**
* Send the document as attachment to one e-mail recipient
*
* @param recipient The recipient of the mail
* @param sender The sender of the mail
* @param subject The subject of the mail
* @param message The actual message of the mail
* @param filename The filename to be send
* @param mimeType The mimetype
* @param attchmnt The attachment
*/
private static void sendDocument(String recipient,
String sender,
String subject,
String message,
String filename,
String mimeType,
byte[] attchmnt) {
try {
Mail mail = new Mail(recipient, sender, subject);
mail.setBody(message);
mail.attach(attchmnt, mimeType, filename);
mail.send();
} catch (MessagingException exc) {
log.error("Couldn't send the mail.", exc);
// Todo: log in some buffer, or schedule for re-try later
}
}
/**
* Get the bytes from the given document resource
*
* @param file The document resource
* @return A byte array
*/
private static byte[] getBytes(File file) {
ByteArrayOutputStream outputStream = null;
try {
outputStream = new ByteArrayOutputStream();
InputStream inputStream = file.getInputStream();
byte[] buf = new byte[8192];
int sz = 0;
while ((sz = inputStream.read(buf, 0, 8192)) != -1) {
outputStream.write(buf, 0, sz);
}
} catch(IOException iox) {
iox.printStackTrace();
}
return outputStream.toByteArray();
}
}

View File

@ -1,315 +0,0 @@
/*
* 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.ui;
import com.arsdigita.bebop.ColumnPanel;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.Tree;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormValidationListener;
import com.arsdigita.bebop.form.FileUpload;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.form.TextArea;
import com.arsdigita.bebop.parameters.StringLengthValidationListener;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.dispatcher.MultipartHttpServletRequest;
import com.arsdigita.docrepo.InvalidNameException;
import com.arsdigita.docrepo.Util;
import com.arsdigita.util.Assert;
import com.arsdigita.web.Web;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.docrepo.BlobObject;
import org.libreccm.docrepo.File;
import org.libreccm.docrepo.Folder;
import org.libreccm.docrepo.Resource;
import org.libreccm.docrepo.ResourceRepository;
import javax.activation.MimeType;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
/**
* Form to upload and submit a file to the document repository.
*
* @author <mailto href="StefanDeusch@computer.org">Stefan Deusch</a>
* @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers</a>
* @version $Id: FileUploadForm.java pboy $
*/
public class FileUploadForm extends Form implements FormInitListener,
FormValidationListener, FormProcessListener, Constants {
private static final Logger log = Logger.getLogger(FileUploadForm.class);
// Form constants
private final static String FILE_UPLOAD = "file-upload";
private final static String FILE_UPLOAD_FORM = "file-upload-form";
private final static String FILE_UPLOAD_INPUT_DESCRIPTION = "file-description";
private FileUpload m_fileUpload;
private StringParameter m_FileDesc;
private Tree m_tree;
private BrowsePane m_parent;
/**
* Constructor.
*
* @param parent The browsePane
* @param tree The tree
*/
public FileUploadForm(BrowsePane parent, Tree tree) {
this(parent, tree, true);
}
/**
* Creates the form for the file upload.
*
* @param parent The browse pane
* @param tree A tree
* @param initListeners Weather there are initial listeners or not
*/
public FileUploadForm(BrowsePane parent, Tree tree, boolean initListeners) {
super(FILE_UPLOAD_FORM, new ColumnPanel(2));
m_parent = parent;
setMethod(Form.POST);
setEncType("multipart/form-data");
m_tree = tree;
m_fileUpload = new FileUpload(FILE_UPLOAD);
m_FileDesc = new StringParameter(FILE_UPLOAD_INPUT_DESCRIPTION);
m_FileDesc.addParameterListener
(new StringLengthValidationListener(4000));
add(new Label(FILE_UPLOAD_ADD_FILE));
add(m_fileUpload);
add(new Label(FILE_DESCRIPTION));
TextArea textArea = new TextArea(m_FileDesc);
textArea.setRows(10);
textArea.setCols(40);
add(textArea);
SimpleContainer sc = new SimpleContainer();
Submit submit = new Submit("submit");
submit.setButtonLabel(FILE_SUBMIT);
sc.add(submit);
CancelButton cancel = new CancelButton(CANCEL);
sc.add(cancel);
add(new Label()); // spacer
add(sc, ColumnPanel.LEFT);
if (initListeners) {
addInitListener(this);
addProcessListener(this);
addValidationListener(this);
}
}
/**
* Post the file to a temporary file on the server and
* insert it into the database
*
* @param e The form section event
*/
protected Long insertFile(FormSectionEvent e)
throws FormProcessException {
log.debug("Inserting a file into the database");
final PageState state = e.getPageState();
final FormData data = e.getFormData();
final HttpServletRequest req = state.getRequest();
// stuff for the file
final String fileName = getFileName(e);
final String fileDescription = (String) data.get(FILE_UPLOAD_INPUT_DESCRIPTION);
final String filePath = (String) data.get(FILE_UPLOAD);
final MimeType mimeType = Util.guessContentType(fileName, req);
if (log.isDebugEnabled()) {
log.debug("getFileName() -> '" + fileName + "'");
log.debug("description == '" + fileDescription + "'");
log.debug("path == '" + filePath + "'");
}
java.io.File src = null;
if (filePath != null && filePath.length() > 0) {
HttpServletRequest mreq = e.getPageState().getRequest();
// Assert.assertTrue(mreq instanceof MultipartHttpServletRequest,
Assert.isTrue(mreq instanceof MultipartHttpServletRequest,
"I got a " + mreq + " when I was " +
"expecting a MultipartHttpServletRequest");
src = ((MultipartHttpServletRequest) mreq).getFile(FILE_UPLOAD);
log.debug("file == '" + src + "'");
}
Folder parent = null;
String selKey = (String) m_tree.getSelectedKey(state);
final CdiUtil cdiUtil = new CdiUtil();
final ResourceRepository resourceRepository = cdiUtil.findBean(
ResourceRepository.class);
if (selKey == null) {
parent = Utils.getRootFolder(state);
} else {
Long folderID = new Long(selKey);
final Resource resource = resourceRepository.findById(folderID);
parent = resource != null && resource.isFolder()
? (Folder) resource : null;
}
// insert the file in the database below parent
final File file = new File;
file.setParent(parent);
file.setName(fileName);
file.setDescription(fileDescription);
file.setIsFolder(false);
file.setPath(filePath);
file.setMimeType(mimeType);
file.setContent(new BlobObject().setContent(src));
// annotate first file upload as initial version
file.setDescription(FILE_UPLOAD_INITIAL_TRANSACTION_DESCRIPTION.
localize(req).toString());
//file.applyTag(FILE_UPLOAD_INITIAL_TRANSACTION_DESCRIPTION.
//localize(req).toString());
file.save();
new KernelExcursion() {
protected void excurse() {
Party currentParty = Kernel.getContext().getParty();
setParty(Kernel.getSystemParty());
PermissionService.grantPermission(new PermissionDescriptor(PrivilegeDescriptor.ADMIN,
file,
currentParty));
Application app = Web.getWebContext().getApplication();
Assert.exists(app, Application.class);
PermissionService.setContext(file, app);
}}.run();
return file.getID();
}
public void init(FormSectionEvent e) {
PageState state = e.getPageState();
if ( Kernel.getContext().getParty() == null ) {
Util.redirectToLoginPage(state);
}
}
/**
* Post the file to a temporary file on the server and
* insert it into the database
*/
public void process(FormSectionEvent e)
throws FormProcessException {
log.debug("Processing form submission");
insertFile(e);
if (m_parent != null) {
m_parent.displayFolderContentPanel(e.getPageState());
}
}
/**
* Gets either the file name from the widget
* or takes the filename from the upload
* widget in this order.
*/
protected String getFileName(FormSectionEvent e) {
FormData data = e.getFormData();
String filename = (String) data.get(FILE_UPLOAD);
return Utils.extractFileName(filename, e.getPageState());
}
/**
* Verify that the parent folder exists and does not contain any
* other files or sub folders with the same name as the file being
* uploaded.
*/
public void validate(FormSectionEvent e) throws FormProcessException {
PageState state = e.getPageState();
FormData data = e.getFormData();
HttpServletRequest req = state.getRequest();
String fname = Utils.extractFileName(getFileName(e), state);
// XXX Not localized as the other errors are.
if (fname.length() > 200) {
data.addError
(FILE_UPLOAD,
"This filename is too long. It must be fewer than 200 " +
"characters.");
}
Folder parent = null;
String selKey = (String) m_tree.getSelectedKey(state);
if (selKey == null) {
parent = Utils.getRootFolder(state);
} else {
BigDecimal folderID = new BigDecimal(selKey);
try {
parent = new Folder(folderID);
} catch(DataObjectNotFoundException nf) {
throw new ObjectNotFoundException(FOLDER_PARENTNOTFOUND_ERROR
.localize(req).toString());
}
}
try {
parent.getResourceID(fname);
data.addError(FILE_UPLOAD,
RESOURCE_EXISTS_ERROR
.localize(req).toString());
} catch(DataObjectNotFoundException nf) {
// ok here
} catch(InvalidNameException ex) {
data.addError(FILE_UPLOAD,
ex.getMessage());
}
}
}

View File

@ -1,43 +0,0 @@
/*
* Copyright (C) 2002-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.util;
import com.arsdigita.globalization.Globalized;
import com.arsdigita.globalization.GlobalizedMessage;
/**
* <p>Contains methods to simplify globalizing keys</p>
*
* @author <a href="mailto:sarnold@redhat.com">sarnold@redhat.com</a>
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
*/
public class GlobalizationUtil implements Globalized {
private static final String BUNDLE_NAME = "com.arsdigita.docrepo.Resources";
public static GlobalizedMessage globalize(String key) {
return new GlobalizedMessage(key, BUNDLE_NAME);
}
public static GlobalizedMessage globalize(String key, Object[] args) {
return new GlobalizedMessage(key, BUNDLE_NAME, args);
}
}

View File

@ -64,11 +64,11 @@ public class BlobObject implements Serializable {
private byte[] content; private byte[] content;
/** /**
* The {@link Resource} the {@code BlobObject} was assigned to. * The {@link File} the {@code BlobObject} was assigned to.
*/ */
@OneToOne(mappedBy = "content") @OneToOne(mappedBy = "content")
@NotEmpty @NotEmpty
private Resource resource; private File file;
/** /**
* Constructor. * Constructor.
@ -93,12 +93,12 @@ public class BlobObject implements Serializable {
this.content = content; this.content = content;
} }
public Resource getResource() { public File getFile() {
return resource; return file;
} }
public void setResource(Resource resource) { public void setFile(File file) {
this.resource = resource; this.file = file;
} }
//< End GETTER & SETTER //< End GETTER & SETTER

View File

@ -0,0 +1,58 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.docrepo;
import org.libreccm.auditing.AbstractAuditedEntityRepository;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
/**
* Repository class for retrieving, storing and deleting {@code BlobObject}s.
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 20/01/2016
*/
@RequestScoped
public class BlobObjectRepository extends
AbstractAuditedEntityRepository<Long, BlobObject> {
@Inject
private EntityManager entityManager;
@Override
public Long getEntityId(BlobObject entity) {
return entity.getBlobObjectId();
}
@Override
public Class<BlobObject> getEntityClass() {
return BlobObject.class;
}
@Override
public boolean isNew(BlobObject entity) {
if (entity == null) {
throw new IllegalArgumentException("Entity to save can't be null.");
}
return entity.getBlobObjectId() == 0;
}
}

View File

@ -19,6 +19,8 @@
package org.libreccm.docrepo; package org.libreccm.docrepo;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table; import javax.persistence.Table;
/** /**
@ -34,6 +36,13 @@ public class File extends Resource {
private static final long serialVersionUID = -504220783419811504L; private static final long serialVersionUID = -504220783419811504L;
/**
* Content of the {@code Resource} as a {@link BlobObject}.
*/
@OneToOne
@JoinColumn(name = "CONTENT_ID")
private BlobObject content;
/** /**
* Constructor calls the super-class-constructor of {@link Resource}. * Constructor calls the super-class-constructor of {@link Resource}.
*/ */
@ -41,4 +50,15 @@ public class File extends Resource {
super(); super();
} }
//> Begin GETTER & SETTER
public BlobObject getContent() {
return content;
}
public void setContent(BlobObject content) {
this.content = content;
}
//< End GETTER & SETTER
} }

View File

@ -19,8 +19,10 @@
package org.libreccm.docrepo; package org.libreccm.docrepo;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne; import javax.persistence.OneToOne;
import javax.persistence.Table; import javax.persistence.Table;
import java.util.List;
/** /**
* Entity class of a folder in the doc-repository. Instances will be persisted * Entity class of a folder in the doc-repository. Instances will be persisted
@ -35,11 +37,17 @@ public class Folder extends Resource {
private static final long serialVersionUID = 1561466556458872622L; private static final long serialVersionUID = 1561466556458872622L;
/**
* The child-{@code Resource}s of the {@code Resource}.
*/
@OneToMany(mappedBy = "parent")
private List<Resource> immediateChildren;
/** /**
* The {@link Repository} this {@code Folder} is assigned to as root. * The {@link Repository} this {@code Folder} is assigned to as root.
*/ */
@OneToOne(mappedBy = "rootFolder") @OneToOne(mappedBy = "rootFolder")
private Repository repository; private Repository rootAssignedRepository;
/** /**
* Constructor calls the super-class-constructor of {@link Resource}. * Constructor calls the super-class-constructor of {@link Resource}.
@ -50,13 +58,22 @@ public class Folder extends Resource {
//> Begin GETTER & SETTER //> Begin GETTER & SETTER
public Repository getRepository() { public List<Resource> getImmediateChildren() {
return repository; return immediateChildren;
} }
public void setRepository(Repository repository) { public void setImmediateChildren(List<Resource> immediateChildren) {
this.repository = repository; this.immediateChildren = immediateChildren;
} }
public Repository getRootAssignedRepository() {
return rootAssignedRepository;
}
public void setRootAssignedRepository(Repository rootAssignedRepository) {
this.rootAssignedRepository = rootAssignedRepository;
}
//< End GETTER & SETTER //< End GETTER & SETTER
} }

View File

@ -29,13 +29,10 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries; import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery; import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.Temporal; import javax.persistence.Temporal;
import javax.persistence.TemporalType; import javax.persistence.TemporalType;
import java.util.Date; import java.util.Date;
import java.util.List;
/** /**
@ -80,13 +77,6 @@ public abstract class Resource extends CcmObject {
@Column(name = "DESCRIPTION") @Column(name = "DESCRIPTION")
private String description; private String description;
/**
* Flag, wheather the {@code Resource} is a {@link Folder} or not.
*/
@Column(name = "IS_FOLDER")
@NotBlank
private boolean isFolder;
/** /**
* Path to the {@code Resource}. * Path to the {@code Resource}.
*/ */
@ -106,13 +96,6 @@ public abstract class Resource extends CcmObject {
@Column(name = "SIZE") @Column(name = "SIZE")
private long size; private long size;
/**
* Content of the {@code Resource} as a {@link BlobObject}.
*/
@OneToOne
@JoinColumn(name = "CONTENT_ID")
private BlobObject content;
/** /**
* Creation date of the {@code Resource}. * Creation date of the {@code Resource}.
*/ */
@ -160,13 +143,7 @@ public abstract class Resource extends CcmObject {
*/ */
@ManyToOne @ManyToOne
@JoinColumn(name = "PARENT_ID") @JoinColumn(name = "PARENT_ID")
private Resource parent; private Folder parent;
/**
* The child-{@code Resource}s of the {@code Resource}.
*/
@OneToMany(mappedBy = "parent")
private List<Resource> immediateChildren;
/** /**
* The {@link Repository} containing this {@code Resource}. * The {@link Repository} containing this {@code Resource}.
@ -200,14 +177,6 @@ public abstract class Resource extends CcmObject {
this.description = description; this.description = description;
} }
public boolean isFolder() {
return isFolder;
}
public void setIsFolder(boolean isFolder) {
this.isFolder = isFolder;
}
public String getPath() { public String getPath() {
return path; return path;
} }
@ -232,14 +201,6 @@ public abstract class Resource extends CcmObject {
this.size = size; this.size = size;
} }
public BlobObject getContent() {
return content;
}
public void setContent(BlobObject content) {
this.content = content;
}
public Date getCreationDate() { public Date getCreationDate() {
return creationDate; return creationDate;
} }
@ -292,18 +253,10 @@ public abstract class Resource extends CcmObject {
return parent; return parent;
} }
public void setParent(Resource parent) { public void setParent(Folder parent) {
this.parent = parent; this.parent = parent;
} }
public List<Resource> getImmediateChildren() {
return immediateChildren;
}
public void setImmediateChildren(List<Resource> immediateChildren) {
this.immediateChildren = immediateChildren;
}
public Repository getRepository() { public Repository getRepository() {
return repository; return repository;
} }
@ -313,12 +266,4 @@ public abstract class Resource extends CcmObject {
} }
//< End GETTER & SETTER //< End GETTER & SETTER
public boolean isRoot() {
return isFolder() && getParent() == null;
}
public boolean isFile() {
return !isFolder();
}
} }

View File

@ -39,27 +39,62 @@ public class ResourceManager {
private ResourceRepository resourceRepository; private ResourceRepository resourceRepository;
/** /**
* Copies a given {@link Resource} to a given {@link Folder}. * Copies a given {@link File} to a given {@link Folder}.
* *
* @param original The {@link Resource} to be copied * @param original The {@link Resource} to be copied
* @param folder The {@link Folder} to copy to * @param folder The {@link Folder} to copy to
*/ */
public void copyToFolder(Resource original, Folder folder) { public void copyToFolder(Resource original, Folder folder) {
Resource copy = original.isFolder() ? new Folder() : new File(); Resource copy = original instanceof File ?
copyFileSpecifics(new File(), (File) original) :
copyFolderSpecifics(new Folder(), (Folder) original);
copy.setName(original.getName()); copy.setName(original.getName());
copy.setDescription(original.getDescription()); copy.setDescription(original.getDescription());
copy.setIsFolder(original.isFolder());
copy.setPath(String.format("%s/%s", folder.getPath(), copy.getName())); copy.setPath(String.format("%s/%s", folder.getPath(), copy.getName()));
copy.setMimeType(original.getMimeType()); copy.setMimeType(original.getMimeType());
copy.setSize(original.getSize()); copy.setSize(original.getSize());
copy.setContent(original.getContent()); copy.setCreationDate(original.getCreationDate());
copy.setLastModifiedDate(original.getLastModifiedDate());
copy.setCreationIp(original.getCreationIp());
copy.setLastModifiedIp(original.getLastModifiedIp());
copy.setCreationUser(original.getCreationUser());
copy.setLastModifiedUser(original.getLastModifiedUser());
copy.setParent(folder); copy.setParent(folder);
copy.setImmediateChildren(original.getImmediateChildren()); copy.setRepository(folder.getRepository());
resourceRepository.save(copy); resourceRepository.save(copy);
} }
/**
* Helper method to copy the {@link File} specific data to the copy.
*
* @param copy The copied {@link File}
* @param original The originl {@link File}
* @return A {@link Resource} with the file-specific data from the
* original {@link File}
*/
private Resource copyFileSpecifics(File copy, File original) {
copy.setContent(original.getContent());
return copy;
}
/**
* Helper method to copy the {@link Folder} specific data to the copy.
*
* @param copy The copied {@link Folder}
* @param original The originl {@link Folder}
* @return A {@link Resource} with the folder-specific data from the
* original {@link Folder}
*/
private Resource copyFolderSpecifics(Folder copy, Folder original) {
copy.setImmediateChildren(original.getImmediateChildren());
copy.setRootAssignedRepository(original.getRootAssignedRepository());
return copy;
}
/** /**
* Determines weather the given name is a valid new name for the also * Determines weather the given name is a valid new name for the also
* given {@link Resource}. * given {@link Resource}.

View File

@ -39,7 +39,8 @@ import java.util.stream.Collectors;
* @version 01/10/2015 * @version 01/10/2015
*/ */
@RequestScoped @RequestScoped
public class ResourceRepository extends AbstractAuditedEntityRepository<Long, Resource> { public class ResourceRepository extends
AbstractAuditedEntityRepository<Long, Resource> {
@Inject @Inject
private EntityManager entityManager; private EntityManager entityManager;

View File

@ -16,23 +16,25 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA * MA 02110-1301 USA
*/ */
package org.libreccm.exchange.exporter.docrepo.exchange.exporter; package org.libreccm.docrepo.portation.exporter;
import org.libreccm.exchange.exporter.ObjectExporter; import org.libreccm.docrepo.File;
import org.libreccm.exchange.exporter.docrepo.Resource; import org.libreccm.portation.exporter.ObjectExporter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
/** /**
* Exporter class for resources. Implements the abstract method of its super. * Exporter class for {@link File}s. Implements the abstract method of its
* super.
* *
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a> * @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 13/01/2016 * @version 13/01/2016
*/ */
public class ResourceExporter extends ObjectExporter<Resource> { public class FileExporter extends ObjectExporter<File> {
@Override @Override
protected String[] getClassName() { protected String[] getClassName() {
return new String[] {Resource.class.getName()}; return new String[] {File.class.getName()};
} }
@Override @Override
@ -40,14 +42,13 @@ public class ResourceExporter extends ObjectExporter<Resource> {
return new String[] { return new String[] {
"name", "name",
"description", "description",
"isFolder",
"path", "path",
"mimeType", "mimeType",
"size", "size",
"blobObject_ID", "blobObject_ID",
"creationDate", "creationDate",
"lastModifiedDate", "lastModifiedDate",
"creationIP", "creationIp",
"lastModifiedIp", "lastModifiedIp",
"creator_ID", "creator_ID",
"modifier_ID", "modifier_ID",
@ -56,28 +57,35 @@ public class ResourceExporter extends ObjectExporter<Resource> {
}; };
} }
// Todo: change ID to UUID
@Override @Override
protected String[] reduceToStrings(Resource exportObject) { protected String[] reduceToStrings(File exportObject) {
ArrayList<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
list.add(exportObject.getName()); list.add(exportObject.getName());
list.add(exportObject.getDescription()); list.add(exportObject.getDescription());
list.add(String.valueOf(exportObject.isFolder()));
list.add(exportObject.getPath()); list.add(exportObject.getPath());
list.add(exportObject.getMimeType() != null ? list.add(exportObject.getMimeType() != null ?
exportObject.getMimeType().toString() : ""); exportObject.getMimeType().toString() : "");
list.add(String.valueOf(exportObject.getSize())); list.add(String.valueOf(exportObject.getSize()));
list.add(String.valueOf(exportObject.getContent().getBlobObjectId())); list.add(exportObject.getContent() != null ? String.valueOf(
exportObject.getContent().getBlobObjectId()) : "");
list.add(exportObject.getCreationDate() != null ? list.add(exportObject.getCreationDate() != null ?
exportObject.getCreationDate().toString() : ""); exportObject.getCreationDate().toString() : "");
list.add(exportObject.getLastModifiedDate() != null ? list.add(exportObject.getLastModifiedDate() != null ?
exportObject.getLastModifiedDate().toString() : ""); exportObject.getLastModifiedDate().toString() : "");
list.add(exportObject.getCreationIp()); list.add(exportObject.getCreationIp());
list.add(exportObject.getLastModifiedIp()); list.add(exportObject.getLastModifiedIp());
list.add(exportObject.getCreationUser().getName()); list.add(exportObject.getCreationUser() != null ? String.valueOf(
list.add(exportObject.getLastModifiedUser().getName()); exportObject.getCreationUser().getPartyId()) : "");
list.add(String.valueOf(exportObject.getParent().getObjectId())); list.add(exportObject.getLastModifiedUser() != null ? String.valueOf(
list.add(String.valueOf(exportObject.getRepository().getObjectId())); exportObject.getLastModifiedUser().getPartyId()) : "");
list.add(exportObject.getParent() != null ? String.valueOf(
exportObject.getParent().getObjectId()) : "");
list.add(exportObject.getRepository() != null ? String.valueOf(
exportObject.getRepository().getObjectId()) : "");
return (String[]) list.toArray(); String[] array = new String[list.size()];
return list.toArray(array);
} }
} }

View File

@ -0,0 +1,138 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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 list copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.docrepo.portation.importer;
import org.apache.log4j.Logger;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.docrepo.BlobObject;
import org.libreccm.docrepo.BlobObjectRepository;
import org.libreccm.docrepo.File;
import org.libreccm.docrepo.Folder;
import org.libreccm.docrepo.Repository;
import org.libreccm.docrepo.RepositoryRepository;
import org.libreccm.docrepo.ResourceRepository;
import org.libreccm.portation.importer.ObjectImporter;
import org.libreccm.security.User;
import org.libreccm.security.UserRepository;
import javax.activation.MimeType;
import javax.activation.MimeTypeParseException;
import java.util.Date;
/**
* Importer class for {@link File}s. Implements the abstract method
* of its super.
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 20/01/2016
*/
public class FileImporter extends ObjectImporter<File> {
private static final Logger log = Logger.getLogger(FileImporter.class);
@Override
protected boolean checkAttributeNames(String[] attributeNames) {
return attributeNames.equals(new String[] {
"name",
"description",
"path",
"mimeType",
"size",
"blobObject_ID",
"creationDate",
"lastModifiedDate",
"creationIp",
"lastModifiedIp",
"creator_ID",
"modifier_ID",
"parent_ID",
"repo_ID"
});
}
@Override
protected File expandFromStrings(String[] importStrings) {
CdiUtil cdiUtil = new CdiUtil();
File file = new File();
file.setName(importStrings[0]);
file.setDescription(importStrings[1]);
file.setPath(importStrings[2]);
MimeType mimeType = new MimeType();
try {
mimeType.setPrimaryType(importStrings[3]);
} catch (MimeTypeParseException e) {
log.warn(String.format("Unable to cast %s to a MimeType.",
importStrings[3]));
}
file.setMimeType(mimeType);
file.setSize(Long.valueOf(importStrings[4]));
BlobObjectRepository blobObjectRepository = cdiUtil.findBean
(BlobObjectRepository.class);
BlobObject blobObject = blobObjectRepository.findById(Long.valueOf
(importStrings[5]));
if (blobObject != null) {
file.setContent(blobObject);
}
Date date = new Date(Long.valueOf(importStrings[6]));
if (date != null) {
file.setCreationDate(date);
}
date = new Date(Long.valueOf(importStrings[7]));
if (date != null) {
file.setLastModifiedDate(date);
}
file.setCreationIp(importStrings[8]);
file.setLastModifiedIp(importStrings[9]);
UserRepository userRepository = cdiUtil.findBean(UserRepository.class);
User user = userRepository.findById(Long.valueOf(importStrings[10]));
if (user != null) {
file.setCreationUser(user);
}
user = userRepository.findById(Long.valueOf(importStrings[11]));
if (user != null) {
file.setLastModifiedUser(user);
}
ResourceRepository resourceRepository = cdiUtil.findBean
(ResourceRepository.class);
Folder folder = (Folder) resourceRepository.findById(Long.valueOf
(importStrings[12]));
if (folder != null) {
file.setParent(folder);
}
RepositoryRepository repositoryRepository = cdiUtil.findBean
(RepositoryRepository.class);
Repository repository = repositoryRepository.findById(Long.valueOf
(importStrings[13]));
if (repository != null) {
file.setRepository(repository);
}
//resourceRepository.save(file);
return file;
}
}

View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.docrepo.portation;
import org.apache.log4j.Logger;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.libreccm.docrepo.File;
import org.libreccm.docrepo.portation.exporter.FileExporter;
import org.libreccm.docrepo.portation.importer.FileImporter;
import org.libreccm.tests.categories.UnitTest;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 13/01/2016
*/
@Category(UnitTest.class)
public class FilePortationTest {
private static final Logger log = Logger.getLogger(FilePortationTest.class);
private static File file;
private static String filename =
"src/test/java/org/libreccm/docrepo/portation/exportTest.csv";
@BeforeClass
public static void createResource() {
file = new File();
file.setName("testname");
file.setDescription("this is a text description");
file.setPath("test/path");
file.setCreationDate(new Date());
file.setLastModifiedDate(new Date());
}
@Test
public void csvShouldBeCreated() {
FileExporter fileExporter = new FileExporter();
fileExporter.setFilename(filename);
try {
fileExporter.exportToCSV(Arrays.asList(file));
} catch (FileNotFoundException e) {
log.error("Error exporting files.");
}
}
@Test
public void fileShouldBeCreated() {
FileImporter fileImporter = new FileImporter();
fileImporter.setFilename(filename);
List<File> files;
try {
files = fileImporter.importFromCSV();
log.info(files.toString());
} catch (FileNotFoundException e) {
log.error("Error exporting files.");
}
}
}

View File

@ -38,7 +38,7 @@
<module>ccm-core</module> <module>ccm-core</module>
<module>ccm-shortcuts</module> <module>ccm-shortcuts</module>
<module>ccm-testutils</module> <module>ccm-testutils</module>
<!--<module>ccm-docrepo</module>--> <module>ccm-docrepo</module>
<!-- Bundle modules --> <!-- Bundle modules -->
<module>ccm-bundle-devel-swarm</module> <module>ccm-bundle-devel-swarm</module>