Project

General

Profile

Download (9.89 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.Arrays;
14
import java.util.List;
15
import java.util.UUID;
16

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

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

    
24
import eu.etaxonomy.cdm.common.CdmUtils;
25

    
26

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

    
55
    public static final CdmPreference NewInstance(PreferenceSubject subject,
56
            PreferencePredicate predicate, String value){
57
        return new CdmPreference(subject, predicate, value);
58
    }
59

    
60

    
61
    public static final CdmPreference NewInstance(PreferenceSubject subject, PreferencePredicate predicate, List<UUID> value){
62
        return new CdmPreference(subject, predicate, uuidListStr(value));
63
    }
64
    public static final CdmPreference NewInstance(PreferenceSubject subject, PreferencePredicate predicate, UUID ... value){
65
        return new CdmPreference(subject, predicate, uuidListStr(Arrays.asList(value)));
66
    }
67

    
68
    public static final CdmPreference NewInstance(PreferenceSubject subject, PreferencePredicate predicate, UUID value){
69
        return new CdmPreference(subject, predicate, value.toString());
70
    }
71

    
72
    /**
73
     * @param predicate
74
     * @param value
75
     * @return
76
     */
77
    public static CdmPreference NewDatabaseInstance(PreferencePredicate predicate, String value) {
78
        return new CdmPreference(PreferenceSubject.NewDatabaseInstance(), predicate, value);
79
    }
80

    
81
    /**
82
     * @param predicate
83
     * @param value
84
     * @return
85
     */
86
    public static CdmPreference NewVaadinInstance(PreferencePredicate predicate, String value) {
87
        return new CdmPreference(PreferenceSubject.NewVaadinInstance(), predicate, value);
88
    }
89

    
90
    public static PrefKey NewKey(PreferenceSubject subject, PreferencePredicate predicate){
91
      return new PrefKey(subject, predicate);
92
    }
93

    
94
//	public static final CdmPreference NewInstance(PreferenceSubjectEnum subject, PreferencePredicate predicate, String value){
95
//		return new CdmPreference(subject, predicate, value);
96
//	}
97
//
98
//	public static PrefKey NewKey(PreferenceSubjectEnum subject, PreferencePredicate predicate){
99
//		return new PrefKey(subject, predicate);
100
//	}
101

    
102

    
103
	@EmbeddedId
104
	private PrefKey key;
105

    
106
	@Column(length=1023)
107
	private String value;
108

    
109
    //if false, the preference should not be overridden by local preferences,
110
	//if true existing local preferences override database preferences
111
	    //and the database preference only defines the default.
112
    private boolean allowOverride = false;
113

    
114
    @Embeddable
115
    public static class PrefKey implements Serializable{
116

    
117
        private static final long serialVersionUID = 9019957853773606194L;
118

    
119
        //required syntax:  /([A-Za-z]+\[.*\])?
120
        //examples /  ,  /TaxonNode[#t10#44#1456#]  for a taxon node preference
121
        @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
122
        private String subject;
123

    
124
        @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
125
        private String predicate;
126

    
127
        //for hibernate use only
128
        private PrefKey(){}
129

    
130
        private PrefKey(PreferenceSubject subject, PreferencePredicate predicate){
131
            this(subject.toString(), predicate.getKey());
132
        }
133
//      private PrefKey(PreferenceSubjectEnum subject, PreferencePredicate predicate){
134
//          this(subject.getKey(), predicate.getKey());
135
//      }
136

    
137
        private PrefKey(String subject, String predicate){
138
            if (subject == null) {
139
                throw new IllegalArgumentException("Subject must not be null for preference");
140
            }
141
            if (predicate == null) {
142
                throw new IllegalArgumentException("Predicate must not be null for preference");
143
            }
144
            if (subject.length() > 255) {
145
                throw new IllegalArgumentException("Subject must not be longer then 255 for preference");
146
            }
147
            if (predicate.length() > 255) {
148
                throw new IllegalArgumentException("Predicate must not be longer then 255 for preference");
149
            }
150
            if (!subject.matches(PreferenceSubject.ROOT + "(([A-Za-z]+\\[.*\\]|"+PreferenceSubject.VAADIN+")"+PreferenceSubject.SEP+")?")){
151
                throw new IllegalArgumentException("Subject does not follow the required syntax");
152
            }
153

    
154

    
155
            this.subject = subject;
156
            this.predicate = predicate;
157
        }
158

    
159
        @Override
160
        public int hashCode() {
161
            final int prime = 31;
162
            int result = 1;
163
            result = prime * result + ((predicate == null) ? 0 : predicate.hashCode());
164
            result = prime * result + ((subject == null) ? 0 : subject.hashCode());
165
            return result;
166
        }
167

    
168
        @Override
169
        public boolean equals(Object obj) {
170
            if (this == obj){
171
                return true;
172
            } else if (obj == null){
173
                return false;
174
            }else if (getClass() != obj.getClass()){
175
                return false;
176
            }else{
177
                PrefKey other = (PrefKey) obj;
178
                return ( predicate.equals(other.predicate) && subject.equals(other.subject));
179
            }
180
        }
181

    
182
    }
183

    
184
//****************** CONSTRUCTOR **********************/
185

    
186
	//for hibernate use only
187
	@SuppressWarnings("unused")
188
	private CdmPreference(){}
189

    
190

    
191
	private CdmPreference(PreferenceSubject subject, PreferencePredicate predicate, String value){
192
		this.key = new PrefKey(subject, predicate);
193
		//TODO are null values allowed?		assert predicate != null : "value must not be null for preference";
194
		if (value != null && value.length() > 1023) {throw new IllegalArgumentException(
195
				String.format("value must not be longer then 1023 characters for preference. Value = %s", value));
196
		}
197
		this.value = value;
198
	}
199

    
200

    
201
    /**
202
     * @param value
203
     * @return
204
     */
205
    protected static String uuidListStr(List<UUID> value) {
206
        String valueStr = "";
207
        for (UUID uuid : value){
208
            valueStr = CdmUtils.concat(",",valueStr, uuid.toString());
209
        }
210
        return valueStr;
211
    }
212

    
213

    
214
	/**
215
	 * Constructor.
216
	 * @param subject must not be null and must not be longer then 255 characters.
217
	 * @param predicate must not be null and must not be longer then 255 characters.
218
	 * @param value must not be longer then 1023 characters.
219
	 */
220
	public CdmPreference(String subject, String predicate, String value){
221
		this.key = new PrefKey(subject, predicate);
222
		//TODO are null values allowed?		assert predicate != null : "value must not be null for preference";
223
		if (value != null && value.length() > 1023) {throw new IllegalArgumentException(
224
			String.format("value must not be longer then 1023 characters for preference. Value = %s", value));
225
		}
226
		this.value = value;
227

    
228
	}
229

    
230
//************************ GETTER / SETTER ***************************/
231

    
232
	public boolean isDatabasePref(){
233
	    return PreferenceSubject.ROOT.equals(key.subject);
234
	}
235

    
236

    
237
	/**
238
	 * @return the subject of the preference
239
	 */
240
	public String getSubject() {
241
		return key.subject;
242
	}
243

    
244
	/**
245
	 * @return the predicate of the preference
246
	 */
247
	public String getPredicate() {
248
		return key.predicate;
249
	}
250

    
251
	/**
252
	 * @return the value of the preference
253
	 */
254
	public String getValue() {
255
		return value;
256
	}
257

    
258
	/**
259
	 * Returns the {@link #getValue() value} as {@link UUID} List.
260
	 * Throws an exception if the value can not be parsed as UUID list.
261
	 * @return
262
	 * @throws IllegalArgumentException
263
	 */
264
	public List<UUID> getValueUuidList() throws IllegalArgumentException {
265
	    List<UUID> result = new ArrayList<>();
266
	    if (StringUtils.isBlank(value)){
267
	        return result;
268
	    }
269
	    String[] splits = getValue().split("[,;]");
270
	    for (String split : splits ){
271
	        try {
272
                if (StringUtils.isBlank(split)){
273
                    continue; //neglect trailing separators
274
                }
275
	            UUID uuid = UUID.fromString(split.trim());
276
                result.add(uuid);
277
            } catch (IllegalArgumentException e) {
278
                throw e;
279
            }
280
	    }
281
	    return result;
282
    }
283

    
284

    
285
//
286
//  we try to avoid setting of values
287
//  public void setValue(String value) {
288
//      this.value = value;
289
//  }
290

    
291
	public PrefKey getKey() {
292
		return key;
293
	}
294

    
295
    public boolean isAllowOverride() {
296
        return allowOverride;
297
    }
298

    
299
    public void setAllowOverride(boolean allowOverride) {
300
        this.allowOverride = allowOverride;
301
    }
302

    
303
}
(3-3/7)