Project

General

Profile

Download (8.56 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.model.metadata;
10

    
11
import java.io.Serializable;
12
import java.util.ArrayList;
13
import java.util.List;
14
import java.util.UUID;
15

    
16
import javax.persistence.Column;
17
import javax.persistence.Embeddable;
18
import javax.persistence.EmbeddedId;
19
import javax.persistence.Entity;
20

    
21
import org.apache.commons.lang3.StringUtils;
22

    
23

    
24
/**
25
 * This class may hold all prefrences data for a CDM database.
26
 * E.g. one may store what the default nomenclatural code is,
27
 * or which default formatter (cache strategy) to use for a
28
 * certain class.
29
 * The structure represents a triple where the first item
30
 * (subject) defines for which object the given information is valid.
31
 * The second item (predicate) describes the type of information
32
 * and the third item (value) represents the actual value.
33
 *
34
 *  E.g. for defining a database wide default nomenclatural code
35
 *  you may define a triple ("database", "eu.etaxonomy.cdm.model.name.NomenclaturalCode", "ICZN").
36
 *  The set of allowed values and semantics for each combination
37
 *  is up to implementing classes.
38
 *  The only restrictions we have is the length of the fields and
39
 *  the fact that the first two items (subject, predicate) do
40
 *  create a unique key.
41
 *
42
 *  Size of single fields may be enlarged in future versions. "Value" may
43
 *  become a CLOB.
44
 *
45
 * @author a.mueller
46
 * @created 03.07.2013
47
 */
48
@Entity
49
public final class CdmPreference implements Serializable {
50
	private static final long serialVersionUID = 4307599154287181582L;
51

    
52
    public static final CdmPreference NewInstance(PreferenceSubject subject, PreferencePredicate predicate, String value){
53
        return new CdmPreference(subject, predicate, value);
54
    }
55

    
56
    /**
57
     * @param test
58
     * @param string
59
     * @return
60
     */
61
    public static CdmPreference NewDatabaseInstance(PreferencePredicate test, String value) {
62
        return new CdmPreference(PreferenceSubject.NewDatabaseInstance(), test, value);
63
    }
64

    
65
    public static PrefKey NewKey(PreferenceSubject subject, PreferencePredicate predicate){
66
      return new PrefKey(subject, predicate);
67
    }
68

    
69
//	public static final CdmPreference NewInstance(PreferenceSubjectEnum subject, PreferencePredicate predicate, String value){
70
//		return new CdmPreference(subject, predicate, value);
71
//	}
72
//
73
//	public static PrefKey NewKey(PreferenceSubjectEnum subject, PreferencePredicate predicate){
74
//		return new PrefKey(subject, predicate);
75
//	}
76

    
77

    
78
	@EmbeddedId
79
	private PrefKey key;
80

    
81
	@Column(length=1023)
82
	private String value;
83

    
84
    //if false, the preference should not be overridden by local preferences,
85
	//if true existing local preferences override database preferences
86
	    //and the database preference only defines the default.
87
    private boolean allowOverride = false;
88

    
89
    @Embeddable
90
    public static class PrefKey implements Serializable{
91

    
92
        private static final long serialVersionUID = 9019957853773606194L;
93

    
94
        //required syntax:  /([A-Za-z]+\[.*\])?
95
        //examples /  ,  /TaxonNode[#t10#44#1456#]  for a taxon node preference
96
        @Column(name="key_subject", length=100) //for now we keep the combined key short as indizes for such keys are very limited in size in some DBMS. Size may be increased later
97
        private String subject;
98

    
99
        @Column(name="key_predicate", length=100) //for now we keep the combined key short as indizes for such keys are very limited in size in some DBMS. Size may be increased later
100
        private String predicate;
101

    
102
        //for hibernate use only
103
        private PrefKey(){}
104

    
105
        private PrefKey(PreferenceSubject subject, PreferencePredicate predicate){
106
            this(subject.toString(), predicate.getKey());
107
        }
108
//      private PrefKey(PreferenceSubjectEnum subject, PreferencePredicate predicate){
109
//          this(subject.getKey(), predicate.getKey());
110
//      }
111

    
112
        private PrefKey(String subject, String predicate){
113
            if (subject == null) {
114
                throw new IllegalArgumentException("Subject must not be null for preference");
115
            }
116
            if (predicate == null) {
117
                throw new IllegalArgumentException("Predicate must not be null for preference");
118
            }
119
            if (subject.length() > 255) {
120
                throw new IllegalArgumentException("Subject must not be longer then 255 for preference");
121
            }
122
            if (predicate.length() > 255) {
123
                throw new IllegalArgumentException("Predicate must not be longer then 255 for preference");
124
            }
125
            if (!subject.matches("/([A-Za-z]+\\[.*\\])?")){
126
                throw new IllegalArgumentException("Predicate does not follow the required syntax");
127
            }
128

    
129

    
130
            this.subject = subject;
131
            this.predicate = predicate;
132
        }
133

    
134
        @Override
135
        public int hashCode() {
136
            final int prime = 31;
137
            int result = 1;
138
            result = prime * result + ((predicate == null) ? 0 : predicate.hashCode());
139
            result = prime * result + ((subject == null) ? 0 : subject.hashCode());
140
            return result;
141
        }
142

    
143
        @Override
144
        public boolean equals(Object obj) {
145
            if (this == obj){
146
                return true;
147
            } else if (obj == null){
148
                return false;
149
            }else if (getClass() != obj.getClass()){
150
                return false;
151
            }else{
152
                PrefKey other = (PrefKey) obj;
153
                return ( predicate.equals(other.predicate) && subject.equals(other.subject));
154
            }
155
        }
156

    
157
    }
158

    
159
//****************** CONSTRUCTOR **********************/
160

    
161
	//for hibernate use only
162
	@SuppressWarnings("unused")
163
	private CdmPreference(){}
164

    
165

    
166
	public CdmPreference(PreferenceSubject subject, PreferencePredicate predicate, String value){
167
		this.key = new PrefKey(subject, predicate);
168
		//TODO are null values allowed?		assert predicate != null : "value must not be null for preference";
169
		if (value != null && value.length() > 1023) {throw new IllegalArgumentException(
170
				String.format("value must not be longer then 1023 characters for preference. Value = %s", value));
171
		}
172
		this.value = value;
173
	}
174

    
175

    
176
	/**
177
	 * Constructor.
178
	 * @param subject must not be null and must not be longer then 255 characters.
179
	 * @param predicate must not be null and must not be longer then 255 characters.
180
	 * @param value must not be longer then 1023 characters.
181
	 */
182
	public CdmPreference(String subject, String predicate, String value){
183
		this.key = new PrefKey(subject, predicate);
184
		//TODO are null values allowed?		assert predicate != null : "value must not be null for preference";
185
		if (value != null && value.length() > 1023) {throw new IllegalArgumentException(
186
			String.format("value must not be longer then 1023 characters for preference. Value = %s", value));
187
		}
188
		this.value = value;
189

    
190
	}
191

    
192
//************************ GETTER / SETTER ***************************/
193

    
194
	public boolean isDatabasePref(){
195
	    return PreferenceSubject.ROOT.equals(key.subject);
196
	}
197

    
198

    
199
	/**
200
	 * @return the subject of the preference
201
	 */
202
	public String getSubject() {
203
		return key.subject;
204
	}
205

    
206
	/**
207
	 * @return the predicate of the preference
208
	 */
209
	public String getPredicate() {
210
		return key.predicate;
211
	}
212

    
213
	/**
214
	 * @return the value of the preference
215
	 */
216
	public String getValue() {
217
		return value;
218
	}
219

    
220
	/**
221
	 * Returns the {@link #getValue() value} as {@link UUID} List.
222
	 * Throws an exception if the value can not be parsed as UUID list.
223
	 * @return
224
	 * @throws IllegalArgumentException
225
	 */
226
	public List<UUID> getValueUuidList() throws IllegalArgumentException {
227
	    List<UUID> result = new ArrayList<>();
228
	    if (StringUtils.isBlank(value)){
229
	        return result;
230
	    }
231
	    String[] splits = getValue().split("[,;]");
232
	    for (String split : splits ){
233
	        try {
234
                if (StringUtils.isBlank(split)){
235
                    continue; //neglect trailing separators
236
                }
237
	            UUID uuid = UUID.fromString(split.trim());
238
                result.add(uuid);
239
            } catch (IllegalArgumentException e) {
240
                throw e;
241
            }
242
	    }
243
	    return result;
244
    }
245

    
246

    
247
//
248
//  we try to avoid setting of values
249
//  public void setValue(String value) {
250
//      this.value = value;
251
//  }
252

    
253
	public PrefKey getKey() {
254
		return key;
255
	}
256

    
257
    public boolean isAllowOverride() {
258
        return allowOverride;
259
    }
260

    
261
    public void setAllowOverride(boolean allowOverride) {
262
        this.allowOverride = allowOverride;
263
    }
264

    
265
}
(3-3/7)