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.Collections;
27 import java.util.HashMap;
28 import java.util.Map;
29 import java.util.Set;
30 import javax.jcr.nodetype.NodeDefinition;
31 import javax.jcr.nodetype.NodeType;
32 import net.jcip.annotations.Immutable;
33 import org.modeshape.graph.ExecutionContext;
34 import org.modeshape.graph.property.Name;
35
36
37
38
39 @Immutable
40 class JcrNodeDefinition extends JcrItemDefinition implements NodeDefinition {
41
42
43 private final boolean allowsSameNameSiblings;
44
45
46
47
48
49 private final Name defaultPrimaryTypeName;
50
51
52 private Map<Name, JcrNodeType> requiredPrimaryTypesByName;
53
54 private JcrNodeType[] requiredPrimaryTypes;
55
56 private Name[] requiredPrimaryTypeNames;
57
58
59 private NodeDefinitionId id;
60
61
62 private final RepositoryNodeTypeManager nodeTypeManager;
63
64 JcrNodeDefinition( ExecutionContext context,
65 JcrNodeType declaringNodeType,
66 Name name,
67 int onParentVersion,
68 boolean autoCreated,
69 boolean mandatory,
70 boolean protectedItem,
71 boolean allowsSameNameSiblings,
72 Name defaultPrimaryTypeName,
73 Name[] requiredPrimaryTypeNames ) {
74 this(context, null, declaringNodeType, name, onParentVersion, autoCreated, mandatory, protectedItem,
75 allowsSameNameSiblings, defaultPrimaryTypeName, requiredPrimaryTypeNames);
76 }
77
78 JcrNodeDefinition( ExecutionContext context,
79 RepositoryNodeTypeManager nodeTypeManager,
80 JcrNodeType declaringNodeType,
81 Name name,
82 int onParentVersion,
83 boolean autoCreated,
84 boolean mandatory,
85 boolean protectedItem,
86 boolean allowsSameNameSiblings,
87 Name defaultPrimaryTypeName,
88 Name[] requiredPrimaryTypeNames ) {
89 super(context, declaringNodeType, name, onParentVersion, autoCreated, mandatory, protectedItem);
90 this.nodeTypeManager = nodeTypeManager;
91 this.allowsSameNameSiblings = allowsSameNameSiblings;
92 this.defaultPrimaryTypeName = defaultPrimaryTypeName;
93 this.requiredPrimaryTypes = new JcrNodeType[requiredPrimaryTypeNames.length];
94 this.requiredPrimaryTypeNames = requiredPrimaryTypeNames;
95 }
96
97 private final String string( Name name ) {
98 if (name == null) return null;
99 if (this.context == null) return name.getString();
100
101 return name.getString(context.getNamespaceRegistry());
102 }
103
104
105
106
107
108
109
110
111
112 private void ensureRequiredPrimaryTypesLoaded() {
113 if (requiredPrimaryTypesByName != null) return;
114 this.requiredPrimaryTypes = new JcrNodeType[requiredPrimaryTypeNames.length];
115 for (int i = 0; i != requiredPrimaryTypeNames.length; ++i) {
116 this.requiredPrimaryTypes[i] = nodeTypeManager.getNodeType(requiredPrimaryTypeNames[i]);
117 }
118 Map<Name, JcrNodeType> requiredPrimaryTypesByName = new HashMap<Name, JcrNodeType>();
119 for (JcrNodeType requiredPrimaryType : requiredPrimaryTypes) {
120 requiredPrimaryTypesByName.put(requiredPrimaryType.getInternalName(), requiredPrimaryType);
121 }
122 this.requiredPrimaryTypesByName = Collections.unmodifiableMap(requiredPrimaryTypesByName);
123
124 }
125
126
127
128
129
130
131 public NodeDefinitionId getId() {
132 if (id == null) {
133
134 id = new NodeDefinitionId(this.declaringNodeType.getInternalName(), this.name, this.requiredPrimaryTypeNames);
135 }
136 return id;
137 }
138
139
140
141
142
143
144 public boolean allowsSameNameSiblings() {
145 return allowsSameNameSiblings;
146 }
147
148
149
150
151 final Name defaultPrimaryTypeName() {
152 return defaultPrimaryTypeName;
153 }
154
155
156
157
158
159
160 public NodeType getDefaultPrimaryType() {
161
162 if (defaultPrimaryTypeName == null) {
163 return null;
164 }
165
166 return nodeTypeManager.getNodeType(defaultPrimaryTypeName);
167 }
168
169
170
171
172
173
174 public NodeType[] getRequiredPrimaryTypes() {
175 ensureRequiredPrimaryTypesLoaded();
176 if (requiredPrimaryTypes.length == 0) {
177
178
179 NodeType[] result = new NodeType[1];
180 result[0] = nodeTypeManager.getNodeType(JcrNtLexicon.BASE);
181 return result;
182 }
183
184 NodeType[] result = new NodeType[requiredPrimaryTypes.length];
185 for (int i = 0; i != requiredPrimaryTypes.length; ++i) {
186 result[i] = requiredPrimaryTypes[i];
187 }
188 return result;
189 }
190
191
192
193
194
195
196
197 Name[] requiredPrimaryTypeNames() {
198 return this.requiredPrimaryTypeNames;
199 }
200
201
202
203
204
205
206 Set<Name> requiredPrimaryTypeNameSet() {
207 ensureRequiredPrimaryTypesLoaded();
208 return requiredPrimaryTypesByName.keySet();
209 }
210
211
212
213
214 public String[] getRequiredPrimaryTypeNames() {
215 if (requiredPrimaryTypeNames == null) return new String[0];
216
217 String[] rptNames = new String[requiredPrimaryTypeNames.length];
218 for (int i = 0; i < requiredPrimaryTypeNames.length; i++) {
219 rptNames[i] = string(requiredPrimaryTypeNames[i]);
220 }
221 return rptNames;
222 }
223
224
225
226
227 public String getDefaultPrimaryTypeName() {
228 return string(this.defaultPrimaryTypeName);
229 }
230
231
232
233
234
235
236
237
238
239
240 final boolean allowsChildWithType( JcrNodeType childPrimaryType ) {
241 if (childPrimaryType == null) {
242
243 if (defaultPrimaryTypeName != null) {
244 return true;
245 }
246 return false;
247 }
248 ensureRequiredPrimaryTypesLoaded();
249
250 for (Name requiredPrimaryTypeName : requiredPrimaryTypesByName.keySet()) {
251 if (!childPrimaryType.isNodeType(requiredPrimaryTypeName)) return false;
252 }
253 return true;
254 }
255
256
257
258
259
260
261
262
263
264 JcrNodeDefinition with( JcrNodeType declaringNodeType ) {
265 return new JcrNodeDefinition(this.context, declaringNodeType.nodeTypeManager(), declaringNodeType, name,
266 getOnParentVersion(), isAutoCreated(), isMandatory(), isProtected(),
267 allowsSameNameSiblings(), defaultPrimaryTypeName, requiredPrimaryTypeNames);
268 }
269
270 JcrNodeDefinition with( ExecutionContext context ) {
271 return new JcrNodeDefinition(context, this.nodeTypeManager, this.declaringNodeType, name, getOnParentVersion(),
272 isAutoCreated(), isMandatory(), isProtected(), allowsSameNameSiblings(),
273 defaultPrimaryTypeName, requiredPrimaryTypeNames);
274 }
275
276 JcrNodeDefinition with( RepositoryNodeTypeManager nodeTypeManager ) {
277 return new JcrNodeDefinition(this.context, nodeTypeManager, this.declaringNodeType, name, getOnParentVersion(),
278 isAutoCreated(), isMandatory(), isProtected(), allowsSameNameSiblings(),
279 defaultPrimaryTypeName, requiredPrimaryTypeNames);
280 }
281
282 @Override
283 public int hashCode() {
284 return getId().toString().hashCode();
285 }
286
287 @Override
288 public boolean equals( Object obj ) {
289 if (this == obj) return true;
290 if (obj == null) return false;
291 if (getClass() != obj.getClass()) return false;
292 JcrNodeDefinition other = (JcrNodeDefinition)obj;
293 if (id == null) {
294 if (other.id != null) return false;
295 } else if (!id.equals(other.id)) return false;
296 return true;
297 }
298
299
300
301
302
303
304 @Override
305 public String toString() {
306 return getId().toString();
307 }
308 }