/** * Copyright (C) 2015 Born Informatik AG (www.born.ch) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * 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. */ package org.wte4j.persistence; import java.util.Arrays; import java.util.Date; import java.util.Map; import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.CollectionTable; import javax.persistence.Column; import javax.persistence.ElementCollection; import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.Lob; import javax.persistence.MapKeyColumn; import javax.persistence.Table; import javax.persistence.TableGenerator; import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.persistence.Transient; import javax.persistence.UniqueConstraint; import javax.persistence.Version; import org.wte4j.LockingException; import org.wte4j.MappingDetail; import org.wte4j.TemplateData; import org.wte4j.User; /** * Persistent data of a wte4j Template */ @Entity @Table(name = "wte4j_template", uniqueConstraints = @UniqueConstraint(columnNames = { "document_name", "language" })) @TableGenerator(name = "wte4j_gen", table = "wte4j_gen", valueColumnName = "sequence_next", pkColumnName = "sequence_name", pkColumnValue = "wte4j_template") public class PersistentTemplate implements TemplateData{ private static final String TEMPLATE_SUFFIX = ".docx"; @Id @GeneratedValue(strategy = GenerationType.TABLE, generator = "wte4j_gen") private Long id; @Column(name = "document_name", nullable = false) private String documentName; @Column(name = "language", nullable = false) private String language; @Transient private Class<?> inputType; @Column(name = "input_class_name", length = 250) private String inputClassName; @ElementCollection(fetch = FetchType.EAGER) @CollectionTable(name = "wte4j_template_properties", joinColumns = @JoinColumn(name = "template_id")) @MapKeyColumn(name = "property_key") @Column(name = "property_value") private Map<String, String> properties; @ElementCollection(fetch = FetchType.EAGER, targetClass = MappingDetail.class) @CollectionTable(name = "wte4j_template_content_mapping", joinColumns = @JoinColumn(name = "template_id")) @MapKeyColumn(name = "conentend_control_id") @AttributeOverrides({ @AttributeOverride(name="value.formatterDefinition",column=@Column(name="formatter_definition",length=250)), @AttributeOverride(name="value.modelKey",column=@Column(name="model_key",length=250)) }) private Map<String, MappingDetail> contentMapping; @Temporal(TemporalType.TIMESTAMP) @Column(name = "created_at", nullable = false, updatable = false) private Date createdAt; @Temporal(TemporalType.TIMESTAMP) @Column(name = "edited_at", nullable = false) private Date editedAt; @Embedded @AttributeOverrides({ @AttributeOverride(name = "userId", column = @Column(name = "editor_user_id", length = 50, nullable = false)), @AttributeOverride(name = "displayName", column = @Column(name = "editor_display_name", length = 100)) }) private User editor; @Column(name = "locking_date", nullable = true) @Temporal(TemporalType.TIMESTAMP) private Date lockingDate; @Embedded @AttributeOverrides({ @AttributeOverride(name = "userId", column = @Column(name = "locking_user_id", length = 50, nullable = true)), @AttributeOverride(name = "displayName", column = @Column(name = "locking_user_display_name", length = 100, nullable = true)) }) private User lockingUser; @Lob @Column(name = "content", nullable = true, columnDefinition = "BLOB") private byte[] content; @Version private Long version; public Long getId() { return id; } public long getVersion() { return version; } public String getDocumentName() { return documentName; } public void setDocumentName(String documentName) { this.documentName = documentName; } public String getLanguage() { return language; } public void setLanguage(String language) { this.language = language; } public String getInputClassName() { return inputClassName; } public String getTemplateFileName() { return documentName + "_" + language + TEMPLATE_SUFFIX; } public void setInputType(Class<?> inputClass) { this.inputClassName = inputClass.getName(); this.inputType = inputClass; } public Class<?> getInputType() { if (inputType == null) { initInputClass(); } return inputType; } public Map<String, String> getProperties() { return properties; } public void setProperties(Map<String, String> modelProperties) { this.properties = modelProperties; } public Map<String, MappingDetail> getContentMapping() { return contentMapping; } public void setContentMapping(Map<String, MappingDetail> contentMapping) { this.contentMapping = contentMapping; } public User getLockingUser() { return lockingUser; } public void setLockingUser(User lockingUser) { this.lockingUser = lockingUser; } public Date getLockingDate() { return lockingDate; } public void setLockingDate(Date lockingDate) { this.lockingDate = lockingDate; } public Date getCreatedAt() { return createdAt; } public void setCreatedAt(Date createdAt) { this.createdAt = createdAt; } public User getEditor() { return editor; } public Date getEditedAt() { return editedAt; } public void setEditedAt(Date date) { editedAt = date; } public void setEditor(User user) { editor = user; } public byte[] getContent() { return content; } protected void setContent(byte[] bytes) { content = Arrays.copyOf(bytes, bytes.length); } public void setContent(byte[] newContent, User newEditor) throws LockingException { if (isLocked() && !isLockedBy(newEditor)) { throw new LockingException("Template is locked by an ohter user"); } setContent(newContent); setEditor(newEditor); setEditedAt(new Date()); if (getCreatedAt() == null) { setCreatedAt(getEditedAt()); } } void initInputClass() { try { inputType = Class.forName(inputClassName); } catch (ClassNotFoundException e) { throw new IllegalStateException("Error restore inputClass", e); } } public boolean isLocked() { return lockingUser != null && lockingUser.getUserId() != null; } public boolean isLockedBy(User user) { return user.equals(lockingUser); } public void unlock() { lockingDate = null; lockingUser = null; } public void lock(User user) throws LockingException { if (isLocked() && !isLockedBy(user)) { throw new LockingException("Template is locked by an other user"); } lockingDate = new Date(); lockingUser = user; } }