1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.context.internal

File ExecutionContextProperty.java

 

Coverage histogram

../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

8
33
10
1
201
94
21
0.64
3.3
10
2.1

Classes

Class Line # Actions
ExecutionContextProperty 33 33 0% 21 2
0.960784396.1%
 

Contributing tests

This file is covered by 841 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.context.internal;
21   
22    import java.lang.ref.WeakReference;
23    import java.lang.reflect.InvocationTargetException;
24   
25    /**
26    * Contains the property value and metadata that governs the maintenance of the property.
27    *
28    * This class may require ReflectPermission suppressAccessChecks to clone the object value.
29    *
30    * @version $Id: bd8d7c862f3a2d9f82d6859329f6b2b67fe830d9 $
31    * @since 4.3M1
32    */
 
33    public class ExecutionContextProperty implements Cloneable
34    {
35    /** The key that is the name of this property in the execution context. */
36    private final String key;
37   
38    /** This is the actual property value. */
39    private Object value;
40   
41    /**
42    * Clone the value when this property is cloned.
43    */
44    private final boolean cloneValue;
45   
46    /** Controls whether the value of this property is final. */
47    private final boolean isFinal;
48   
49    /**
50    * Controls whether this property should be inherited across execution contexts. It will be inherited as long as an
51    * execution context containing the property is the current execution context. It will not be propagated to parent
52    * execution contexts. Hence, it may be removed by a call to popExecutionContext.
53    */
54    private final boolean inherited;
55   
56    /** Indicate that the value may not be {@code null}. */
57    private final boolean nonNull;
58   
59    /**
60    * @see #getType()
61    */
62    private final Class<?> type;
63   
64    /** @see #isClonedFrom(ExecutionContextProperty) */
65    private WeakReference<ExecutionContextProperty> clonedFrom;
66   
67    /**
68    * @param key The execution context key.
69    * @param initialValue The initial value.
70    * @param cloneValue Indicate that the value should be cloned when the property is cloned.
71    * @param isFinal Indicate that the value may not be updated from the initial value.
72    * @param inherited Indicate that the property should be inherited when activating a new execution context.
73    * @param nonNull Indicate that the property value may not be {@literal null}.
74    * @param type Set a class which the value must be assignable to.
75    */
 
76  340998 toggle public ExecutionContextProperty(String key, Object initialValue, boolean cloneValue, boolean isFinal,
77    boolean inherited, boolean nonNull, Class<?> type)
78    {
79  341005 this.key = key;
80  340976 this.value = initialValue;
81  340973 this.cloneValue = cloneValue;
82  340968 this.isFinal = isFinal;
83  340957 this.inherited = inherited;
84  340958 this.nonNull = nonNull;
85  340955 this.type = type;
86  340958 checkValue(initialValue);
87    }
88   
89    /**
90    * Check that the value is compatible with the configure constraints.
91    *
92    * @param value The value.
93    * @throws IllegalArgumentException if the value is null and this property has the nonNull attribute set, or if the
94    * type is set for this value, but the value is not assignable to the set type.
95    */
 
96  651387 toggle private void checkValue(Object value)
97    {
98  651454 if (this.nonNull && value == null) {
99  1 throw new IllegalArgumentException(String.format("The property [%s] may not be null!", getKey()));
100    }
101  651461 if (getType() != null && value != null && !getType().isAssignableFrom(value.getClass())) {
102  1 throw new IllegalArgumentException(
103    String.format("The value of property [%s] must be of type [%s], but was [%s]",
104    getKey(), getType(), value.getClass()));
105    }
106    }
107   
108    /**
109    * @param value The object value.
110    * @throws IllegalArgumentException if the value is null and this property has the nonNull attribute set, or if the
111    * type is set for this value, but the value is not assignable to the set type.
112    */
 
113  310477 toggle public void setValue(Object value)
114    {
115  310485 checkValue(value);
116  310501 this.value = value;
117    }
118   
119    /** @return The object value. */
 
120  38348751 toggle public Object getValue()
121    {
122  38348762 return this.value;
123    }
124   
125    /** @return The key of this property. */
 
126  863201 toggle public String getKey()
127    {
128  863219 return this.key;
129    }
130   
131    /** @return wether this property is final or not. */
 
132  265875 toggle public boolean isFinal()
133    {
134  265879 return this.isFinal;
135    }
136   
137    /** @return wether this property should be inherited across execution contexts or not. */
 
138  483291 toggle public boolean isInherited()
139    {
140  483278 return this.inherited;
141    }
142   
143    /**
144    * @return the type of the value
145    */
 
146  708194 toggle private Class<?> getType()
147    {
148  708196 return this.type;
149    }
150   
 
151  56775 toggle @Override
152    public ExecutionContextProperty clone()
153    {
154  56771 ExecutionContextProperty clone;
155   
156  56773 Object clonedValue;
157   
158  56772 if (this.cloneValue) {
159  22934 try {
160  22934 clonedValue = getValue().getClass().getMethod("clone").invoke(getValue());
161    } catch (NoSuchMethodException e) {
162  1 throw new IllegalStateException(String.format(
163    "cloneValue attribute was set on property [%s], "
164    + "but the value had class [%s] which has no public clone method", getKey(),
165    getValue().getClass().getName()));
166    } catch (InvocationTargetException e) {
167  0 throw new RuntimeException(e);
168    } catch (IllegalAccessException e) {
169  0 throw new RuntimeException(e);
170    }
171    } else {
172  33842 clonedValue = getValue();
173    }
174   
175  56773 clone = new ExecutionContextProperty(getKey(), clonedValue, this.cloneValue, isFinal(), isInherited(),
176    this.nonNull, getType());
177   
178  56767 if (isFinal() && isInherited()) {
179    // We make this a weak reference, because we are only interested in it as long
180    // as it is references by the current execution co
181  2 clone.clonedFrom = new WeakReference<ExecutionContextProperty>(this);
182    }
183   
184  56772 return clone;
185    }
186   
187    /**
188    * Check that this instance was cloned from the specified instance.
189    *
190    * When aggressively enforcing the inheritance of a property p, it will be disallowed to inherit from the execution
191    * context containing p if the inheriting context contains property p' with the same key as p, unless p' was cloned
192    * from p.
193    *
194    * @param property The original property.
195    * @return If the return value is {@code true}, then this property was cloned from the given property.
196    */
 
197  2 toggle public boolean isClonedFrom(ExecutionContextProperty property)
198    {
199  2 return this.clonedFrom != null && this.clonedFrom.get() == property;
200    }
201    }