[FEATURE]

- adds dependency for 'com.opencsv' to parent-pom.xml and core-pom.xml
- adds package exchange to ccm-core for the export-import-routines
- adds class ObjectExporter to the exchange-package for the basic export-functionalities
- adds dummy package docrepo.exchange.exporter into the exchange package of core
- adds ResourceExporter to the dummy package for implementation of the abstact methods of the ObjectExporter

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3792 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
tosmers 2016-01-13 16:58:46 +00:00
parent 97567275e2
commit b35e44a867
13 changed files with 1334 additions and 1 deletions

View File

@ -178,7 +178,13 @@
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,115 @@
/*
* 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;
import com.opencsv.CSVWriter;
import org.apache.commons.lang.NullArgumentException;
import org.apache.log4j.Logger;
import org.libreccm.security.User;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
/**
* Main class for exporting database objects as .csv-textfiles. Subclasses
* are required to implement the method {@code asList} matching their own
* needs. This is necessary, because every object class stored in the
* database has its own parameters which refer sometimes to other object
* classes. But these other object classes do not need to be exported in
* their entirety, only their uuid for later re-identification.
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 13/01/2016
*/
public abstract class ObjectExporter<T> {
private static final Logger log = Logger.getLogger(ObjectExporter.class);
private String filename = "ccm_ng-defaultExportFilename.csv";
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 ObjectExporter() {}
/**
* Exports a list of objects of type {@code T}, e.g. a list of
* {@link User}s, as a .csv-textfile with the specified {@code filename}.
*
* @param exportObjects List of objects of type {@code T} to be exported
*/
public void export(List<T> exportObjects) throws NullArgumentException {
CSVWriter csvWriter = null;
if (filename == null) {
throw new NullArgumentException(filename);
}
try {
csvWriter = new CSVWriter(new FileWriter(filename),
separator);
csvWriter.writeAll(asList(exportObjects));
csvWriter.close();
} catch (IOException e) {
//Todo: what to do
e.printStackTrace();
}
}
/**
* Abstract method to force extending subclasses to implement this
* method, so the needed list for the export is matching their special
* needs.
*
* @param exportObjects List of objects of type {@code T} to be exported
* @return A list of strings containing all database information of the
* wanted object class.
*/
public abstract List<String[]> asList(List<T> exportObjects);
/**
* Abstract method to reduce the types of a single export object to
* strings.
*
* @param exportObject A single exportObject
* @return A list of strings representing the parameters of the
* export object
*/
protected abstract String[] reduceToString(T exportObject);
}

View File

@ -0,0 +1,147 @@
/*
* 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

@ -0,0 +1,44 @@
/*
* 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

@ -0,0 +1,62 @@
/*
* 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

@ -0,0 +1,46 @@
/*
* 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

@ -0,0 +1,126 @@
/*
* 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

@ -0,0 +1,95 @@
/*
* 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

@ -0,0 +1,324 @@
/*
* 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

@ -0,0 +1,108 @@
/*
* 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

@ -0,0 +1,156 @@
/*
* 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

@ -0,0 +1,98 @@
/*
* 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.exchange;
import org.libreccm.exchange.exporter.ObjectExporter;
import org.libreccm.exchange.exporter.docrepo.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* Exporter class for resources. Implements the abstract method of its super.
*
* @author <a href="mailto:tosmers@uni-bremen.de">Tobias Osmers</a>
* @version 13/01/2016
*/
public class ResourceExporter extends ObjectExporter<Resource> {
@Override
public List<String[]> asList(List<Resource> exportObjects) {
List<String[]> exportList = new ArrayList<>();
exportList.add(new String[]{Resource.class.getName()});
exportList.add(new String[]{
"name",
"description",
"isFolder",
"path",
"mimeType",
"size",
"blobObject_ID",
"creationDate",
"lastModifiedDate",
"creationIP",
"lastModifiedIp",
"creator_ID",
"modifier_ID",
"parent_ID",
"repo_ID"
});
return exportList.addAll(exportObjects.stream().map(
this::reduceToString).collect(Collectors.toList()))
? exportList : exportList;
}
@Override
protected String[] reduceToString(Resource exportObject) {
return new String[] {
// name
exportObject.getName(),
// description
exportObject.getDescription(),
// isFolder
String.valueOf(exportObject.isFolder()),
// path
exportObject.getPath(),
// mimeType
exportObject.getMimeType().toString(),
// size
String.valueOf(exportObject.getSize()),
// blobObject_ID
String.valueOf(exportObject.getContent().getBlobObjectId()),
// creationDate
exportObject.getCreationDate().toString(),
// lastModifiedDate
exportObject.getLastModifiedDate().toString(),
// creationIp
exportObject.getCreationIp(),
// lastModifiedIp
exportObject.getLastModifiedIp(),
// creator_ID
exportObject.getCreationUser().getName(),
// modifier_ID
exportObject.getLastModifiedUser().getName(),
// parent_ID
String.valueOf(exportObject.getParent().getObjectId()),
// repo_ID
String.valueOf(exportObject.getRepository().getObjectId()),
};
}
}

View File

@ -425,6 +425,12 @@
<artifactId>xml-resolver</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>3.6</version>
</dependency>
<!--
**********************