1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.modeshape.jcr;
25
26 import java.util.Iterator;
27 import javax.jcr.InvalidItemStateException;
28 import javax.jcr.Item;
29 import javax.jcr.ItemNotFoundException;
30 import javax.jcr.ItemVisitor;
31 import javax.jcr.Node;
32 import javax.jcr.PathNotFoundException;
33 import javax.jcr.Property;
34 import javax.jcr.RepositoryException;
35 import javax.jcr.lock.Lock;
36 import javax.jcr.lock.LockException;
37 import javax.jcr.nodetype.ConstraintViolationException;
38 import javax.jcr.nodetype.PropertyDefinition;
39 import javax.jcr.version.VersionException;
40 import net.jcip.annotations.NotThreadSafe;
41 import org.modeshape.common.util.CheckArg;
42 import org.modeshape.graph.property.Name;
43 import org.modeshape.graph.property.Path;
44 import org.modeshape.graph.property.ValueFactory;
45 import org.modeshape.graph.session.GraphSession.PropertyInfo;
46 import org.modeshape.jcr.SessionCache.JcrPropertyPayload;
47 import org.modeshape.jcr.SessionCache.NodeEditor;
48
49
50
51
52 @NotThreadSafe
53 abstract class AbstractJcrProperty extends AbstractJcrItem implements Property, Comparable<Property> {
54
55 protected final AbstractJcrNode node;
56 protected final Name name;
57
58 AbstractJcrProperty( SessionCache cache,
59 AbstractJcrNode node,
60 Name name ) {
61 super(cache);
62 assert node != null;
63 assert name != null;
64 this.node = node;
65 this.name = name;
66 }
67
68 final NodeEditor editor() throws ItemNotFoundException, InvalidItemStateException, RepositoryException {
69 return node.editor();
70 }
71
72 public abstract boolean isMultiple();
73
74
75
76
77
78
79
80
81
82
83
84
85 protected final void checkForLock() throws LockException, RepositoryException {
86
87 if (this.getParent().isLocked() && !getParent().getLock().isLockOwningSession()) {
88 Lock parentLock = this.getParent().getLock();
89 if (parentLock != null && parentLock.getLockToken() == null) {
90 throw new LockException(JcrI18n.lockTokenNotHeld.text(this.getParent().location));
91 }
92 }
93 }
94
95
96
97
98
99
100
101 public final void accept( ItemVisitor visitor ) throws RepositoryException {
102 CheckArg.isNotNull(visitor, "visitor");
103 checkSession();
104 visitor.visit(this);
105 }
106
107 final PropertyInfo<JcrPropertyPayload> propertyInfo() throws PathNotFoundException, RepositoryException {
108 return node.nodeInfo().getProperty(name);
109 }
110
111 final Name name() {
112 return name;
113 }
114
115 final JcrPropertyPayload payload() throws RepositoryException {
116 return propertyInfo().getPayload();
117 }
118
119 final org.modeshape.graph.property.Property property() throws RepositoryException {
120 return propertyInfo().getProperty();
121 }
122
123 JcrValue createValue( Object value ) throws RepositoryException {
124 return new JcrValue(context().getValueFactories(), this.cache, payload().getPropertyType(), value);
125 }
126
127 final JcrValue createValue( Object value,
128 int propertyType ) {
129 return new JcrValue(context().getValueFactories(), this.cache, propertyType, value);
130 }
131
132 @Override
133 Path path() throws RepositoryException {
134 return context().getValueFactories().getPathFactory().create(node.path(), name);
135 }
136
137
138
139
140
141
142 public int getType() throws RepositoryException {
143 checkSession();
144 return payload().getPropertyType();
145 }
146
147
148
149
150
151
152 public final PropertyDefinition getDefinition() throws RepositoryException {
153 checkSession();
154 return cache.session().nodeTypeManager().getPropertyDefinition(payload().getPropertyDefinitionId());
155 }
156
157
158
159
160
161
162
163
164
165
166 public final String getName() {
167 return name.getString(namespaces());
168 }
169
170
171
172
173
174
175 public final AbstractJcrNode getParent() {
176 return node;
177 }
178
179
180
181
182
183
184 public final String getPath() throws RepositoryException {
185 return path().getString(namespaces());
186 }
187
188
189
190
191
192
193 public final boolean isModified() {
194 try {
195 checkSession();
196 return propertyInfo().isModified();
197 } catch (RepositoryException re) {
198 throw new IllegalStateException(re);
199 }
200 }
201
202
203
204
205
206
207 public final boolean isNew() {
208 try {
209 checkSession();
210 return propertyInfo().isNew();
211 } catch (RepositoryException re) {
212 throw new IllegalStateException(re);
213 }
214 }
215
216
217
218
219
220
221
222 public final boolean isNode() {
223 return false;
224 }
225
226
227
228
229
230
231 @Override
232 public final boolean isSame( Item otherItem ) throws RepositoryException {
233 checkSession();
234 if (otherItem instanceof Property) {
235 Property otherProperty = (Property)otherItem;
236
237 if (!getParent().isSame(otherProperty.getParent())) return false;
238
239 return getName().equals(otherProperty.getName());
240 }
241 return false;
242 }
243
244
245
246
247
248
249
250 public void refresh( boolean keepChanges ) {
251 throw new UnsupportedOperationException();
252 }
253
254
255
256
257
258
259 public void remove() throws VersionException, LockException, ConstraintViolationException, RepositoryException {
260 checkSession();
261 AbstractJcrNode parentNode = getParent();
262 if (parentNode.isLocked()) {
263 Lock parentLock = parentNode.lockManager().getLock(parentNode);
264 if (parentLock != null && !parentLock.isLockOwningSession()) {
265 throw new LockException(JcrI18n.lockTokenNotHeld.text(getPath()));
266 }
267 }
268
269 if (!parentNode.isCheckedOut()) {
270 throw new VersionException(JcrI18n.nodeIsCheckedIn.text(getPath()));
271 }
272
273 editor().removeProperty(name);
274 }
275
276
277
278
279
280
281 public void save() throws RepositoryException {
282 checkSession();
283
284
285 getParent().save();
286 }
287
288
289
290
291
292
293 public int compareTo( Property that ) {
294 if (that == this) return 0;
295 try {
296 return this.getName().compareTo(that.getName());
297 } catch (RepositoryException e) {
298 throw new RuntimeException(e);
299 }
300 }
301
302
303
304
305
306
307 @Override
308 public String toString() {
309 try {
310 ValueFactory<String> stringFactory = session().getExecutionContext().getValueFactories().getStringFactory();
311 StringBuilder sb = new StringBuilder();
312 sb.append(getName()).append('=');
313 org.modeshape.graph.property.Property property = propertyInfo().getProperty();
314 if (isMultiple()) {
315 sb.append('[');
316 Iterator<?> iter = property.iterator();
317 if (iter.hasNext()) {
318 sb.append(stringFactory.create(iter.next()));
319 if (iter.hasNext()) sb.append(',');
320 }
321 sb.append(']');
322 } else {
323 sb.append(stringFactory.create(property.getFirstValue()));
324 }
325 return sb.toString();
326 } catch (RepositoryException e) {
327 return super.toString();
328 }
329 }
330 }