362 lines
11 KiB
Java
Raw Normal View History

2012-08-16 21:51:59 -03:00
/*
2022-03-17 18:47:34 -03:00
* Copyright [2022] [wisemapping]
*
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
* It is basically the Apache License, Version 2.0 (the "License") plus the
* "powered by wisemapping" text requirement on every single page;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the license at
*
* http://www.wisemapping.org/license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
2012-08-16 21:51:59 -03:00
package com.wisemapping.model;
import com.wisemapping.exceptions.AccessDeniedSecurityException;
import com.wisemapping.exceptions.InvalidMindmapException;
2012-08-16 21:51:59 -03:00
import com.wisemapping.exceptions.WiseMappingException;
import com.wisemapping.util.ZipUtils;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
2022-02-21 09:08:28 -08:00
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
2012-08-16 21:51:59 -03:00
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
2023-07-28 22:46:38 -07:00
import jakarta.persistence.*;
2024-01-21 22:09:28 -08:00
2012-08-16 21:51:59 -03:00
import java.io.IOException;
import java.io.Serializable;
2012-08-16 21:51:59 -03:00
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
2022-01-10 16:51:06 -08:00
import java.util.*;
2012-08-16 21:51:59 -03:00
@Entity
@Table(name = "MINDMAP")
2022-02-21 09:08:28 -08:00
public class Mindmap implements Serializable {
2012-08-16 21:51:59 -03:00
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
2012-08-16 21:51:59 -03:00
private int id;
2022-02-21 09:08:28 -08:00
@Column(name = "creation_date")
2012-08-16 21:51:59 -03:00
private Calendar creationTime;
@Column(name = "edition_date")
2012-08-16 21:51:59 -03:00
private Calendar lastModificationTime;
2024-01-21 22:09:28 -08:00
@ManyToOne(fetch = FetchType.EAGER)
2022-01-18 13:16:39 -08:00
@JoinColumn(name = "creator_id", unique = true)
2024-02-17 11:18:43 -08:00
private Account creator;
2023-07-30 22:50:04 -07:00
@ManyToOne
2022-01-18 13:16:39 -08:00
@JoinColumn(name = "last_editor_id", nullable = false)
2022-02-21 09:08:28 -08:00
@NotFound(action = NotFoundAction.IGNORE)
2024-02-17 11:18:43 -08:00
private Account lastEditor;
2012-08-16 21:51:59 -03:00
private String description;
@Column(name = "public")
private boolean isPublic;
2023-11-20 19:37:08 -08:00
@OneToMany(mappedBy = "mindMap", orphanRemoval = true, cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
@Fetch(FetchMode.JOIN)
private Set<Collaboration> collaborations = new HashSet<>();
2022-08-06 16:21:17 -07:00
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE})
@Fetch(FetchMode.JOIN)
@JoinTable(
name = "R_LABEL_MINDMAP",
joinColumns = @JoinColumn(name = "mindmap_id"),
inverseJoinColumns = @JoinColumn(name = "label_id"))
2024-02-17 11:18:43 -08:00
private Set<MindmapLabel> labels = new LinkedHashSet<>();
2012-08-16 21:51:59 -03:00
private String title;
@Column(name = "xml")
@Basic(fetch = FetchType.LAZY)
2013-03-30 01:09:28 -03:00
private byte[] zippedXml;
2012-08-16 21:51:59 -03:00
public Mindmap() {
}
2013-03-30 01:09:28 -03:00
public void setUnzipXml(@NotNull byte[] value) {
try {
final byte[] zip = ZipUtils.bytesToZip(value);
this.setZippedXml(zip);
} catch (IOException e) {
throw new IllegalStateException(e);
}
2012-08-16 21:51:59 -03:00
}
public void setXmlStr(@NotNull String xml) throws InvalidMindmapException {
// Is a valid mindmap ... ?
MindmapUtils.verifyMindmap(xml);
this.setUnzipXml(xml.getBytes(StandardCharsets.UTF_8));
2012-08-16 21:51:59 -03:00
}
2013-03-30 01:09:28 -03:00
@NotNull
public byte[] getUnzipXml() {
byte[] result = new byte[]{};
if (zippedXml != null) {
2013-03-29 14:57:21 -03:00
try {
2013-03-30 01:09:28 -03:00
final byte[] zip = this.getZippedXml();
result = ZipUtils.zipToBytes(zip);
2013-03-29 14:57:21 -03:00
} catch (IOException e) {
throw new IllegalStateException(e);
}
2012-08-16 21:51:59 -03:00
}
return result;
}
2013-03-30 01:09:28 -03:00
@NotNull
public String getXmlStr() throws UnsupportedEncodingException {
return new String(this.getUnzipXml(), StandardCharsets.UTF_8);
2013-03-30 01:09:28 -03:00
}
@NotNull
public byte[] getZippedXml() {
return zippedXml;
}
public void setZippedXml(@NotNull byte[] value) {
this.zippedXml = value;
2012-08-16 21:51:59 -03:00
}
public Set<Collaboration> getCollaborations() {
return collaborations;
}
public void setCollaborations(Set<Collaboration> collaborations) {
this.collaborations = collaborations;
}
public void addCollaboration(@NotNull Collaboration collaboration) {
collaborations.add(collaboration);
}
public void removedCollaboration(@NotNull Collaboration collaboration) {
// https://stackoverflow.com/questions/25125210/hibernate-persistentset-remove-operation-not-working
this.collaborations.remove(collaboration);
collaboration.setMindMap(null);
2022-09-27 18:47:56 -07:00
}
public void removedCollaboration(@NotNull Set<Collaboration> collaborations) {
this.collaborations.removeAll(collaborations);
2012-08-16 21:51:59 -03:00
}
@NotNull
2024-02-17 11:18:43 -08:00
public Set<MindmapLabel> getLabels() {
2014-01-28 02:28:16 -03:00
return labels;
}
2024-02-17 11:18:43 -08:00
public void setLabels(@NotNull final Set<MindmapLabel> labels) {
2014-01-28 02:28:16 -03:00
this.labels = labels;
}
2024-02-17 11:18:43 -08:00
public void addLabel(@NotNull final MindmapLabel label) {
2014-01-28 02:28:16 -03:00
this.labels.add(label);
}
2022-01-18 13:16:39 -08:00
public Optional<Collaboration> findCollaboration(@NotNull Collaborator collaborator) {
return this.collaborations
.stream()
2022-02-21 09:08:28 -08:00
.filter(c -> c.getCollaborator().identityEquality(collaborator))
2022-01-18 13:16:39 -08:00
.findAny();
2012-08-16 21:51:59 -03:00
}
@Nullable
public Collaboration findCollaboration(@NotNull String email) {
Collaboration result = null;
for (Collaboration collaboration : collaborations) {
if (collaboration.getCollaborator().getEmail().equals(email)) {
result = collaboration;
break;
}
}
return result;
}
2024-02-17 11:18:43 -08:00
public boolean isCreator(@NotNull Account user) {
2022-09-27 18:47:56 -07:00
return this.getCreator() != null && this.getCreator().identityEquality(user);
}
2012-08-16 21:51:59 -03:00
public boolean isPublic() {
return isPublic;
}
2020-11-22 12:53:35 -08:00
2012-08-16 21:51:59 -03:00
public void setPublic(boolean isPublic) {
this.isPublic = isPublic;
}
public Calendar getLastModificationTime() {
return lastModificationTime;
}
public void setLastModificationTime(Calendar lastModificationTime) {
this.lastModificationTime = lastModificationTime;
}
@Nullable
2024-02-17 11:18:43 -08:00
public Account getLastEditor() {
2012-08-16 21:51:59 -03:00
return lastEditor;
}
2024-02-17 11:18:43 -08:00
public void setLastEditor(@Nullable Account lastEditor) {
2012-08-16 21:51:59 -03:00
this.lastEditor = lastEditor;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
2013-01-31 20:01:15 -03:00
@NotNull
2012-08-16 21:51:59 -03:00
public String getXmlAsJsLiteral()
throws IOException {
String xml = this.getXmlStr();
2013-01-31 20:01:15 -03:00
2022-01-18 13:16:39 -08:00
xml = xml.replace("'", "\\'");
xml = xml.replace("\n", "\\n");
xml = xml.replace("\r", "");
2013-01-31 20:01:15 -03:00
2022-01-18 13:16:39 -08:00
xml = xml.replace("\\b", "\\\\b");
xml = xml.replace("\\t", "\\\\t");
xml = xml.replace("\\r", "\\\\r");
xml = xml.replace("\\f", "\\\\f");
xml = xml.trim();
2012-08-16 21:51:59 -03:00
return xml;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Calendar getCreationTime() {
return creationTime;
}
public void setCreationTime(Calendar creationTime) {
this.creationTime = creationTime;
}
2024-02-17 11:18:43 -08:00
public void setCreator(@NotNull Account creator) {
2012-08-16 21:51:59 -03:00
this.creator = creator;
}
2024-02-17 11:18:43 -08:00
public Account getCreator() {
2012-08-16 21:51:59 -03:00
return creator;
}
2022-01-18 13:16:39 -08:00
@Nullable
2012-08-16 21:51:59 -03:00
private CollaborationProperties findUserProperty(@NotNull Collaborator collaborator) {
2022-01-18 13:16:39 -08:00
final Optional<Collaboration> collaboration = this.findCollaboration(collaborator);
return collaboration.map(Collaboration::getCollaborationProperties).orElse(null);
2012-08-16 21:51:59 -03:00
}
public void setStarred(@NotNull Collaborator collaborator, boolean value) throws WiseMappingException {
final CollaborationProperties collaborationProperties = findCollaborationProperties(collaborator);
collaborationProperties.setStarred(value);
}
@NotNull
public CollaborationProperties findCollaborationProperties(@NotNull Collaborator collaborator) throws WiseMappingException {
2022-01-10 16:51:06 -08:00
return Objects.requireNonNull(this.findCollaborationProperties(collaborator, true));
2012-09-15 11:35:53 -03:00
}
@Nullable
public CollaborationProperties findCollaborationProperties(@NotNull Collaborator collaborator, boolean forceCheck) throws WiseMappingException {
2012-08-16 21:51:59 -03:00
if (collaborator == null) {
throw new IllegalStateException("Collaborator can not be null");
}
2022-01-18 13:16:39 -08:00
final Optional<Collaboration> collaboration = this.findCollaboration(collaborator);
2012-09-15 11:35:53 -03:00
CollaborationProperties result = null;
2022-01-18 13:16:39 -08:00
if (collaboration.isPresent()) {
result = collaboration.get().getCollaborationProperties();
2012-09-15 11:35:53 -03:00
} else {
if (forceCheck)
throw new AccessDeniedSecurityException("Collaborator " + collaborator.getEmail() + " could not access " + this.getId());
2012-08-16 21:51:59 -03:00
}
2012-09-15 11:35:53 -03:00
return result;
2012-08-16 21:51:59 -03:00
}
public boolean isStarred(@NotNull Collaborator collaborator) {
final CollaborationProperties collaboratorProperty = this.findUserProperty(collaborator);
return collaboratorProperty != null && collaboratorProperty.getStarred();
}
public static String getDefaultMindmapXml(@NotNull final String title) {
2024-02-06 22:26:44 -08:00
return "<map version=\"tango\" theme=\"prism\">" +
"<topic central=\"true\" text=\"" +
escapeXmlAttribute(title) +
"\"/></map>";
2012-08-16 21:51:59 -03:00
}
2022-10-24 19:02:41 -07:00
static private String escapeXmlAttribute(String attValue) {
// Hack: Find out of the box function.
String result = attValue.replace("&", "&amp;");
result = result.replace("<", "&lt;");
result = result.replace("gt", "&gt;");
result = result.replace("\"", "&quot;");
return result;
}
2012-08-16 21:51:59 -03:00
public Mindmap shallowClone() {
final Mindmap result = new Mindmap();
result.setDescription(this.getDescription());
result.setTitle(this.getTitle());
2013-03-30 01:09:28 -03:00
result.setUnzipXml(this.getUnzipXml());
2012-08-16 21:51:59 -03:00
return result;
}
2012-09-15 11:35:53 -03:00
public boolean hasPermissions(@Nullable Collaborator collaborator, @NotNull CollaborationRole role) {
2012-08-16 21:51:59 -03:00
boolean result = false;
2012-08-26 16:53:33 -03:00
if (collaborator != null) {
2022-01-18 13:16:39 -08:00
final Optional<Collaboration> collaboration = this.findCollaboration(collaborator);
if (collaboration.isPresent()) {
result = collaboration.get().hasPermissions(role);
2012-08-26 16:53:33 -03:00
}
2012-08-16 21:51:59 -03:00
}
return result;
}
2014-01-29 03:59:05 -03:00
public boolean hasLabel(@NotNull final String name) {
2024-02-17 11:18:43 -08:00
for (MindmapLabel label : this.labels) {
2014-01-29 03:59:05 -03:00
if (label.getTitle().equals(name)) {
return true;
}
}
return false;
}
2024-02-17 11:18:43 -08:00
public void removeLabel(@NotNull final MindmapLabel label) {
this.labels.remove(label);
}
2012-08-16 21:51:59 -03:00
}