001/* 002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * Florent Guillaume 011 */ 012package org.nuxeo.ecm.core.opencmis.impl.client; 013 014import java.io.InputStream; 015import java.math.BigDecimal; 016import java.math.BigInteger; 017import java.util.ArrayList; 018import java.util.Collection; 019import java.util.Collections; 020import java.util.GregorianCalendar; 021import java.util.List; 022import java.util.Map; 023import java.util.Map.Entry; 024import java.util.Set; 025 026import org.apache.chemistry.opencmis.client.api.ChangeEvent; 027import org.apache.chemistry.opencmis.client.api.ChangeEvents; 028import org.apache.chemistry.opencmis.client.api.ObjectFactory; 029import org.apache.chemistry.opencmis.client.api.ObjectType; 030import org.apache.chemistry.opencmis.client.api.OperationContext; 031import org.apache.chemistry.opencmis.client.api.Policy; 032import org.apache.chemistry.opencmis.client.api.Property; 033import org.apache.chemistry.opencmis.client.api.QueryResult; 034import org.apache.chemistry.opencmis.client.api.Rendition; 035import org.apache.chemistry.opencmis.client.api.SecondaryType; 036import org.apache.chemistry.opencmis.client.api.Session; 037import org.apache.chemistry.opencmis.client.runtime.PropertyImpl; 038import org.apache.chemistry.opencmis.client.runtime.RenditionImpl; 039import org.apache.chemistry.opencmis.client.runtime.objecttype.DocumentTypeImpl; 040import org.apache.chemistry.opencmis.client.runtime.objecttype.FolderTypeImpl; 041import org.apache.chemistry.opencmis.client.runtime.objecttype.PolicyTypeImpl; 042import org.apache.chemistry.opencmis.client.runtime.objecttype.RelationshipTypeImpl; 043import org.apache.chemistry.opencmis.commons.PropertyIds; 044import org.apache.chemistry.opencmis.commons.data.Ace; 045import org.apache.chemistry.opencmis.commons.data.Acl; 046import org.apache.chemistry.opencmis.commons.data.ContentStream; 047import org.apache.chemistry.opencmis.commons.data.ObjectData; 048import org.apache.chemistry.opencmis.commons.data.ObjectList; 049import org.apache.chemistry.opencmis.commons.data.Properties; 050import org.apache.chemistry.opencmis.commons.data.PropertyData; 051import org.apache.chemistry.opencmis.commons.data.PropertyId; 052import org.apache.chemistry.opencmis.commons.data.RenditionData; 053import org.apache.chemistry.opencmis.commons.data.RepositoryInfo; 054import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition; 055import org.apache.chemistry.opencmis.commons.definitions.FolderTypeDefinition; 056import org.apache.chemistry.opencmis.commons.definitions.PolicyTypeDefinition; 057import org.apache.chemistry.opencmis.commons.definitions.PropertyBooleanDefinition; 058import org.apache.chemistry.opencmis.commons.definitions.PropertyDateTimeDefinition; 059import org.apache.chemistry.opencmis.commons.definitions.PropertyDecimalDefinition; 060import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition; 061import org.apache.chemistry.opencmis.commons.definitions.PropertyHtmlDefinition; 062import org.apache.chemistry.opencmis.commons.definitions.PropertyIdDefinition; 063import org.apache.chemistry.opencmis.commons.definitions.PropertyIntegerDefinition; 064import org.apache.chemistry.opencmis.commons.definitions.PropertyStringDefinition; 065import org.apache.chemistry.opencmis.commons.definitions.PropertyUriDefinition; 066import org.apache.chemistry.opencmis.commons.definitions.RelationshipTypeDefinition; 067import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition; 068import org.apache.chemistry.opencmis.commons.enums.Cardinality; 069import org.apache.chemistry.opencmis.commons.enums.Updatability; 070import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException; 071import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlListImpl; 072import org.apache.chemistry.opencmis.commons.impl.dataobjects.BindingsObjectFactoryImpl; 073import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl; 074import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertiesImpl; 075import org.apache.chemistry.opencmis.commons.spi.BindingsObjectFactory; 076import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoObjectData; 077 078/** 079 * Factory for {@link NuxeoObject} and its related classes. 080 */ 081public class NuxeoObjectFactory implements ObjectFactory { 082 083 private final NuxeoSession session; 084 085 private static final BindingsObjectFactory of = new BindingsObjectFactoryImpl(); 086 087 public NuxeoObjectFactory(NuxeoSession session) { 088 this.session = session; 089 } 090 091 @Override 092 public void initialize(Session session, Map<String, String> parameters) { 093 // TODO 094 throw new UnsupportedOperationException(); 095 } 096 097 @Override 098 public RepositoryInfo convertRepositoryInfo(RepositoryInfo repositoryInfo) { 099 return repositoryInfo; 100 } 101 102 @Override 103 public NuxeoObject convertObject(ObjectData data, OperationContext context) { 104 if (data == null || data.getProperties() == null || data.getProperties().getProperties() == null) { 105 return null; 106 } 107 ObjectType type; 108 PropertyData<?> propData = data.getProperties().getProperties().get(PropertyIds.OBJECT_TYPE_ID); 109 if (!(propData instanceof PropertyId)) { 110 throw new IllegalArgumentException("Property cmis:objectTypeId must be of type PropertyIdData, not: " 111 + propData.getClass().getName()); 112 } 113 type = session.getTypeDefinition((String) propData.getFirstValue()); 114 return NuxeoObject.construct(session, (NuxeoObjectData) data, type); 115 } 116 117 @Override 118 public ObjectType getTypeFromObjectData(ObjectData objectData) { 119 // TODO Auto-generated method stub 120 throw new UnsupportedOperationException(); 121 } 122 123 @Override 124 public Ace createAce(String principal, List<String> permissions) { 125 // TODO Auto-generated method stub 126 throw new UnsupportedOperationException(); 127 } 128 129 @Override 130 public Acl createAcl(List<Ace> aces) { 131 // TODO Auto-generated method stub 132 throw new UnsupportedOperationException(); 133 } 134 135 @Override 136 public <T> Property<T> createProperty(PropertyDefinition<T> type, List<T> values) { 137 return new PropertyImpl<T>(type, values); 138 } 139 140 @Override 141 public ContentStream createContentStream(String filename, long length, String mimetype, InputStream stream) { 142 return new ContentStreamImpl(filename, BigInteger.valueOf(length), mimetype, stream); 143 } 144 145 @Override 146 public ContentStream createContentStream(String filename, long length, String mimetype, InputStream stream, 147 boolean partial) { 148 // TODO partial 149 return createContentStream(filename, length, mimetype, stream); 150 } 151 152 @Override 153 public Acl convertAces(List<Ace> aces) { 154 return aces == null ? null : new AccessControlListImpl(aces); 155 } 156 157 @Override 158 public ContentStream convertContentStream(ContentStream contentStream) { 159 if (contentStream == null) { 160 return null; 161 } 162 long len = contentStream.getLength(); 163 BigInteger length = len < 0 ? null : BigInteger.valueOf(len); 164 return of.createContentStream(contentStream.getFileName(), length, contentStream.getMimeType(), 165 contentStream.getStream()); 166 } 167 168 @Override 169 public List<String> convertPolicies(List<Policy> policies) { 170 if (policies == null) { 171 return null; 172 } 173 List<String> policyIds = new ArrayList<String>(policies.size()); 174 for (Policy p : policies) { 175 policyIds.add(p.getId()); 176 } 177 return policyIds; 178 } 179 180 @Override 181 public Map<String, Property<?>> convertProperties(ObjectType objectType, Collection<SecondaryType> secondaryTypes, 182 Properties properties) { 183 throw new UnsupportedOperationException(); 184 } 185 186 @Override 187 public Properties convertProperties(Map<String, ?> properties, ObjectType type, 188 Collection<SecondaryType> secondaryTypes, Set<Updatability> updatabilityFilter) { 189 if (properties == null) { 190 return null; 191 } 192 // TODO secondaryTypes 193 // TODO updatabilityFilter 194 PropertiesImpl props = new PropertiesImpl(); 195 for (Entry<String, ?> es : properties.entrySet()) { 196 PropertyData<?> prop = convertProperty(es.getKey(), es.getValue(), type); 197 props.addProperty(prop); 198 } 199 return props; 200 } 201 202 @SuppressWarnings("unchecked") 203 protected static PropertyData<?> convertProperty(String key, Object value, ObjectType type) { 204 PropertyDefinition<?> pd = type.getPropertyDefinitions().get(key); 205 if (pd == null) { 206 throw new IllegalArgumentException("Unknown property '" + key + "' for type: " + type.getId()); 207 } 208 boolean single = pd.getCardinality() == Cardinality.SINGLE; 209 210 List<?> values; 211 if (value == null) { 212 values = null; 213 } else if (value instanceof List<?>) { 214 if (single) { 215 throw new IllegalArgumentException("Property '" + key + "' is not a multi value property!"); 216 } 217 values = (List<?>) value; 218 } else { 219 if (!single) { 220 throw new IllegalArgumentException("Property '" + key + "' is not a single value property!"); 221 } 222 values = Collections.singletonList(value); 223 } 224 Object firstValue = values == null ? null : values.get(0); 225 226 if (pd instanceof PropertyStringDefinition) { 227 return of.createPropertyStringData(key, (List<String>) values); 228 } else if (pd instanceof PropertyIdDefinition) { 229 return of.createPropertyIdData(key, (List<String>) values); 230 } else if (pd instanceof PropertyHtmlDefinition) { 231 return of.createPropertyHtmlData(key, (List<String>) values); 232 } else if (pd instanceof PropertyUriDefinition) { 233 return of.createPropertyUriData(key, (List<String>) values); 234 } else if (pd instanceof PropertyIntegerDefinition) { 235 if (firstValue == null) { 236 return of.createPropertyIntegerData(key, (List<BigInteger>) null); 237 } else if (firstValue instanceof BigInteger) { 238 return of.createPropertyIntegerData(key, (List<BigInteger>) values); 239 } else if ((firstValue instanceof Byte) || (firstValue instanceof Short) || (firstValue instanceof Integer) 240 || (firstValue instanceof Long)) { 241 List<BigInteger> list = new ArrayList<BigInteger>(values.size()); 242 for (Object v : values) { 243 list.add(BigInteger.valueOf(((Number) v).longValue())); 244 } 245 return of.createPropertyIntegerData(key, list); 246 } else { 247 throw new IllegalArgumentException("Property '" + key + "' is an Integer property"); 248 } 249 } else if (pd instanceof PropertyBooleanDefinition) { 250 return of.createPropertyBooleanData(key, (List<Boolean>) values); 251 } else if (pd instanceof PropertyDecimalDefinition) { 252 return of.createPropertyDecimalData(key, (List<BigDecimal>) values); 253 } else if (pd instanceof PropertyDateTimeDefinition) { 254 return of.createPropertyDateTimeData(key, (List<GregorianCalendar>) values); 255 } 256 throw new CmisRuntimeException("Unknown class: " + pd.getClass().getName()); 257 } 258 259 @Override 260 public List<PropertyData<?>> convertQueryProperties(Properties properties) { 261 if (properties == null || properties.getProperties() == null) { 262 return null; 263 } 264 return new ArrayList<PropertyData<?>>(properties.getPropertyList()); 265 } 266 267 @Override 268 public QueryResult convertQueryResult(ObjectData objectData) { 269 throw new UnsupportedOperationException(); 270 } 271 272 @Override 273 public Rendition convertRendition(String objectId, RenditionData rendition) { 274 if (rendition == null) { 275 return null; 276 } 277 BigInteger rl = rendition.getBigLength(); 278 BigInteger rh = rendition.getBigHeight(); 279 BigInteger rw = rendition.getBigWidth(); 280 long length = rl == null ? -1 : rl.longValue(); 281 int height = rh == null ? -1 : rh.intValue(); 282 int width = rw == null ? -1 : rw.intValue(); 283 return new RenditionImpl(session, objectId, rendition.getStreamId(), rendition.getRenditionDocumentId(), 284 rendition.getKind(), length, rendition.getMimeType(), rendition.getTitle(), height, width); 285 } 286 287 @Override 288 public ObjectType convertTypeDefinition(TypeDefinition typeDefinition) { 289 if (typeDefinition instanceof DocumentTypeDefinition) { 290 return new DocumentTypeImpl(session, (DocumentTypeDefinition) typeDefinition); 291 } else if (typeDefinition instanceof FolderTypeDefinition) { 292 return new FolderTypeImpl(session, (FolderTypeDefinition) typeDefinition); 293 } else if (typeDefinition instanceof RelationshipTypeDefinition) { 294 return new RelationshipTypeImpl(session, (RelationshipTypeDefinition) typeDefinition); 295 } else if (typeDefinition instanceof PolicyTypeDefinition) { 296 return new PolicyTypeImpl(session, (PolicyTypeDefinition) typeDefinition); 297 } 298 throw new CmisRuntimeException("Unknown base class: " + typeDefinition.getClass().getName()); 299 } 300 301 @Override 302 public ChangeEvent convertChangeEvent(ObjectData objectData) { 303 // TODO Auto-generated method stub 304 throw new UnsupportedOperationException(); 305 } 306 307 @Override 308 public ChangeEvents convertChangeEvents(String changeLogToken, ObjectList objectList) { 309 // TODO Auto-generated method stub 310 throw new UnsupportedOperationException(); 311 } 312 313}