1   package com.trendmicro.grid.acl.ds.jpa.entities;
2   
3   import com.trendmicro.grid.acl.Limits;
4   import com.trendmicro.grid.acl.ds.datatypes.SharedPackageInformation;
5   import com.trendmicro.grid.acl.ds.jpa.types.TagListFieldBridge;
6   import com.trendmicro.grid.acl.ds.jpa.util.NameValidator;
7   import org.hibernate.annotations.Index;
8   import org.hibernate.annotations.NaturalId;
9   import org.hibernate.annotations.Type;
10  import org.hibernate.search.annotations.*;
11  import org.slf4j.Logger;
12  import org.slf4j.LoggerFactory;
13  
14  import javax.persistence.*;
15  import java.util.Date;
16  
17  import static com.trendmicro.grid.acl.Limits.MAX_DISPLAY_NAME_LENGTH;
18  import static com.trendmicro.grid.acl.Limits.MAX_NAME_LENGTH;
19  import static com.trendmicro.grid.acl.ds.jpa.util.JpaUtils.extractName;
20  
21  /**
22   * Binds PackageInformation to the table "PACKAGES".
23   *
24   * @author juergen_kellerer, 2010-06-10
25   * @version 1.0
26   */
27  @Cacheable
28  @Embeddable
29  public class JpaPackageInformation extends SharedPackageInformation {
30  
31  	public static final String ROOT_PACKAGE_NAME = "ROOT";
32  
33  	private static final Logger log = LoggerFactory.getLogger(JpaPackageInformation.class);
34  	private static final long serialVersionUID = 5419280948223626735L;
35  
36  	private Date firstSeen;
37  
38  	public JpaPackageInformation() {
39  	}
40  
41  	public JpaPackageInformation(String name, String displayName, String familyName, String vendorName,
42  	                             String[] tags, JpaFileInformation packageFileInformation) {
43  		super(name, displayName, familyName, vendorName, tags, packageFileInformation);
44  		validateAndSetNames();
45  	}
46  
47  	public void validateAndSetNames() {
48  		if (name == null || name.isEmpty()) {
49  			log.warn("TMACL-00910: The package name is empty on '{}', this is an invalid state and will lead to problems.", this);
50  			if (name == null) return;
51  		}
52  
53  		final String vendorName = extractName(name, 1);
54  		final String familyName = extractName(name, 2);
55  
56  		final NameValidator nameValidator = NameValidator.getInstance();
57  		nameValidator.validatePackageFamilyName(vendorName, familyName);
58  		nameValidator.validatePackageName(vendorName, name);
59  
60  		this.vendorName = vendorName;
61  		this.familyName = familyName;
62  	}
63  
64  	@Override
65  	@NaturalId
66  	@Type(type = "nstring")
67  	@Column(name = "NAME", length = MAX_NAME_LENGTH, nullable = false, unique = true, updatable = false)
68  	// DB index configuration
69  	@Index(name = "IX_PACKAGE__NAME_INDEX")
70  	// Fulltext index configuration
71  	@Field(store = Store.YES, index = org.hibernate.search.annotations.Index.NO, analyze = Analyze.NO, norms = Norms.NO, termVector = TermVector.NO)
72  	public String getName() {
73  		return name;
74  	}
75  
76  	public void setName(String name) {
77  		this.name = name;
78  		if (name != null) validateAndSetNames();
79  	}
80  
81  	@Override
82  	@Type(type = "nstring")
83  	@Column(name = "DISPLAY_NAME", length = MAX_DISPLAY_NAME_LENGTH, nullable = false)
84  	public String getDisplayName() {
85  		return displayName;
86  	}
87  
88  	public void setDisplayName(String displayName) {
89  		this.displayName = displayName;
90  	}
91  
92  	@Temporal(TemporalType.TIMESTAMP)
93  	@Column(name = "CREATED", nullable = false)
94  	// DB index configuration
95  	@Index(name = "IX_PACKAGE__CREATED_INDEX")
96  	// Fulltext index configuration
97  	@Field(analyze = Analyze.NO, norms = Norms.NO, termVector = TermVector.NO)
98  	@DateBridge(resolution = Resolution.DAY)
99  	public Date getFirstSeen() {
100 		if (firstSeen == null) firstSeen = new Date();
101 		return firstSeen;
102 	}
103 
104 	public void setFirstSeen(Date firstSeen) {
105 		// Note: Converting Timestamp to Date to avoid that "equals()" fails to compare 2 instances.
106 		//       (Copy on set increases security on mutable type.)
107 		this.firstSeen = firstSeen == null ? null : new Date(firstSeen.getTime());
108 	}
109 
110 	@Override
111 	@Column(name = "REFERENCED_FILES_COUNT", updatable = false, insertable = false)
112 	public Integer getContainedFilesCount() {
113 		return containedFilesCount;
114 	}
115 
116 	public void setContainedFilesCount(Integer containedFilesCount) {
117 		this.containedFilesCount = containedFilesCount;
118 	}
119 
120 	@Type(type = "taglist")
121 	@Column(name = "TAGS", length = Limits.MAX_TAG_STRING_LENGTH, nullable = true)
122 	// Fulltext index configuration
123 	@Field(analyze = Analyze.NO, norms = Norms.NO, termVector = TermVector.NO)
124 	@FieldBridge(impl = TagListFieldBridge.class)
125 	public String[] getTagsAsArray() {
126 		return tags;
127 	}
128 
129 	public void setTagsAsArray(String[] tags) {
130 		this.tags = tags;
131 		tagsAreSorted = true; // taglist type guarantees that tags are sorted.
132 	}
133 
134 	@Override
135 	@Transient
136 	public JpaFileInformation getPackageFileInformation() {
137 		return (JpaFileInformation) super.getPackageFileInformation();
138 	}
139 
140 	public void setPackageFileInformation(JpaFileInformation packageFileInformation) {
141 		this.packageFileInformation = packageFileInformation;
142 	}
143 
144 	/**
145 	 * {@inheritDoc}
146 	 */
147 	@Override
148 	public String toString() {
149 		return "JpaPackageInformation{" +
150 				"name='" + name + '\'' +
151 				", familyName='" + familyName + '\'' +
152 				", vendorName='" + vendorName + '\'' +
153 				", displayName='" + displayName + '\'' +
154 				", firstSeen='" + firstSeen + '\'' +
155 				", tags='" + getTags() + '\'' +
156 				", containedFilesCount='" + containedFilesCount + '\'' +
157 				", packageFileInformation=" + packageFileInformation +
158 				'}';
159 	}
160 }