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.Arrays;
27 import java.util.List;
28 import javax.jcr.PropertyType;
29 import javax.jcr.RepositoryException;
30 import javax.jcr.Value;
31 import javax.jcr.nodetype.NodeDefinition;
32 import javax.jcr.nodetype.NodeTypeTemplate;
33 import javax.jcr.nodetype.PropertyDefinition;
34 import javax.jcr.version.OnParentVersionAction;
35 import net.jcip.annotations.NotThreadSafe;
36 import org.modeshape.graph.ExecutionContext;
37 import org.modeshape.graph.Graph;
38 import org.modeshape.graph.JcrLexicon;
39 import org.modeshape.graph.JcrNtLexicon;
40 import org.modeshape.graph.connector.inmemory.InMemoryRepositorySource;
41 import org.modeshape.graph.io.Destination;
42 import org.modeshape.graph.io.GraphBatchDestination;
43 import org.modeshape.graph.property.Name;
44 import org.modeshape.graph.property.NameFactory;
45 import org.modeshape.graph.property.Path;
46 import org.modeshape.graph.property.PathFactory;
47 import org.modeshape.graph.property.PropertyFactory;
48 import org.modeshape.graph.property.ValueFactory;
49 import org.modeshape.jcr.nodetype.InvalidNodeTypeDefinitionException;
50
51
52
53
54
55
56
57
58
59
60 @NotThreadSafe
61 class NodeTemplateNodeTypeSource implements JcrNodeTypeSource {
62
63 private final Graph graph;
64 private final PathFactory pathFactory;
65 private final NameFactory nameFactory;
66 private final ValueFactory<Boolean> booleanFactory;
67 private final ValueFactory<String> stringFactory;
68 private final Destination destination;
69
70 public NodeTemplateNodeTypeSource( NodeTypeTemplate nodeTypeTemplate ) throws InvalidNodeTypeDefinitionException {
71 this(Arrays.asList(new NodeTypeTemplate[] {nodeTypeTemplate}));
72 }
73
74 public NodeTemplateNodeTypeSource( List<NodeTypeTemplate> nodeTypeTemplates ) throws InvalidNodeTypeDefinitionException {
75
76 ExecutionContext context = null;
77
78 if (nodeTypeTemplates.isEmpty()) {
79 context = new ExecutionContext();
80 } else {
81 for (NodeTypeTemplate ntt : nodeTypeTemplates) {
82 if (!(ntt instanceof JcrNodeTypeTemplate)) {
83 throw new IllegalArgumentException(JcrI18n.cannotConvertValue.text(ntt.getClass(), JcrNodeTypeTemplate.class));
84 }
85
86 JcrNodeTypeTemplate jntt = (JcrNodeTypeTemplate)ntt;
87 if (context == null) {
88 context = jntt.getExecutionContext();
89 assert context != null;
90 } else {
91 if (context != jntt.getExecutionContext()) {
92 throw new IllegalArgumentException(JcrI18n.allNodeTypeTemplatesMustComeFromSameSession.text());
93 }
94 }
95 }
96 }
97
98 assert context != null;
99 this.pathFactory = context.getValueFactories().getPathFactory();
100 this.nameFactory = context.getValueFactories().getNameFactory();
101 this.booleanFactory = context.getValueFactories().getBooleanFactory();
102 this.stringFactory = context.getValueFactories().getStringFactory();
103
104 PathFactory pathFactory = context.getValueFactories().getPathFactory();
105 InMemoryRepositorySource source = new InMemoryRepositorySource();
106 source.setName("NodeTypeTemplate Import Source");
107 this.graph = Graph.create(source, context);
108 Graph.Batch batch = graph.batch();
109 destination = new GraphBatchDestination(batch);
110
111 Path rootPath = pathFactory.createRootPath();
112 for (NodeTypeTemplate template : nodeTypeTemplates) {
113 this.createNodeType((JcrNodeTypeTemplate)template, rootPath);
114 }
115
116 destination.submit();
117 }
118
119
120
121
122
123
124 public final Graph getNodeTypes() {
125 return graph;
126 }
127
128 private boolean booleanFrom( Object value,
129 boolean defaultValue ) {
130 if (value == null) return defaultValue;
131
132 return booleanFactory.create(value);
133 }
134
135 private Name nameFrom( Object value ) {
136 return nameFactory.create(value);
137 }
138
139 private Name[] namesFrom( Object[] values ) {
140 if (values == null) return new Name[0];
141
142 Name[] names = new Name[values.length];
143 for (int i = 0; i < values.length; i++) {
144 names[i] = nameFactory.create(values[i]);
145 }
146
147 return names;
148 }
149
150 private String[] stringsFrom( Object[] values ) {
151 if (values == null) return new String[0];
152
153 String[] strings = new String[values.length];
154 for (int i = 0; i < values.length; i++) {
155 strings[i] = stringFactory.create(values[i]);
156 }
157
158 return strings;
159 }
160
161
162
163
164
165
166
167
168
169 protected Path createNodeType( JcrNodeTypeTemplate nodeType,
170 Path parentPath ) throws InvalidNodeTypeDefinitionException {
171
172 Name name = nameFrom(nodeType.getName());
173 Name[] supertypes = namesFrom(nodeType.declaredSupertypeNames());
174 boolean isAbstract = booleanFrom(nodeType.isAbstract(), false);
175 boolean hasOrderableChildNodes = booleanFrom(nodeType.hasOrderableChildNodes(), false);
176 boolean isMixin = booleanFrom(nodeType.isMixin(), false);
177 boolean isQueryable = true;
178 Name primaryItemName = nameFrom(nodeType.getPrimaryItemName());
179
180
181 if (name == null) throw new InvalidNodeTypeDefinitionException(JcrI18n.invalidNodeTypeName.text());
182 Path path = pathFactory.create(parentPath, name);
183
184 PropertyFactory factory = nodeType.getExecutionContext().getPropertyFactory();
185 destination.create(path,
186 factory.create(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.NODE_TYPE),
187 factory.create(JcrLexicon.SUPERTYPES, (Object[])supertypes),
188 factory.create(JcrLexicon.IS_ABSTRACT, isAbstract),
189 factory.create(JcrLexicon.HAS_ORDERABLE_CHILD_NODES, hasOrderableChildNodes),
190 factory.create(JcrLexicon.IS_MIXIN, isMixin),
191 factory.create(JcrLexicon.IS_QUERYABLE, isQueryable),
192 factory.create(JcrLexicon.NODE_TYPE_NAME, name),
193 factory.create(JcrLexicon.PRIMARY_ITEM_NAME, primaryItemName));
194
195 for (PropertyDefinition propDefn : nodeType.getPropertyDefinitionTemplates()) {
196 createPropertyDefinition((JcrPropertyDefinitionTemplate)propDefn, path);
197 }
198
199 for (NodeDefinition nodeDefn : nodeType.getNodeDefinitionTemplates()) {
200 createChildDefinition((JcrNodeDefinitionTemplate)nodeDefn, path);
201 }
202
203 return path;
204 }
205
206
207
208
209
210
211
212
213 protected Path createPropertyDefinition( JcrPropertyDefinitionTemplate propDefn,
214 Path parentPath ) {
215 Name name = nameFrom(propDefn.getName());
216 String requiredType = PropertyType.nameFromValue(propDefn.getRequiredType()).toUpperCase();
217 Value[] rawValues = propDefn.getDefaultValues();
218 boolean multiple = booleanFrom(propDefn.isMultiple(), false);
219 boolean mandatory = booleanFrom(propDefn.isMandatory(), false);
220 boolean autoCreated = booleanFrom(propDefn.isAutoCreated(), false);
221 boolean isProtected = booleanFrom(propDefn.isProtected(), false);
222 String onParentVersion = OnParentVersionAction.nameFromValue(propDefn.getOnParentVersion()).toUpperCase();
223
224
225
226 String[] valueConstraints = stringsFrom(propDefn.getValueConstraints());
227
228
229 if (name == null) name = JcrNodeType.RESIDUAL_NAME;
230 Path path = pathFactory.create(parentPath, JcrLexicon.PROPERTY_DEFINITION);
231
232 Object[] defaultValues;
233
234 if (rawValues == null) {
235 defaultValues = new Object[0];
236 } else {
237 try {
238 defaultValues = new Object[rawValues.length];
239 for (int i = 0; i < rawValues.length; i++) {
240 defaultValues[i] = rawValues[i].getString();
241 }
242 } catch (RepositoryException re) {
243 throw new IllegalStateException(re);
244 }
245 }
246
247 PropertyFactory factory = propDefn.getExecutionContext().getPropertyFactory();
248 destination.create(path,
249 factory.create(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.PROPERTY_DEFINITION),
250 factory.create(JcrLexicon.REQUIRED_TYPE, requiredType),
251 factory.create(JcrLexicon.DEFAULT_VALUES, defaultValues),
252 factory.create(JcrLexicon.MULTIPLE, multiple),
253 factory.create(JcrLexicon.MANDATORY, mandatory),
254 factory.create(JcrLexicon.NAME, name),
255 factory.create(JcrLexicon.AUTO_CREATED, autoCreated),
256 factory.create(JcrLexicon.PROTECTED, isProtected),
257 factory.create(JcrLexicon.ON_PARENT_VERSION, onParentVersion),
258
259
260
261 factory.create(JcrLexicon.VALUE_CONSTRAINTS, (Object[])valueConstraints));
262
263 return path;
264 }
265
266
267
268
269
270
271
272
273 protected Path createChildDefinition( JcrNodeDefinitionTemplate childDefn,
274 Path parentPath ) {
275 Name name = nameFrom(childDefn.getName());
276 Name[] requiredPrimaryTypes = namesFrom(childDefn.getRequiredPrimaryTypeNames());
277 Name defaultPrimaryType = nameFrom(childDefn.getDefaultPrimaryTypeName());
278 boolean mandatory = booleanFrom(childDefn.isMandatory(), false);
279 boolean autoCreated = booleanFrom(childDefn.isAutoCreated(), false);
280 boolean isProtected = booleanFrom(childDefn.isProtected(), false);
281 String onParentVersion = OnParentVersionAction.nameFromValue(childDefn.getOnParentVersion()).toUpperCase();
282 boolean sameNameSiblings = booleanFrom(childDefn.allowsSameNameSiblings(), false);
283
284
285 if (name == null) name = JcrNodeType.RESIDUAL_NAME;
286 Path path = pathFactory.create(parentPath, JcrLexicon.CHILD_NODE_DEFINITION);
287
288 PropertyFactory factory = childDefn.getExecutionContext().getPropertyFactory();
289 destination.create(path,
290 factory.create(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.CHILD_NODE_DEFINITION),
291 factory.create(JcrLexicon.REQUIRED_PRIMARY_TYPES, (Object[])requiredPrimaryTypes),
292 factory.create(JcrLexicon.DEFAULT_PRIMARY_TYPE, defaultPrimaryType),
293 factory.create(JcrLexicon.MANDATORY, mandatory),
294 factory.create(JcrLexicon.NAME, name),
295 factory.create(JcrLexicon.AUTO_CREATED, autoCreated),
296 factory.create(JcrLexicon.PROTECTED, isProtected),
297 factory.create(JcrLexicon.ON_PARENT_VERSION, onParentVersion),
298 factory.create(JcrLexicon.SAME_NAME_SIBLINGS, sameNameSiblings));
299
300 return path;
301 }
302 }