This project has retired. For details please refer to its
Attic page.
ObjectFactoryImpl 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.client.runtime.repository;
20
21 import java.io.InputStream;
22 import java.io.Serializable;
23 import java.math.BigDecimal;
24 import java.math.BigInteger;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.Date;
28 import java.util.GregorianCalendar;
29 import java.util.HashMap;
30 import java.util.LinkedHashMap;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Set;
34
35 import org.apache.chemistry.opencmis.client.api.ChangeEvent;
36 import org.apache.chemistry.opencmis.client.api.ChangeEvents;
37 import org.apache.chemistry.opencmis.client.api.CmisObject;
38 import org.apache.chemistry.opencmis.client.api.ObjectFactory;
39 import org.apache.chemistry.opencmis.client.api.ObjectType;
40 import org.apache.chemistry.opencmis.client.api.OperationContext;
41 import org.apache.chemistry.opencmis.client.api.Policy;
42 import org.apache.chemistry.opencmis.client.api.Property;
43 import org.apache.chemistry.opencmis.client.api.QueryResult;
44 import org.apache.chemistry.opencmis.client.api.Rendition;
45 import org.apache.chemistry.opencmis.client.api.Session;
46 import org.apache.chemistry.opencmis.client.runtime.ChangeEventImpl;
47 import org.apache.chemistry.opencmis.client.runtime.ChangeEventsImpl;
48 import org.apache.chemistry.opencmis.client.runtime.DocumentImpl;
49 import org.apache.chemistry.opencmis.client.runtime.FolderImpl;
50 import org.apache.chemistry.opencmis.client.runtime.PolicyImpl;
51 import org.apache.chemistry.opencmis.client.runtime.PropertyImpl;
52 import org.apache.chemistry.opencmis.client.runtime.QueryResultImpl;
53 import org.apache.chemistry.opencmis.client.runtime.RelationshipImpl;
54 import org.apache.chemistry.opencmis.client.runtime.RenditionImpl;
55 import org.apache.chemistry.opencmis.client.runtime.SessionImpl;
56 import org.apache.chemistry.opencmis.client.runtime.objecttype.DocumentTypeImpl;
57 import org.apache.chemistry.opencmis.client.runtime.objecttype.FolderTypeImpl;
58 import org.apache.chemistry.opencmis.client.runtime.objecttype.PolicyTypeImpl;
59 import org.apache.chemistry.opencmis.client.runtime.objecttype.RelationshipTypeImpl;
60 import org.apache.chemistry.opencmis.commons.PropertyIds;
61 import org.apache.chemistry.opencmis.commons.data.Ace;
62 import org.apache.chemistry.opencmis.commons.data.Acl;
63 import org.apache.chemistry.opencmis.commons.data.ContentStream;
64 import org.apache.chemistry.opencmis.commons.data.ObjectData;
65 import org.apache.chemistry.opencmis.commons.data.ObjectList;
66 import org.apache.chemistry.opencmis.commons.data.Properties;
67 import org.apache.chemistry.opencmis.commons.data.PropertyData;
68 import org.apache.chemistry.opencmis.commons.data.PropertyId;
69 import org.apache.chemistry.opencmis.commons.data.RenditionData;
70 import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
71 import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition;
72 import org.apache.chemistry.opencmis.commons.definitions.FolderTypeDefinition;
73 import org.apache.chemistry.opencmis.commons.definitions.PolicyTypeDefinition;
74 import org.apache.chemistry.opencmis.commons.definitions.PropertyBooleanDefinition;
75 import org.apache.chemistry.opencmis.commons.definitions.PropertyDateTimeDefinition;
76 import org.apache.chemistry.opencmis.commons.definitions.PropertyDecimalDefinition;
77 import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
78 import org.apache.chemistry.opencmis.commons.definitions.PropertyHtmlDefinition;
79 import org.apache.chemistry.opencmis.commons.definitions.PropertyIdDefinition;
80 import org.apache.chemistry.opencmis.commons.definitions.PropertyIntegerDefinition;
81 import org.apache.chemistry.opencmis.commons.definitions.PropertyStringDefinition;
82 import org.apache.chemistry.opencmis.commons.definitions.PropertyUriDefinition;
83 import org.apache.chemistry.opencmis.commons.definitions.RelationshipTypeDefinition;
84 import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
85 import org.apache.chemistry.opencmis.commons.enums.Cardinality;
86 import org.apache.chemistry.opencmis.commons.enums.ChangeType;
87 import org.apache.chemistry.opencmis.commons.enums.Updatability;
88 import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
89 import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
90 import org.apache.chemistry.opencmis.commons.spi.BindingsObjectFactory;
91
92
93
94
95 public class ObjectFactoryImpl implements ObjectFactory, Serializable {
96
97 private static final long serialVersionUID = 1L;
98
99 private Session session;
100
101
102
103
104 public ObjectFactoryImpl() {
105 }
106
107 public void initialize(Session session, Map<String, String> parameters) {
108 this.session = session;
109 }
110
111
112
113
114 protected BindingsObjectFactory getBindingsObjectFactory() {
115 return session.getBinding().getObjectFactory();
116 }
117
118
119
120 public RepositoryInfo convertRepositoryInfo(RepositoryInfo repositoryInfo) {
121 return repositoryInfo;
122 }
123
124
125
126 public Acl convertAces(List<Ace> aces) {
127 if (aces == null) {
128 return null;
129 }
130
131 BindingsObjectFactory bof = getBindingsObjectFactory();
132
133 List<Ace> bindingAces = new ArrayList<Ace>();
134 for (Ace ace : aces) {
135 bindingAces.add(bof.createAccessControlEntry(ace.getPrincipalId(), ace.getPermissions()));
136 }
137
138 return bof.createAccessControlList(bindingAces);
139 }
140
141 public Ace createAce(String principal, List<String> permissions) {
142 BindingsObjectFactory bof = getBindingsObjectFactory();
143
144 Ace ace = bof.createAccessControlEntry(principal, permissions);
145
146 return ace;
147 }
148
149 public Acl createAcl(List<Ace> aces) {
150 BindingsObjectFactory bof = getBindingsObjectFactory();
151
152 Acl acl = bof.createAccessControlList(aces);
153
154 return acl;
155 }
156
157
158
159 public List<String> convertPolicies(List<Policy> policies) {
160 if (policies == null) {
161 return null;
162 }
163
164 List<String> result = new ArrayList<String>();
165
166 for (Policy policy : policies) {
167 if ((policy != null) && (policy.getId() != null)) {
168 result.add(policy.getId());
169 }
170 }
171
172 return result;
173 }
174
175
176
177 public Rendition convertRendition(String objectId, RenditionData rendition) {
178 if (rendition == null) {
179 throw new IllegalArgumentException("Rendition must be set!");
180 }
181
182 long length = (rendition.getBigLength() == null ? -1 : rendition.getBigLength().longValue());
183 int height = (rendition.getBigHeight() == null ? -1 : rendition.getBigHeight().intValue());
184 int width = (rendition.getBigWidth() == null ? -1 : rendition.getBigWidth().intValue());
185
186 return new RenditionImpl(this.session, objectId, rendition.getStreamId(), rendition.getRenditionDocumentId(),
187 rendition.getKind(), length, rendition.getMimeType(), rendition.getTitle(), height, width);
188 }
189
190
191
192 public ContentStream createContentStream(String filename, long length, String mimetype, InputStream stream) {
193 return new ContentStreamImpl(filename, BigInteger.valueOf(length), mimetype, stream);
194 }
195
196 public ContentStream convertContentStream(ContentStream contentStream) {
197 if (contentStream == null) {
198 return null;
199 }
200
201 BigInteger length = (contentStream.getLength() < 0 ? null : BigInteger.valueOf(contentStream.getLength()));
202
203 return getBindingsObjectFactory().createContentStream(contentStream.getFileName(), length,
204 contentStream.getMimeType(), contentStream.getStream());
205 }
206
207
208
209 public ObjectType convertTypeDefinition(TypeDefinition typeDefinition) {
210 if (typeDefinition instanceof DocumentTypeDefinition) {
211 return new DocumentTypeImpl(this.session, (DocumentTypeDefinition) typeDefinition);
212 } else if (typeDefinition instanceof FolderTypeDefinition) {
213 return new FolderTypeImpl(this.session, (FolderTypeDefinition) typeDefinition);
214 } else if (typeDefinition instanceof RelationshipTypeDefinition) {
215 return new RelationshipTypeImpl(this.session, (RelationshipTypeDefinition) typeDefinition);
216 } else if (typeDefinition instanceof PolicyTypeDefinition) {
217 return new PolicyTypeImpl(this.session, (PolicyTypeDefinition) typeDefinition);
218 } else if (typeDefinition == null) {
219 throw new CmisRuntimeException("No base type supplied!");
220 } else {
221 throw new CmisRuntimeException("Unknown base type! Received " + typeDefinition.getClass().getName());
222 }
223 }
224
225 public ObjectType getTypeFromObjectData(ObjectData objectData) {
226 if ((objectData == null) || (objectData.getProperties() == null)
227 || (objectData.getProperties().getProperties() == null)) {
228 return null;
229 }
230
231 PropertyData<?> typeProperty = objectData.getProperties().getProperties().get(PropertyIds.OBJECT_TYPE_ID);
232 if (!(typeProperty instanceof PropertyId)) {
233 return null;
234 }
235
236 return this.session.getTypeDefinition((String) typeProperty.getFirstValue());
237 }
238
239
240
241 public <T> Property<T> createProperty(PropertyDefinition<T> type, List<T> values) {
242 return new PropertyImpl<T>(type, values);
243 }
244
245 @SuppressWarnings("unchecked")
246 protected <T> Property<T> convertProperty(ObjectType objectType, PropertyData<T> pd) {
247 PropertyDefinition<T> definition = (PropertyDefinition<T>) objectType.getPropertyDefinitions().get(pd.getId());
248 if (definition == null) {
249
250 throw new CmisRuntimeException("Property '" + pd.getId() + "' doesn't exist!");
251 }
252 return createProperty(definition, pd.getValues());
253 }
254
255 public Map<String, Property<?>> convertProperties(ObjectType objectType, Properties properties) {
256
257 if (objectType == null) {
258 throw new IllegalArgumentException("Object type must set!");
259 }
260
261 if (objectType.getPropertyDefinitions() == null) {
262 throw new IllegalArgumentException("Object type has no property defintions!");
263 }
264
265 if ((properties == null) || (properties.getProperties() == null)) {
266 throw new IllegalArgumentException("Properties must be set!");
267 }
268
269
270 Map<String, Property<?>> result = new LinkedHashMap<String, Property<?>>();
271 for (Map.Entry<String, PropertyData<?>> entry : properties.getProperties().entrySet()) {
272
273 Property<?> apiProperty = convertProperty(objectType, entry.getValue());
274 result.put(entry.getKey(), apiProperty);
275 }
276
277 return result;
278 }
279
280 @SuppressWarnings("unchecked")
281 public Properties convertProperties(Map<String, ?> properties, ObjectType type, Set<Updatability> updatabilityFilter) {
282
283 if (properties == null) {
284 return null;
285 }
286
287
288 if (type == null) {
289 Object typeId = properties.get(PropertyIds.OBJECT_TYPE_ID);
290 if (!(typeId instanceof String)) {
291 throw new IllegalArgumentException("Type or type property must be set!");
292 }
293
294 type = session.getTypeDefinition(typeId.toString());
295 }
296
297
298 BindingsObjectFactory bof = getBindingsObjectFactory();
299 List<PropertyData<?>> propertyList = new ArrayList<PropertyData<?>>();
300
301
302 for (Map.Entry<String, ?> property : properties.entrySet()) {
303 if ((property == null) || (property.getKey() == null)) {
304 continue;
305 }
306
307 String id = property.getKey();
308 Object value = property.getValue();
309
310 if (value instanceof Property<?>) {
311 Property<?> p = (Property<?>) value;
312 if (!id.equals(p.getId())) {
313 throw new IllegalArgumentException("Property id mismatch: '" + id + "' != '" + p.getId() + "'!");
314 }
315 value = (p.getDefinition().getCardinality() == Cardinality.SINGLE ? p.getFirstValue() : p.getValues());
316 }
317
318
319 PropertyDefinition<?> definition = type.getPropertyDefinitions().get(id);
320 if (definition == null) {
321 throw new IllegalArgumentException("Property '" + id + "' is not valid for this type!");
322 }
323
324
325 if (updatabilityFilter != null) {
326 if (!updatabilityFilter.contains(definition.getUpdatability())) {
327 continue;
328 }
329 }
330
331
332 List<?> values;
333 if (value == null) {
334 values = null;
335 } else if (value instanceof List<?>) {
336 if (definition.getCardinality() != Cardinality.MULTI) {
337 throw new IllegalArgumentException("Property '" + id + "' is not a multi value property!");
338 }
339 values = (List<?>) value;
340
341
342
343 Class<?> valueClazz = null;
344 for (Object o : values) {
345 if (o == null) {
346 throw new IllegalArgumentException("Property '" + id + "' contains null values!");
347 }
348 if (valueClazz == null) {
349 valueClazz = o.getClass();
350 } else {
351 if (!valueClazz.isInstance(o)) {
352 throw new IllegalArgumentException("Property '" + id + "' is inhomogeneous!");
353 }
354 }
355 }
356 } else {
357 if (definition.getCardinality() != Cardinality.SINGLE) {
358 throw new IllegalArgumentException("Property '" + id + "' is not a single value property!");
359 }
360 values = Collections.singletonList(value);
361 }
362
363
364 PropertyData<?> propertyData = null;
365 Object firstValue = (values == null || values.isEmpty() ? null : values.get(0));
366
367 if (definition instanceof PropertyStringDefinition) {
368 if (firstValue == null) {
369 propertyData = bof.createPropertyStringData(id, (List<String>) null);
370 } else if (firstValue instanceof String) {
371 propertyData = bof.createPropertyStringData(id, (List<String>) values);
372 } else {
373 throwWrongTypeError(firstValue, "string", String.class, id);
374 }
375 } else if (definition instanceof PropertyIdDefinition) {
376 if (firstValue == null) {
377 propertyData = bof.createPropertyIdData(id, (List<String>) null);
378 } else if (firstValue instanceof String) {
379 propertyData = bof.createPropertyIdData(id, (List<String>) values);
380 } else {
381 throwWrongTypeError(firstValue, "string", String.class, id);
382 }
383 } else if (definition instanceof PropertyHtmlDefinition) {
384 if (firstValue == null) {
385 propertyData = bof.createPropertyHtmlData(id, (List<String>) values);
386 } else if (firstValue instanceof String) {
387 propertyData = bof.createPropertyHtmlData(id, (List<String>) values);
388 } else {
389 throwWrongTypeError(firstValue, "html", String.class, id);
390 }
391 } else if (definition instanceof PropertyUriDefinition) {
392 if (firstValue == null) {
393 propertyData = bof.createPropertyUriData(id, (List<String>) null);
394 } else if (firstValue instanceof String) {
395 propertyData = bof.createPropertyUriData(id, (List<String>) values);
396 } else {
397 throwWrongTypeError(firstValue, "uri", String.class, id);
398 }
399 } else if (definition instanceof PropertyIntegerDefinition) {
400 if (firstValue == null) {
401 propertyData = bof.createPropertyIntegerData(id, (List<BigInteger>) null);
402 } else if (firstValue instanceof BigInteger) {
403 propertyData = bof.createPropertyIntegerData(id, (List<BigInteger>) values);
404 } else if ((firstValue instanceof Byte) || (firstValue instanceof Short)
405 || (firstValue instanceof Integer) || (firstValue instanceof Long)) {
406
407 List<BigInteger> list = new ArrayList<BigInteger>(values.size());
408 for (Object v : values) {
409 list.add(BigInteger.valueOf(((Number) v).longValue()));
410 }
411
412 propertyData = bof.createPropertyIntegerData(id, list);
413 } else {
414 throwWrongTypeError(firstValue, "integer", BigInteger.class, id);
415 }
416 } else if (definition instanceof PropertyBooleanDefinition) {
417 if (firstValue == null) {
418 propertyData = bof.createPropertyBooleanData(id, (List<Boolean>) null);
419 } else if (firstValue instanceof Boolean) {
420 propertyData = bof.createPropertyBooleanData(id, (List<Boolean>) values);
421 } else {
422 throwWrongTypeError(firstValue, "boolean", Boolean.class, id);
423 }
424 } else if (definition instanceof PropertyDecimalDefinition) {
425 if (firstValue == null) {
426 propertyData = bof.createPropertyDecimalData(id, (List<BigDecimal>) null);
427 } else if (firstValue instanceof BigDecimal) {
428 propertyData = bof.createPropertyDecimalData(id, (List<BigDecimal>) values);
429 } else if ((firstValue instanceof Float) || (firstValue instanceof Double)
430 || (firstValue instanceof Byte) || (firstValue instanceof Short)
431 || (firstValue instanceof Integer) || (firstValue instanceof Long)) {
432
433
434 List<BigDecimal> list = new ArrayList<BigDecimal>(values.size());
435 for (Object v : values) {
436 list.add(new BigDecimal(v.toString()));
437 }
438
439 propertyData = bof.createPropertyDecimalData(id, list);
440 } else {
441 throwWrongTypeError(firstValue, "decimal", BigDecimal.class, id);
442 }
443 } else if (definition instanceof PropertyDateTimeDefinition) {
444 if (firstValue == null) {
445 propertyData = bof.createPropertyDateTimeData(id, (List<GregorianCalendar>) null);
446 } else if (firstValue instanceof GregorianCalendar) {
447 propertyData = bof.createPropertyDateTimeData(id, (List<GregorianCalendar>) values);
448 } else if (firstValue instanceof Date) {
449 List<GregorianCalendar> list = new ArrayList<GregorianCalendar>(values.size());
450 for (Object d : values) {
451 GregorianCalendar cal = new GregorianCalendar();
452 cal.setTime((Date)d);
453 list.add(cal);
454 }
455 propertyData = bof.createPropertyDateTimeData(id, list);
456 } else {
457 throwWrongTypeError(firstValue, "datetime", GregorianCalendar.class, id);
458 }
459 }
460
461
462 if (propertyData == null) {
463 throw new IllegalArgumentException("Property '" + id + "' doesn't match the property defintion!");
464 }
465
466 propertyList.add(propertyData);
467 }
468
469 return bof.createPropertiesData(propertyList);
470 }
471
472 public List<PropertyData<?>> convertQueryProperties(Properties properties) {
473
474 if ((properties == null) || (properties.getProperties() == null)) {
475 throw new IllegalArgumentException("Properties must be set!");
476 }
477 return new ArrayList<PropertyData<?>>(properties.getPropertyList());
478 }
479
480
481
482 public CmisObject convertObject(ObjectData objectData, OperationContext context) {
483 if (objectData == null) {
484 throw new IllegalArgumentException("Object data is null!");
485 }
486
487 ObjectType type = getTypeFromObjectData(objectData);
488
489
490 switch (objectData.getBaseTypeId()) {
491 case CMIS_DOCUMENT:
492 return new DocumentImpl((SessionImpl) this.session, type, objectData, context);
493 case CMIS_FOLDER:
494 return new FolderImpl((SessionImpl) this.session, type, objectData, context);
495 case CMIS_POLICY:
496 return new PolicyImpl((SessionImpl) this.session, type, objectData, context);
497 case CMIS_RELATIONSHIP:
498 return new RelationshipImpl((SessionImpl) this.session, type, objectData, context);
499 default:
500 throw new CmisRuntimeException("unsupported type: " + objectData.getBaseTypeId());
501 }
502 }
503
504 public QueryResult convertQueryResult(ObjectData objectData) {
505 if (objectData == null) {
506 throw new IllegalArgumentException("Object data is null!");
507 }
508
509 return new QueryResultImpl(session, objectData);
510 }
511
512 public ChangeEvent convertChangeEvent(ObjectData objectData) {
513 ChangeType changeType = null;
514 GregorianCalendar changeTime = null;
515 String objectId = null;
516 Map<String, List<?>> properties = null;
517 List<String> policyIds = null;
518 Acl acl = null;
519
520 if (objectData.getChangeEventInfo() != null) {
521 changeType = objectData.getChangeEventInfo().getChangeType();
522 changeTime = objectData.getChangeEventInfo().getChangeTime();
523 }
524
525 if ((objectData.getProperties() != null) && (objectData.getProperties().getPropertyList() != null)) {
526 properties = new HashMap<String, List<?>>();
527
528 for (PropertyData<?> property : objectData.getProperties().getPropertyList()) {
529 properties.put(property.getId(), property.getValues());
530 }
531
532 if (properties.containsKey(PropertyIds.OBJECT_ID)) {
533 List<?> objectIdList = properties.get(PropertyIds.OBJECT_ID);
534 if ((objectIdList != null) && (!objectIdList.isEmpty())) {
535 objectId = objectIdList.get(0).toString();
536 }
537 }
538
539 if ((objectData.getPolicyIds() != null) && (objectData.getPolicyIds().getPolicyIds() != null)) {
540 policyIds = objectData.getPolicyIds().getPolicyIds();
541 }
542
543 if (objectData.getAcl() != null) {
544 acl = objectData.getAcl();
545 }
546 }
547
548 return new ChangeEventImpl(changeType, changeTime, objectId, properties, policyIds, acl);
549 }
550
551 public ChangeEvents convertChangeEvents(String changeLogToken, ObjectList objectList) {
552 if (objectList == null) {
553 return null;
554 }
555
556 List<ChangeEvent> events = new ArrayList<ChangeEvent>();
557 if (objectList.getObjects() != null) {
558 for (ObjectData objectData : objectList.getObjects()) {
559 if (objectData == null) {
560 continue;
561 }
562
563 events.add(convertChangeEvent(objectData));
564 }
565 }
566
567 boolean hasMoreItems = (objectList.hasMoreItems() == null ? false : objectList.hasMoreItems().booleanValue());
568 long totalNumItems = (objectList.getNumItems() == null ? -1 : objectList.getNumItems().longValue());
569
570 return new ChangeEventsImpl(changeLogToken, events, hasMoreItems, totalNumItems);
571 }
572
573 private void throwWrongTypeError(Object obj, String type, Class<?> clazz, String id) {
574 String expectedTypes;
575 if (clazz.equals(BigInteger.class))
576 expectedTypes = "<BigInteger, Byte, Short, Integer, Long>";
577 else if (clazz.equals(BigDecimal.class))
578 expectedTypes = "<BigDecimal, Double, Float, Byte, Short, Integer, Long>";
579 else if (clazz.equals(GregorianCalendar.class))
580 expectedTypes = "<java.util.GregorianCalendar, java.util.Date>";
581 else
582 expectedTypes = clazz.getName();
583
584 String message = "Property '" + id +"' is a " + type + " property. Expected type '"
585 + expectedTypes + "' but received a '" + obj.getClass().getName() + "' property.";
586
587 throw new IllegalArgumentException(message);
588 }
589 }
590