Project

General

Profile

Download (9.55 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
import eu.etaxonomy.cdm.common.CdmUtils;
24

    
25

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

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

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

    
67
    /**
68
     * @param predicate
69
     * @param value
70
     * @return
71
     */
72
    public static CdmPreference NewVaadinInstance(PreferencePredicate predicate, String value) {
73
        return new CdmPreference(PreferenceSubject.NewVaadinInstance(), predicate, value);
74
    }
75

    
76
    public static PrefKey NewKey(PreferenceSubject subject, PreferencePredicate predicate){
77
      return new PrefKey(subject, predicate);
78
    }
79

    
80
//	public static final CdmPreference NewInstance(PreferenceSubjectEnum subject, PreferencePredicate predicate, String value){
81
//		return new CdmPreference(subject, predicate, value);
82
//	}
83
//
84
//	public static PrefKey NewKey(PreferenceSubjectEnum subject, PreferencePredicate predicate){
85
//		return new PrefKey(subject, predicate);
86
//	}
87

    
88

    
89
	@EmbeddedId
90
	private PrefKey key;
91

    
92
	@Column(length=1023)
93
	private String value;
94

    
95
    //if false, the preference should not be overridden by local preferences,
96
	//if true existing local preferences override database preferences
97
	    //and the database preference only defines the default.
98
    private boolean allowOverride = false;
99

    
100
    @Embeddable
101
    public static class PrefKey implements Serializable{
102

    
103
        private static final long serialVersionUID = 9019957853773606194L;
104

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

    
110
        @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
111
        private String predicate;
112

    
113
        //for hibernate use only
114
        private PrefKey(){}
115

    
116
        private PrefKey(PreferenceSubject subject, PreferencePredicate predicate){
117
            this(subject.toString(), predicate.getKey());
118
        }
119
//      private PrefKey(PreferenceSubjectEnum subject, PreferencePredicate predicate){
120
//          this(subject.getKey(), predicate.getKey());
121
//      }
122

    
123
        private PrefKey(String subject, String predicate){
124
            if (subject == null) {
125
                throw new IllegalArgumentException("Subject must not be null for preference");
126
            }
127
            if (predicate == null) {
128
                throw new IllegalArgumentException("Predicate must not be null for preference");
129
            }
130
            if (subject.length() > 255) {
131
                throw new IllegalArgumentException("Subject must not be longer then 255 for preference");
132
            }
133
            if (predicate.length() > 255) {
134
                throw new IllegalArgumentException("Predicate must not be longer then 255 for preference");
135
            }
136
            if (!subject.matches(PreferenceSubject.ROOT + "(([A-Za-z]+\\[.*\\]|"+PreferenceSubject.VAADIN+")"+PreferenceSubject.SEP+")?")){
137
                throw new IllegalArgumentException("Subject does not follow the required syntax");
138
            }
139

    
140

    
141
            this.subject = subject;
142
            this.predicate = predicate;
143
        }
144

    
145
        @Override
146
        public int hashCode() {
147
            final int prime = 31;
148
            int result = 1;
149
            result = prime * result + ((predicate == null) ? 0 : predicate.hashCode());
150
            result = prime * result + ((subject == null) ? 0 : subject.hashCode());
151
            return result;
152
        }
153

    
154
        @Override
155
        public boolean equals(Object obj) {
156
            if (this == obj){
157
                return true;
158
            } else if (obj == null){
159
                return false;
160
            }else if (getClass() != obj.getClass()){
161
                return false;
162
            }else{
163
                PrefKey other = (PrefKey) obj;
164
                return ( predicate.equals(other.predicate) && subject.equals(other.subject));
165
            }
166
        }
167

    
168
    }
169

    
170
//****************** CONSTRUCTOR **********************/
171

    
172
	//for hibernate use only
173
	@SuppressWarnings("unused")
174
	private CdmPreference(){}
175

    
176

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

    
186
    public CdmPreference(PreferenceSubject subject, PreferencePredicate predicate, List<UUID> value){
187
        this(subject, predicate, uuidListStr(value));
188
    }
189

    
190
    public CdmPreference(PreferenceSubject subject, PreferencePredicate predicate, UUID value){
191
        this(subject, predicate, value.toString());
192
    }
193

    
194
    /**
195
     * @param value
196
     * @return
197
     */
198
    protected static String uuidListStr(List<UUID> value) {
199
        String valueStr = "";
200
        for (UUID uuid : value){
201
            valueStr = CdmUtils.concat(",",valueStr, uuid.toString());
202
        }
203
        return valueStr;
204
    }
205

    
206

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

    
221
	}
222

    
223
//************************ GETTER / SETTER ***************************/
224

    
225
	public boolean isDatabasePref(){
226
	    return PreferenceSubject.ROOT.equals(key.subject);
227
	}
228

    
229

    
230
	/**
231
	 * @return the subject of the preference
232
	 */
233
	public String getSubject() {
234
		return key.subject;
235
	}
236

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

    
244
	/**
245
	 * @return the value of the preference
246
	 */
247
	public String getValue() {
248
		return value;
249
	}
250

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

    
277

    
278
//
279
//  we try to avoid setting of values
280
//  public void setValue(String value) {
281
//      this.value = value;
282
//  }
283

    
284
	public PrefKey getKey() {
285
		return key;
286
	}
287

    
288
    public boolean isAllowOverride() {
289
        return allowOverride;
290
    }
291

    
292
    public void setAllowOverride(boolean allowOverride) {
293
        this.allowOverride = allowOverride;
294
    }
295

    
296
}
(3-3/7)