This project has retired. For details please refer to its
Attic page.
JcrTypeManager xref
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.chemistry.opencmis.jcr;
20
21 import org.apache.chemistry.opencmis.commons.PropertyIds;
22 import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition;
23 import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
24 import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
25 import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer;
26 import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionList;
27 import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
28 import org.apache.chemistry.opencmis.commons.enums.Cardinality;
29 import org.apache.chemistry.opencmis.commons.enums.PropertyType;
30 import org.apache.chemistry.opencmis.commons.enums.Updatability;
31 import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
32 import org.apache.chemistry.opencmis.commons.impl.Converter;
33 import org.apache.chemistry.opencmis.commons.impl.dataobjects.AbstractPropertyDefinition;
34 import org.apache.chemistry.opencmis.commons.impl.dataobjects.AbstractTypeDefinition;
35 import org.apache.chemistry.opencmis.commons.impl.dataobjects.DocumentTypeDefinitionImpl;
36 import org.apache.chemistry.opencmis.commons.impl.dataobjects.FolderTypeDefinitionImpl;
37 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyBooleanDefinitionImpl;
38 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyDateTimeDefinitionImpl;
39 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyDecimalDefinitionImpl;
40 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyHtmlDefinitionImpl;
41 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIdDefinitionImpl;
42 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIntegerDefinitionImpl;
43 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyStringDefinitionImpl;
44 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyUriDefinitionImpl;
45 import org.apache.chemistry.opencmis.commons.impl.dataobjects.TypeDefinitionContainerImpl;
46 import org.apache.chemistry.opencmis.commons.impl.dataobjects.TypeDefinitionListImpl;
47 import org.apache.chemistry.opencmis.server.support.TypeManager;
48 import org.apache.commons.logging.Log;
49 import org.apache.commons.logging.LogFactory;
50
51 import java.math.BigInteger;
52 import java.util.ArrayList;
53 import java.util.Collection;
54 import java.util.HashMap;
55 import java.util.List;
56 import java.util.Map;
57
58
59
60
61 public class JcrTypeManager implements TypeManager {
62 private static final Log log = LogFactory.getLog(JcrTypeManager.class);
63
64 public static final String DOCUMENT_TYPE_ID = "cmis:document";
65 public static final String FOLDER_TYPE_ID = "cmis:folder";
66 public static final String RELATIONSHIP_TYPE_ID = "cmis:relationship";
67 public static final String POLICY_TYPE_ID = "cmis:policy";
68 public static final String NAMESPACE = "http://opencmis.org/jcr";
69
70 private final Map<String, TypeDefinitionContainerImpl> fTypes;
71
72 public JcrTypeManager() {
73 fTypes = new HashMap<String, TypeDefinitionContainerImpl>();
74 }
75
76
77
78
79
80
81 public boolean addType(TypeDefinition type) {
82 if (type == null) {
83 return false;
84 }
85
86 if (fTypes.containsKey(type.getId())) {
87
88 return false;
89 }
90
91 AbstractTypeDefinition newType = (AbstractTypeDefinition) copyTypeDefinition(type);
92
93 if (!newType.getBaseTypeId().value().equals(newType.getId())) {
94
95
96 TypeDefinition baseType;
97 if (newType.getBaseTypeId() == BaseTypeId.CMIS_DOCUMENT) {
98 baseType = copyTypeDefinition(fTypes.get(DOCUMENT_TYPE_ID).getTypeDefinition());
99 }
100 else if (newType.getBaseTypeId() == BaseTypeId.CMIS_FOLDER) {
101 baseType = copyTypeDefinition(fTypes.get(FOLDER_TYPE_ID).getTypeDefinition());
102 }
103 else if (newType.getBaseTypeId() == BaseTypeId.CMIS_RELATIONSHIP) {
104 baseType = copyTypeDefinition(fTypes.get(RELATIONSHIP_TYPE_ID).getTypeDefinition());
105 }
106 else if (newType.getBaseTypeId() == BaseTypeId.CMIS_POLICY) {
107 baseType = copyTypeDefinition(fTypes.get(POLICY_TYPE_ID).getTypeDefinition());
108 }
109 else {
110 return false;
111 }
112
113
114 for (PropertyDefinition<?> propDef : baseType.getPropertyDefinitions().values()) {
115 ((AbstractPropertyDefinition<?>) propDef).setIsInherited(true);
116 newType.addPropertyDefinition(propDef);
117 }
118
119 }
120
121
122 addTypeInternal(newType);
123
124 log.info("Added type '" + newType.getId() + "'.");
125
126 return true;
127 }
128
129 public TypeDefinition getType(String typeId) {
130 TypeDefinitionContainer tc = fTypes.get(typeId);
131 return tc == null ? null : tc.getTypeDefinition();
132 }
133
134 public static boolean isVersionable(TypeDefinition typeDef) {
135 return typeDef instanceof DocumentTypeDefinition
136 ? ((DocumentTypeDefinition) typeDef).isVersionable()
137 : false;
138 }
139
140 public static TypeDefinition copyTypeDefinition(TypeDefinition type) {
141 return Converter.convert(Converter.convert(type));
142 }
143
144
145
146
147 public TypeDefinitionList getTypeChildren(String typeId, boolean includePropertyDefinitions,
148 BigInteger maxItems, BigInteger skipCount) {
149
150 TypeDefinitionListImpl result = new TypeDefinitionListImpl(new ArrayList<TypeDefinition>());
151
152 int skip = skipCount == null ? 0 : skipCount.intValue();
153 if (skip < 0) {
154 skip = 0;
155 }
156
157 int max = maxItems == null ? Integer.MAX_VALUE : maxItems.intValue();
158 if (max < 1) {
159 return result;
160 }
161
162 if (typeId == null) {
163 if (skip < 1) {
164 result.getList().add(copyTypeDefinition(fTypes.get(FOLDER_TYPE_ID).getTypeDefinition()));
165 max--;
166 }
167 if (skip < 2 && max > 0) {
168 result.getList().add(copyTypeDefinition(fTypes.get(DOCUMENT_TYPE_ID).getTypeDefinition()));
169 }
170
171 result.setHasMoreItems(result.getList().size() + skip < 2);
172 result.setNumItems(BigInteger.valueOf(2));
173 }
174 else {
175 TypeDefinitionContainer tc = fTypes.get(typeId);
176 if (tc == null || tc.getChildren() == null) {
177 return result;
178 }
179
180 for (TypeDefinitionContainer child : tc.getChildren()) {
181 if (skip > 0) {
182 skip--;
183 continue;
184 }
185
186 result.getList().add(copyTypeDefinition(child.getTypeDefinition()));
187
188 max--;
189 if (max == 0) {
190 break;
191 }
192 }
193
194 result.setHasMoreItems(result.getList().size() + skip < tc.getChildren().size());
195 result.setNumItems(BigInteger.valueOf(tc.getChildren().size()));
196 }
197
198 if (!includePropertyDefinitions) {
199 for (TypeDefinition type : result.getList()) {
200 type.getPropertyDefinitions().clear();
201 }
202 }
203
204 return result;
205 }
206
207
208
209
210 public List<TypeDefinitionContainer> getTypesDescendants(String typeId, BigInteger depth,
211 Boolean includePropertyDefinitions) {
212
213 List<TypeDefinitionContainer> result = new ArrayList<TypeDefinitionContainer>();
214
215
216 int d = depth == null ? -1 : depth.intValue();
217 if (d == 0) {
218 throw new CmisInvalidArgumentException("Depth must not be 0!");
219 }
220
221
222 boolean ipd = Boolean.TRUE.equals(includePropertyDefinitions);
223
224 if (typeId == null) {
225 result.add(getTypesDescendants(d, fTypes.get(FOLDER_TYPE_ID), ipd));
226 result.add(getTypesDescendants(d, fTypes.get(DOCUMENT_TYPE_ID), ipd));
227 }
228 else {
229 TypeDefinitionContainer tc = fTypes.get(typeId);
230 if (tc != null) {
231 result.add(getTypesDescendants(d, tc, ipd));
232 }
233 }
234
235 return result;
236 }
237
238
239
240 public TypeDefinitionContainer getTypeById(String typeId) {
241 return fTypes.get(typeId);
242 }
243
244 public TypeDefinition getTypeByQueryName(String typeQueryName) {
245 for (TypeDefinitionContainerImpl type : fTypes.values()) {
246 TypeDefinition typeDef = type.getTypeDefinition();
247 if (typeDef.getQueryName().equals(typeQueryName)) {
248 return typeDef;
249 }
250 }
251
252 return null;
253 }
254
255 public Collection<TypeDefinitionContainer> getTypeDefinitionList() {
256 Collection<TypeDefinitionContainer> types = new ArrayList<TypeDefinitionContainer>(fTypes.size());
257 types.addAll(fTypes.values());
258 return types;
259 }
260
261 public List<TypeDefinitionContainer> getRootTypes() {
262 List<TypeDefinitionContainer> types = new ArrayList<TypeDefinitionContainer>(2);
263 types.add(fTypes.get(FOLDER_TYPE_ID));
264 types.add(fTypes.get(DOCUMENT_TYPE_ID));
265 return types;
266 }
267
268 public String getPropertyIdForQueryName(TypeDefinition typeDefinition, String propQueryName) {
269 for (PropertyDefinition<?> pd : typeDefinition.getPropertyDefinitions().values()) {
270 if (pd.getQueryName().equals(propQueryName)) {
271 return pd.getId();
272 }
273 }
274
275 return null;
276 }
277
278 public static void addBasePropertyDefinitions(AbstractTypeDefinition type) {
279 type.addPropertyDefinition(createPropDef(PropertyIds.BASE_TYPE_ID, "Base Type Id", "Base Type Id",
280 PropertyType.ID, Cardinality.SINGLE, Updatability.READONLY, false, true));
281
282 type.addPropertyDefinition(createPropDef(PropertyIds.OBJECT_ID, "Object Id", "Object Id", PropertyType.ID,
283 Cardinality.SINGLE, Updatability.READONLY, false, true));
284
285 type.addPropertyDefinition(createPropDef(PropertyIds.OBJECT_TYPE_ID, "Type Id", "Type Id", PropertyType.ID,
286 Cardinality.SINGLE, Updatability.ONCREATE, false, true));
287
288 type.addPropertyDefinition(createPropDef(PropertyIds.NAME, "Name", "Name", PropertyType.STRING,
289 Cardinality.SINGLE, Updatability.READWRITE, false, true));
290
291 type.addPropertyDefinition(createPropDef(PropertyIds.CREATED_BY, "Created By", "Created By",
292 PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, true));
293
294 type.addPropertyDefinition(createPropDef(PropertyIds.CREATION_DATE, "Creation Date", "Creation Date",
295 PropertyType.DATETIME, Cardinality.SINGLE, Updatability.READONLY, false, true));
296
297 type.addPropertyDefinition(createPropDef(PropertyIds.LAST_MODIFIED_BY, "Last Modified By", "Last Modified By",
298 PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, true));
299
300 type.addPropertyDefinition(createPropDef(PropertyIds.LAST_MODIFICATION_DATE, "Last Modification Date",
301 "Last Modification Date", PropertyType.DATETIME, Cardinality.SINGLE, Updatability.READONLY, false, true));
302
303 type.addPropertyDefinition(createPropDef(PropertyIds.CHANGE_TOKEN, "Change Token", "Change Token",
304 PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, false));
305 }
306
307 public static void addFolderPropertyDefinitions(FolderTypeDefinitionImpl type) {
308 type.addPropertyDefinition(createPropDef(PropertyIds.PARENT_ID, "Parent Id", "Parent Id", PropertyType.ID,
309 Cardinality.SINGLE, Updatability.READONLY, false, false));
310
311 type.addPropertyDefinition(createPropDef(PropertyIds.ALLOWED_CHILD_OBJECT_TYPE_IDS,
312 "Allowed Child Object Type Ids", "Allowed Child Object Type Ids", PropertyType.ID, Cardinality.MULTI,
313 Updatability.READONLY, false, false));
314
315 type.addPropertyDefinition(createPropDef(PropertyIds.PATH, "Path", "Path", PropertyType.STRING,
316 Cardinality.SINGLE, Updatability.READONLY, false, false));
317 }
318
319 public static void addDocumentPropertyDefinitions(DocumentTypeDefinitionImpl type) {
320 type.addPropertyDefinition(createPropDef(PropertyIds.IS_IMMUTABLE, "Is Immutable", "Is Immutable",
321 PropertyType.BOOLEAN, Cardinality.SINGLE, Updatability.READONLY, false, false));
322
323 type.addPropertyDefinition(createPropDef(PropertyIds.IS_LATEST_VERSION, "Is Latest Version",
324 "Is Latest Version", PropertyType.BOOLEAN, Cardinality.SINGLE, Updatability.READONLY, false, false));
325
326 type.addPropertyDefinition(createPropDef(PropertyIds.IS_MAJOR_VERSION, "Is Major Version", "Is Major Version",
327 PropertyType.BOOLEAN, Cardinality.SINGLE, Updatability.READONLY, false, false));
328
329 type.addPropertyDefinition(createPropDef(PropertyIds.IS_LATEST_MAJOR_VERSION, "Is Latest Major Version",
330 "Is Latest Major Version", PropertyType.BOOLEAN, Cardinality.SINGLE, Updatability.READONLY, false,
331 false));
332
333 type.addPropertyDefinition(createPropDef(PropertyIds.VERSION_LABEL, "Version Label", "Version Label",
334 PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, false));
335
336 type.addPropertyDefinition(createPropDef(PropertyIds.VERSION_SERIES_ID, "Version Series Id",
337 "Version Series Id", PropertyType.ID, Cardinality.SINGLE, Updatability.READONLY, false, true));
338
339 type.addPropertyDefinition(createPropDef(PropertyIds.IS_VERSION_SERIES_CHECKED_OUT,
340 "Is Version Series Checked Out", "Is Version Series Checked Out", PropertyType.BOOLEAN,
341 Cardinality.SINGLE, Updatability.READONLY, false, true));
342
343 type.addPropertyDefinition(createPropDef(PropertyIds.VERSION_SERIES_CHECKED_OUT_ID,
344 "Version Series Checked Out Id", "Version Series Checked Out Id", PropertyType.ID, Cardinality.SINGLE,
345 Updatability.READONLY, false, false));
346
347 type.addPropertyDefinition(createPropDef(PropertyIds.VERSION_SERIES_CHECKED_OUT_BY,
348 "Version Series Checked Out By", "Version Series Checked Out By", PropertyType.ID, Cardinality.SINGLE,
349 Updatability.READONLY, false, false));
350
351 type.addPropertyDefinition(createPropDef(PropertyIds.CHECKIN_COMMENT, "Checkin Comment", "Checkin Comment",
352 PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, false));
353
354 type.addPropertyDefinition(createPropDef(PropertyIds.CONTENT_STREAM_LENGTH, "Content Stream Length",
355 "Content Stream Length", PropertyType.INTEGER, Cardinality.SINGLE, Updatability.READONLY, false, false));
356
357 type.addPropertyDefinition(createPropDef(PropertyIds.CONTENT_STREAM_MIME_TYPE, "MIME Type", "MIME Type",
358 PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, false));
359
360 type.addPropertyDefinition(createPropDef(PropertyIds.CONTENT_STREAM_FILE_NAME, "Filename", "Filename",
361 PropertyType.STRING, Cardinality.SINGLE, Updatability.READONLY, false, false));
362
363 type.addPropertyDefinition(createPropDef(PropertyIds.CONTENT_STREAM_ID, "Content Stream Id",
364 "Content Stream Id", PropertyType.ID, Cardinality.SINGLE, Updatability.READONLY, false, false));
365 }
366
367
368
369
370 public static PropertyDefinition<?> createPropDef(String id, String displayName, String description,
371 PropertyType datatype, Cardinality cardinality, Updatability updateability, boolean inherited,
372 boolean required) {
373
374 AbstractPropertyDefinition<?> result;
375
376 switch (datatype) {
377 case BOOLEAN:
378 result = new PropertyBooleanDefinitionImpl();
379 break;
380 case DATETIME:
381 result = new PropertyDateTimeDefinitionImpl();
382 break;
383 case DECIMAL:
384 result = new PropertyDecimalDefinitionImpl();
385 break;
386 case HTML:
387 result = new PropertyHtmlDefinitionImpl();
388 break;
389 case ID:
390 result = new PropertyIdDefinitionImpl();
391 break;
392 case INTEGER:
393 result = new PropertyIntegerDefinitionImpl();
394 break;
395 case STRING:
396 result = new PropertyStringDefinitionImpl();
397 break;
398 case URI:
399 result = new PropertyUriDefinitionImpl();
400 break;
401 default:
402 throw new RuntimeException("Unknown datatype! Spec change?");
403 }
404
405 result.setId(id);
406 result.setLocalName(id);
407 result.setDisplayName(displayName);
408 result.setDescription(description);
409 result.setPropertyType(datatype);
410 result.setCardinality(cardinality);
411 result.setUpdatability(updateability);
412 result.setIsInherited(inherited);
413 result.setIsRequired(required);
414 result.setIsQueryable(false);
415 result.setQueryName(id);
416
417 return result;
418 }
419
420
421
422
423
424
425 private void addTypeInternal(AbstractTypeDefinition type) {
426 if (type == null) {
427 return;
428 }
429
430 TypeDefinitionContainerImpl tc = new TypeDefinitionContainerImpl();
431 tc.setTypeDefinition(type);
432
433
434 if (type.getParentTypeId() != null) {
435 TypeDefinitionContainerImpl tdc = fTypes.get(type.getParentTypeId());
436 if (tdc != null) {
437 if (tdc.getChildren() == null) {
438 tdc.setChildren(new ArrayList<TypeDefinitionContainer>());
439 }
440 tdc.getChildren().add(tc);
441 }
442 }
443
444 fTypes.put(type.getId(), tc);
445 }
446
447
448
449
450 private static TypeDefinitionContainer getTypesDescendants(int depth, TypeDefinitionContainer tc,
451 boolean includePropertyDefinitions) {
452
453 TypeDefinitionContainerImpl result = new TypeDefinitionContainerImpl();
454
455 TypeDefinition type = copyTypeDefinition(tc.getTypeDefinition());
456 if (!includePropertyDefinitions) {
457 type.getPropertyDefinitions().clear();
458 }
459
460 result.setTypeDefinition(type);
461
462 if (depth != 0) {
463 if (tc.getChildren() != null) {
464 result.setChildren(new ArrayList<TypeDefinitionContainer>());
465 for (TypeDefinitionContainer tdc : tc.getChildren()) {
466 result.getChildren().add(
467 getTypesDescendants(depth < 0 ? -1 : depth - 1, tdc, includePropertyDefinitions));
468 }
469 }
470 }
471
472 return result;
473 }
474
475 }