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 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()) {
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 visitor.visit(this);
104 }
105
106 final PropertyInfo<JcrPropertyPayload> propertyInfo() throws PathNotFoundException, RepositoryException {
107 return node.nodeInfo().getProperty(name);
108 }
109
110 final Name name() {
111 return name;
112 }
113
114 final JcrPropertyPayload payload() throws RepositoryException {
115 return propertyInfo().getPayload();
116 }
117
118 final org.modeshape.graph.property.Property property() throws RepositoryException {
119 return propertyInfo().getProperty();
120 }
121
122 JcrValue createValue( Object value ) throws RepositoryException {
123 return new JcrValue(context().getValueFactories(), this.cache, payload().getPropertyType(), value);
124 }
125
126 final JcrValue createValue( Object value,
127 int propertyType ) {
128 return new JcrValue(context().getValueFactories(), this.cache, propertyType, value);
129 }
130
131 @Override
132 Path path() throws RepositoryException {
133 return context().getValueFactories().getPathFactory().create(node.path(), name);
134 }
135
136
137
138
139
140
141 public int getType() throws RepositoryException {
142 return payload().getPropertyType();
143 }
144
145
146
147
148
149
150 public final PropertyDefinition getDefinition() throws RepositoryException {
151 return cache.session().nodeTypeManager().getPropertyDefinition(payload().getPropertyDefinitionId());
152 }
153
154
155
156
157
158
159
160
161
162
163 public final String getName() {
164 return name.getString(namespaces());
165 }
166
167
168
169
170
171
172 public final AbstractJcrNode getParent() {
173 return node;
174 }
175
176
177
178
179
180
181 public final String getPath() throws RepositoryException {
182 return path().getString(namespaces());
183 }
184
185
186
187
188
189
190 public final boolean isModified() {
191 try {
192 return propertyInfo().isModified();
193 } catch (RepositoryException re) {
194 throw new IllegalStateException(re);
195 }
196 }
197
198
199
200
201
202
203 public final boolean isNew() {
204 try {
205 return propertyInfo().isNew();
206 } catch (RepositoryException re) {
207 throw new IllegalStateException(re);
208 }
209 }
210
211
212
213
214
215
216
217 public final boolean isNode() {
218 return false;
219 }
220
221
222
223
224
225
226 @Override
227 public final boolean isSame( Item otherItem ) throws RepositoryException {
228 if (otherItem instanceof Property) {
229 Property otherProperty = (Property)otherItem;
230
231 if (!getParent().isSame(otherProperty.getParent())) return false;
232
233 return getName().equals(otherProperty.getName());
234 }
235 return false;
236 }
237
238
239
240
241
242
243
244 public void refresh( boolean keepChanges ) {
245 throw new UnsupportedOperationException();
246 }
247
248
249
250
251
252
253 public void remove() throws VersionException, LockException, ConstraintViolationException, RepositoryException {
254 editor().removeProperty(name);
255 }
256
257
258
259
260
261
262
263 public void save() {
264 throw new UnsupportedOperationException();
265 }
266
267
268
269
270
271
272 public int compareTo( Property that ) {
273 if (that == this) return 0;
274 try {
275 return this.getName().compareTo(that.getName());
276 } catch (RepositoryException e) {
277 throw new RuntimeException(e);
278 }
279 }
280
281
282
283
284
285
286 @Override
287 public String toString() {
288 try {
289 ValueFactory<String> stringFactory = session().getExecutionContext().getValueFactories().getStringFactory();
290 StringBuilder sb = new StringBuilder();
291 sb.append(getName()).append('=');
292 org.modeshape.graph.property.Property property = propertyInfo().getProperty();
293 if (isMultiple()) {
294 sb.append('[');
295 Iterator<?> iter = property.iterator();
296 if (iter.hasNext()) {
297 sb.append(stringFactory.create(iter.next()));
298 if (iter.hasNext()) sb.append(',');
299 }
300 sb.append(']');
301 } else {
302 sb.append(stringFactory.create(property.getFirstValue()));
303 }
304 return sb.toString();
305 } catch (RepositoryException e) {
306 return super.toString();
307 }
308 }
309 }