Project

General

Profile

Download (9.2 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 test
60
     * @param string
61
     * @return
62
     */
63
    public static CdmPreference NewDatabaseInstance(PreferencePredicate test, String value) {
64
        return new CdmPreference(PreferenceSubject.NewDatabaseInstance(), test, value);
65
    }
66

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

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

    
79

    
80
	@EmbeddedId
81
	private PrefKey key;
82

    
83
	@Column(length=1023)
84
	private String value;
85

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

    
91
    @Embeddable
92
    public static class PrefKey implements Serializable{
93

    
94
        private static final long serialVersionUID = 9019957853773606194L;
95

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

    
101
        @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
102
        private String predicate;
103

    
104
        //for hibernate use only
105
        private PrefKey(){}
106

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

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

    
131

    
132
            this.subject = subject;
133
            this.predicate = predicate;
134
        }
135

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

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

    
159
    }
160

    
161
//****************** CONSTRUCTOR **********************/
162

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

    
167

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

    
177
    public CdmPreference(PreferenceSubject subject, PreferencePredicate predicate, List<UUID> value){
178
        this(subject, predicate, uuidListStr(value));
179
    }
180

    
181
    public CdmPreference(PreferenceSubject subject, PreferencePredicate predicate, UUID value){
182
        this(subject, predicate, value.toString());
183
    }
184

    
185
    /**
186
     * @param value
187
     * @return
188
     */
189
    protected static String uuidListStr(List<UUID> value) {
190
        String valueStr = "";
191
        for (UUID uuid : value){
192
            valueStr = CdmUtils.concat(",",valueStr, uuid.toString());
193
        }
194
        return valueStr;
195
    }
196

    
197

    
198
	/**
199
	 * Constructor.
200
	 * @param subject must not be null and must not be longer then 255 characters.
201
	 * @param predicate must not be null and must not be longer then 255 characters.
202
	 * @param value must not be longer then 1023 characters.
203
	 */
204
	public CdmPreference(String subject, String predicate, String value){
205
		this.key = new PrefKey(subject, predicate);
206
		//TODO are null values allowed?		assert predicate != null : "value must not be null for preference";
207
		if (value != null && value.length() > 1023) {throw new IllegalArgumentException(
208
			String.format("value must not be longer then 1023 characters for preference. Value = %s", value));
209
		}
210
		this.value = value;
211

    
212
	}
213

    
214
//************************ GETTER / SETTER ***************************/
215

    
216
	public boolean isDatabasePref(){
217
	    return PreferenceSubject.ROOT.equals(key.subject);
218
	}
219

    
220

    
221
	/**
222
	 * @return the subject of the preference
223
	 */
224
	public String getSubject() {
225
		return key.subject;
226
	}
227

    
228
	/**
229
	 * @return the predicate of the preference
230
	 */
231
	public String getPredicate() {
232
		return key.predicate;
233
	}
234

    
235
	/**
236
	 * @return the value of the preference
237
	 */
238
	public String getValue() {
239
		return value;
240
	}
241

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

    
268

    
269
//
270
//  we try to avoid setting of values
271
//  public void setValue(String value) {
272
//      this.value = value;
273
//  }
274

    
275
	public PrefKey getKey() {
276
		return key;
277
	}
278

    
279
    public boolean isAllowOverride() {
280
        return allowOverride;
281
    }
282

    
283
    public void setAllowOverride(boolean allowOverride) {
284
        this.allowOverride = allowOverride;
285
    }
286

    
287
}
(3-3/7)