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